Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Lazarus on Thu 26/01/2006 09:36:55

Title: Walk to object before interaction?
Post by: Lazarus on Thu 26/01/2006 09:36:55
Hi I'm in the process of making a new template and I'm having a problem with the "Walk to" cursor.

In the template I have set cursor 9 as the default "Walk to" as I wanted this to appear in the
object/ hotspot interaction window.

The problem I have is that the player character performs the interaction then walks over to it, is there away to change this so the player character walks to the object/hotspot first then performs the interaction?

In the Script Header I have:
#define eModeWalkto 0 // setting cursor 9 to use mode 0

and in "on mouse click" I have
else if (button==eMouseLeft) {
ProcessClick(mouse.x, mouse.y, mouse.Mode);
  if (mouse.Mode == eModeWalkto) {
   if (IsInteractionAvailable(mouse.x,mouse.y, eModeWalkto) == 1){
    ProcessClick(mouse.x, mouse.y, eModeWalkto);
    }
  }
else ProcessClick(mouse.x, mouse.y, eModeWalkto);
}


any help wouild be grateful

*I'm using ags 2.70 at present becuase I'm in the middle of a project*
Title: Re: mouse.Mode (eModeWalkto)
Post by: Ashen on Thu 26/01/2006 11:03:59
Firstly, I'm not sure why you've got the if ... else there for eModeWalkto, since it'll run without checking if the interaction isn't available when the mode is anything else.

Secondly, if you want the eModeWalkto interaction to run before the mouse.Mode interaction, try putting the script first:


else if (button==eMouseLeft) {
  if (mouse.Mode == eModeWalkto) {
    if (IsInteractionAvailable(mouse.x,mouse.y, eModeWalkto) == 1){
      ProcessClick(mouse.x, mouse.y, eModeWalkto);
    }
  }
  else ProcessClick(mouse.x, mouse.y, eModeWalkto);
  ProcessClick(mouse.x, mouse.y, mouse.Mode);
}
Title: Re: mouse.Mode (eModeWalkto)
Post by: Lazarus on Thu 26/01/2006 11:25:53
I tried your code and all that happened was the interaction was performed for the object, but didn't walk to it .
Title: Re: mouse.Mode (eModeWalkto)
Post by: Ashen on Thu 26/01/2006 11:34:56
So, now it's not walking at all, rather than just at the wrong time?

OK, break it down further:
What are you trying to make it do, exactly? Why have you set cursor 9 as the "default walk to", if you're just making it run cursor 0?
By default, cursor 0 won't do anything when clicked on (I think) objects and characters. It's also non-blocking, so if that's all that's running, the ProcessClick(mouse.x, mouse.y, mouse.Mode) command might also be cancelling it - while previously it was running after any blocking commands. Sorry, I thought you'd set it to run a different interaction.

Can you give an example of the interactions that don't work?
Title: Re: mouse.Mode (eModeWalkto)
Post by: Lazarus on Thu 26/01/2006 11:51:42
Ok I think it was a bit confusing so now "Walk to" cursor is back to normal and cursor 9 is now "Go to"

What I'm aiming for is to be able to click on object/hotspot
the character then walks to object and preforms the interaction in this case "Go to".
As an example under "Got to" interaction he might display a message or change room.

I'm trying to set it up so that it has the same effect as say walking onto a region.

else if (button==eMouseLeft) {
Ã,  if (mouse.Mode == eModeWalkto) {
Ã,  Ã,  if (IsInteractionAvailable(mouse.x,mouse.y, eModeGoto) == 1){
Ã,  Ã,  Ã,  ProcessClick(mouse.x, mouse.y, eModeWalkto); // walk to object
Ã,  Ã,  Ã,  ProcessClick(mouse.x, mouse.y, eModeGoto); // perform action
Ã,  Ã,  }
Ã,  }
Ã,  else ProcessClick(mouse.x, mouse.y, eModeWalkto);
Ã,  ProcessClick(mouse.x, mouse.y, mouse.Mode);
}
Title: Re: mouse.Mode (eModeWalkto)
Post by: Ashen on Thu 26/01/2006 12:09:40
OK, see if I've got this straight:

  else if (button == eMouseLeft) {
    if (mouse.Mode == eModeWalkto) {
      if (IsInteractionAvailable(mouse.x, mouse.y, eModeGoto) == 1) {
        ProcessClick(mouse.x,  mouse.y,  eModeGoto);
      }
      else ProcessClick(mouse.x, mouse.y, eModeWalkto);
    }
    else ProcessClick(mouse.x, mouse.y, mouse.Mode);
  }


This will:
- Check if the mode is eModeWalkto.
- If it is, it'll either run the interaction for eModeGoto (if there is one), or eModeWalkto (if not).
- If the mode isn't eModeWalkto, it'll process the click as normal.

Is that right so far?

Now, you can either include the 'walk to object' part in the 'Go to' interaction (which would give you more control over where exactly they ended up), or add a blocking player.Walk(...) command to on_mouse_click:
      if (IsInteractionAvailable(mouse.x, mouse.y, eModeGoto) == 1) {
        player.Walk(mouse.x, mouse.y, eBlock);
        ProcessClick(mouse.x,  mouse.y,  eModeGoto);
      }

(NOTE: If you use the player.Walk command, you might have to store the coordinates - in case  the mouse has moved before it gets to the ProcessClick.)
Title: Re: mouse.Mode (eModeWalkto)
Post by: Lazarus on Thu 26/01/2006 12:21:53
Ok
player.Walk(mouse.x, mouse.y, eBlock);
works.
how do you go about storing the coordinates if they change there mind while walking to the object?
Title: Re: mouse.Mode (eModeWalkto)
Post by: Ashen on Thu 26/01/2006 12:34:39
Just use ints:


      if (IsInteractionAvailable(mouse.x, mouse.y, eModeGoto) == 1) {
        int xpos = mouse.x + GetViewportX();
        int ypos = mouse.y + GetViewPortY();
        // Get Viewport X/Y are there for scrolling rooms
        player.Walk(xpos, ypos, eBlock);
        ProcessClick(xpos, ypos,  eModeGoto);
      }


But that only stores against the mouse moving during the walk, not against the player changing their mind and clicking somewhere else. (I think you added the bit about it being like a region after I'd made my last post.) In that case, you'd probably want non-blocking movement, which would be trickier to set up.

EDIT:
Make xpos and ypos global (or at least able to be used in the whole global script), and add a bool called GoneTo:

//Top of global script
int XPos;
int YPos;
bool GoneTo;


Then change the condition in on_mouse_click to:

  else if (button == eMouseLeft) {
    if (mouse.Mode == eModeWalkto) {   
      if (IsInteractionAvailable(mouse.x, mouse.y,eModeGoTo) == 1) { 
        XPos = mouse.x + GetViewportX();
        YPos = mouse.y + GetViewportY();
        GoneTo = true;
      }
      else GoneTo = false;
      // This cancels the action if they click somewhere else along the way.
    }
    ProcessClick(mouse.x, mouse.y, mouse.Mode);
  }


Finally, add a check to repeatedly_execute to run the GoTo interaction - if needed - when the player stops moving:

  if (GoneTo == true && player.Moving == false) {
     ProcessClick (XPos,  YPos,  eModeGoTo);
     GoneTo = false;
  }


And that should give you non-blocking movement, followed by an action which can be cancelled by clicking elsewhere. Might take a little changing, depending on how you want to handle other modes - for example can any click anywhere cancel it, or just one that runs another interaction?
Title: Re: Walk to object before interaction?
Post by: Lazarus on Fri 27/01/2006 09:53:21
Thanks for the hard work I would never have come up with that solution.

Edit:
I did some testing and when player changes their mind while walking to an (object1) works fine if they cancel with the "walk to" command.

But if say they change their mind and "look at" another (object2) the interaction for "look at" runs (object2), then the interaction for (object1) then continues.

Is there away for any sort of interation to cancel the first interaction?

Many thanks again

Edit:
Thats fixed it thank you again Ashen
Title: Re: Walk to object before interaction?
Post by: Ashen on Sat 28/01/2006 09:06:27
You just need to change the conditions around:
  else if (button == eMouseLeft) {
    if (mouse.Mode == eModeWalkto && IsInteractionAvailable(mouse.x, mouse.y,eModeGoTo)) { 
        XPos = mouse.x + GetViewportX();
        YPos = mouse.y + GetViewportY();
        GoneTo = true;
    }
    else {
      GoneTo = false;
      player.StopMoving(); // Otherwise - if you clicked somewhere without an interaction - the character will finish the walk to but not do the action.
    }
    ProcessClick(mouse.x, mouse.y, mouse.Mode);
  }