Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ General ➜ Consistency checks between game lists and groups of triggers

Consistency checks between game lists and groups of triggers

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Daniel P   USA  (97 posts)  Bio
Date Sun 30 May 2010 05:57 AM (UTC)

Amended on Sun 30 May 2010 05:58 AM (UTC) by Daniel P

Message
Here's my scenario: I have a HUGE group of triggers to color individual names of people..probably 500 or so (Achaea - House enemies are red, for those of you who care).

However, I'm pretty much doing manual additions and deletions as these characters' statuses change. What I'm wanting to know is, is there a way to set up some sort of alias that will search a trigger's match and run a command on it as a variable of some sort?

My suspicions are that I have too many triggers for the amount of enemies the org has, and am confused when I run across one who is acting chummy with the org or its affiliations. And then I check the org's enemy list, matching that name and they're not in there. I'd hate to manually check every single trigger I have and remove the ones that are no longer in the org's official list.

So in other words, I want to write a script that will pull all the -match- values of the triggers of an Enemies trigger group into an array or table or whatever, and then check each with the game's enemies list, and probably following those which don't match with a Note("Not an Enemy"). Or for even MORE fun, automatically delete the trigger from the list.

Or maybe just write the name to a blank Notepad window.

Or maybe I should be storing my "offline" enemies list in some easier, more robust manner. I absolutely do NOT want to regexp every name in a single trigger: match = (name1|name2|...|name500). That would be..bad.

Ideas?

-Daniel
Top

Posted by Nick Gammon   Australia  (23,057 posts)  Bio   Forum Administrator
Date Reply #1 on Sun 30 May 2010 07:07 AM (UTC)
Message
You only want the names in one place, so a Lua table is a logical place. Once in a table, and you have a match, a simple table lookup will confirm whether or not it is in it.

The table could also generate the regexp, if you want (just concatenate the names with a "|" between them).

A simple bit of code could be used to add to, or remove from, the table (and then just serialize the table to disk for next time).

I seem to recall something similar was done a while ago.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Daniel P   USA  (97 posts)  Bio
Date Reply #2 on Mon 31 May 2010 04:37 PM (UTC)

Amended on Mon 31 May 2010 05:04 PM (UTC) by Daniel P

Message
I really don't like tables. I mean, I understand how they work and how to write them in, but they still confuse the heck out of me. But I bet they're great with memory conservation.

But instead I came up with a fairly workable solution using trigger manipulation..

Have a counter variable that will name triggers as they are added:
ADD ENEMY *

AddTrigger("enemy"..GetVariable("enemynum"),"%1","",41,custom_colour.Custom7,0,"","",100,0)
SetTriggerOption("enemy"..GetVariable("enemynum"),"repeat","1")
SetTriggerOption("enemy"..GetVariable("enemynum"),group","house enemies")
SetVariable("enemynum",(tonumber(GetVariable("enemynum"))+1))


Then I have a delete script which will simply delete the trigger, but the enemynum variable will stay the same and keep incrementing.

As for the actual checker, I have a basic idea, but it needs error handling:
Alias: HOUSE ENEMY CHECK

EnableTrigger("hechecker",true)
SetVariable("v_hecheck","1")
if (tonumber(IsTrigger("enemy"..GetVariable("v_hecheck"))) == 0 then
   Send("house enemies "..GetTriggerInfo("enemy"..GetVariable("v_hecheck"),1))
else
   SetVariable("v_hecheck",(tonumber(GetVariable("v_hecheck)))+1)
end -- if


The HOUSE ENEMIES * command returns the matched enemies and a line that can be triggered with:

Trigger (name = "hechecker"): Total: *.

if tonumber("%1") == 0 then
  Note("%1 is not an enemy")
  --AppendToNotepad("\n%1")
  --DeleteTrigger("enemy"..GetVariable("v_hecheck"))
end -- if

SetVariable("v_hecheck",(tonumber(GetVariable("v_hecheck"))  +1))

if tonumber(GetVariable("v_hecheck")) >= tonumber(GetVariable("enemynum")) then
  Note("Enemy Checking Finished")
  SetVariable("v_hecheck",1)
  EnableTrigger("hechecker",false)
else
  if (tonumber(IsTrigger("enemy"..GetVariable("v_hecheck"))) == 0 then
    Send("house enemies "..GetTriggerInfo("enemy"..GetVariables("v_hecheck"),1))
  else
    Note("Trigger enemy"..GetVariables("v_hecheck").." has been previously removed."
  end -- if trigger exists
end -- if


I haven't actually tested any of this, but if I'm not mistaken, I'm missing a while loop somewhere. If the trigger does not exist, the script will simply break at that point, even though I want it to move on to the next iteration.

I'm going to have to give this a bit more thought...or just buckle down and learn tables, which I don't relish the thought of.
Top

Posted by Nick Gammon   Australia  (23,057 posts)  Bio   Forum Administrator
Date Reply #3 on Mon 31 May 2010 10:10 PM (UTC)
Message
Daniel Powell said:

I really don't like tables. I mean, I understand how they work and how to write them in, but they still confuse the heck out of me. But I bet they're great with memory conservation.


They aren't great for conserving memory, they are just great for handling lists of things (like enemies). This is an ideal place to use them. Instead of all that confusing stuff, you can add, delete, load, save enemies in a few lines of code. Here is an example:


-- Initial table of enemies
enemies = {
  Grelinwan = true,
  Hairadric = true,
  Sardo = true,
  Grolith = true,
  Crilili = true,

-- more here

  }  -- end enemies table


-- add an enemy

enemies ["Hilis"] = true


-- delete an enemy from table

enemies ["Grolith"] = nil


-- function to check if someone is an enemy

function enemy_check (someone)
  if enemies [someone] then
    print (someone, "is an enemy")
  else
    print (someone, "is NOT an enemy")
  end -- if
end -- function

-- check if enemy

print (enemy_check ("Nick"))  --> Nick is NOT an enemy
print (enemy_check ("Grelinwan"))  --> Grelinwan is an enemy


-- print all enemies

for k in pairs (enemies) do
  print (k)
end -- for

--[[

Output:

Hairadric
Grelinwan
Crilili
Hilis
Sardo

--]]

-- sort into alphabetic order

local t = {}
for k in pairs (enemies) do table.insert (t, k) end
table.sort (t)
for i, name in ipairs (t) do print (name) end

--[[

Output:

Crilili
Grelinwan
Hairadric
Hilis
Sardo

--]]

-- turn (above) sorted table into a something you can use in a trigger match

trigger_match = "(" .. table.concat (t, "|") .. ")"

print (trigger_match) --> (Crilili|Grelinwan|Hairadric|Hilis|Sardo)


-- serialize into a variable (for saving for next time)

require "serialize"
SetVariable("enemies", "enemies = " .. serialize.save_simple ( enemies ) )

print (GetVariable "enemies")

--[[

Output:

enemies = {
  Hairadric = true,
  Grelinwan = true,
  Crilili = true,
  Hilis = true,
  Sardo = true,
  }

--]]



-- get variables back next time (do in OnPluginInstall or during the world open event):

assert (loadstring (GetVariable ("enemies"))) () 


Note that adding a new enemy, or deleting an existing one, is a single, easy-to-understand line of code.

The list can be serialized so it is saved for next time, and can be turned into the trigger match string so you can test for anyone in the list.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Daniel P   USA  (97 posts)  Bio
Date Reply #4 on Thu 03 Jun 2010 04:40 AM (UTC)
Message
Somehow, looking that over makes perfect sense. Thanks so much for clarifying! Just a couple help queries on the terms I don't recognize and I'll be good to go.

I happened to run across a problem with the other solution of creating and deleting triggers as I go. Apparently there's a bit more to AddTrigger() than I had anticipated when using in a plugin. The triggers I add with the function aren't stored in the state file, and so they aren't permanent. So this is as good a solution as any, I say.
Top

Posted by Nick Gammon   Australia  (23,057 posts)  Bio   Forum Administrator
Date Reply #5 on Thu 03 Jun 2010 05:07 AM (UTC)
Message
Yes, the state file is really just variables. Adding a trigger effectively would modify the plugin itself, and plugins are really supposed to be read-only. The state files are named in such a way (world ID/plugin ID) that you get a different state file for each world, per plugin.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


17,032 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.