Triggering on variables

Posted by Penguin on Mon 05 Aug 2002 02:27 PM — 24 posts, 89,277 views.

#0
Is it possible to trigger on variables now? Forgive me if I'm mistaken, but I thought in version 3.24, one can trigger on variables. Let's say I have a variable "Loser" and it's value is set to "Penguin".

Will I be able to set a trigger "@Loser *" which sends "emote %1". This will basically imitate whatever "Loser" (in this case, Penguin) does. Eg. When I see "Penguin roars!" I would be able to send "emote roars!" However it doesn't seem to work. Is my trigger set wrongly?
Canada #1
Since you are using the latest MUSHclient, there is one thing you could do to allow us to help you better:

Select the trigger that is giving you problems. Where you would usually hit the "edit" button to configure the trigger, instead hit the "copy" button on the right side.

Next, come to the forums here, and use your windows controls to "paste" the trigger code here. (With CTRL-V for example)

Off the cuff, it seems like your trigger should work. I don't use variables in my triggers, so I don't really have experience with this. I might try clicking the "expand variables" checkbox and see if that makes a difference.
Australia Forum Administrator #2
Quote:

I would be able to send "emote roars!"


You mean "emote Penguin" however yes, that should work, providing you check "expand variables".

I agree with Magnum, copy and paste the actual trigger so we can check it.
Canada #3
No, he says he want to copy what the person stored in the variable does, not emote to that person.
Australia Forum Administrator #4
Ah, OK. Anyway, checking "expand variables" should do it.
#5
In case anyone is still wondering what this is about, here's an example. It appears to work as requested, shown as follows:

(Note: I catch "> " 0-infinite times for my prompt. You should be able to leave that in without a problem as it can catch it 0 times.)

  <trigger
   enabled="y"
   expand_variables="y"
   match="^[&gt; ]*You say: @a (.*)$"
   regexp="y"
   send_to="2"
   sequence="10"
  >
  <send>emote %1
1: '%1'
2: '%2'
3: '%3'
4: '%4'
5: '%5'
6: '%6'
7: '%7'
8: '%8'
9: '%9'
10:'%10'</send>
  </trigger>
  <variable name="a">BLAH</variable>


Try: say BLAH does something
Then: say BLAH3 does something



Nick, please try this. I've noticed that %10 has an extra '0' character added to the end of itself on v3.24.
#6
This may not come under the same heading but anyway.. due to my infinite curiosity(stupidity), I would like to ask if there's like a way to interact with the client. (Don't worry, I'm not lacking in interactive skills with real people)

Is it possible (codable/already available) to have perhaps a trigger that when matched, gives you a choice of things to do.

Like lets say I trigger on "Llama checks you out."
Can I have perhaps a few choices (predetermined and typed out in maybe a script file or something by the user naturally) appear? Maybe have something like

(1) Run away and hide
(2) Introduce yourself
(3) Kill Llama
Make your choice:

appear and then enter either 1, 2 or 3 which are maybe aliases to do certain things?
Um do you get what I'm trying to say?
Canada #7
I take it by not commenting on your previous problem in this thread, you probably resolved it.

To answer your question, there are a number of ways you could accomplish that task.

One would be to write script to present a window to you with the options... but that wouldn't be wise, because your client would stall until you answered the question.

What I would probably do is have a subroutine send the question with 'World.Note' functions, and then I would set the actions to take within variables.

Next, I would create an "answer" alias, like "pick *" for example. The alias would call a script which would "World.Send" the variable.

Dim arrAnswers(10)

Sub Ask_Encounter_Question (TriggerName, TriggerLine, arrWilcards)
  World.Note "Llama has checked you out. Do you want to:"
  World.Note "1: Run away and hide."
  World.Note "2: Introduce yourself."
  World.Note "3: Kill Llama."
  ArrAnswers(0) = 3   'Number of valid answers for this question.
  arrAnswers(1) = "south, south, south"  'Whatever you do in the mud to "Run away and hide."
  arrAnswers(2) = "greet llama"  'Whatever you do in the mud to "Introduce yourself."
  arrAnswers(3) = "kill llama"  'Whatever you do in the mud to "Kill Llama."
End Sub

Alias: pick *
Label: Select_Answer
Script: Act_on_Answer

Sub Act_on_Answer (AliasName, AliasLine, arrWildcards)
  Dim x
  If Not IsNumeric(ArrWildcards(1)) Then
    World.Note "Invalid answer: You must pick a number."
  Else
    If CInt(arrWildcards(1)) > arrAnswers(0) Then
      World.Note "Invalid answer: Not one of the choices."
    Else
      World.Send arrAnswers(CInt(ArrWildcards(1)))
    End If
  End If
  'Clear the answers using a For-Next loop:
  For x = LBound(arrAnswers) to UBound(arrAnswers)
    arrAnswers(x) = Empty
  Next
  arrAnswers(0) = 0
End Sub
Amended on Tue 06 Aug 2002 05:12 PM by Magnum
Australia Forum Administrator #8
Quote:

Note: I catch "> " 0-infinite times for my prompt.

match="^[&gt; ]*You say: @a (.*)$"



Vaejor, that will catch ">" OR " " infinite times. You might mean:


match="^(&gt; )*You say: @a (.*)$"


Then you would have to emote %2, or use the other idea you (or Magnum) had to stop it going into a wildcard, which I don't remember.
Amended on Tue 06 Aug 2002 11:19 PM by Nick Gammon
Australia Forum Administrator #9
Quote:

Nick, please try this. I've noticed that %10 has an extra '0' character added to the end of itself on v3.24.


It should be %0 - all those replacement symbols are one character. You are getting %1 followed by a zero.
#10
Quote:
It should be %0 - all those replacement symbols are one character. You are getting %1 followed by a zero.


Ah, okay, well that explains it then. Don't know why I thought it was 1-10.

Quote:
Vaejor, that will catch ">" OR " " infinite times. You might mean:


match="^(&gt; )*You say: @a (.*)$"



Then you would have to emote %2, or use the other idea you (or Magnum) had to stop it going into a wildcard, which I don't remember.


Yeah, I started using [> ]* initially so I wouldn't catch it into %1 before Magnum mentioned the (?:> )* style processing, so I've stuck to it. Since my prompt is the only thing that really uses ">" or " " at the beginning of the line, I feel safe enough leaving it like that; at least until my next major rewrite of all my triggers.
#11
Yup, I have already resolved the previous problem by checking expanding variables.

As for the question thingy, let's say Llama approaches me but I don't want to run away, introduce myself or kill him. Is there a way to exit the questionaire by typing "exit" or something? And also, would I be able to also like type "exitall" to exit that particular question and stop any other triggers which may bring up questions like those until activated by myself?
Australia Forum Administrator #12
In the example presented by Magnum, you would have to reply "pick <something>" (which is an alias) to respond. Simply not answering would amount to exiting. In other words, you *can* reply "pick x" but don't have to.
#13
I copied and pasted the exact script (removing the explanation like "'Number of valid answers for this question." and "'Whatever you do in the mud to "Introduce yourself.") and set up the alias as shown. However a scripting error window pops out when I click OK on the alias configuration window. It says that

Event: Execution of line 566 column 13

Description: Syntax error
Line in error:
Alias: pick *

Line 566 of my script file contains the line:

' arrAnswers(2) = "greet llama"'

(It's arrAnswers(2) in a newline with two spaces before that, moving the cursor 13 times would then bring me to between opening bracket and the 2) I don't see anything wrong with it, since no error was detected with arrAnswers(1) or arrAnswers(2). Could someone help me out?

Also, I seem to recall that in version 3.20, errors in the script file would be brought out by the Scripting Error window while attempting to save the script file. Is it changed now?
Canada #14
Ahh... Heh heh. These three lines:

Alias: pick *
Label: Select_Answer
Script: Act_on_Answer

...I did not expect you to paste that in as a part of your script file. They were intended as instructions to you, to make that alias manually. Delete those three line.

You can copy this code below into the windows clipboard, then click your alias icon to bring up the alias menu, and click the "paste" button on the right side to add this alias:

<aliases>
  <alias
   name="Select_Answer"
   script="Act_on_Answer"
   match="pick *"
   enabled="y"
   ignore_case="y"
  >
  </alias>
</aliases>

Ok?

Incidentally, I just guessed at what your "flee" commands might be (moving in a direction)... and I put multiple commands seperated by a "," . This would probably not work on any MUD. If you wanted to put multiple commands you would do it like this:

arrAnswers(1) = "south" & vbNewline & "south" & vbNewLine & "south"

"vbNewline" is a special variable (A CONSTANT), which is built into Visual Basic. In this case, it represents hitting the 'Enter/Return' key. That's what you would use the send multiple commands for an answer.

Also, the script is not completely fool-proof. You could use "pick 0" in the mud, and it would send "3" to the mud (in this example). If you type "pick -1", it would probably cause a runtime error. (Because I forgot to check to make sure the number you answer isn't < 1).

Sub Act_on_Answer (AliasName, AliasLine, arrWildcards)
  Dim x
  If Not IsNumeric(ArrWildcards(1)) Then
    World.Note "Invalid answer: You must pick a number."
  Else
    If CInt(arrWildcards(1)) > arrAnswers(0) Then
      World.Note "Invalid answer: Not one of the choices."
    ElseIf NOT CInt(arrWildcards(1)) < 1 Then
      World.Send arrAnswers(CInt(ArrWildcards(1)))
    Else
      World.Note "Question ignored and reset."
    End If
  End If
  'Clear the answers using a For-Next loop:
  For x = LBound(arrAnswers) to UBound(arrAnswers)
    arrAnswers(x) = Empty
  Next
  arrAnswers(0) = 0
End Sub

That new code above checks to see if the answer is a number less than 1, and if so, it sends nothing to the mud, but still clears the answers. (And wouldn't cause a runtime error). ...So, to be tidy, if you didn't want to pick one of the given answers, you could use "pick 0" to reset the question.
Amended on Wed 07 Aug 2002 06:54 PM by Magnum
Canada #15
Reminder, This is PAGE 2 on the forums, Check page 1, I have a new post there too.
Quote:

And also, would I be able to also like type "exitall" to exit that particular question and stop any other triggers which may bring up questions like those until activated by myself?

Hmm. Ok, first of all, I assume you made a trigger to call the "Ask_Encounter_Question". Let's say it's something like this:

<triggers>
  <trigger
   enabled="y"
   match="Llama checks you out."
   name="Mob_Llama_Enters"
   script="Ask_Encounter_Question"
   sequence="100"
  >
  </trigger>
</triggers>

The sample label above for the trigger is "Mob_Llama_Enters". We could build a subroutine to turn the trigger on and off:

Sub Toggle_AutoQuestion (Aliasname, AliasLine, arrWildcards)
  Dim TriggerState
  Dim TriggerName
  TriggerName = "Mob_Llama_Enters"
  If World.IsTrigger(TriggerName) Then
    TriggerState = World.GetTriggerInfo(TriggerName, 8)
    If TriggerState Then
      World.EnableTrigger TriggerName, vbFalse
      World.Note "Trigger Disabled: " & TriggerName
    Else
      World.EnableTrigger TriggerName, vbTrue
      World.Note "Trigger Enabled: " & TriggerName
    End if
  Else
    World.Note "Error: Couldn't find the trigger: " & TriggerName
  End If
End Sub

That subroutine checks to see if the trigger exists. If so, if it was enabled, then it becomes disabled. If it was disabled, then it becomes enabled. You would use an alias to call that subroutine:

<aliases>
  <alias
   name="Toggle_AutoQuestion"
   script="Toggle_AutoQuestion"
   match="autoq"
   enabled="y"
   ignore_case="y"
  >
  </alias>
</aliases>

Use the copy and paste mentioned in the previous message to add that as an alias.

All of this code I have provided you works with just one trigger, hardcoded to a single mob. If you are interested in learning Visual Basic, you may want to take this on as a project, and see if you can modify the code so that it would work on multiple mobs (without duplicating the script a bunch of times for each mob) It might not be too hard.

Nick, I would like to point him to the Visual Basic Manual help file, but I don't want to navigate MS's site to find the link. Any chance you could host it yourself here as well, since so many people here are likely to need it?
Amended on Wed 07 Aug 2002 06:43 PM by Magnum
#16
lol.. I forgot to remove the alias thing from the script:P oops.
grin anyway I managed to get the questions to work:) Thanks.. however there seems to be a problem with the "autoq" command. The error message "Error: Couldn't find the trigger: Mob_Llama_Enters" appears when I type "autoq". And after typing that, the question still appears when triggered.
Canada #17
Do either:

- Replace the line:

TriggerName = "Mob_Llama_Enters"

... with a different value in quotes. Put the actual label of your 'Llama enters' trigger.

OR

- Check/Change the label of your 'Llama enters' trigger, and make sure it matches what is in quotes, above.

Incidentally, I realized later, if you enter something that causes an error, with the "pick" alias, the question gets reset anyway. For example, if you typed "pick 4", then you get told that's not an option, and the question is reset. You can't do "pick 3" after that. Indeed, You can only use the "pick" alias once, then the answers are reset! That could be a problem if you wanted to do "pick 1" and then "pick 2" after.

Why not take a stab at coding and see if you can edit the script so it's more flexible? :)
Australia Forum Administrator #18
So, "pick 4" is really "exitall?

Perhaps don't disable the alias if an invalid answer is given?

eg.


If Not IsNumeric(ArrWildcards(1)) Then
    World.Note "Invalid answer: You must pick a number."
     Exit Sub
  Else
#19
Yup, entering an invalid choice clears the question, which works quite fine for me. However I still have problems with the "autoq" thing. Just to get me back on track, "autoq" is supposed to exit all further questions which may occur due to triggers right?

Anyway the same error message still appears

Error: Couldn't find the trigger: R_question

even though I changed the label of the trigger to "R_question" and edited the value of TriggerName in the script file to "R_question" Don't see what's wrong.. unless something is wrong with the script itself?
Canada #20
Heh... Ok, I'll blame this one on Nick. :) :)

I checked the documentation for "World.IsTrigger()" here:
http://www.gammon.com.au/scripts/function.php?name=IsTrigger&searchfor=

and realized, the function returns a "0" if the trigger does exist. That contradicts standard Visual Basic Programming. If you do this:

/World.Note True

directly in the command box, you will see a "-1" result. If you change it to False, you will see a "0" result.

...So, "World.IsTrigger()" is giving us backwards results. Oh well, we will compensate. Change the appropriate line to this:

  If NOT World.IsTrigger(TriggerName) Then

...And things should work, I believe.

P.S. to Nick: I can see why you made this function the way you did... Heh, just a surprise for those of us who don't RTFM till something goes wrong... LOL.
Australia Forum Administrator #21
Strictly speaking, it returns eOK, where eOK happens to be defined as 0.

The reason was, I wanted to return more than just "true" or "false", as the other return value was "bad label".

The return of eOK is consistent with the way most other trigger routines work.

However I agree that I then do, rather confusingly, use 0 or 1 in some other places to indicate false or true, in circumstances where they are the only two valid responses.

Also, also, in Jscript (and C etc) true is 1, not -1.
Australia Forum Administrator #22
Quote:

Also, I seem to recall that in version 3.20, errors in the script file would be brought out by the Scripting Error window while attempting to save the script file. Is it changed now?


It attempts to compile script files when you save the script, and when you save an alias (etc.) with a script argument it tries to resolve that (ie. find the routine for it), so you may well get an error message at that point too.
#23
Following the Above codes i have been able to create many 'selection screens'...however...instead of using e.g 'autoq_look' or 'autoq_login' to check the current status of the selection screen, how would i be able to write a script to show all the autoq commands' status..
e.g autoq_status (and it shows autoq_look status : enabled, autoq_login : disabled...etc etc...)