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, confirm your email, resolve issues, 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.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ Lua ➜ Auto-Envenomer (Need help making one.)

Auto-Envenomer (Need help making one.)

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


Posted by Rivius   (99 posts)  Bio
Date Tue 26 Oct 2010 03:38 PM (UTC)
Message
Alright, I am a warrior in the MUD Lusternia. Warriors have a skill called envenom which allows us to rub some venom on our swords. Now, when you strike with a sword, there's a chance that the venom will wipe off, or a chance that it will stay on the sword, OR it may be delivered to the person.

As such, venoms are a little unpredictable.


What I want to do, is make a system which sets a poison combination mode and re-envenoms your swords automatically according to that combo.

Now, a godsend is the command "WP" which probes our weapons and checks to see what poisons are on it. Here are some examples of its output:

Example 1: One poison
It is a one-handed weapon.
Damage: 33 Precision: 235 Speed: 211
A loboshigaru rapier has the following poisons or magical effects on it:
1) dulak

Example 2: No poisons
It is a one-handed weapon.
Damage: 33 Precision: 235 Speed: 211
A loboshigaru rapier has no poisons or magical effects on it.

Example 3: Multiple poisons
It is a one-handed weapon.
Damage: 33 Precision: 235 Speed: 211
A loboshigaru rapier has the following poisons or magical effects on it:
1) haemotox
2) haemotox
3) haemotox
4) haemotox



Now what I want to be able to do is make a function or something that checks each rapier through WP @sword1 and WP @sword2 and checks to see if the specified poisons are on it or not, and if it is, it applies them, and if there are poisons not specified, if wipes them off. An example in pseudocode

VENOMMODESWORD1 MORPHITE

CHECKRAPIER DOES-->

WP @sword1

WHICH SHOWS

It is a one-handed weapon.
Damage: 33 Precision: 235 Speed: 211
A loboshigaru rapier has the following poisons or magical effects on it:
1) haemotox

SENDS:
WIPE @sword1
ENVENOM @sword1 with MORPHITE


or lets say WP just sent

It is a one-handed weapon.
Damage: 33 Precision: 235 Speed: 211
A loboshigaru rapier has no poisons or magical effects on it.

it would only send
ENVENOM @sword1 with MORPHITE


I would also want to gag those WP lines. But I figure I could make a trigger group called "hideWP" that omits each line and enable the group during the script.

I was just wondering if you people could point me in the direction of:

- How to actually take the poisons list from WP and store it.

- How to compare this against some supposed EVENOMMODE

etc...


Note: By ENVENOMMODE I basically am thinking of calling an alias that sets the venom mode to "morphite" for example. I wouldn't want to put more than one venom on it.


I only know how to do some very basic things with lua. But I'm willing to learn if you help guide me through. This sort of thing would greatly,greatly, greatly optimize my poison usage.
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #1 on Tue 26 Oct 2010 10:30 PM (UTC)
Message
You can use SendNoEcho to send commands without having them echoed.

I would make a trigger that matches something like:


* has the following poisons or magical effects on it:


That would enable a second trigger like this:


^(\d+)\) (.*)$


The second one would be a regular expression (so \d+ means one or more digits).

I would also enable another trigger matching "*" (everything) put put it at a lower priority than the one that catches poisons. So as long as you get a poison line you don't get the "catch all" trigger. Once you run out of poisons the "catch all" trigger fires and disables both of them.

Then it would be a case of adding each poison to a Lua table.

- Nick Gammon

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

Posted by Rivius   (99 posts)  Bio
Date Reply #2 on Tue 26 Oct 2010 10:57 PM (UTC)

Amended on Wed 27 Oct 2010 05:28 PM (UTC) by Rivius

Message
Nick Gammon said:

You can use SendNoEcho to send commands without having them echoed.

I would make a trigger that matches something like:


* has the following poisons or magical effects on it:


That would enable a second trigger like this:


^(\d+)\) (.*)$


The second one would be a regular expression (so \d+ means one or more digits).

I would also enable another trigger matching "*" (everything) put put it at a lower priority than the one that catches poisons. So as long as you get a poison line you don't get the "catch all" trigger. Once you run out of poisons the "catch all" trigger fires and disables both of them.

Then it would be a case of adding each poison to a Lua table.


Thanks a bunch for the response, Nick :)
This is actually where it gets problematic for me (actually the whole thing sounds hard to me. I know the logic, but to actually do the code >.>...new to this)

Alright to recap what you said, so now I have this trigger:

^.+ has the following poisons or magical effects on it:$


enable this trigger:

^(\d+)\) (.*)$


So I suppose %1 catches the poison/effect.

I guess by lua table you mean something like this


    poisons = {
      "aleutian",
      "anatine",
      "anerod",
      "botulinum",
      "calcise",
      "chansu",
      "charybdon",
      "contortrin",
      "crotamine",
      "dendroxin",
      "dulak",
      "escozul",
      "hadrudin",
      "haemotox",
      "ibululu",
      "inyoka",
      "mactans",
      "mantakaya",
      "mellitin",
      "morphite",
      "niricol",
      "pyrotoxin",
      "saxitin",
      "senso",
      "tetrodin"
    },


Which I guess I have to use to compare against. But how do I go about taking those various listed %1's from the lines that'll come up, and compare them. All I want to do is say, Send(wipe sword) if there's a poison I don't want, and apply the one I want if it isn't present (ignoring other things in the list).

----

EDIT:

Ok. So I'll take this a step at a time.

This is my alias that should kick off the process.


<aliases>
  <alias
   match="checkrapier"
   enabled="y"
   expand_variables="y"
   send_to="12"
   sequence="100"
  >
  <send>EnableGroup("wp_hide", true)
Execute("WP @sword2")
</send>
  </alias>
</aliases>



<triggers>
  <trigger
   group="wp_hide"
   match="^(\d+)\) (.*)$"
   omit_from_output="y"
   regexp="y"
   sequence="100"
  >
  </trigger>
  <trigger
   group="wp_hide"
   match="^.+ has the following poisons or magical effects on it:$"
   omit_from_output="y"
   regexp="y"
   sequence="100"
  >
  </trigger>
  <trigger
   group="wp_hide"
   match="^Damage\: (.+) Precision\: (.+) Speed\: (.+)$"
   omit_from_output="y"
   regexp="y"
   sequence="100"
  >
  </trigger>
  <trigger
   group="wp_hide"
   match="^It is a (one|two)-handed weapon.$"
   omit_from_output="y"
   regexp="y"
   sequence="100"
  >
  </trigger>
</triggers>


That gags the whole thing. Not sure where to stick a EnableGroup("wp_hide", false) yet so that it doesn't interfere with regular WP's.

but I suppose the meat occurs here:
  <trigger
   group="wp_hide"
   match="^(\d+)\) (.*)$"
   omit_from_output="y"
   regexp="y"
   sequence="100"
  >
  </trigger>


I'm guessing in that trigger I'd say something like...
if %1 == aleutan or anatine or anerod or botulinum... [the whole list]

then

table.insert(pois, %1)


or something like that?

>.> <.<
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #3 on Wed 27 Oct 2010 11:10 PM (UTC)
Message
Well it would be more like this:


<triggers>
  <trigger
   group="wp_hide"
   match="^(\d+)\) (.*)$"
   name="poison_line"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
applied_poisons ["%2"] = true
</send>
  </trigger>

  <trigger
   enabled="y"
   group="wp_hide"
   match="^.+ has the following poisons or magical effects on it:$"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
applied_poisons = {}
EnableTrigger ("poison_line", true)
EnableTrigger ("end_of_poisons", true)
</send>
  </trigger>

  <trigger
   enabled="y"
   group="wp_hide"
   match="^Damage\: (.+) Precision\: (.+) Speed\: (.+)$"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
damage = "%1"
precision = "%2"
speed = "%3"
</send>
  </trigger>

  <trigger
   enabled="y"
   group="wp_hide"
   match="^It is a (one|two)-handed weapon.$"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
weapon_type = "%1"
</send>
  </trigger>

  <trigger
   group="wp_hide"
   keep_evaluating="y"
   match="*"
   name="end_of_poisons"
   send_to="12"
   sequence="200"
  >
  <send>
EnableTrigger ("poison_line", false)   -- disable poison line info
EnableTrigger ("end_of_poisons", false)  -- disable self

for poison in pairs (applied_poisons) do
  print ("You have applied", poison)
end -- for

print ("type=", weapon_type)
print ("damage= ", damage)
print ("precision= ", precision)
print ("speed= ", speed)</send>
  </trigger>
</triggers>


As the stuff comes in, we remember it in the table applied_poisons (which we set to empty on the line "has the following poisons or magical effects on it").

Then the catch-all trigger fires when we run out of poison lines, and in my case just shows debugging information, eg.


You have applied saxitin
You have applied hadrudin
You have applied haemotox
type= one
damage=  33
precision=  235
speed=  211


Now what you would need to do is work out what you *want* applied, which you don't already have applied.

For example, with your table of all possible poisons:


    poisons = {
      "aleutian",
      "anatine",
      "anerod",
      "botulinum",
      "calcise",
      "chansu",
      "charybdon",
      "contortrin",
      "crotamine",
      "dendroxin",
      "dulak",
      "escozul",
      "hadrudin",
      "haemotox",
      "ibululu",
      "inyoka",
      "mactans",
      "mantakaya",
      "mellitin",
      "morphite",
      "niricol",
      "pyrotoxin",
      "saxitin",
      "senso",
      "tetrodin"
    }

for i, name in ipairs (poisons) do
  if not applied_poisons [name] then
    print ("not applied:", name)
  end -- if
end -- for



This shows:


not applied: aleutian
not applied: anatine
not applied: anerod
not applied: botulinum
not applied: calcise
not applied: chansu
not applied: charybdon
not applied: contortrin
not applied: crotamine
not applied: dendroxin
not applied: dulak
not applied: escozul
not applied: ibululu
not applied: inyoka
not applied: mactans
not applied: mantakaya
not applied: mellitin
not applied: morphite
not applied: niricol
not applied: pyrotoxin
not applied: senso
not applied: tetrodin


Now you probably can't apply all of those, so now the code needs to decide which ones to use (for example, put the list in order, and keep going until you have four poisons applied).

- Nick Gammon

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

Posted by Rivius   (99 posts)  Bio
Date Reply #4 on Thu 28 Oct 2010 01:27 AM (UTC)
Message
Nick, you're a bloody genius! With what you showed me there, I can see now if a sword is lacking the specified venom like so:


if not applied_poisons ["@s1venom"] then
    print ("not applied: @s1venom")
end


However, how would I also check to see if a venom that is NOT the one specified in s1venom is also on the sword. It doesn't matter exactly which it is, as long as it is NOT s1venom and it is on the sword, no matter what, I want the condition to be true.

for example let's say I set s1venom to be morphite and there is morphite AND haemotox on the sword, I just want to wipe it. That's really the last bit I don't have a clue how to do.

Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #5 on Thu 28 Oct 2010 01:47 AM (UTC)
Message
One method would be to count them:


local count = 0
for name in pairs (applied_poisons) do
  count = count + 1
end -- for


Now you can see if there is venom there and if the count is more than 1 then it must be the wanted one and something else, eg.


if applied_poisons ["@s1venom"] and count > 1 then

  -- we have another one

end -- if


Or if you want to know its name (and remove it maybe)


for name in pairs (applied_poisons) do
  if name ~= "@s1venom" then
    Send ("remove venom " .. name)
  end -- if
end -- for



- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #6 on Thu 28 Oct 2010 01:48 AM (UTC)
Message
That doesn't totally address one venom being on more than once, in that case you really want a count, rather than true and false. But perhaps I'll leave that as an exercise ...

- Nick Gammon

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

Posted by Rivius   (99 posts)  Bio
Date Reply #7 on Thu 28 Oct 2010 02:09 AM (UTC)
Message
Ah. Well, I don't need the count, thankfully. Wiping is an all or nothing thing.

The only thing is, I really need to check against the list of all possible poisons, because there are other things that are not poisons that may come up.

So...tell me if this would make sense...

Maybe in
^(\d+)\) (.*)$

I can say

    poisons = {
      "aleutian",
      "anatine",
      "anerod",
      "botulinum",
      "calcise",
      "chansu",
      "charybdon",
      "contortrin",
      "crotamine",
      "dendroxin",
      "dulak",
      "escozul",
      "hadrudin",
      "haemotox",
      "ibululu",
      "inyoka",
      "mactans",
      "mantakaya",
      "mellitin",
      "morphite",
      "niricol",
      "pyrotoxin",
      "saxitin",
      "senso",
      "tetrodin"
    }
for name in pairs (poisons) do
if poisons [%2] then
    applied_poisons ["%2"] = true
end -- if
end -- for


and from there


for name in pairs (applied_poisons) do
  if name ~= "@s1venom" then
    Send ("remove venom " .. name)
  end -- if
end -- for

should be fullproof to check against poisons only?
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #8 on Thu 28 Oct 2010 02:26 AM (UTC)
Message
Do this:


for i, name in ipairs (poisons) do
  if name == "%2" then
    applied_poisons ["%2"] = true
    break
  end -- if
end -- for


You weren't using "name" in your loop. Also that loop is actually keyed by number (eg. 1, 2, 3) so you need the second thing (the value) which is the name of the poison.

- Nick Gammon

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

Posted by Rivius   (99 posts)  Bio
Date Reply #9 on Thu 28 Oct 2010 02:30 AM (UTC)
Message
*facepalm* Thanks again. Works like a charm. I was actually wondering why that wasn't working when I tried it out >.> <.<

Now I think I have the pieces to make this thing work. I'll see if I don't run into any problems now.
Top

Posted by Rivius   (99 posts)  Bio
Date Reply #10 on Thu 28 Oct 2010 04:58 AM (UTC)

Amended on Thu 28 Oct 2010 06:19 AM (UTC) by Rivius

Message
*cough* Ok. Looks to be the last problem hopefully:

Now that this is working here are my triggers below. Now what I want to do is make it so that after the alias below (check *) is called, I can still WP and it wouldn't be gagged. Also, I'd like to be able to check 1;check 2 .
Is this possible?


<triggers>
  <trigger
   enabled="y"
   group="wp_hide"
   match="^.+ has the following poisons or magical effects on it:$|^.+ has no poisons or magical effects on it\.$"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
applied_poisons = {}
EnableTrigger ("poison_line", true)
EnableTrigger ("end_of_poisons", true)
</send>
  </trigger>
  <trigger
   enabled="y"
   group="wp_hide"
   match="^Damage\: (.+) Precision\: (.+) Speed\: (.+)$"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
damage = "%1"
precision = "%2"
speed = "%3"
</send>
  </trigger>
  <trigger
   enabled="y"
   group="wp_hide"
   match="^It is a (one|two)-handed weapon.$"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
weapon_type = "%1"
</send>
  </trigger>
  <trigger
   expand_variables="y"
   group="wp_hide"
   keep_evaluating="y"
   match="*"
   name="end_of_poisons"
   send_to="12"
   sequence="200"
  >
  <send>EnableTrigger ("poison_line", false)   -- disable poison line info
EnableTrigger ("end_of_poisons", false)  -- disable self


if current_rapier==@sword1 then
--
&#9;for name in pairs (applied_poisons) do
&#9;&#9;if name ~= "@s1venom" then 
&#9;&#9;&#9;print("Wrong setup.")
&#9;&#9;&#9;&#9;&#9;Send("WIPE @sword1")
&#9;&#9;&#9;&#9;&#9;Send("Envenom @sword1 with @s1venom")
&#9;&#9;&#9;&#9;break 
&#9;&#9;end&#9;
&#9;end -- for
&#9;
&#9;if next(applied_poisons)==nil then
&#9;&#9;print ("not applied: @s1venom")
&#9;&#9;Send("Envenom @sword1 with @s1venom")
&#9;end -- if
&#9;
elseif current_rapier==@sword2 then
&#9;&#9;for name in pairs (applied_poisons) do
&#9;&#9;&#9;if name ~= "@s2venom" then
&#9;&#9;&#9;&#9;print("Wrong setup.")
&#9;&#9;&#9;&#9;&#9;Send("WIPE @sword2")
&#9;&#9;&#9;&#9;&#9;Send("Envenom @sword2 with @s2venom")
&#9;&#9;&#9;&#9;&#9;break
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;end -- for

&#9;&#9;if next(applied_poisons)==nil then
    print ("not applied: @s2venom")
&#9;Send("Envenom @sword2 with @s2venom")
&#9;end -- if
&#9;


end
</send>
  </trigger>
  <trigger
   group="wp_hide"
   match="^(\d+)\) (.*)$"
   name="poison_line"
   omit_from_output="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
applied_poisons ["%2"] = true
</send>
  </trigger>
</triggers>




The alias that kicks it off:


<aliases>
  <alias
   match="check *"
   enabled="y"
   expand_variables="y"
   send_to="12"
   sequence="100"
  >
  <send>if %1==1 then
current_rapier=@sword1
else
current_rapier=@sword2
end --if


EnableGroup("wp_hide", true)
SendNoEcho("WP " ..current_rapier)
</send>
  </alias>
</aliases>
Top

Posted by Nick Gammon   Australia  (23,140 posts)  Bio   Forum Administrator
Date Reply #11 on Sat 30 Oct 2010 01:55 AM (UTC)
Message
Well, anything's possible. However I would be careful about stuff like this:


if current_rapier==@sword1 then


Template:faq=32 Please read the MUSHclient FAQ - point 32.


That is relevant here. Think of what will happen to the code when the variable @sword1 is expanded.

- Nick Gammon

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

Posted by Rivius   (99 posts)  Bio
Date Reply #12 on Sun 31 Oct 2010 01:44 AM (UTC)

Amended on Sun 31 Oct 2010 01:53 AM (UTC) by Rivius

Message
Ok! I just decided to override the second command with an alias so I have

(WP|WEAPONP|WEAPONPROBE) *

in my alias's regular expression but it doesn't seem to pick up * as %2... >.>

The wild care can be either a number, a word or a word followed by a number.


EDIT: Nevermind. Got it...

(WP|WEAPONP|WEAPONPROBE) (\w+)
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.


32,381 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.