diff --git a/Source/Scripts/_EQ_ItemRoulette_FormChunks.psc b/Source/Scripts/_EQ_ItemRoulette_FormChunks.psc new file mode 100644 index 0000000..76925fc --- /dev/null +++ b/Source/Scripts/_EQ_ItemRoulette_FormChunks.psc @@ -0,0 +1,100 @@ +Scriptname _EQ_ItemRoulette_FormChunks extends Form + +Form[] Property Children Auto + +Function SortByName() + ; based on "Optimized QuickSort - C Implementation" by darel rex finley (http://alienryderflex.com/quicksort/) + Int[] Beg = new Int[127] + Int[] End = new Int[127] + String[] Names = new String[127] + Int i = 0 + Int L + Int R + Int swap + Form piv + String pivName + + Beg[0] = 0 + End[0] = Children.Length + + While(i < Children.Length) + If Children[i] != None + Names[i] = Children[i].GetName() + Else + Names[i] = "" + EndIf + i += 1 + EndWhile + + i = 0 + While (i >= 0) + L = Beg[i] + R = End[i] - 1; + If (L < R) + piv = Children[L] + pivName = Names[L] + While (L < R) + While ((Names[R] >= pivName) && (L < R)) + R -= 1 + EndWhile + If (L < R) + Names[L] = Names[R] + Children[L] = Children[R] + L += 1 + EndIf + While ((Names[L] <= pivName) && (L < R)) + L += 1 + EndWhile + If (L < R) + Names[R] = Names[L] + Children[R] = Children[L] + R -= 1 + EndIf + EndWhile + Children[L] = piv + Names[L] = pivName + Beg[i + 1] = L + 1 + End[i + 1] = End[i] + End[i] = L + i += 1 + If (End[i] - Beg[i] > End[i - 1] - Beg[i - 1]) + swap = Beg[i] + Beg[i] = Beg[i - 1] + Beg[i - 1] = swap + swap = End[i] + End[i] = End[i - 1] + End[i - 1] = swap + EndIf + Else + i -= 1 + EndIf + EndWhile +EndFunction + +Function SortByNameRecursive() + SortByName() + Int childIndex = 0 + While childIndex < Children.Length + Form child = Children[childIndex] + _EQ_ItemRoulette_FormChunks subChunk = (child as _EQ_ItemRoulette_FormChunks) + If(subChunk != None) + subChunk.SortByNameRecursive() + EndIf + childIndex += 1 + EndWhile +EndFunction + +Function PrintNamesRecursive() + Int childIndex = 0 + While childIndex < Children.Length + Form child = Children[childIndex] + _EQ_ItemRoulette_FormChunks subChunk = (child as _EQ_ItemRoulette_FormChunks) + If(subChunk != None) + Debug.Trace("Chunk") + subChunk.PrintNamesRecursive() + ElseIf child != None + Debug.Trace(child.GetName()) + EndIf + childIndex += 1 + EndWhile +EndFunction \ No newline at end of file diff --git a/Source/Scripts/_EQ_ItemRoulette_Quest.psc b/Source/Scripts/_EQ_ItemRoulette_Quest.psc index 7b719c8..af5df7b 100644 --- a/Source/Scripts/_EQ_ItemRoulette_Quest.psc +++ b/Source/Scripts/_EQ_ItemRoulette_Quest.psc @@ -2,11 +2,15 @@ Scriptname _EQ_ItemRoulette_Quest extends Quest Actor Property PlayerRef Auto Static Property _EQ_ItemRoulette_Roulette Auto +Activator Property FormChunks Auto ObjectReference[] DisplayItems +Form[] SpawnedForms +Form[] UnspawnedForms ObjectReference Roulette Int MAX_ITEMS +Float UI_TRANSLATE_SPEED Float UI_DISTANCE Float UI_DEGREES Float UI_ZEES @@ -23,6 +27,7 @@ Function Main() UI_DEGREES = 14.0 UI_ZEES = 12.0 UI_ITEM_SCALE = 0.25 + UI_TRANSLATE_SPEED = 10000 DisplayItems = New ObjectReference[127] int index = 0 @@ -31,8 +36,23 @@ Function Main() index += 1 EndWhile + UnspawnedForms = New Form[127] + index = 0 + While index < MAX_ITEMS + UnspawnedForms[index] = None + index += 1 + EndWhile + + SpawnedForms = New Form[127] + index = 0 + While index < MAX_ITEMS + SpawnedForms[index] = None + index += 1 + EndWhile + Debug.Trace("Item Roulette loaded") Roulette = PlayerRef.PlaceAtMe(_EQ_ItemRoulette_Roulette) + Roulette.SetMotionType(Roulette.Motion_Keyframed) RegisterForModEvent("_EQ_ItemRoulette_Activate", "OnMyAction") VRIK.VrikAddGestureAction("_EQ_ItemRoulette_Activate", "Activate Item Roulette") RegisterForSingleUpdate(0.01) @@ -41,9 +61,26 @@ EndFunction Event OnUpdate() Float playerAngle = PlayerRef.GetAngleZ() - Roulette.TranslateTo(PlayerRef.X + UI_DISTANCE * Math.sin(playerAngle), PlayerRef.Y + UI_DISTANCE * Math.cos(playerAngle), VRIK.VrikGetHmdZ(), 0, 0, playerAngle, 1000) - Int index = 0 + While index < MAX_ITEMS + Form unspawnedForm = UnspawnedForms[index] + if unspawnedForm != None + If unspawnedForm != SpawnedForms[index] + SpawnedForms[index] = unspawnedForm + ObjectReference displayItem = Roulette.PlaceAtMe(unspawnedForm) + DisplayItems[index] = displayItem + displayItem.SetScale(UI_ITEM_SCALE) + displayItem.SetMotionType(displayItem.Motion_Keyframed) + EndIf + Else + index += 1000 + EndIf + index += 1 + EndWhile + + Roulette.TranslateTo(PlayerRef.X + UI_DISTANCE * Math.sin(playerAngle), PlayerRef.Y + UI_DISTANCE * Math.cos(playerAngle), VRIK.VrikGetHmdZ(), 0, 0, playerAngle, UI_TRANSLATE_SPEED) + + index = 0 While index < MAX_ITEMS && DisplayItems[index] != None ; T-LCR-B Float top = 0 @@ -60,7 +97,7 @@ Event OnUpdate() Else top = UI_ZEES EndIf - DisplayItems[index].MoveTo(PlayerRef, UI_DISTANCE * Math.sin(playerAngle - left), UI_DISTANCE * Math.cos(playerAngle - left), (VRIK.VrikGetHmdZ() - PlayerRef.Z) - top) + DisplayItems[index].TranslateTo(PlayerRef.X + UI_DISTANCE * Math.sin(playerAngle - left), PlayerRef.Y + UI_DISTANCE * Math.cos(playerAngle - left), VRIK.VrikGetHmdZ() - top, 0, 0, playerAngle, UI_TRANSLATE_SPEED) index += 1 EndWhile @@ -69,16 +106,45 @@ EndEvent Event OnMyAction(string eventName, string strArg, float numArg, Form sender) Debug.Trace("VRIK activated me!") + ;/ + Get list of all inventory item names, sorted alphabetically + break into groups of five + find a common label for that group + group the groups in a similar manner until there are only five? + /; Int numItems = PlayerRef.getNumItems() - Int formIndex = numItems + Debug.Trace("Found " + numItems + " items") + + _EQ_ItemRoulette_FormChunks sortChunks = ((Roulette.PlaceAtMe(FormChunks) as Form) as _EQ_ItemRoulette_FormChunks) + sortChunks.Children = new Form[127] + Int formIndex = 0 + Int chunkIndex = -1 + Int chunkItemIndex = 127 + _EQ_ItemRoulette_FormChunks chunk + While formIndex < numItems + If chunkItemIndex >= 127 + chunkItemIndex = 0 + chunkIndex += 1 + chunk = ((Roulette.PlaceAtMe(FormChunks) as Form) as _EQ_ItemRoulette_FormChunks) + chunk.Children = new Form[127] + sortChunks.Children[chunkIndex] = chunk + EndIf + chunk.Children[chunkItemIndex] = PlayerRef.GetNthForm(formIndex) + formIndex += 1 + chunkItemIndex += 1 + EndWhile + + Debug.Trace("Sorting") + sortChunks.SortByNameRecursive() + Debug.Trace("Printing") + sortChunks.PrintNamesRecursive() + Int count = 0 + formIndex = numItems While formIndex > 0 && formIndex > numItems - MAX_ITEMS formIndex -= 1 count = numItems - formIndex Form invItem = PlayerRef.GetNthForm(formIndex) - ObjectReference invItemInst = PlayerRef.DropObject(invItem) - invItemInst.SetScale(UI_ITEM_SCALE) - invItemInst.SetMotionType(invItemInst.Motion_Keyframed) - DisplayItems[count - 1] = invItemInst + UnspawnedForms[count - 1] = invItem EndWhile EndEvent \ No newline at end of file diff --git a/Source/Textures/_EQ_ItemRoulette/roulette_container.xcf b/Source/Textures/_EQ_ItemRoulette/roulette_container.xcf index 34dd0d2..db44e4c 100644 Binary files a/Source/Textures/_EQ_ItemRoulette/roulette_container.xcf and b/Source/Textures/_EQ_ItemRoulette/roulette_container.xcf differ diff --git a/plugin/Data/_EQ_ItemRoulette.esp b/plugin/Data/_EQ_ItemRoulette.esp index 821f3d4..2ba7f18 100644 Binary files a/plugin/Data/_EQ_ItemRoulette.esp and b/plugin/Data/_EQ_ItemRoulette.esp differ