|
Hello, I'm having a problem with a variable after updating an old app from Lua 5.0/IUP 2.4 to Lua 5.1/IUP 3.30. In the old version, the variable behaves the way I want, but in the updated version, it decrements by 1 and I can't figure out why. I tried checking https://www.lua.org/manual/5.1/manual.html#7 and https://www.tecgraf.puc-rio.br/iup/en/migration_guide.html for ideas about what might've changed, but couldn't find anything. I'm guessing it's probably a Lua issue, unless there's some change to iup.list that could be affecting this. I managed to create a stand-alone script that demonstrates the problem, but it's long because I'm fixing up an old app made by someone more experienced than I, so there's a lot of complicated-looking nested arrays that made it difficult to come up with something simpler. How to trigger the problem: Run the script and for Offensive Power Type, select #3 ("Ranged"). Then, change Character Class to "Mage". Some message boxes with info about the variables will pop up during an update function. What I want to happen is despite the change in Class updating the Power Types available in box #2, the box #2 selection should remain on item #3, although the item's text will change. That's how it works when I test it with Lua 5.0 and IUP 2.4. What happens since the update is during the update function, when 'i' gets to iteration #3, the Power Types listbox value decrements to 2 and shows "Cast Spell", while the "Available Powers" list is populated by the powers associated with the correct value, #3 ("Summon"). If you select Power Type #2 and then change Class, the same decrementing variable problem occurs, but happens at iteration #2, which is also when one of the strings I'm watching via iup.Message updates to a new value. I wrote some comments in the script with more details.
Does anyone know what might be causing this? Lua script: ----------------------------------------------------------------- require'iuplua' local profile = ""> profile.__index = profile local t = {} t.className = "Warrior" --name of character class initially displayed in listbox #1 t.classNum = 1 --# corresponding to character class initially displayed in listbox #1 t.offensePowerType = 1 --# corresponding to the offensive power category initially displayed in listbox #2 setmetatable(t,profile) --in actual app, a Profile saves settings that can be loaded later local dlg = {} local powersBox = iup.list{size = "80x100"} --displays available powers based on choices made from listboxes -- POWER TABLES ----------------------------------------------------------- local offensePowTypeTable = { --These are displayed in listbox #2 and change depending on what character class is selected in listbox #1. --I'm not sure why there's a separate table for this. Maybe to use ipairs instead of pairs? --Warrior > Offense > {"Brawl","Melee","Ranged"}, --Mage > Offense > {"Use Potion","Cast Spell","Summon"} } local powersTable = { ["Warrior"] = { ["Offense"] = { ["Brawl"] = { [1] = "Punch", [2] = "Kick" }, ["Melee"] = { [1] = "Swing Mace", [2] = "Swing Sword" }, ["Ranged"] = { [1] = "Shoot Bow", [2] = "Throw Shuriken" } } --["Defense"] = {} --table shortened for brevity }, ["Mage"] = { ["Offense"] = { ["Use Potion"] = { [1] = "Heal", [2] = "Boost Power" }, ["Cast Spell"] = { [1] = "Shoot Fireball", [2] = "Shoot Lightning Chain" }, ["Summon"] = { [1] = "Not the Bees!", [2] = "Call Demons" } } --["Defense"] = {} } } -- LIST CREATION/CONTROL FUNCTIONS ------------------------------------------------- local function makeListbox(label,list,val,callback) --creates a dropdown list with label and callback local ttable = {} for i = 1,#list do ttable[i] = list[i] end ttable.dropdown = "YES" ttable.value = val --what index should be selected(shown) in dropdown local tlist = iup.list(ttable) tlist.size = "100x" tlist.action = ""> return iup.hbox{iup.label{title = label}, tlist}, tlist --function will return 2 results end local function updateListbox(listbox,newtable,inspect,getVal) for i,v in ipairs(newtable) do listbox[i] = v --copies the list from newtable to listbox if inspect then --my makeshift debug method. I don't know much about debuggers. iup.Message("t.offensePowerType #"..t.offensePowerType.." "..getVal[t.offensePowerType], "Iteration #"..i..":".. "\ntOffListbox["..i.."] == "..v.. "\ntOffListbox.value (selected): #"..getVal.value.." "..getVal[getVal.value]) -- I want 't.offensePowerType' and 'tOffListbox.value' to match so the selection stays in the same position --regardless of the items in the list changing. When the mesg box shows that 'i' and 'tOffListbox.value' are about to equal --each other, the number of 'tOffListbox.value' decrements by 1. That's also the moment that the value of --'tOffListbox[t.offensePowerType]' swaps to the other character class's equivalent power type. end end end local function reloadPowListbox(t) --when user selects new class in listbox #1, change the list of power types in listbox #2 local powersList = {"Run","Jump"} --starts by adding basic abilities all classes have for i,v in ipairs(powersTable[t.className]["Offense"][offensePowTypeTable[t.classNum][t.offensePowerType]]) do
--ex. powersTable > Warrior > Offense >? offensePowTypeTable > array 1: Warrior > index 1: Melee > iterate over warrior's offensive melee powers --How is it possible to use ipairs on 2 tables like that? I don't understand the syntax.
table.insert(powersList,v) end t.powersList = powersList end -- CREATE AND PLACE ITEMS ------------------------------------------------------------ local tOff, tOffListbox = makeListbox("Offensive Power Types: ",offensePowTypeTable[t.classNum],t.offensePowerType, function(_,str,i,v) t.modified = true if v == 1 then t.offensePowerType = i reloadPowListbox(t) updateListbox(powersBox,t.powersList) end end) --I don't know why 2 variables are being used. tOff is the label, hbox, listbox. tOffListbox is just the listbox. --Can the listbox not be changed if enclosed in the hbox? --Do tOffListbox and tOff refer to the same listbox or are there 2 identical copies of a listbox? local tClassBox = makeListbox("Choose Character Class: ",{"Warrior","Mage"},t.classNum, function(_,str,i,v) t.modified = true if v == 1 then --clicked on an item in list t.className = str --stores the currently selected class name t.classNum = i --is updated to hold current index number updateListbox(tOffListbox,offensePowTypeTable[i],"inspect",tOffListbox) reloadPowListbox(t) updateListbox(powersBox,t.powersList) --update available powers box end end ) table.insert(dlg,tClassBox) table.insert(dlg,tOff) reloadPowListbox(t) updateListbox(powersBox,t.powersList) local dialog = iup.dialog{title = "a dialog", iup.hbox{ iup.vbox(dlg), iup.vbox{iup.label{title = "Available Powers:"}, powersBox}; cgap = "5x5", ncmargin = "10x10" }} dialog:show() if (iup.MainLoopLevel()==0) then iup.MainLoop() dialog:destroy() iup.Close() end |