Tables within tables and priorities for triggers

Posted by ReallyCurious on Fri 21 Dec 2007 06:02 PM — 14 posts, 50,985 views.

USA #0
What I'm trying to do is update the script I am using for pvp on the mud that I play. Right now, the way I do it is I have all "enemy" names in 1 table and if a person listed in this table flies in/arrives/is standing here etc, pk script will fire. That's worked well so far but now I want to make it more manageable with character classes. I want to know if I can create tables within this original table and still have priorities work, which in lua depends on which value is first in the table.

For example:

Right now what I use is:

enemy_list = {"Shaun","Nick","ReallyCurious","Onoitsu"}

What I am trying to do:

enemy_list = {}
enemy_list.warriors = {"Nick","ReallyCurious","Onoitsu"}
enemy_list.necromancers = {"Shaun"}
etc

This way it'd be easier to maintain and update and also, I want to use this same table as a better who_list analyzer which tells to our guild channel all enemy characters and their class when I type who.
Australia Forum Administrator #1
A bit depends on what order you want things in. Do you want the "main" order to be player names, or classes (eg. all warriors before all mages)?

Another approach would be to have one main table but have the class as part of the entry, eg.



enemy_list = {
  Shaun = "necromancer",
  Nick = "warrior",
  ReallyCurious = "warrior",
  Onoitsu = "warrior",
   }


That way, you check if someone is in the table, and find what class they are, in one action. Or you could keep it ordered like this:




enemy_list = {
  { Shaun = "necromancer" },
  { Nick = "warrior" },
  { ReallyCurious = "warrior" },
  { Onoitsu = "warrior" },
   }


Now the table is still in numeric sequence, and each entry is another table, and inside that table you have a single item which is the player name and class. Or you could do it differently again:


enemy_list = {
{ name = "Shaun", class = "necromancer" },
{ name = "Nick", class = "warrior" },
{ name = "ReallyCurious", class = "warrior" },
{ name = "Onoitsu", class = "warrior", },
}


Now the subtable has two entries, the "name" entry which is the player name, and the "class" entry which is the player class.
USA #2
Ok, first off, how did I suddenly become an enemy, and the only necromancer to boot? Don't you people like me at all?

For what it sounds like you are doing, the second option Nick listed sounds like a better idea, that way you can replace the name with "name(class)" as a sub with "name(..enemy_list[name]..")" or so. If you are looking for something that would be really easy to maintian as a list, you could just generate the list like so:

enemy_init = {}
enemy_init.warrior = {"Nick","ReallyCurious","Onoitsu"}
enemy_init.necromancer = {"Shaun"}

enemy_list = {}
for k,v in pairs( enemy_init ) do
  for _,i in pairs( v ) do
    enemy_list[i] = k
  end
end
Amended on Thu 27 Dec 2007 04:54 PM by Shaun Biggs
USA #3
I set up the table like this:

In my script file goes -

enemy_list = {}
enemy_list.warrior = {"nick","shaun","steve"}
enemy_list.necromancer = {"onoitsu","reallycurious"}

---
Now I hit an alias which does:
who_check = {}
Enables 2 triggers
sends a 'who' command to the mud to get the players online.

The first trigger captures all names and adds them to who_check table - who_check.%name = true.

The second trigger fires on the end of the who list, and that contains:

enemy_check = {}
SetVariable("Enemy_Online","")

for k,v in pairs( enemy_list ) do
for _,i in pairs( v ) do
enemy_check[i] = k
end
end

for k,v in pairs( enemy_check ) do
if who_check [k] then
SetVariable("Enemy_Online", GetVariable("Enemy_Online") .. " " .. k .. "(" .. v .. ")")
table.insert (enemy_count, 1, k)
end
end

And then disables these 2 triggers.

I put those names into enemey_count table so I can see the # of enemy on by getting the # of keys in the table.

This gives me a nice way of seeing all enemy names with their class now by using one alias.

But now I can't figure out how to get this alias which adds highlights to work.

DeleteTriggerGroup("Highlights Enemy")
for i,v in ipairs(enemy_list) do
require "addxml"
addxml.trigger { match = v,
regexp = true,
['repeat'] = true, -- repeat is lua kw
send = "",
sequence = 100,
name = v,
enabled = true,
custom_colour = 8,
keep_evaluating = true,
group = "Highlights Enemy",
}
end
ColourNote("white", "red", "Enemy highlights updated")

This is what I used with the previous table in the script file:

enemy_list = {"nick","shaun","reallycurious"}

I'm not sure how to get this to work now.
USA #4
And also the pk script I used doesn't work anymore as well.

Previously with the other table of enemy names

enemy_list = {"nick","shaun","reallycurious"}

I would use this alias, "pk enemy *"


pk_list = enemy_list
EnableTriggerGroup("Pk_Test", true)
SetVariable("attack", "%1")
ColourNote("white", "black", "PK List:  Set to -- Enemy -- ATTACK: %1")


--

"Pk_Test" triggers would capture when people are in the room or entering the room and if one is in pk_list, to fire:


pk_check = {} -- create table or erase previous values
     for i,v in ipairs(pk_list) do
  if v == ("%<check>") then 
  EnableTriggerGroup("pk_checks", true)
EnableTriggerGroup("Pk_Test", false)

pk_check.%<check> = true
 end
end


"pk_checks" Group will then take all the following people entering or leaving the room and add them to pk_check table
pk_check.%<check>. And on prompt line would fire this:


EnableTrigger("pk_check_start1", false)  -- the names of "pk_checks" 3 triggers
EnableTrigger("pk_check_start2", false)
EnableTrigger("pk_check_stop", false)

for i,v in ipairs(pk_list) do
  if pk_check [v] then
    print("PK:  Target set on: " .. v)
   SetVariable("target", v)
  Send(GetVariable("attack").. " " .. v)
  break
 end -- if
end -- for


So this would fire on the first name in my enemy_list table which gives me a way of setting priorities. I'm not sure how to do this with the new table which has character classes in it.

That's the end of my very long post. Looking forward to the responses.
Amended on Thu 10 Jul 2008 06:24 AM by Nick Gammon
Australia Forum Administrator #5
Quote:

But now I can't figure out how to get this alias which adds highlights to work.



I ran your script:


enemy_list = {"nick","shaun","reallycurious"}

DeleteTriggerGroup("Highlights Enemy")
require "addxml"

for i,v in ipairs(enemy_list) do

  addxml.trigger { 
      match = v, 
      regexp = true,
      ['repeat'] = true, -- repeat is lua kw
      send = "", 
      sequence = 100,
      name = v,
      enabled = true,
      custom_colour = 8,
      keep_evaluating = true,
      group = "Highlights Enemy",
      }
  end
  
ColourNote("white", "red", "Enemy highlights updated")


And it added three triggers, see below, so what is the problem exactly?


<triggers>
  <trigger
   custom_colour="8"
   enabled="y"
   group="Highlights Enemy"
   keep_evaluating="y"
   match="shaun"
   name="shaun"
   regexp="y"
   repeat="y"
   sequence="100"
  >
  </trigger>
  <trigger
   custom_colour="8"
   enabled="y"
   group="Highlights Enemy"
   keep_evaluating="y"
   match="reallycurious"
   name="reallycurious"
   regexp="y"
   repeat="y"
   sequence="100"
  >
  </trigger>
  <trigger
   custom_colour="8"
   enabled="y"
   group="Highlights Enemy"
   keep_evaluating="y"
   match="nick"
   name="nick"
   regexp="y"
   repeat="y"
   sequence="100"
  >
  </trigger>
</triggers>


Australia Forum Administrator #6
I find this sort of stuff almost impossible to read:


pk_check = {} -- create table or erase previous values
     for i,v in ipairs(pk_list) do
  if v == ("%<check>") then 
  EnableTriggerGroup("pk_checks", true)
EnableTriggerGroup("Pk_Test", false)

pk_check.%<check> = true
 end
end


It would help very much to get into the habit of indenting, so it is obvious what is part of the if, what is part of the for, and so on, like this:


pk_check = {} -- create table or erase previous values

for i,v in ipairs(pk_list) do
  if v == ("%<check>") then 
    EnableTriggerGroup("pk_checks", true)
    EnableTriggerGroup("Pk_Test", false)
    pk_check.%<check> = true
  end  -- if
end  -- for


Amended on Thu 10 Jul 2008 06:27 AM by Nick Gammon
Australia Forum Administrator #7
Anyway, on to the question, assuming you have a list like this:


enemy_list = {
  { name = "Shaun", class = "necromancer" },
  { name = "Nick", class = "warrior" },
  { name = "ReallyCurious", class = "warrior" },
  { name = "Onoitsu", class = "warrior", },
}  -- end enemy_list


Instead of simply checking for a name, you look for the name field in the subtable, like this:


for i,v in ipairs(enemy_list) do
  if v.name == "%<check>" then 
    EnableTriggerGroup("pk_checks", true)
    EnableTriggerGroup("Pk_Test", false)
    pk_check.%<check> = true
  end  -- if
end  -- for


USA #8

Thanks, and sorry for the sloppiness.  I've changed the table around and I think I've got almost everything I wanted.

enemy_list = {
  {warrior = {"Nick","Shaun"}},
  {druid = {"Tom","Steve"}},
}

For the highlights alias it's just adding a few more lines:

DeleteTriggerGroup("Enemy Highlights")

for i,v in ipairs( enemy_list ) do
  for i,v in pairs ( v ) do
    for i,v in ipairs ( v ) do
      require "addxml"
      addxml.trigger { match = v, 
                  regexp = true,
                  ['repeat'] = true, -- repeat is lua kw
                  send = "", 
                  sequence = 100,
                  name = v,
                  enabled = true,
                  custom_colour = 8,
                  keep_evaluating = true,
                  group = "Highlights Test",
                     }
    end  -- for
  end  -- for
end  -- for
ColourNote("white", "red", "enemy highlights updated")

--

This is also the same way I iterate through the table to get the names for the PKscript and it is working well as far as I can see from the testing I've done.

--

However, I'm stuck on this thing:

enemy_list = {
  {warrior = {"Nick","Shaun"}},
  {druid = {"Tom","Steve"}},
}

who_check = {}
who_check.Tom = true
who_check.Burgandy = true

for i,v in ipairs( enemy_list ) do
  for i,v in pairs ( v ) do
    for i,v in ipairs ( v ) do
      if who_check [v] then
        print ( v )
      end
    end
  end
end

This will return Tom, and I'm trying to get the class of Tom here as well so that it returns Tom(druid), for example.  Can I do this here?

*edit* also this isn't how i typed this post with everything starting at the margin.  not sure why it's like that

Amended on Sat 12 Jul 2008 09:58 AM by ReallyCurious
Australia Forum Administrator #9
When you make a post there is a link "What are forum codes?":

http://www.gammon.com.au/forum/bbforumcode.php


Hint: You want the [code] tag.
Amended on Sat 12 Jul 2008 07:55 AM by Nick Gammon
USA #10

Okay, got that
USA #11
Please, if you could answer my last question Nick.
Australia Forum Administrator #12
I usually put print statements in to see what is happening.

In your case you have made things very hard for yourself by having 3 nested loops, all of which are indexed by i and v. In other words, each "v" is going to shadow the earlier one, so you can't see what it is.

Either give things meaningful names, or use an underscore to show you don't care what the name is, like this:


for _, enemy in ipairs( enemy_list ) do   -- for each class in the list
  for class, names in pairs ( enemy ) do  -- extract class and list of names
    for _, who in ipairs ( names ) do  -- for each name in the list of names
      if who_check [who] then   -- see if this one matches
        print ( who, class )   -- return name and class
      end  -- if
    end  -- for each name
  end  -- for each class
end  -- for enemy list


My code printed:


Tom druid


USA #13
thanks. never knew i could break up tables like that.