Reading output window from a script

Posted by Jeffrey F. Pia on Wed 01 May 2002 09:01 PM — 7 posts, 28,628 views.

#0
Here's something that I haven't seen covered in previous posts.

I have a list of spells that I want to cast. Currently I use an alias "SPELLUP" which casts them all in a row, and I have a trigger to recast each spell that fails. What ends up happening is that all the spells get attempted, and any spells that fail are reattempted after the last spell on the list is tried. What I would like to do is use a script that looks something like this:

For iSpell = 1 to UBound(List)
    bSuccess = False
    iAttempt = 0
    Do
        iAttempt = iAttempt + 1
        Cast List(iSpell)
        'Read a few lines from output to determine results
        'If spell does not fail, bSuccess = true
    Loop until bSuccess or (iAttempt = 5)
    If Not (bSuccess) then
        world.send "Unable to cast " & List(iSpell)
        Exit Sub
    End If
Next iSpell

Is it possible to read X lines from the output window to catch a line that notes a spell's success or failure? I say X because the MUD's response to my casting may take a second or two, and other lines may be sent before it. Or would I have to use a Trigger to catch the line and send the results to a variable (is that possible without executing another script?), all while using a Do Loop to force the script to wait, say 3 seconds, then check the variable for results?
Amended on Wed 01 May 2002 09:04 PM by Jeffrey F. Pia
Australia Forum Administrator #1
First, in terms of reading lines, you are in luck. In the next version (3.18), planned for release any day now, you can do that. See this description:


http://www.gammon.com.au/scripts/function.php?name=GetLineInfo


However your script as written will not really work. This is because while executing a script, MUSHclient is not processing input. Thus this simply won't work as expected:


world.send "something"
'
' loop until response appears
'


Even using the new "read line" feature you need to work a bit differently. Something like this:

  1. One script (or alias or whatever) sends things
  2. A trigger notes responses as they arrive over the next few seconds - maybe storing them in variables
  3. When the time is up - either use a timer or trigger on some identifying text - look at those variables and see which spells need to be recast. Or, perhaps, use the "getlineinfo" feature to process previous lines. However I am inclined to think a trigger would be simpler.
#2
Okay, since no additional data can be processed while a script is running, the new readline feature probably won't help this situation as much as I'd like... I'd like to hear your thoughts on this pseudo-code using 4 variables, 3 scripts, 2 triggers, 1 alias, and a partridge in a pear tree:

'These variable get initialized in the code, but will start
'out with these values
sVariable1 = delimited list of spells to be cast and their Success/Fail trigger lines
'(i.e. SpellName, SuccessLine, FailLine;)

sVariable2 = sVariable1 'temp list of spells
iVariable3 = 0 'track # of attempts

'saftey check - will be set to false if sleeping, if
'healing spells become priority, etc.
bVariable4 = True

Alias1 calls Script1

'I don't remember what parameters an Alias passes, so I'll
'use 3 (like Triggers).  Doesn't matter since I'm going to
'be looking only at variables anyway.
Sub Script1 (x, y, z) 
    Check value of iVariable3 'Check # of attempts
    If iVariable3 <= 5 and bVariable4 then 'cast spell
        world.send "cast " & 1st spell in Variable2
        create 2 temp triggers (success and fail lines)
    Else 'quit after 5th attempt
        world.note "Failed cast"
        Delete temp triggers
        iVariable3 = 0
        sVariable2 = sVariable1
        Exit Sub
    End If
End Sub

Trigger1 catches failed cast line
    Call Script2

Sub Script2 (x, y, z)
    iVariable3 = iVariable3 + 1 'Count attempts
    Call Script1
End Sub

Trigger2 catches successful cast line
    Call Script3

Sub Script3 (x, y, z)
    Delete temp triggers
    iVariable3 = 0
    Delete 1st spell in sVariable2
    If sVariable2 = "" then
        sVariable2 = sVariable1
        Exit Sub
    Else
        Call Script1
    End If
End Sub
Canada #3
Just out of curiousity, can your player be in the process of casting multiple spells, at any one time?

For example, can you cast "protection spell", and while waiting for it to attempt, cast "heal spell"?

On the mud I play, you can only "concentrate" on one skill or spell at a time. I decided to write what I call a "spell queue" to work with this. My script requires a large amount of triggers though, and requires an alias for each skill/spell. If you think you may be interested, do a search in these forums for "queue", and you should find it.

I haven't posted the code, because it's usage would require all those triggers & aliases, and I couldn't be bothered to document them all, when no one seemed interested. The code was written for "Ages of Despair" which is an LPC type Mud. So far, it's only written for about 3 guilds, but adding skill/spell scriptlets is relatively easy. Mostly Copy & Paste.
Australia Forum Administrator #4
It looks broadly OK. :)

Personally I would use more meaningful names, like "sListOfSpells" rather than "sVariable1" however I guess this is just your pseudocode.
#5
Quote:

Just out of curiousity, can your player be in the process of casting multiple spells, at any one time?


Not, only one spell at a time. The actual casting is instantaneous (the only wait being normal system lag), but spell failure is a little too common for my tastes, resulting in many recasts.

Quote:

On the mud I play, you can only "concentrate" on one skill or spell at a time. I decided to write what I call a "spell queue" to work with this


Sounds interesting. How does your process differ from the process detailed above? I'd love to take a look at it. I'm always up for learning new ways of doing things.

Quote:

Personally I would use more meaningful names, like "sListOfSpells" rather than "sVariable1" however I guess this is just your pseudocode.


Yes, definitely. This was just a "quick-and-dirty" pseudo-code. The actual code will be much more readable.
Canada #6
I have just posted the bulk of my Spell Queue related code to the thread I created for it:

http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=949&page=999999

You really see how the project evolved from an idea to the final code. ...Well, sort of. :)

On my mud, when casting a spell or skill, you see this:

You begin concentrating on the spell.

After a short duration (which varries by spell), you get:

You have finished concentrating on the spell.
You heal your own wounds.

Of course, the "You heal your own wounds." changes according to whatever spell you cast. If you move from the room, you will interrupt your concentration. If you start casting a new spell, you interrupt the old one. Spells may still fail, but you aren't usually informed until concentration is complete.

My script will retry failed attempts, and you can "stack" spells so they will cast one after the other, without interrupting. You can pause the queue, too.