Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: SSH on Thu 08/06/2006 14:43:40

Title: Is this safe: Cancelling blocking actions
Post by: SSH on Thu 08/06/2006 14:43:40
I wondered if it would be safe to create code like this:


int storebutton;
int count;

function repeatedly_execute_always() {
if  (count>1) count--;
if (count==1 && (mouse.IsButtonDown(eMouseRight) || mouse.IsButtonDown(eMouseLeft)) && player.Moving) {
  player.StopMoving(); // Cancel wahtever blocking action was going on
}
}


function on_mouse_click(MouseButton button) {
  storebutton=button;
  count=15;
}


Why wouldn't it be? Well, if you had an interaction that did:


function hotspot1_a() {
  // script for Hotspot 1 (Hotspot 1): Interact hotspot
  player.Walk(hotspot[1].WalkToX, hotspot[1].WalkToY, eBlock);
  player.Say("Done");
}


then stopping the character walkign in rep_ex_always will leave the Say function never called. Does AGS build up some stack of "hung functions" when you do this, or does it just give up on them? Becasue it seems to work in a quick test (i.e. clicking during blocking stops the action) but maybe after 100 or 1000 cancelled walks, it would die?

Title: Re: Is this safe: Cancelling blocking actions
Post by: Kweepa on Thu 08/06/2006 16:13:19
You could simulate this by using (pseudo code)


rep_ex_always
if (!player.Moving) hotspot[1].RunInteraction(eCursorMode_Interact); else player.StopMoving();


and just let it run.
Title: Re: Is this safe: Cancelling blocking actions
Post by: Pumaman on Thu 08/06/2006 18:27:59
Yes, the code that you've posted is safe. By calling StopMoving in rep_exec_always, it will mark the character as Stopped, then the main thread will notice that the character has finished, and continue to run. I'm not sure why you claim that "Say" would never be called -- I just tried a sample game with this code and when StopMoving was called from rep_exec_always, the main scirpt resumed and the Say() was executed as expected.

For more on blocking scripts see here:
http://www.adventuregamestudio.co.uk/manual/BlockingScripts.htm
Title: Re: Is this safe: Cancelling blocking actions
Post by: SSH on Fri 09/06/2006 10:50:29
Well, in http://ssh.me.uk/cancel.zip you can click on the coloured bits at each end with the "interact" cursor and the following happens:

a) if you click away the "Doing" message, roger cancels his walk and says "Done", i.e. finishes the script
b) if you wait until he starts moving then click, he stops and doesn't say "Done"
c) if you set walkto points on the hotspots and then click to cancel, he doesn't even say "doing"

Title: Re: Is this safe: Cancelling blocking actions
Post by: Gilbert on Fri 09/06/2006 11:49:03
I think I'd found the reason of your problem, actually no matter what the second "Done" message DID display.

The problem lies in here:
if (count==1 && (mouse.IsButtonDown(eMouseRight) || mouse.IsButtonDown(eMouseLeft)) && player.Moving) {

So, if you click while he's moving, when the StopMoving(); function is called it's obvious that you must still be holding the mouse button in that particular loop, when the Display() line is executed, it's registered as a mouse click so the text goes away immediately.

If you click it while "Doing" is displayed, when you click away the text the mouse click had been registered, if you're still holding the button it won't be considered as another click when "Done" is displayed.

You may test it by adding some visible effect which won't be clicked away after the player moves (like Rawprinting a message, etc.), and you'll see the subsequent actions are indeed called.

EDIT:
Another fast way to check is, that you insert another Display() after "Done" (like "Done2" say for example), and you'll see that when you click while walking it looks as if the first "Done" is not executed (actually you clicked the text away) but the second "Done2" is still visible.
Title: Re: Is this safe: Cancelling blocking actions
Post by: Pumaman on Fri 09/06/2006 20:20:23
Yes, Gilbert's explanation sounds plausible.

Because IsButtonDown is asynchronous, you will probably detect the mouse being down before AGS actually processes it as a click itself, therefore that will then click away the Say() line.
Title: Re: Is this safe: Cancelling blocking actions
Post by: SSH on Sat 10/06/2006 07:38:36
Also, clicks usually register on MouseUp