|
haiku Wanderer
Joined: 19 Nov 2004 Posts: 70
|
Posted: Fri Sep 07, 2007 2:38 am
recursive aliases |
Two things:
First thing: does anyone know how cmud handles things like recursive aliases?
Say I had these triggers and this alias:
Code: |
#ALIAS cureBlindedPeople {#IF (%numitems(@BlindedMembers) > 0) {cast cure blind %item(@BlindedMembers,1); cureBlindedPeople } {}} groupMonitor
#TRIGGER {^(%w) is blinded!$} {#ADDITEM BlindedMembers %1 } groupMonitor
#TRIGGER {^You receive*$} {cureBlindedPeople} groupMonitor
|
Would that work?
Second thing: Is that syntactically how I would assign variables/triggers/aliases to a specific class (in this case the groupMonitor class folder) |
|
|
|
haiku Wanderer
Joined: 19 Nov 2004 Posts: 70
|
Posted: Fri Sep 07, 2007 2:41 am |
oh, and presumably there would be a trigger to remove someone from @BlindedMembers. I don't currently have the text.
|
|
|
|
haiku Wanderer
Joined: 19 Nov 2004 Posts: 70
|
Posted: Fri Sep 07, 2007 3:40 am |
nope, infinite loop.
Ended up solving by just calling the alias at
You cast Cure Blind |
|
|
|
gamma_ray Magician
Joined: 17 Apr 2005 Posts: 496
|
Posted: Fri Sep 07, 2007 3:51 am |
Why don't you use a for loop?
#for (@BlindedMembers) {cast cure blind %i} |
|
|
|
haiku Wanderer
Joined: 19 Nov 2004 Posts: 70
|
Posted: Fri Sep 07, 2007 4:49 am |
because, this is a skill based mud. level 1 cure blind is not as effective as level 7 or level 10 cure blind. I might need to cast it 3-4 times, so I want to continue all the way until
Code: |
(%w) is no longer blind.
|
at which point I'll remove them from the list. |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri Sep 07, 2007 9:22 am |
Your class syntax should be correct - you might need to put quotes around the strings.
The problem with your recursive alias as it stands is that there's nothing inside the alias that'll limit its execution. CMUD will max out your CPU, running the alias over and over again - potentially hundreds or thousands of times before the message is received. There are a couple of possible solutions - you could use a wait (in CMUD 2) or an alarm. You could also remove the recursive aspect of the alias entirely and have the act of casting the cure blind spell run the alias again. That's probably what you intended anyway, yes? That the script will wait until the spell has been cast before attempting to cast it again. |
|
|
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Fri Sep 07, 2007 8:22 pm |
Why not the following?
Code: |
#TRIGGER {(%w) is blinded!} {#ADDITEM blindmembers %1;cureblindmembers}
#ALIAS cureblindmembers {#FOR (@blindmembers) {cast cure blind %i;#wait 2500};blindcheck}
#TRIGGER {(%w) is no longer blind.} {#DELITEM blindmembers %1}
#ALIAS blindcheck {#IF (%numitems(@blindmembers)>0) {cureblindmembers}} |
What this will do is go through your blindmembers list, cast cure blind on them each once, and if the message comes back they are no longer blind, they are removed from the list. At the end of casting the spells, it'll cycle back through to see if there are any missed casts, and if there are still blind people, it'll recast again. The #wait 2500 in the cureblindmembers is the length of time it takes to cast a spell based on your MUD. Average round time (as I've come to know it) is 2.5 seconds. Just change that to match your MUD round time, and you shouldn't have any troubles. Just a thought.
If there are any errors in my suggestion, I'm sure someone will point it out. But it's a start, and hopefully will accomplish what you're looking to do. I realize it won't cast the spell on the same person 3-4 times in a row, but I'm sure there's a way to go about setting that up, too.
Charneus |
|
|
|
Progonoi Magician
Joined: 28 Jan 2007 Posts: 430
|
Posted: Fri Sep 07, 2007 8:54 pm |
Is there a message present when you cast cure blind but the member will still stay blind? If there is such, its pretty easy to do it with 3 triggers.
* is blind - add to list, try to cure
* is still blind - try to cure once again
* is cured - delete from list.
If thats the case, however, I don't know if forall is the best way to go.
You'll add a name to blindList each time you see the message "is blind". Then you'll try to cure first item in the list (first name in the list) and once that finally over, you'll move on. #Forall runs through all of them and unless you'll make some sort of counter or secondary list to variations where item didn't get cured, it may become tricky. So.
Code: |
#trigger "Blind_Cap" {^(%w) is blinded!$} {blinded_members=%additem(%1,@blinded_members);CureBlind}
#alias CureBlind {#if ((@blinded_members)!=%null)) {cast cure blind %item(@blinded_members,1)}}
#trigger "Failed_Blind" {^(%w) is still blind!$} {CureBlind}
#trigger "Cure_Success" {^(%w) is no longer blind!$} {blinded_members=%delnItem(@blinded_members,1);CureBlind}
|
This is untested and may miss a brace or bracket here or there, but in case there's a third message I wrote about present, This should be the best way for solving this.
I hope this helps.
EDIT: Edit'ed after Char's suggestion. Thanks. I must have missed the backloop part.
Prog |
|
Last edited by Progonoi on Fri Sep 07, 2007 9:31 pm; edited 1 time in total |
|
|
|
Fang Xianfu GURU
Joined: 26 Jan 2004 Posts: 5155 Location: United Kingdom
|
Posted: Fri Sep 07, 2007 9:01 pm |
EDIT: Ninja'd by prog. I'm referring to Charneus' script.
That script doesn't actually reproduce the behaviour of the script posted by the OP. His script casts on one person until that person is removed from the list, rather than repeatedly casting on the whole list. Perhaps something like this?
#TRIGGER {(%w) is blinded!} {#ADDITEM blindmembers %1;cureblindmembers}
#ALIAS cureblindmembers {cast cure blind %item(@blindmembers,1);#alarm +2.5 {blindcheck}}
#TRIGGER {(%w) is no longer blind.} {#DELITEM blindmembers %1}
#ALIAS blindcheck {#IF (%numitems(@blindmembers)>0) {cureblindmembers}} |
|
|
|
charneus Wizard
Joined: 19 Jun 2005 Posts: 1876 Location: California
|
Posted: Fri Sep 07, 2007 9:04 pm |
Your suggestion is a great one, Prog. However, it doesn't loop back through to check to see if there are more blind people. You may want to make the following change:
Code: |
#TRIGGER "Cure_Success" {^(%w) is no longer blind!$} {blinded_members=%delnitem(@blinded_members,1);cureblind} |
This will allow it to check if there are any others in the blind_members list, and if so, will cure them as well. Of course, that is assuming there is a failure message such as the one you've provided.
Charneus
EDIT: Fang, you're right - my suggestion was to go through the entire list first, then recast any misses. I knew someone would be able to fix it up a little better. I normally just throw things out there for suggestion purposes. :) If my idea doesn't work, at least it helps give someone else something to work with. :D |
|
|
|
gamma_ray Magician
Joined: 17 Apr 2005 Posts: 496
|
Posted: Sat Sep 08, 2007 1:58 am |
I kind of agree that going through the whole list first and then recasting any misses is probably the best way to go, but not with a delay. I think the ultimately fastest way would be:
#for (blind stuff) {enables the next trigger, then casts cure on the whole list}
#t+ a trigger that recures every time it gets the "you cure so and so but not enough" message
and a trigger (always enabled) that takes people off the list and every time it does that it checks how many are left--if no one, disable previous trigger (note that this should include "you can't find so and so" as well as "so and so can see, yay").
But I also get the feeling that I'm missing something vital about the game, can you really cast cure blind as frequently as you can enter it? |
|
|
|
haiku Wanderer
Joined: 19 Nov 2004 Posts: 70
|
Posted: Sun Sep 09, 2007 4:26 am |
Quote: |
can you really cast cure blind as frequently as you can enter it? |
No, it has a casting time of 4 rounds. typically there's a ranger and a cleric in the group (both of which get cure blind), so the tank will generally issue a generic group-tell command like
which shows up on their screen as:
Code: |
Arkane tells the group (in vyanian): "cb trent"
|
Since it's a group-oriented mud, you might have 2 clerics; 1 ranger, 1 cleric; or just one cleric. the problem is that everyoen triggers off of gt "cb Trent" and I want to get away from that... just do it magically |
|
|
|
gamma_ray Magician
Joined: 17 Apr 2005 Posts: 496
|
Posted: Sun Sep 09, 2007 4:44 am |
OK, so what else have you got to work with? (How many of these lines do you get, and what do they look like?)
- message when a player is blinded
- list of people who are in your group (so you don't cure The Enemy!)
- message when a player is partially unblinded
- message when a player is completely unblinded
- message when you can cast again
- message when you try and cast but the person you try and cast at isn't there |
|
|
|
haiku Wanderer
Joined: 19 Nov 2004 Posts: 70
|
Posted: Sun Sep 09, 2007 5:39 am |
Here's what I've got so far:
Code: |
#TRIG {^(%w) is blinded!$} {#ADDITEM BlindedMembers %1;#SHOW @BlindedMembers}
#TRIG {^(%w) is no longer blind.$} {#DELITEM BlindedMembers %1; #SHOW @BlindedMembers; cureBlindedPeople}
#TRIG {^(%1) wasn't blind.$} {#DELITEM BlindedMembers %1; cureBlindedPeople}
#TRIG {^(%1) looks a little better.%} {}
#ALIAS cureBlindedPeople {#IF (%numitems(@BlindedMembers) > 0) {cast cure blind %item(@BlindedMembers,1)} {}}
|
Standard output:
Code: |
++ You cast cure blind. ++
Sabrina looks a little better.
-or-
Sabrina is no longer blind. etc
|
It's kicked off when I get experience:
Code: |
#TRIG {You receive*$} {cureBlindedPeople}
|
|
|
|
|
|
|