Seeing things last
chimeric
Member Posts: 1,163
A question to those who have experimented with creature scripts. I have this code:
Example: let's say the scripted creature is surrounded by three hobgoblins, and Hobgoblin 2 is the one in the spell state. If the creature looks no further at finding him and digs into the actions sections for orders, then all is well. But if it keeps looking - because See([ANYONE]) forces it go through ALL those in sight, and the one in the spell state is not necessarily the last to be looked at - then it's going to see Hobgoblin 3. He will be the one signed in the book as LastSeen, so the action, triggered by the spell state of one creature, will actually target another. No? Yes?
This is a practical question. I have this script for a creature who I want to attack Kagain in this spell state. So it does. However, when I remove the spell state from him and put it on Edwin (and apply a Feeblemind to make the creature run its scripts anew), it goes back to hacking at the dwarf. Edwin is in sight too, with his brand-new spell state. Might it not be that the creature thinks it's enough that someone nearby is in the spell state and then hits whoever happens to be LastSeen for it? Moving Edwin away does not help: once the creature has fixed its sights on this target, there is no reason for it to re-run the script when it's on Attack(). (Or am I wrong about this?)
I could use AttackReevaluate(), but that comes with other problems.
My first thought when I saw this stubborn behavior was that Kagain's state was never really removed. So I applied another effect that set the Global to 1, a Feeblemind, and the creature obediently calmed down. When I next set the Global to 0 again and again put Edwin in the spell state, the creature did indeed switch to him. This means Kagain's state went away as intended. The above is the only explanation I have.
I wanted to use a simple See([ANYONE]) to avoid going through Nearest, SecondNearest and so forth when this snag came up.
IF Global("C&CWHITE","GLOBAL",0) See([ANYONE]) CheckSpellState(LastSeenBy(Myself),C&CWHITE) THEN RESPONSE #100 Attack(LastSeenBy(Myself)) ENDAs you can see, this is a vision check in two parts. One is asking whether the creature sees anyone at all. Maybe it looks at them one by one, or perhaps sees them all together. The second part is asking whether, among those it sees, the last one is in that spell state (so I suppose its "gaze" goes from one to the next, after all). Then the command is for it to attack the last creature seen - it says nothing about the spell state here. By this point - by the time we get to commands - we are just using the "anchor" hooked on to the creature from the trigger. The premise is that LastSeenByMyself() in the triggers and in the actions is the same creature. Is that actually so? It should be so, but does the checking in triggers stop after the right creature is found, or does it go on?
Example: let's say the scripted creature is surrounded by three hobgoblins, and Hobgoblin 2 is the one in the spell state. If the creature looks no further at finding him and digs into the actions sections for orders, then all is well. But if it keeps looking - because See([ANYONE]) forces it go through ALL those in sight, and the one in the spell state is not necessarily the last to be looked at - then it's going to see Hobgoblin 3. He will be the one signed in the book as LastSeen, so the action, triggered by the spell state of one creature, will actually target another. No? Yes?
This is a practical question. I have this script for a creature who I want to attack Kagain in this spell state. So it does. However, when I remove the spell state from him and put it on Edwin (and apply a Feeblemind to make the creature run its scripts anew), it goes back to hacking at the dwarf. Edwin is in sight too, with his brand-new spell state. Might it not be that the creature thinks it's enough that someone nearby is in the spell state and then hits whoever happens to be LastSeen for it? Moving Edwin away does not help: once the creature has fixed its sights on this target, there is no reason for it to re-run the script when it's on Attack(). (Or am I wrong about this?)
I could use AttackReevaluate(), but that comes with other problems.
My first thought when I saw this stubborn behavior was that Kagain's state was never really removed. So I applied another effect that set the Global to 1, a Feeblemind, and the creature obediently calmed down. When I next set the Global to 0 again and again put Edwin in the spell state, the creature did indeed switch to him. This means Kagain's state went away as intended. The above is the only explanation I have.
I wanted to use a simple See([ANYONE]) to avoid going through Nearest, SecondNearest and so forth when this snag came up.
0
Comments
See() itself doesn't loop, but [0] does. So, at first the script goes through objects within owner's line of sight and matches a nearest [ANYONE] among them - which is simply nearest in this case, - and then checks if the owner can See() it and flags it as LastSeenBy().
LastSeenBy() is set by the latest See() and Detect() trigger. Triggers are evaluated once, one by one, until the script restarts.
See above. See([ANYONE]) will flag the nearest hobgoblin, but unless it has the spellstate active, the CheckSpellState() will return false and the block will fail with no action executed.
Is Kagain still closer than Edwin? If yes, then See([ANYONE]) will still return Kagain as LastSeenBy(), and since he no longer has the state, the whole block will return false.
Attack() is not a very good action, because it sticks to attacking until the target dies. I honestly don't remember if it can be interrupted in the middle by the same script, but supposedly no. Even if it does, and See()s somebody else - i.e. will have a new LastSeenBy() marker, - no new Attack() will be issued unless Edwin gets closer than Kagain. I'm a bit puzzled by what you say about feeblemind, however... If it really did break the action, then it should stand still and do nothing.
Nope, I'm afraid. Anything you can't put inside of []'s has to be checked via SecondNearest() etc.
It is still a one-second pause, though, plus the time the new check for states will take... It would be ideal if I could stick a Feeblemind in the global effects of the other spell, the one that sets the target, to hit everyone on the map who is attacking under the influence of the first spell. Pass it through Apply Effects List and a second spell state. That way choosing a new target would automatically free everyone hitting on the old one. Come to think of it, this may be necessary, or they'll never stop.