 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Thu Feb 02, 2012 8:46 pm
Beginner scripting help request - double-casting only if target still alive |
Hello, again!
Moving on to another topic, I'm trying to learn more about conditional triggers.
Here's the scenario - I would like an alias that primes a spell, casts it twice at a target, and if it's still alive, fire it once more. If the target is dead, do not cast the third volley (save mana, allow for rebuffing, quaff potions between fights, etc.). It uses an embedded, pre-defined alias, "zz", for picking the actual spell (hence, zz $target). The idea is that usually two spells will kill it, but sometimes I've "lost my concentration" or the damage was too low to kill it on the first two shots. Also, I occasionally roll a critical hit and the target dies in one casting - it would be optimal if it would only cast once in these situations.
I was thinking of a WHILE sort of loop, but I really don't want it to spam the spells over and over again without giving me a chance to quaff a mana potion or heal after the third shot, just in case (and if I want to modify this for use on tougher mobs).
MUD responses:
1) Target is not available, because it is already dead: "Cast the spell on whom?"
2) Target has been killed: "A {MOB NAME} is DEAD!!
Framework:
Code: |
; Reload mana
#WAIT 300;quaff 'mana potion';#WAIT 500
;
; Cast the spell once!
zz $target
;
; LOGIC: Only fire again if the creature is actually there and still alive - Second volley!
zz
;
; LOGIC: Only fire again if the creature is actually there and still alive - Third time's the charm!
zz
|
It seems simple enough, but apparently I'm more simple lol. I'm thinking I need to account for either message displaying to prevent the extra spells?
I've been experimenting with #TEMP to cull for the MUD responses but to no avail so far.
Any help with those conditional pieces of logic would be much appreciated. |
|
|
 |
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Thu Feb 02, 2012 9:30 pm |
There are several ways of doing this. One that pops into mind is to have a variable @alive which has a value of TRUE if the target is alive and FALSE if the target is dead. In your script, insert #WAIT commands between zz commands, and put #IF statements around the zz commands, to test the value of @alive. Outside of the script, create triggers for "cast the spell on whom?" and "A * is DEAD" which set @alive to FALSE. You'll need some other code somewhere to set @alive to TRUE, but you'll have to figure out where it makes sense to put that.
Another way would be a complicated multistate trigger, but that is probably harder. |
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Thu Feb 02, 2012 10:23 pm |
Okay, I think that makes sense.
So feed the alias the target name, then inside the alias, determine if the given target is present and still alive. Perhaps I can force in a LOOK command or something to determine if the target is actually there. If the MUD responds with something other than "You do not see that here.", set @alive to TRUE? Then the trigger should eventually fire when it dies, setting it to FALSE. Each subsequent attempt to cast would be subject to whether @alive is TRUE or FALSE.
I might even want to set @alive to the target name, and match against the fed target name? That way I could avoid something like having the wrong toggle (like if I fled a fight, never killing the mob, and it is still "alive"). Trying to think of anything I'm missing so far.
Does that sound right? |
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Thu Feb 02, 2012 10:24 pm |
EDIT: Sorry for double posting - Somehow I managed to hit Quote and double-posted... can't find a delete post option?
|
|
|
 |
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Fri Feb 03, 2012 12:49 am |
Yeah, you could combine the target name and alive status in one variable.
You could do the test inside the zz alias, but I was figuring on doing something like:
Code: |
#WAIT 1000
#IF (@target) {zz @target}
|
That way, the script waits for the other triggers to fire (changing the value of @target), then tests @target before executing zz. |
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Fri Feb 03, 2012 11:05 am |
Sorry, I really am brand new to this language and while I think I get the logic, I'm still very much struggling with the syntax and which commands to use, when.
Maybe I'm over-thinking this, but is there a way to see if a trigger evaluates to FALSE or does it just continue to watch until it fires?
Trying to simplify this:
Alias call:
fireball (target mob name)
Alias code:
; Fire first spell
cast 'fireball' $target
;
; Was the target there and alive?
#TRIGGER {^Your fireball } {#VA alive $target}
;
; Fireball to the face until dead
#TRIGGER (@alive=$target) {cast 'fireball' $target} "" "LoopExp"
#TEMP ( is DEAD!!) {#VA alive FALSE}
I think you can see what I'm trying to do here, but does it work like that? Or does the TEMP need to be somehow inside the TRIGGER (i.e., will it ever recognize the mob has died)? |
|
|
 |
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Fri Feb 03, 2012 2:50 pm |
#TRIGGER will create a permanent trigger which will execute its action every time the trigger pattern matches. You do not want to use #TRIGGER in your alias to keep creating this trigger. The code you post above will not do what you want.
In addition "#TRIGGER (@alive=$target) {..." is completely wrong. You can't use parentheses there, and you don't even want to use a trigger. What you are looking for is #WHILE.
You are definitely overthinking this. You need two separate things--your alias and one or more triggers that set @alive to FALSE. Your alias should be something like:
Code: |
#VAR alive %1
#T+ deadtrigger
#WHILE (@alive) {
cast 'fireball' @alive
#WAIT 1000
}
|
Then in the command line, create a trigger using the following command:
Code: |
#TRIGGER deadtrigger {@alive is DEAD!!} {#VAR @alive FALSE; #T- deadtrigger}
|
Now for the explanation. The alias sets @alive to the name of your target, then turn on the trigger named 'deadtrigger'. Then it goes into a loop; as long as @alive is not FALSE, it will cast a fireball then wait for one second, then start the loop again. The reason for the one second wait is to allow time for the mud to send its response. If the mud sends the message "FillInNameOfTarget is DEAD!!", then deadtrigger fires. This resets @alive to FALSE (breaking the loop in the alias) and then deadtrigger turns itself off.
That's all you need. |
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Fri Feb 03, 2012 6:51 pm |
Rahab wrote: |
In addition "#TRIGGER (@alive=$target) {..." is completely wrong. You can't use parentheses there, and you don't even want to use a trigger. What you are looking for is #WHILE. |
I was just getting the syntax from the help file:
Quote: |
Loop Expression
The "Loop Expression" state will fire the trigger for each line that is received while the Expression given in the Pattern field is true. Normal Expression triggers only execute when the expression is true when any variable is set. The Loop Expression type is a way to continue performing an action while an expression is true. However, keep in mind that with the Loop Expression type, the expression is only tested when a new line is received from the MUD.
Consider this difference:
#TRIGGER (@a=1) {It matched!}
As soon as the variable @a becomes 1 (for example, enter "A=1" on the command line), the trigger will fire. It doesn't need any text from the MUD to execute. Now try a new Loop Expression trigger:
#TRIGGER (@a=1) {Hello!} "" "LoopExp"
Enter "A=1" on the command line. Notice this trigger doesn't fire yet. But now, for each line received from the MUD, it will fire. Set A=0 and now it will stop firing.
The Param for LoopExp gives the maximum number of times the trigger will fire. So, for example:
#TRIGGER {Zugg} {#CW high,red}
#COND {@a=1} {#BEEP} {LoopExp|Param=2}
This will wait for the "Zugg" text from the MUD. Then, if @a=1 it will beep for the next 2 lines, or until @a stops being 1, whichever happens first. If @a isn't equal to 1 when the first state matches, the trigger will reset back to the first state. |
It seemed like a good way to force the trigger to continuously fire until the value of @alive changed.
Still, your example looks much cleaner and easier to follow. One question, though - it looks like you would have to send the exact mob name into the alias with that design. If you use a partial name, it looks like the trigger will hunt for the partial name in the "@alive is DEAD!!" pattern. I thought I saw a pattern match string that can account for this (still learning this piecemeal). Could I use something like:
Code: |
#TRIGGER deadtrigger {^%a@alive%a is DEAD!!} {#VAR @alive FALSE; #T- deadtrigger} |
|
|
|
 |
Rahab Wizard
Joined: 22 Mar 2007 Posts: 2320
|
Posted: Fri Feb 03, 2012 9:22 pm |
Yes, you could do something like that, which would let you use shorter forms of the name (clever idea there!). The easiest trigger pattern to do this would be:
Code: |
#TRIGGER deadtrigger {@alive* is DEAD!!} {#VAR @alive FALSE; #T- deadtrigger}
|
Since the pattern doesn't start with ^, it won't matter if the name you use is not the first part of the full name; it will still match. And the * will match anything you didn't include at the end of the name.
One thing to worry about with this, though is to be sure to use an abbreviated form of the name that won't be accidentally confused with some other critter that might die in the middle of things. For instance, if you have Kendra and Dragon in the room, don't use "dra" in your alias...
[edit]If you will always use a full word for your alias, you can put a space on either side of @alive in your pattern to make sure it only matches a full word. |
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Sat Feb 04, 2012 12:54 am |
Sweet. This is working pretty well now, with one exception. Occasionally, the target mob flees, or moves to another room before the script can fire.
The MUD text when you cast a spell on a non-existant target is "They aren't here." (always at the beginning of the line).
Is this a case where I need to create a #COND clause?
Code: |
#COND deadtrigger {^They aren't here.} {#VAR @alive FALSE; #T- deadtrigger} |
|
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Sat Feb 04, 2012 1:03 am |
Nevermind - I resolved it by adding a second trigger. Works REALLY well... I can't thank you enough for the help. Learning quite a bit just scanning this forum!
|
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Sat Feb 04, 2012 1:39 am |
I've also improved it a bit by quaffing mana pots only when necessary (the cost of one casting of fireball is about the amount a mana pot refills).
Code: |
Start of the alias, outside the WHILE loop:
#LOOP @mpots {quaff mana}
#VAR mpots 0
Inside the WHILE loop:
#VAR mpots (@mpots + 1) |
So this basically counts how often I've actually cast the spell, and only uses that many mana potions. It's not perfect, as I've seen it miscount due to some logic error in my placement but the margin of error is minimal (occasionally quaffs to pots when it should only use one). I can live with that until I improve my skills :) |
|
|
 |
AtriumXP Beginner
Joined: 02 Feb 2012 Posts: 16
|
Posted: Sun Feb 19, 2012 4:37 pm |
Another improvement, using the PROMPT variables to monitor health. It also does away with counting the spells altogether, and instead just quaffs with each iteration. Much cleaner this way and probably more efficient.
Code: |
#VAR alive %1
#VAR first 0
#MATH checkhpforpot .85*@maxhp
;
#T+ deadtriggera
#T+ deadtriggerb
#T+ deadtriggerc
;
#WAIT 500
#WHILE (@alive) {
#IF (@first < 1) {#VAR first 1;zz @alive} {zz}
quaff mana
#IF (@hp < @checkhpforpot) {quaff 'blue potion'}
#WAIT 500
#IF (@hp < @checkhpforpot) {quaff 'blue potion'}
#T+ deadtriggerc
#WAIT 1000
} |
I know that second instance of " #T+ deadtriggerc" (inside the WHILE loop) looks weird but if I don't have it there, the script sometimes fails to fire it. Probably a logic error I'm overlooking, but this is a simple fix that definitely works. |
|
|
 |
|
|
|
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
|
|