Page 1 of 1

Converting lists to tables in lua

Posted: Tue Apr 07, 2015 12:10 am
by Noobasaurus
I was told that since I have some lovely lists of if/then statements that I should post them here and get help on how to make them into an organized table. Here's one of my lists:
Hidden/Spoiler:
[code]
function resourceUpdater()
print("resourceUpdater")
wood = Curwood + wood
Curwood = 0
stone = Curstone + stone
Curstone = 0
SetTeamPoints(1, Curwood)
SetTeamPoints(2, wood)
if wood >= 450 and wood < 500 then
RespawnObject("logs")
KillObject("logs1")
KillObject("logs2")
KillObject("log1")
KillObject("log3")
KillObject("log4")
KillObject("log5")
KillObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end
if wood >= 900 and wood < 950 then
RespawnObject("logs1")
KillObject("logs2")
KillObject("log1")
KillObject("log3")
KillObject("log4")
KillObject("log5")
KillObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end

if wood >= 1350 then
RespawnObject("logs2")
end
if wood < 450 then
KillObject("logs")
KillObject("logs1")
KillObject("logs2")
end
if wood >= 50 and wood < 100 or wood >= 500 and wood < 150 or wood >= 950 and wood < 1000 or wood >= 1400 and wood < 1450 then
RespawnObject("log1")
KillObject("log3")
KillObject("log4")
KillObject("log5")
KillObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end
if wood >= 100 and wood < 150 or wood >= 550 and wood < 600 or wood >= 1000 and wood < 1050 or wood >= 1450 and wood < 1500 then
RespawnObject("log1")
RespawnObject("log3")
KillObject("log4")
KillObject("log5")
KillObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end
if wood >= 150 and wood < 200 or wood >= 600 and wood < 650 or wood >= 1050 and wood < 1100 or wood >= 1500 and wood < 1550 then
RespawnObject("log1")
RespawnObject("log3")
RespawnObject("log4")
KillObject("log5")
KillObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end
if wood >= 200 and wood < 250 or wood >= 650 and wood < 700 or wood >= 1100 and wood < 1150 or wood >= 1550 and wood < 1600 then
RespawnObject("log1")
RespawnObject("log3")
RespawnObject("log4")
RespawnObject("log5")
KillObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end
if wood >= 250 and wood < 300 or wood >= 700 and wood < 750 or wood >= 1150 and wood < 1200 or wood >= 1600 and wood < 1650 then
RespawnObject("log1")
RespawnObject("log3")
RespawnObject("log4")
RespawnObject("log5")
RespawnObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end
if wood >= 300 and wood < 350 or wood >= 750 and wood < 800 or wood >= 1200 and wood < 1250 or wood >= 1650 and wood < 1700 then
RespawnObject("log1")
RespawnObject("log3")
RespawnObject("log4")
RespawnObject("log5")
RespawnObject("log6")
RespawnObject("log7")
KillObject("log8")
KillObject("log9")
end
if wood >= 350 and wood < 400 or wood >= 800 and wood < 850 or wood >= 1250 and wood < 1300 or wood >= 1700 and wood < 1750 then
RespawnObject("log1")
RespawnObject("log3")
RespawnObject("log4")
RespawnObject("log5")
RespawnObject("log6")
RespawnObject("log7")
RespawnObject("log8")
KillObject("log9")
end
if wood >= 400 and wood < 450 or wood >= 850 and wood < 900 or wood >= 1300 and wood < 1350 or wood >= 1750 then
RespawnObject("log1")
RespawnObject("log3")
RespawnObject("log4")
RespawnObject("log5")
RespawnObject("log6")
RespawnObject("log7")
RespawnObject("log8")
RespawnObject("log9")
end
end
[/code]
As usual, help with doing this is much appreciated.

Re: Converting lists to tables in lua

Posted: Tue Apr 07, 2015 12:27 am
by razac920
Well I'm having trouble following the logic behind how the amount of wood you have affects which logs respawn, so maybe you can clarify that for me?
One simplification I can think of is to use for loops and concatenation of strings, to convert

Code: Select all

      KillObject("log1")
      KillObject("log3")
      KillObject("log4")
      KillObject("log5")
      KillObject("log6")
      KillObject("log7")
      KillObject("log8")
      KillObject("log9")
to something like:

Code: Select all

for i=1,9 do
  if i == 2 then
    i = i + 1
  end
  KillObject("log"..tostring(i))
end

Re: Converting lists to tables in lua

Posted: Tue Apr 07, 2015 12:34 am
by Noobasaurus
Hm, okay. Each 50 wood means one tree, so it will place a log in your base. At 9 logs, it takes away all the logs on the ground and creates a logholder with 9 logs. It does the same at 18 and 27, and then stops there.

Perhaps a slightly better list to make into a table would be this:
Hidden/Spoiler:
[code]
if ccClass == 0 and hammerLevel == 1 and swordLevel == 0 then
SelectCharacterClass(ccPlayerC, "snw_inf_player6") --pick their new class
ccClass = 1
elseif ccClass == 0 and hammerLevel == 2 and swordLevel == 0 then
SelectCharacterClass(ccPlayerC, "snw_inf_player6") --pick their new class
ccClass = 1
elseif ccClass == 0 and hammerLevel == 1 and swordLevel == 1 then
SelectCharacterClass(ccPlayerC, "snw_inf_player8") --pick their new class
ccClass = 1
elseif ccClass == 0 and hammerLevel == 1 and swordLevel == 2 then
SelectCharacterClass(ccPlayerC, "snw_inf_player9") --pick their new class
ccClass = 1
elseif ccClass == 0 and hammerLevel == 0 and swordLevel == 1 then
SelectCharacterClass(ccPlayerC, "snw_inf_player4") --pick their new class
ccClass = 1
elseif ccClass == 1 and axeLevel == 1 then
SelectCharacterClass(ccPlayerC, "snw_inf_player3") --pick their new class
ccClass = 0
elseif ccClass == 1 and axeLevel == 0 then
SelectCharacterClass(ccPlayerC, "snw_inf_player2") --pick their new class
ccClass = 0
end[/code]
Now, really, it isn't that long, but if there's a better alternative I'm always open.

Re: Converting lists to tables in lua

Posted: Tue Apr 07, 2015 12:50 am
by razac920
Seems like the only two values you are interested in are wood / 450 and wood % 450.
You could do something like this, if logs is a list of your "logholder" objects and log is a list of your log objects

Code: Select all

logscount = wood / 450 //integer division
logcount = wood % 450 //modulus = remainder
for i=1,logscount do
  RespawnObject(logs[i])
end
for i=(logscount+1),[maxlogs#] do
  KillObject(logs[i])
end
for i=1,logcount do
  RespawnObject(log[i])
end
for i=(logcount+1),[maxlog#=8] do
  KillObject(log[i])
end
Edit: As for your other block of code, ehh I can't come up with a clear pattern for how the different weapon levels determine the class name (the numbers at the end seem arbitrary). Of course, you could always just rename your classes to be "snw_inf_playerabcd", where a = ccClass, b = hammerLevel, c = swordLevel, and d = axeLevel. Then you could simplify down to

Code: Select all

SelectCharacterClass(ccPlayerC,"snw_inf_player"..tostring(ccClass)..tostring(hammerLevel)..tostring(swordLevel)..tostring(axeLevel))
ccClass = 1 - ccClass
Or you could make a 4D array(or 4D lua table equivalent) of classnames given those 4 inputs.

Re: Converting lists to tables in lua

Posted: Tue Apr 07, 2015 12:40 pm
by Noobasaurus
I tried out some of your code, fiddled around with it for a bit, but then decided that it was a little bit too complex for what I'm doing right now. Really, now that I look at it, the code before wasn't that bad and perhaps it was a slightly too conditional to condense without a bunch of extra work. So thank you for the help anyway. :)

Re: Converting lists to tables in lua

Posted: Tue Apr 07, 2015 2:04 pm
by jedimoose32
Slightly off-topic: razac, I see you keep using tostring when you concatenate... I've never needed to do that. For instance, this format has never given me any trouble:

Code: Select all

SelectCharacterClass(ccPlayerC, "snw_inf_player" .. ccClass .. hammerLevel .. swordLevel .. axeLevel)
Is there any particular reason for using tostring?
Lua 5.1 Reference Manual wrote: Lua provides automatic conversions between numbers and strings at run time ... Lua applies such coercions not only in arithmetic operators, but also in other places that expect a number. Conversely, whenever it finds a number where it expects a string, Lua converts the number to a string

Re: Converting lists to tables in lua

Posted: Wed Apr 08, 2015 11:19 pm
by [RDH]Zerted
For the wood, those are all if statements instead of if/elseif and some of them overlap, meaning a few of those blocks are run at the same time, so there's no simple way to reduce that without also changing your logic. However you can make it easier to read. Example:
Hidden/Spoiler:
[code]function between(item, low, high)
return (item >= low) and (item < high)
end

--did you notice you have the 500 and 150 backwards. Was that on purpose?
if between(w, 50,100) or between(w, 500,150) or between(w, 950,1000) or between(w, 1400,1450) then
RespawnObject("log1")
KillObject("log3")
KillObject("log4")
KillObject("log5")
KillObject("log6")
KillObject("log7")
KillObject("log8")
KillObject("log9")
end[/code]
You can make a helper functions for RespawnObject and KillObject too. Example of what that could look like:
Hidden/Spoiler:
[code]function RespawnObjects(obj, ...)
for i=1,table.getn(arg) do
RespawnObject(obj .. arg)
end
end
function KillObjects(obj, ...)
for i=1,table.getn(arg) do
KillObject(obj .. arg)
end
end

if between(w, 50,100) or between(w, 500,150) or between(w, 950,1000) or between(w, 1400,1450) then
RespawnObjects("log", 1)
KillObjects("log", 3, 4, 5, 6, 7, 8, 9)
end[/code]
But sometimes it's easier to temporary comment out a KillObject() line than temporary remove one function parameter. It all depends.


About the second code post. For if statements structured like that you'd want to create a lookup table/matrix. Example:

Code: Select all

hammerSwordLevels = {{{}, {}}, {{}, {}}}
hammerSwordLevels[0][1][0] = "snw_inf_player6"
hammerSwordLevels[0][2][0] = "snw_inf_player6"
hammerSwordLevels[0][1][1] = "snw_inf_player8"
--etc...

local nextClass = hammerSwordLevels[ccClass+1][hammerLevel+1][swordLevel+1]
SelectCharacterClass(ccPlayerC, nextClass)
ccClass = 1 - ccClass

Re: Converting lists to tables in lua

Posted: Sat Apr 11, 2015 8:34 pm
by Noobasaurus
Okay, this time I've got a real list. I tried making a loop based on the code others posted, but I really had no clue what I was doing. Here's what my list looks like.
Hidden/Spoiler:
[code]
if GetEntityName(object) == "com_item_hero_healthrecharge" then
classTo = "prh_inf_healthdroid"
print("hpdroid")
changeClass()
elseif GetEntityName(object) == "com_item_hero_healthrecharge1" then
classTo = "prh_inf_healthdroid"
print("hpdroid")
changeClass()
elseif GetEntityName(object) == "com_item_hero_healthrecharge2" then
classTo = "prh_inf_healthdroid"
print("hpdroid")
changeClass()
elseif GetEntityName(object) == "com_item_hero_healthrecharge3" then
classTo = "prh_inf_healthdroid"
print("hpdroid")
changeClass()
elseif GetEntityName(object) == "com_item_hero_healthrecharge4" then
classTo = "prh_inf_healthdroid"
print("hpdroid")
changeClass()
elseif GetEntityName(object) == "com_item_hero_healthrecharge5" then
classTo = "prh_inf_healthdroid"
print("hpdroid")
changeClass()
end[/code]
It's all the same except for the numbers at the very end.

Re: Converting lists to tables in lua

Posted: Sat Apr 11, 2015 9:09 pm
by razac920

Code: Select all

    objects = {"com_item_hero_healthrecharge","com_item_hero_healthrecharge1",...}
    objectslength = 6
    for i=1,6 do
      if GetEntityName(object) == objects[i] then
        classTo = "prh_inf_healthdroid"
        print("hpdroid")
        changeClass()
      end
    end
Ask question if any of the format/logic is unclear.

Re: Converting lists to tables in lua

Posted: Sat Apr 11, 2015 9:20 pm
by Noobasaurus
Is objectslength just there for reference? I don't see it being used anywhere. And I'm starting to understand lists now. It's saying "get all the whole numbers between 1 and 6, and then get all of the list values for these i values, and if it matches then blah blah." Thank you.

Re: Converting lists to tables in lua

Posted: Sat Apr 11, 2015 9:29 pm
by razac920
Oops my bad, yeah I meant to write:
for i=1,objectslength do

That way the code can easily be generalized/modified, since you only need to define objectslength once (but you might have multiple places in the code where you call it).

And yep, that's exactly the logic behind for-loops.

Edit: Suppose instead of just 6 objects you had a much longer list, say 200, and you didn't want to define that list explicitly (missing 1 comma would be hard to track).
You could define it like so:

Code: Select all

    objects = {}
    for i=1,200 do
      objects[i] = "com_item_hero_healthrecharge"..i // or "com_item_herorecharge"..tostring(i)
    end

Re: Converting lists to tables in lua

Posted: Sat Apr 11, 2015 9:43 pm
by Noobasaurus
Ah, yes, that second one is much better. It's a lot easier to edit the amount of objects than before. Thanks!

Re: Converting lists to tables in lua

Posted: Sat Apr 11, 2015 10:54 pm
by [RDH]Zerted
Loops for checking something are slow. Avoid them if possible, but at the very least stop looping when you find the result you're looking for. Since you do the same thing in every case, you could have used a bunch of "or"s to reduce all that to a single if statement. Here's how to avoid the loop by using a lookup table:

Code: Select all

local names = {
   com_item_hero_healthrecharge1 = true,
   com_item_hero_healthrecharge2 = true,
   com_item_hero_healthrecharge3 = true,
   com_item_hero_healthrecharge4 = true,
   com_item_hero_healthrecharge5 = true,
}
if names[GetEntityName(object) or ""] then 
   classTo = "prh_inf_healthdroid"
   print("hpdroid")
   changeClass()
end
The or "" is there because I don't think table[nil] works and I don't know if GetEntityName ever returns nil or not. If whatever GetEntityName returns is ever a false value, that code would then cause the check to be: names[""]