Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » zMUD General Discussion
geniusclown
Magician


Joined: 23 Apr 2003
Posts: 358
Location: USA

PostPosted: Sat Aug 21, 2004 4:56 pm   

Multistate core (Dragonrealms)
 
I'm working on a core multistate trigger to handle commands in DR (code quoted below). So far, it's got 3 queues:

"do_noRt" is a list of one-time commands that will not cause a roundtime (but I can't send more than 3 at a time, or the server says "Sorry, you may only type ahead 2 commands."). To prevent a long list from being sent all at once, it has a condition that triggers on %gsl(q), which is essentially a prompt.

"do_first" is a list of one-time commands that will cause roundtime, so it has a condition that waits for the roundtime (handled by another script using the variable @roundtime, which counts down).

"do_loop" is a single command that will cause roundtime, and is executed over and over.

After executing any command, the trigger resets itself to State 0, using the #STATE command, where it waits for one of the above three queues to have a value.

My problem is, when it does this, it doesn't immediately attempt to evaluate the expression of State 0, and hangs until I receive something from the MUD, or one of the 3 queues is altered. If the first 2 queues are empty and it executes do_loop, it resets itself because it runs out of states rather than executing a #STATE command, and State 0 evaluates itself like it should.

I'm looking for suggestions on how to get State 0 to evaluate itself automatically after being reset by the #STATE command. #SET won't do it, because that forces the trigger state to "true", regardless of if there's anything in the queues.

I tried tacking on a dummy state and going to it instead of State 0, but it would just hang on that State 8 the same as it does State 0, so that's not a solution.

Quote:
#CLASS {Do}
#ALIAS que {#IF (%ismember( %1, @do_types)) {#IF (%1="loop") {do_loop = %2} {#VAR do_%1 %additem( %-2, @{do_%1})} {#ECHO {Syntax~: que ~{@do_types~} ~{command to que~}}}}}
#VAR do_noRt {}
#VAR do_first {}
#VAR do_loop {}
#VAR do_types {noRt|first|loop}
#TRIGGER "doit" {@do_noRt or @do_first or @do_loop} {} "" {exp}
#COND {@roundtime=0} {#IF (@do_noRt) {#STATE doit 2} {#IF (@do_first) {#STATE doit 4} {#IF (@do_loop) {#STATE doit 6}}}} {exp}
#COND {} {#EXEC %pop( do_noRt)} {wait|param=1}
#COND {q} {#STATE doit} {gsl}
#COND {} {#EXEC %pop( do_first)} {wait|param=1}
#COND {@roundtime>0} {#STATE doit} {exp}
#COND {} {#EXEC @do_loop} {wait|param=1}
#COND {@roundtime>0} {} {exp}
#BUTTON 50 {~[%state( doit)~] @do_noRt,@do_first,@do_loop} {#SET doit %state( doit)} {} {} {} {} {} {Size} {200} {22} {} {} {} {} {} {} {} "" {} {} {}
_________________
.geniusclown
Reply with quote
geniusclown
Magician


Joined: 23 Apr 2003
Posts: 358
Location: USA

PostPosted: Sun Sep 12, 2004 1:33 am   
 
I've been working on this script a bit, and made several modifications. Its purpose is the same, but the means are a little different. I've now set only 2 queues - 1 to execute immediately (@do), and 1 to loop (@loop). Here's the core multistate trigger:
Quote:
#TRIGGER "doit" {@do or @loop} {} "" {exp}
#COND {@roundtime=0} {#IF (@do) {#EXEC %pop( do);#IF (%item( @do, 1)="noRt") {#NOOP %pop( do);#SET doit 2}} {#IF (@loop) {#STATE doit 4} {#STATE doit}}} {exp}
#COND {@roundtime>0} {} {exp}
#COND {} {#STATE doit} {wait|param=1}
#COND {} {#EXEC @loop} {wait|param=1}
#COND {@roundtime>0} {} {exp}

It works very well, with one glaring exception. If @roundtime is already 0 when the first trigger fires (i.e. I put something in @do or @loop), the trigger will hang in state 1 until some variable changes, or I force it to move on via #SET. How can I guarantee that as soon as state 0 is true and it moves to state 1, it checks to see if the expression in state 1 is true?
_________________
.geniusclown
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Sun Sep 12, 2004 4:04 am   
 
Use an alarm or wait state instead and simply test @roundtime in an #IF.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
LightBulb
MASTER


Joined: 28 Nov 2000
Posts: 4817
Location: USA

PostPosted: Sun Sep 12, 2004 6:06 am   
 
If you have problems when roundtime is already zero, then make sure it isn't.
#TRIGGER "doit" {@do or @loop} {#IF (@roundtime = 0) {#VAR roundtime 1}} "" {exp}
_________________
LightBulb
Senior member

Most scripts in this forum are written for Command Line entry.
Don't even open the Settings Editor unless its use is specified or obvious.
Reply with quote
geniusclown
Magician


Joined: 23 Apr 2003
Posts: 358
Location: USA

PostPosted: Sun Sep 12, 2004 4:24 pm   
 
This works, but is more of a band-aid... it's not the best solution because I lose a second, which can be precious if I'm in combat. It also causes a delay if I have other stuff going on at the same time (again, usually in combat).

I still don't understand why the trigger wouldn't attempt to evaluate the expression as soon as it enters state 1. Can someone explain this for me, please?
_________________
.geniusclown
Reply with quote
LightBulb
MASTER


Joined: 28 Nov 2000
Posts: 4817
Location: USA

PostPosted: Mon Sep 13, 2004 5:33 am   
 
Because no variable changes value at the moment the trigger enters state 1. The help for the 'exp' option is quite explicit. The expression will be evaluated when a variable changes value (and not until then).

Type Category for detailed descriptions see: Trigger Types
exp expression trigger (expression is tested whenever a variable is changed)

Yes, the fix I suggested is a 'bandaid'. A real fix would be to check the expression before advancing the state, and execute the appropriate action when it is already true.

#TRIGGER "doit" {@do or @loop} {#IF (@roundtime = 0) {#IF (@do) {#EXEC %pop( do);#IF (%item( @do, 1)="noRt") {#NOOP %pop( do);#STATE doit 3}} {#STATE doit 4}}} "" {exp}
#COND {@roundtime=0} {#IF (@do) {#EXEC %pop( do);#IF (%item( @do, 1)="noRt") {#NOOP %pop( do);#SET doit 2}} {#IF (@loop) {#STATE doit 4} {#STATE doit}}} {exp}
#COND {@roundtime>0} {} {exp}
#COND {} {#STATE doit} {wait|param=1}
#COND {} {#EXEC @loop} {wait|param=1}
#COND {@roundtime>0} {} {exp}

Since either @do or @loop must be true for the trigger (state 0) to fire, when @do wasn't true there was no need to test @loop and I just went straight to state 4. I also altered the #SET 2 to #STATE 3 but I'm not sure this is correct, it might need to be #STATE 2. Depends on whether you meant to skip state 2 or advance to state 2, I assumed you meant to skip state 2.
_________________
LightBulb
Senior member

Most scripts in this forum are written for Command Line entry.
Don't even open the Settings Editor unless its use is specified or obvious.
Reply with quote
geniusclown
Magician


Joined: 23 Apr 2003
Posts: 358
Location: USA

PostPosted: Tue Sep 14, 2004 5:45 am   
 
I do realize that exp trigger states wait for variables to change, but I thought that they would check immediately when going into the state in the first place. I wonder if throwing in a line such as #ALA +0.01 do=@do could make it evaluate immediately?

Yes, I wanted to skip over state 2, which is where it waits for a roundtime... having the member "noRt" is intended to tell the trigger not to wait for roundtime before advancing. However, using #STATE doit 3 will accomplish the same thing.

Your solution seems a bit redundant, which is probably why I hadn't thought about it... my whole point of the core is to elimanate redundant code I have running rampant in my classes... It looks like it'll do what I need it to, so I'll try it out next time I'm in game.

You're living up to your namesake yet again, LightBulb, as always. I appreciate the insight.
_________________
.geniusclown
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » zMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net