Jump to content

scripting weirdness


Avenger

Recommended Posts

Here is a small script:

 

IF
 Global("ping","global",1)
THEN
 RESPONSE #100
   DisplayString(Myself,11)  
   Wait(10)
   DisplayString(Myself,1)  
END

IF
 Global("ping","global",2)
THEN
 RESPONSE #100
   DisplayString(Myself,12)  
   Wait(10)
   DisplayString(Myself,2)  
END

 

If i use the console and set ping to 1, i see strref #11 and after 10 seconds strref #1

All fine.

But if i set ping to 1 and then set ping to 2 within 10 seconds, i see only #11, then i

see #12 and after 10 seconds #2.

What happens to #1 :)

How does the engine know that it should scratch the queued actions?

Link to comment

Wanna hear a dumb answer?

 

You wont see 1 anymore because the global 2 overwrote it.

 

see... told ya a dumb answer. its like variables if you set the variable once then later set it again and dont have a placeholder for the first one then the second one will overwrite the first one. (hope that came out right and dont sound like gibberish)

 

:)

 

if i am totally off track just delete my post so the whole community dont see that i am an idiot.

 

:D

 

ronin

Link to comment

Wait() must not be a locking action?

 

I don't think anybody knows where and under what circumstances the engine will decide to drop actions from the queue, especially since nobody knows which actions actually go on the queue, nor how the engine handles actions on the queue, nor whether there really is a queue or we just make this shit up. ;-)

 

In IE, the solution is to either wrap it with SetInterrupt() actions, or split it up into multiple blocks.

 

Short answer: not a clue, sorry.

Link to comment

While it (the first wait) was waiting you set the variable ping to 2 so you will never see ping as 1. I think the wait could be valid for the first block and the second fires while the first block is still waiting. A simple test could tell you, change the second ping to ping1 and see if you see 11 and then right afterwards 12.

 

ronin

Link to comment

IF
 Global("ping","global",1)
THEN
 RESPONSE #100
   setglobal("ping","global",2)
setinterrupt(false)
   DisplayString(Myself,11)  // ~Firewall north~
   Wait(10)
setinterrupt(true)
   DisplayString(Myself,1)
END

 

yes, modifying the code this way:

if i have the setinterrupts in place, then i see #11 <delay> #1 and #12 <delay> #2

If i leave them, i will never see #1.

I guess this isn't as terrible as i first thought, it simply means, the queue is cleared when a new block is put on it :)

Setinterrupt can prevent this as expected.

 

[edit]

of course, i forgot about continue()

I wonder what happens if i just continue()-d.

Link to comment
Wait() must not be a locking action?

 

I don't think anybody knows where and under what circumstances the engine will decide to drop actions from the queue, especially since nobody knows which actions actually go on the queue, nor how the engine handles actions on the queue, nor whether there really is a queue or we just make this shit up. ;-)

 

Well, as far as i understand, all actions that are not instants (not in instant.ids) go on the queue.

And you are right, Wait() isn't on the list.

 

Now i can continue and resolve the mysteries of ClearAllActions(), which doesn't clear ALL actions :)

Link to comment

But is it a dynamic queue? I know there exists the concept of action lists, and that the engine has a method of holding or locking AI, but I have no idea how it works. Does the engine simply handle one action list at a time (holding AI until the list is empty), or is the action list updated dynamically (as new actions are added)?

 

For the code in question, I would always do

IF
Global("Ping","GLOBAL",1)
THEN
RESPONSE #100
DisplayString(Myself,11)
Wait(10)
DisplayString(Myself,1)
SetGlobal("Ping","GLOBAL",2)
END

As long as the trigger for a block is true, I haven't seen the engine really drop the actions; I've never seen the engine try to execute the same block more than once (i.e., I've never seen a case where the above would restart during the Wait() and end up displaying 11 more than once).

 

I'm not convinced SetInterrupt() has any effect in area scripts, but I still use it for long/complex action lists. It's not very good for creature scripts, though, since they then fail to respond to things like getting attacked.

 

This is a huge problem in the Amkethran extras, if you want to check scripts where action lists are continually dropped (they execute one of the RESPONSE blocks for walking around or displaying strings, but rarely finish before starting over with a new RESPONSE block). Partially solved by using MoveToPointNoInterrupt(), but a lot still requires SetInterrupt(), which allows them to be attacked freely without consequence. :(

Link to comment

To me it seems the AI works this way:

 

if a condition is true then

if the queue isn't empty then

if this isn't a continued block then

if this is the same block as currently in the queue then do nothing

else clear the queue and mark this as the one in the queue

end

end

stuff this block in the queue

if the block ends with continue start from the beginning

end

 

So a continue-d block (one that is to be added to the block after a continue was detected in the same AI cycle) will not clear the queue it will be added to it.

The same block won't clear the queue either, it will simply leave the queue alone.

 

I hope it was clear :)

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...