|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Sun Aug 26, 2001 2:34 pm
String lists and pattern matching |
Hi All
What I want to do is have a string list of acceptable room contents i.e. a coin, 10 coins, a corpse of war hero, odd bits and peices of a war hero, a pile of dust.
the corpse and odd bits are different stages in the decompisition of a dead monster.
what i want to do is take a line like
odd bits and peices of a war hero
and do an %ismember on a string list that has
odd bits *
so that it will work with the odd bits of any monster.
I hope this makes sense.
Graywolf |
|
|
|
TonDiening GURU
Joined: 26 Jul 2001 Posts: 1958 Location: Canada
|
Posted: Sun Aug 26, 2001 6:36 pm |
How about just triggering on {^odd bits}?
Idea:
When I define a zone's acceptable item list I use %selline and a button
to %additem. It is a quick and dirty way to grab the different items and
monsters. Then you just clean up the variable that collects it. |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Mon Aug 27, 2001 1:45 am |
any other idea's?
Graywolf |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Mon Aug 27, 2001 1:45 pm |
I need a genius here. guru's please help. let me know if you need any more info.
Graywolf |
|
|
|
iljhar GURU
Joined: 10 Oct 2000 Posts: 1116 Location: USA
|
Posted: Mon Aug 27, 2001 8:11 pm |
How about something like:
#trigger {odd bits (*){,|.}} {#if (%ismember(%1, @decaying_things)) {get odd}}
#var decaying_things {and pieces of a war hero|and chunks of a dragon|and decayed remnants of a wood elf}
If you know that there will always be an "and pieces of" after the odd bits, then you can put "and pieces of" in the trigger and take it out of the variable.
Iljhar |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Mon Aug 27, 2001 9:32 pm |
there will always be and pieces after odd bit.
The problem with doning it the way you suggested is that i would have to make and array with 3 different decaying stages for each monster, that would be huge.
maybe i should just gag any decaying stuff that wouldn't be hard. hrmm
Could i go through my string list and delete items that resembled a pattern?
any ideas?
Graywolf |
|
|
|
iljhar GURU
Joined: 10 Oct 2000 Posts: 1116 Location: USA
|
Posted: Mon Aug 27, 2001 9:35 pm |
What stages of decay are there? And what does it look like? I figured the "and pieces of" would tell you the stage of decay...
Iljhar |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Mon Aug 27, 2001 10:07 pm |
there are many set stages of decay depending on the critter you are fighting.
when you kill something it goes though each of these stages. that is why i was looking for a way to just look for a pattern in my string list as opposed to an exact match.
Graywolf |
|
|
|
iljhar GURU
Joined: 10 Oct 2000 Posts: 1116 Location: USA
|
Posted: Mon Aug 27, 2001 10:08 pm |
Can you please give an example of some of those stages?
Iljhar |
|
|
|
Kjata GURU
Joined: 10 Oct 2000 Posts: 4379 Location: USA
|
Posted: Mon Aug 27, 2001 10:11 pm |
I really do not understand very well what you are trying to do. Maybe a little more info would help.
You should also know that stringlist cannot contain patterns since they are literals.
Kjata |
|
|
|
MattLofton GURU
Joined: 23 Dec 2000 Posts: 4834 Location: USA
|
Posted: Mon Aug 27, 2001 11:21 pm |
quote:
I really do not understand very well what you are trying to do. Maybe a little more info would help.
You should also know that stringlist cannot contain patterns since they are literals.
Kjata
Heh, that's only %99 right A pattern is something that matches (according to ZMud, otherwise it's a regularly repeating sequence of symbols), and I would think "this is a test" would match "this is a test".
That said, you have the option of creating several literal-patterned triggers or one stringlist-patterned trigger.
ie, {@players} = {Tim|Mark|Jim|Ron} if @players = Tim|Mark|Jim|Ron
Ok, on to graywolf. Is the of a|an (monster) bit always there? Dunno how many stages of decay their are or if they're localized to certain monsters, but if you put them all in a variable you could use this pattern:
{@decaystages} of {a|an} *
li'l shmoe of Dragon's Gate MUD |
|
|
|
Kjata GURU
Joined: 10 Oct 2000 Posts: 4379 Location: USA
|
Posted: Tue Aug 28, 2001 1:25 am |
Hehe, you know what I meant.
Kjata |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Tue Aug 28, 2001 1:22 pm |
What I am trying to do is check the room for players characters, before I will attack a monster. I have a class for each monster that I am killing. In the class I have a sting list with the monsters names that I don’t mind being in the room with me. I want to have a string list called AllowableItems I want that string list to be outside my class and I want it to be more generic. In other words I want it to have one line in the string list that will allow both of these cases. Let me know if you need more explanation. Below is a list of a couple monsters as the decompose, there are many different stages for the different monsters.
The decaying remains of Oxman Glovehammer.
The decaying remains of a cheery war hero.
Room Description
-- There are two obvious exits: south and east.
Oxman Glovehammer.
I kill him
Room Description
-- There are two obvious exits: south and east.
The horridly battered corpse of Oxman Glovehammer.
>
Wait 45 seconds and look again.
Room Description
-- There are two obvious exits: south and east.
The decaying remains of Oxman Glovehammer.
Wait 45 seconds and look again.
Room Description
-- There are two obvious exits: south and east.
The bones and dust of Oxman Glovehammer.
Wait 45 seconds and look again.
Room Description
-- There are two obvious exits: south and east.
A pile of dust.
Wait 45 seconds and look again.
Room Description
-- There are two obvious exits: south and east.
>
Wait 45 seconds and look again.
Room Description2
-- There is one obvious exit: south.
A well-built head guard.
A leather-skinned, old war hero.
A strong Viking warrior.
>
Wait 45 seconds and look again.
Room Description2
-- There is one obvious exit: south.
The corpse of a cheery war hero.
A well-built head guard.
A strong Viking warrior.
>
Wait 45 seconds and look again.
Room Description2
-- There is one obvious exit: south.
A well-built head guard.
The decaying remains of a cheery war hero.
A strong Viking warrior.
>
Wait 45 seconds and look again.
Room Description2
-- There is one obvious exit: south.
A well-built head guard.
The bones and dust of a cheery war hero.
A strong Viking warrior.
>
Wait 45 seconds and look again.
Room Description2
-- There is one obvious exit: south.
A well-built head guard.
A pile of dust.
A strong Viking warrior.
>
Graywolf |
|
|
|
Kjata GURU
Joined: 10 Oct 2000 Posts: 4379 Location: USA
|
Posted: Tue Aug 28, 2001 6:03 pm |
Ok. So, is your trigger matching a complete line and then you want to compare that line to a string list or are you using a specific pattern in your tirgger to match certain lines. If you are matching the whole line, then you can use the =~ to see if that line matches a pattern. Example:
#TRIGGER {(%*)} {#IF (("%1" =~ "odd bits *") or ("%1" =~ "The decaying remains of *")) {#SH Allowable item.} {#SH Not allowable item.}}
Kjata |
|
|
|
iljhar GURU
Joined: 10 Oct 2000 Posts: 1116 Location: USA
|
Posted: Tue Aug 28, 2001 8:43 pm |
Okay, I think I see where you're going w/this. Right now, you've got a trigger set up to capture all the objects, PCs and NPCs in the room, right? So now you've also got a list of objects that you don't want your script to accidently try to kill the objects in the room, right? You want the dead parts to work on ANY corpse, right? Try this:
#var Items {a coin|10 coins|A pile of dust|The decaying remains of|The horridly battered corpse of|The bones and dust of}
#trigger {Trigger To signify the end of the room capture} {#forall @Items {#var CurrentItem %i;#var Counter 1;#while (@Counter<=%numitems(@RoomContents)) {#if (%begins(%item(@RoomContents, @Counter), @CurrentItem)) {#delnitem RoomContents %i;#add Counter -1};#add Counter 1}}}
The trigger has 2 loops. The outer loop goes through the Items variable and places them in the CurrentItem variable, one by one. The inner loop checks the CurrentItem variable against each item in the RoomContents variable. If the beginning of any item in the RoomContents variable matches with the CurrentItem variable, then it gets taken out of the RoomContents variable. You'll notice I subtract 1 from the Counter variable if there is a match. This is to ensure that you don't skip an item in the RoomContents variable. If it weren't in there, then you might try to attack an object, and you don't want to do that. ;)
Iljhar |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Tue Aug 28, 2001 9:17 pm |
This is absolute beauty. I am almost psitive this will work thank. I will keep you all updated if it works.
Graywolf |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Thu Aug 30, 2001 1:39 am |
I spent 6 hours to get this to work. silly little bugs like haveing a @in front of a variable when it wasn't supposed to be there took me hours arggghhh. well here is my master piece.
It goes though the contents in the room and deletes out the contents that are acceptable, like corpses and stuff. the reason i wanted this code is so that i could check for playercharactors in a room before i start fighting a monster. so that i wont steal it from someone. This is one part of my check. I also check to see if someone has claimed the monster. I allow other monsters to be in the room and coins and corpses in differing degrees of decay.
Please let me know what you think. because i can't get my wife to see any merit in it.
#CLASS {SmartBots|Attack}
#ALIAS DeleteAcceptableContents {
Counter = %numitems( @RoomContents)
#until (@Counter=0) {
CheckingItem=%item( @RoomContents, @Counter)
Counter2 = %numitems( @AcceptableContents)
#until (@Counter2=0) {
CheckingItem2=%item( @AcceptableContents, @Counter2)
#If %begins( @CheckingItem, @CheckingItem2) {
#DelNItem RoomContents (@Counter)
#Abort
}
#Add Counter2 -1
}
#Add Counter -1
}
}
#VAR RoomContents {A well-built head guard.|A strong Viking warrior.}
#VAR AcceptableContents {The oddly fading body|Odd bits and pieces of the corpse|The glowing corpse|The corpse of|The faintly phosphorescing remains|The decaying remains|A pile of faintly glowing|A few odd edges of the corpse}
#VAR Counter {0}
#VAR CheckingItem {A well-built head guard.}
#VAR Counter2 {0}
#VAR CheckingItem2 {The oddly fading body}
#TRIGGER {^-- There [is|are] %w obvious [exit|exits]:} {
@RoomContents = %null
#T+ "Get Room Contents."
}
#CLASS 0
#CLASS {SmartBots|Attack|Get Room Contents.}
#TRIGGER {*} {#AddItem RoomContents %line}
#TRIGGER {^~>} {
#DELN RoomContents 1
#T- "Get Room Contents."
DeleteAcceptableContents
} "" {prompt}
#CLASS 0
Graywolf |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Thu Aug 30, 2001 1:50 am |
For some reason it gets into an endless loop when i speedwalk. counter goes below 0 and keeps looping. so i changed the code to say counter<1 and it still keeps going... arrrghhhh any ideas?
Graywolf |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Thu Aug 30, 2001 1:54 am |
i fixed it by putting in a
#if (counter<0) {#abort}
after the #add Counter -1
but i would still like to know why the until loop keeps screwing up.
Graywolf |
|
|
|
iljhar GURU
Joined: 10 Oct 2000 Posts: 1116 Location: USA
|
Posted: Thu Aug 30, 2001 2:21 am |
change the DeleteAcceptableContents alias to this:
#ALIAS DeleteAcceptableContents {
Counter = %numitems( @RoomContents)
#until (@Counter<1) {
CheckingItem=%item( @RoomContents, @Counter)
Counter2 = %numitems( @AcceptableContents)
#until (@Counter2<1) {
CheckingItem2=%item( @AcceptableContents, @Counter2)
#If %begins( @CheckingItem, @CheckingItem2) {
#DelNItem RoomContents (@Counter)
#Abort
}
#Add Counter2 -1
}
#Add Counter -1
}
}
The reason why you get an endless loop is because you have your conditional only check to see if @counter and @counter2 is 0. If for some reason it goes below 0, then your loops will go forever because you keep subtracting from the variables, so it keep getting bigger and bigger in the negative direction and will never get to 0, so by changing the conditional to <1 it'll catch the times your counter variables go below 0.
Iljhar |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Thu Aug 30, 2001 3:12 am |
Is there a loop structure that is less buggy than until?
Graywolf |
|
|
|
iljhar GURU
Joined: 10 Oct 2000 Posts: 1116 Location: USA
|
Posted: Thu Aug 30, 2001 4:15 am |
what do you mean by buggy? does it cause bad things to happen to your characters? You can try the #loop command or the #while command, maybe those would be better?
Iljhar |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Thu Aug 30, 2001 1:06 pm |
by buggy i mean it isn't working properly ie the counter goes negative and it doesn't stop the loop. i had to use an if statment in conjuntion with the abort command to exit the loop based on the same check that the until statment is supposed to be checking.
Graywolf |
|
|
|
iljhar GURU
Joined: 10 Oct 2000 Posts: 1116 Location: USA
|
Posted: Thu Aug 30, 2001 2:46 pm |
Okay, in that case, the command itself is not buggy. The loop doesn't know anything else but what YOU tell it. So if you tell it to keep looping until a variable is 0 or a variable is greater than 10 or a variable is not equal to 0, then that loop will keep going until that variable reaches 0 or that variable becomes greater than 10 or that variable becomes another number other than 0. So, unfortunately, it's not the proram, it's your logic that's flawed. While that may seem harsh, it's true. :( So in the future, if you want a loop to keep going until it hits 0 or is negative, then make the conditional check to see if the variable is less than 1.
Iljhar |
|
|
|
graywolf Apprentice
Joined: 21 Jul 2001 Posts: 116 Location: USA
|
Posted: Fri Aug 31, 2001 1:36 pm |
Not to be harsh but ...
if you read the two posts before your post where you copied my code down... you will see i made those changes before you responded making that suggestion. And the until loop still goes on and on when the counter goes negative. but this only happens when i use a path, and the function gets called many times before it gets to finish. I don't think that the loop is working properly in that case. I think the problem has to do with the way Zugg makes the stack. I watch it in the debugger and try to step though it. it seems to do the
#Until counter < 0
line numerous times before entering the loop. Why it would do this i have know idea.
Any Idea's?
Graywolf |
|
|
|
|
|