Maintain 'SaveCursorUntilItLeaves' Between Rooms - SOLVED

Started by spooey, Mon 22/03/2021 03:26:06

Previous topic - Next topic

spooey

Hello,
As a learning exercise, I'm trying to make a loose recreation of some of the mechanics of MYST. To this end, I have set up hotspots that when clicked, send the player to a different Room corresponding to where they clicked (for example, if the player wants to look to their left, and the player clicks the hotspot over the left region of the screen, they will be sent to a room representing that viewing angle). To simulate the MYST experience further, I'm experimenting with custom cursors that point in the direction the player wants to go (points left if over the 'turn left' hotspot, right if over the hotspot to the right - that sort of thing).

The scripts I use are:
Code: ags
function hHotspot2_MouseMove()
{
  mouse.SaveCursorUntilItLeaves();
  mouse.Mode=eModeTurnleft;
}

function hHotspot2_AnyClick()
{
  player.ChangeRoom(2);
}


So the thing is:
If the mouse is moved over a 'turn left' hotspot, it changes to a new mouse.Mode (eTurnleft). If that hotspot is clicked, it transitions to Room 2. And, if you click the hotspot in Room 1 and then don't move the mouse, it will still be touching another 'turn left' hotspot that would call for eTurnleft (the hotspot in the left region of Room 2).
The problem is, following the transition, the mouse will be reset to its default mouse.Mode until it is moved, despite starting already on top of the hotspot that would turn it into eTurnleft.

My assumption is that 'hHotspot2_MouseMove()' isn't checking for the mouse touching the hotspot, it's literally checking for the mouse being moved while touching the hotspot. 'mouse.SaveCursorUntilItLeaves' may also be contributing, too, since the cursor is 'leaving' by changing rooms.

The behavior I want to do, if possible, is that if the mouse exits a screen in one Mode, and it starts in the next room on a hotspot with the same MouseMove function, that it maintains the Mode rather than waiting to be moved.

(here is a demonstration to clarify - pay attention to the cursor behavior when it is not moving)



Any help is greatly appreciated, and thanks very much for your time.

Khris

The best solution to this issue is to implement the mechanism in a global way, meaning having as little duplicate code as possible.
Adding a MouseMove handler and its code to each exit room hotspot requires tons of duplicate code, and if you ever wanted to change anything about this behavior, you'd have to edit every single hotspot.

Hotspots are one of the many things in AGS that support Custom properties, so an ideal solution here is to have a direction and newroom property, then use a bit of code in the global script. Here's example code:

Code: ags
function MouseOverExit() {
  Hotspot *h = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
  int dir = 0;
  if (h) dir = h.GetProperty("direction"); // default value: 0, up: 1, left: 2, etc.
  if (dir > 0) {
    // mouse is over exit hotspot
    mouse.ChangeModeGraphic(eModeInteract, 50 + dir);  // hand pointing left is in sprite slot 51, etc.
  }
  else {
    mouse.ChangeModeGraphic(eModeInteract, 2); //  default interact cursor sprite slot
  }
}

  // inside repeatedly_execute_always
  MouseOverExit();


Similarly, clicking an exit hotspot can be detected inside the global on_mouse_click, and the destination room can be read from the properties.
Since the cursor graphic is potentially updated 40 times per second independent of movement, this will also fix your original problem.

spooey

This works perfectly, cannot thank you enough! And it really will save so much time this way, too.

SMF spam blocked by CleanTalk