[SOLVED] How to allow eModeWalkto to trigger AnyClick function on Hotspots?

Started by Feenyx, Wed 15/10/2014 19:41:53

Previous topic - Next topic

Feenyx

Here is the thing,

Is there a way in AGS 3.3.0 to change the scripts to allow the eModeWalkto click on hotspot to trigger AnyClick and to avoid a lot of struggle by adding regions / restored walkable areas for changing room?
I've already tried to set the "Automaticly move the Player in walk mode" from the game settings, but the character doesn't move to the hotspot anymore.

Note: Also, I have to be able to open/close doors using the Interact function, so I don't want to use that same function to change rooms.

From previous thread:

Quote from: Khris on Wed 27/08/2014 16:04:14
Walk-to point causes the player to walk to the hotspot, but the function is never called (since eModeWalkto clicks on hotspots send the player to the WalkToPoint by default but don't trigger AnyClick()).

Two solutions: either use a region and its "steps onto" event for the room change, or use "interact with hotspot" and the interact cursor mode (either the player has to interact with the ladder to use it, or left-clicking on hotspots automatically runs the "interact with" event, depending on the UI you're using).

Here is what I got:

Code: ags

function oDoor1_Interact()  //Object of Closed door
{
oDoor1.Visible = false;  //Will OPEN the door (visually)
}

function hDoor1_Interact()  //Hotspot of Opened door
{
oDoor1.Visible = true;  //Will CLOSE the door (visually)
}

function hDoor1_AnyClick()  //Hotspot of Opened door
{
player.ChangeRoom(5, 948, 232);
}


Here is another out dated post that could help but which was said to not be compatible with AGS 3+:

Quote from: mchammer on Tue 29/01/2008 21:05:39
This is from old thread, havent tested it tho so im not sure if it works:
Quote
Yeah, by default AGS won't run anyclick interaction while in walk mode. To change that behavior open the general settings pane and put a tick next to the "Don't automatically move character in walk mode" option. But with that option enabled that player won't be able to move around, therefore to correct it you have to adjust the on_mouse_click function in the global script by putting an explicit code that handles moving:

function on_mouse_click(int button) {
   // called when a mouse button is clicked. button is either LEFT or RIGHT
   if (IsGamePaused() == 1) {
   // Game is paused, so do nothing (ie. don't allow mouse click)
   }
   else if (button==LEFT) {
      if (GetCursorMode() == MODE_WALK) MoveCharacter(GetPlayerCharacter(), GetViewportX()+mouse.x, GetViewportY()+mouse.y);
      ProcessClick(mouse.x, mouse.y, GetCursorMode());
   }
   else {   // right-click, so cycle cursor
      SetNextCursorMode();
  }
}

Code there is bit old, I guess new code would be something like that:
Code: ags

function on_mouse_click(MouseButton button) // called when a mouse button is clicked. button is either LEFT or RIGHT
  {
  if (IsGamePaused() == 1) // Game is paused, so do nothing (ie. don't allow mouse click)
    {
    }
  else if (button == eMouseLeft) 
    {
    if (mouse.Mode = eModeWalkTo) player.Walk(GetViewportX()+mouse.x, GetViewportY()+mouse.y,eNoBlock, eWalkableAreas);
    ProcessClick(mouse.x,mouse.y, mouse.Mode);
    }
  else // right-click
    {
    mouse.SelectNextMode();   
    }
  }


Please help? ???

Cassiebsg

Don't know how to solve your problem, but a solution could be to have another object for the open door, and so the player clicks on the open door object to close it, and the hotspot of the open door, to change room. Think it would a logical solution for the player to understand what is he/she is doing. ;)
There are those who believe that life here began out there...

Feenyx

Quote from: Cassiebsg on Wed 15/10/2014 20:02:30
Don't know how to solve your problem, but a solution could be to have another object for the open door, and so the player clicks on the open door object to close it, and the hotspot of the open door, to change room. Think it would a logical solution for the player to understand what is he/she is doing. ;)

For some doors, once opened, you can't even see them anymore, so that would be a problem if I wish to close it again.

Basically, I want to do like in Day of the Tentacle, where Bernard uses functions like "Open", "Close" (I combined those within the Interact function in AGS). However, in AGS, the eModeWalkto is not considered an interaction.

Cassiebsg

You're not doing a 100% identical game (otherwise you would need to use the original verbs), so where the door open/disappears to, is entirely your choice. ;)

But maybe Khris or someone with more experience will have a solution for your problem.
There are those who believe that life here began out there...

Crimson Wizard

Quote from: Feenyx on Wed 15/10/2014 20:46:20
Basically, I want to do like in Day of the Tentacle, where Bernard uses functions like "Open", "Close" (I combined those within the Interact function in AGS). However, in AGS, the eModeWalkto is not considered an interaction.
Have you considered using 9-verb MI template? It already simulates 9 commands in Lucas Arts style (Push, Pull, Open, Close etc).

Regarding your question, in AGS you may intercept any mouse clicks and do what you like with them, in "on_mouse_click" function (in GlobalScript). You may also force-trigger any kind of event anytime you want.

For example (based on default template):
Code: ags

function on_mouse_click(MouseButton button) // called when a mouse button is clicked. button is either LEFT or RIGHT
{
  if (IsGamePaused() == 1) // Game is paused, so do nothing (ie. don't allow mouse click)
  {
  }
  else if (button == eMouseLeft) 
  {
    // if it is walk-to command
    if (mouse.Mode == eModeWalkto)
    {
      // if there's a hotspot under mouse cursor
      if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot)
      {
        // then fire "interact" event
        ProcessClick(mouse.x, mouse.y, eModeInteract);
        return; // do not do anything else
      }
    }
    // in all other cases - just do default action
    ProcessClick(mouse.x,mouse.y, mouse.Mode);
  }
  else // right-click, so cycle cursor
  {   
    mouse.SelectNextMode();
  }
}

Feenyx

Quote from: Crimson Wizard on Wed 15/10/2014 20:59:59
For example (based on default template):
Code: ags

function on_mouse_click(MouseButton button) // called when a mouse button is clicked. button is either LEFT or RIGHT
{
  if (IsGamePaused() == 1) // Game is paused, so do nothing (ie. don't allow mouse click)
  {
  }
  else if (button == eMouseLeft) 
  {
    // if it is walk-to command
    if (mouse.Mode == eModeWalkto)
    {
      // if there's a hotspot under mouse cursor
      if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot)
      {
        // then fire "interact" event
        ProcessClick(mouse.x, mouse.y, eModeInteract);
        return; // do not do anything else
      }
    }
    // in all other cases - just do default action
    ProcessClick(mouse.x,mouse.y, mouse.Mode);
  }
  else // right-click, so cycle cursor
  {   
    mouse.SelectNextMode();
  }
}


Great this worked! The eModeWalkto worked as AnyClick on my Hotspot.

However, this creates another problem. How do I make it to close the door if I use the Interact function without interpreting it for AnyClick?
Is that possible?

Feenyx

Quote from: Crimson Wizard on Wed 15/10/2014 20:59:59
Have you considered using 9-verb MI template? It already simulates 9 commands in Lucas Arts style (Push, Pull, Open, Close etc).

I wanted to use Sierra's interface but I'm starting to think that it would be simpler to just switch back to LucasArts UI. But the "Walk" button probably would show the same situation with the Hotspots. Right?

Crimson Wizard

Quote from: Feenyx on Wed 15/10/2014 21:12:45
However, this creates another problem. How do I make it to close the door if I use the Interact function without interpreting it for AnyClick?

Well, you don't have to use "interact" there, you may change for, e.g., eModePointer (this is the most "generic" mode I know).
Code: ags

ProcessClick(mouse.x, mouse.y, eModePointer);


Quote from: Feenyx on Wed 15/10/2014 21:17:22
Quote from: Crimson Wizard on Wed 15/10/2014 20:59:59
Have you considered using 9-verb MI template? It already simulates 9 commands in Lucas Arts style (Push, Pull, Open, Close etc).

I wanted to use Sierra's interface but I'm starting to think that it would be simpler to just switch back to LucasArts UI. But the "Walk" button probably would show the same situation with the Hotspots. Right?
AFAIK they have their own custom system there, which is different from default one in AGS.
You'd better first read comments in their script. Also there was a manual in PDF format, but I forgot where I found one. You may ask in the template thread: http://www.adventuregamestudio.co.uk/forums/index.php?topic=38874.0
E: BTW that reminds me, we forgot to include their PDF to AGS 3.3.0 package. :(

Ghost

The 9Verb Template is a pretty nifty bit of code; it's really all custom made and, if you're willing to dig through the (extensive) codebase you can alter and simplify/extend it to fit your needs. It's quite a lot especially when you're just starting off, but the current maintainers are friendly and will probably be able to help you out quickly.

There was another thread where Khris posted a code snippet to catch AnyClick and make it do pretty much whatever you wanted it "to be". I will see if I can find the link.

I agree that it is an odd choice to combine a classic of ONE company with the trademark interface of ANOTHER. DOTT was one of the last games that used the classic verb interface for some genuinely good puzzles (which would've fallen flat with a simpler (BASS) GUI).
Since you already spend a lot of time to make the remake look very close to the classic, I'd consider using SCUMM.

__
edit:
HERE is the pdf manual for the 9Verb template. Good thing some of us are still on AGS 3.2.1 :=
https://www.mediafire.com/?ssa7lq8g72jwer1


Feenyx

Thanks for all the good answers and suggestions. I will definitely take a look at this. (nod)

Feenyx

Quote from: Crimson Wizard on Wed 15/10/2014 21:40:21

Well, you don't have to use "interact" there, you may change for, e.g., eModePointer (this is the most "generic" mode I know).
Code: ags

ProcessClick(mouse.x, mouse.y, eModePointer);



Thanks Crimson, but how to I use that within the script?

Crimson Wizard

Quote from: Feenyx on Thu 16/10/2014 16:26:29
Quote from: Crimson Wizard on Wed 15/10/2014 21:40:21

Well, you don't have to use "interact" there, you may change for, e.g., eModePointer (this is the most "generic" mode I know).
Code: ags

ProcessClick(mouse.x, mouse.y, eModePointer);



Thanks Crimson, but how to I use that within the script?

If I understood you right, you wanted to use Interact to open/close the door, and Any (other) Click to do something else, right?
First replace the mode you use to trigger AnyClick for WalkTo cursor to something except Interact, for example - Pointer:
Code: ags

      // if there's a hotspot under mouse cursor
      if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot)
      {
          // then fire "interact" event
          ProcessClick(mouse.x, mouse.y, eModePointer);
          return; // do not do anything else
      }


Now, in the AnyClick event you need to check the mouse cursor mode. If it is Interact, then do nothing, otherwise continue as usual. This way if player clicked on hotspot with Interact cursor, it will process only actions in Interact handler, and not AnyClick actions.
Code: ags

function hDoor1_AnyClick()  //Hotspot of Opened door
{
    if (mouse.Mode != eModeInteract)
    {
        player.ChangeRoom(5, 948, 232);
    }
}

Feenyx

Quote from: Crimson Wizard on Thu 16/10/2014 16:50:11
If I understood you right, you wanted to use Interact to open/close the door, and Any (other) Click to do something else, right?
First replace the mode you use to trigger AnyClick for WalkTo cursor to something except Interact, for example - Pointer:
Code: ags

      // if there's a hotspot under mouse cursor
      if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot)
      {
          // then fire "interact" event
          ProcessClick(mouse.x, mouse.y, eModePointer);
          return; // do not do anything else
      }


Now, in the AnyClick event you need to check the mouse cursor mode. If it is Interact, then do nothing, otherwise continue as usual. This way if player clicked on hotspot with Interact cursor, it will process only actions in Interact handler, and not AnyClick actions.
Code: ags

function hDoor1_AnyClick()  //Hotspot of Opened door
{
    if (mouse.Mode != eModeInteract)
    {
        player.ChangeRoom(5, 948, 232);
    }
}


This worked nicely! However what if I don't want the eModeLookat or the eModeTalkto or the eModeUseinv to be considered as AnyClick as well?
I'm sorry, I just figured out now that what I needed is the AnyClick to be replaced with eModeWalkto only and the eModeInteract for open/close doors as a priority over AnyClick (Walkto).

Crimson Wizard

Quote from: Feenyx on Thu 16/10/2014 17:43:43
This worked nicely! However what if I don't want the eModeLookat or the eModeTalkto or the eModeUseinv to be considered as AnyClick as well?
I'm sorry, I just figured out now that what I needed is the AnyClick to be replaced with eModeWalkto only and the eModeInteract for open/close doors as a priority over AnyClick (Walkto).

Hmm, maybe you should use custom UserMode instead. There are two extra cursor modes called Usermode1 and 2. Just use their events as "custom action" for your door; that is -

ProcessClick(mouse.x, mouse.y, eUsermode1);

and create a new event handler for that mode.
You may also rename the mode to something more appealing, like "CustomAction".

Feenyx

Quote from: Crimson Wizard on Thu 16/10/2014 18:31:04
Hmm, maybe you should use custom UserMode instead. There are two extra cursor modes called Usermode1 and 2. Just use their events as "custom action" for your door; that is -

ProcessClick(mouse.x, mouse.y, eUsermode1);

and create a new event handler for that mode.
You may also rename the mode to something more appealing, like "CustomAction".

That would also be an option but that would mean I have to use a different cursor than Walkto just to change rooms?

Crimson Wizard

Quote from: Feenyx on Thu 16/10/2014 19:01:27
That would also be an option but that would mean I have to use a different cursor than Walkto just to change rooms?
No, you are still using WalkTo mode, but you simulate the custom mode event when the WalkTo is clicked on hotspot with ProcessClick.

Feenyx

Quote from: Crimson Wizard on Thu 16/10/2014 18:31:04
Hmm, maybe you should use custom UserMode instead. There are two extra cursor modes called Usermode1 and 2. Just use their events as "custom action" for your door; that is -

ProcessClick(mouse.x, mouse.y, eUsermode1);

and create a new event handler for that mode.
You may also rename the mode to something more appealing, like "CustomAction".

Do you think that you could show me how to write it in the scripts? I guess I can't figure it out on my own just yet. :( Thanks for your patience.

Crimson Wizard

Okay, in the aforementioned on_mouse_click you change the script like this:
Code: ags

      // if there's a hotspot under mouse cursor
      if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot)
      {
          // then fire "interact" event
          ProcessClick(mouse.x, mouse.y, eModeUsermode1); <----- note I am using custom Usermode1 here
          return; // do not do anything else
      }


Now go to the Hotspot's events panel (it is where you have already have "Interact" and "AnyClick" events) and find "Usermode1 hotspot" entry. Select it and click on "..." to create a new event handler. It will be named something like hDoor1_Mode8 by default, but you may call it differently, just make sure that name in script matches the name in events table.
Move all the code from "hDoor1_AnyClick()" to "hDoor1_Mode8()".
You may delete hDoor1_AnyClick afterwards, just don't forget to remove its name from the hotspot's events table.

Feenyx

Thank you so much Crimson, this works perfectly! I cannot thank you enough!!

SMF spam blocked by CleanTalk