Walk to object before interaction?

Started by Lazarus, Thu 26/01/2006 09:36:55

Previous topic - Next topic

Lazarus

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:
Code: ags
#define eModeWalkto 0 // setting cursor 9 to use mode 0


and in "on mouse click" I have
Code: ags
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*
*Currently using AGS Editor 2.70 (Build 2.70.601)*

Ashen

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:

Code: ags

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);
}
I know what you're thinking ... Don't think that.

Lazarus

I tried your code and all that happened was the interaction was performed for the object, but didn't walk to it .
*Currently using AGS Editor 2.70 (Build 2.70.601)*

Ashen

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?
I know what you're thinking ... Don't think that.

Lazarus

#4
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.

Code: ags
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);
}
*Currently using AGS Editor 2.70 (Build 2.70.601)*

Ashen

#5
OK, see if I've got this straight:
Code: ags

  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:
Code: ags
      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.)
I know what you're thinking ... Don't think that.

Lazarus

Ok
Code: ags
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?
*Currently using AGS Editor 2.70 (Build 2.70.601)*

Ashen

#7
Just use ints:

Code: ags

      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:
Code: ags

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


Then change the condition in on_mouse_click to:
Code: ags

  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:
Code: ags

  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?
I know what you're thinking ... Don't think that.

Lazarus

#8
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
*Currently using AGS Editor 2.70 (Build 2.70.601)*

Ashen

You just need to change the conditions around:
Code: ags
  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);
  }

I know what you're thinking ... Don't think that.

SMF spam blocked by CleanTalk