Non-blocking walks (not totally) (SOLVED!)

Started by aerguin, Tue 19/06/2007 20:44:46

Previous topic - Next topic

aerguin

Ok, I have a problem when I want my buddy to walk and do something after.
Let's say I have a Bluecup and want to Pick it up. After walking to the Bluecup, Instead of picking it up, I want him to say "too hot".

I'm using my own GUIs and MouseModes and everything that don't resemble at all anything from Sierra or Lucasarts. If, in the Pick Up interaction, I first define the Walk action as Non-blocking, and after that tell the guy to talk, he will say "too hot" right at the beginning, before reaching the cup. If I put a conditional like
if(!cEgo.Moving) DispMessage...
it won't do anything cause the program will check this IF once, right after the guy starts moving, and it won't enter.

The other option is to make the Walk Blocking. This works as the character reaches the end and then says "too hot" but it blocks EVERYTHING!! I want it to be possible that if the player changes his mind while the guy is walking towards the cup he can so something else or tell the character to go somewhere else. This is what Lucasarts games (at least fate of atlantis) do.

So I want it to be Blocking for the following actions in that interaction, but NOT for the rest of the game options. Any workarounds?

(In Hotspots there is this little nice feature so the player automatically walks to the hotspot when interacting, but it's totally blocking anyways, and the strange Action-GUI-Mode-Cursor thing I've written doesn't work too well with this feature).

I've thought about a key or something that can STOP all blocking functions. Does this exist?
Still something plainer, like a simple click, would be better.

Thanks!

Khris

#1
You seem to know your way around scripting, so I'll keep this short:

Code: ags
function went(int x, int y) {
  player.Walk(x, y);
  int mb=0;
  while(player.Moving && mb==0) {
    if (Mouse.IsButtonDown(eMouseLeft)) mb=eMouseLeft;
    if (Mouse.IsButtonDown(eMouseRight)) mb=eMouseRight;
    Wait(1);
  }
  if (mb) { // click -> walk was intercepted
    on_mouse_click(mb);
    return 0;
  }
  if (player.x==x && player.y==y) return 1; // no click -> player reached his destination
  return -1; // no click, but player wasn't able to reach his destination
}


In the interaction, use
Code: ags
if (went(180, 140)) {
  // do stuff 
}


Or use
Code: ags
int a=went(180, 140);
if (a) {
  if (a==-1) player.Say("I can't reach it.");
  else {
    // do stuff
  }
}


Afaik, it's not necessary to manually call on_mouse_click from within the function to process the intercepting click.
EDIT: It is, code corrected.

aerguin

I don't have AGS with me right now so I didn't try it but it looks like it will work in the sense that the player will stop moving with a click, good thing!

But, will the mouse clicks be processed? It looks like there are big possibilities for the "click" to come in the Wait(1) function, so if that's a Blocking function wouldn't the call to the on_mouse_click be skipped?
Of course if it does skip it I could myself call it inside the respective IF.

I'll check the program this afternoon hopefully. Thanks anyways!

Khris

This is the shortened, rewritten to new-style code version of a function from a LA-template I know to work, so there shouldn't be any problem.

And Wait(1) will only block the game for 1/40s, nobody clicks that fast ;)

aerguin

Yes, as I thought the mouse click is not processed, as the program is stuck in the while loop with the Wait function, and this effectively acts as a Blocking function. It exits the loop well though, thanks to the check to the button, and so the user is able to do something else after the first click.

It had an easy fix though. This is what I added to automatically run what the user wanted:

if (mb) // click -> walk was intercepted
{   
on_mouse_click(mb);
return 0; 
}

So now right before exiting the function with the 0, the program executes that click the user made.
Thanks a lot!!

SMF spam blocked by CleanTalk