Trying to disable eModeWalkto gives unexpected and inconsistent results

Started by Khris, Wed 17/07/2019 07:53:34

Previous topic - Next topic

Khris

Somebody was reporting an issue in relation to my GotThere module in combination with a two-button interface. Turns out that after deselecting the current inventory item, the game naturally reverted to eModeWalkto instead of the game's default cursor eModeInteract. While trying to fix this without changing any module code, I ran into the following, really weird behavior (AGS 3.4.1 / Default Game):

When I try to disable eModeWalkto by setting its "StandardMode" property to false:

  • game still starts with eModeWalkto active (fine, guess)
  • current cursor eModeUseinv and  player.ActiveInventory = null;  sets mode to eModeWalkto
  • mouse.SelectNextMode(); skips over it
  • turning the mouse wheel north doesn't (this is basically a "bug" in the template code, since it should be consistent with turning it south)
To be fair, StandardMode isn't used to disable the cursor, it's used to tell AGS that you want custom behavior.

When I instead call  mouse.DisableMode(eModeWalkto);  i.e. the proper method to remove a cursor from the game:

  • game starts with eModeLookat as expected
  • current cursor eModeUseinv and  player.ActiveInventory = null;  sets mode to eModeWalkto though
  • mouse.SelectNextMode(); doesn't skip over it, i.e. doesn't care if the mode is disabled or not
  • turning the mouse wheel north doesn't either (again a "bug" in the template, this time consistent with turning the wheel south)

When I turn off "StandardMode" and call  mouse.DisableMode(eModeWalkto);  I get the expected mix of the inconsistent behavior.


Conclusion:

  • mouse.SelectNextMode() needs to check whether a cursor is disabled
  • setting  player.ActiveInventory  to  null  currently does no check whatsoever on its own
  • the template's mouse wheel north handling is buggy

tilapisha

Hi Khris,

I'm trying to fix this issue in my game:
Quoteafter deselecting the current inventory item, the game naturally reverted to eModeWalkto instead of the game's default cursor eModeInteract

I am trying to create a one-click interface, using only eModeInteract and inventory items. I turned off Standard Mode for all cursors, and tried to put this
Code: ags
  mouse.DisableMode(eModeWalkto);
  mouse.DisableMode(eModeLookat);
  mouse.DisableMode(eModeTalkto);
  mouse.DisableMode(eModePickup);
in the default_options function.

The cursor still reverts to eModeWalkTo. Did you ever figure out a finite solution to this?

tilapisha

Quote from: monkey0506 on Mon 02/05/2011 05:57:18
Yeah..it might not be immediately apparent, but as I said it is by design. If you try to set it to a cursor mode and that mode is disabled, it will first look for a standard mode that is enabled. If it finds one, then that standard mode will be the mode set. If no standard mode is found enabled, then it will just look for any enabled mode. If no enabled modes are found at all, then the cursor mode isn't changed.

This knowledge is based entirely on the testing that I've done, not any examination of source code or anything. There may be other underlying things that I'm still missing, but based on the testing I've done (which has been extensive), the above information is correct.

Edit: Thanks to some additional testing by Sephiroth, it turns out that at some point between game_start and..well..the rest of the game, AGS is definitely re-enabling eModeWalkto. I don't know about other modes, but eModeWalkto is definitely restored if disabled.

I tested it in repeatedly_execute, and it is definitely possible to permanently disable it later on in the script, but you cannot disable it permanently from game_start.

Code: ags
function repeatedly_execute()
{
  mouse.Mode = eModeWalkto;
  if ((mouse.Mode == eModeWalkto) && (Game.DoOnceOnly("GOOSNARGH!")))
  {
    mouse.Mode = eModeLookat;
    mouse.DisableMode(eModeWalkto);
    mouse.Mode = eModeWalkto;
  }
  else if (mouse.Mode == eModeWalkto) AbortGame("%d", mouse.Mode);
}


The game never aborts, so disabling it was successful.

My further testing has shown that this is the most effective way of disabling eModeWalkto:

Code: ags
function on_event(EventType event, int data)
{
  if (event == eEventEnterRoomBeforeFadein)
  {
    CursorMode mode = mouse.Mode;
    if (mode == eModeWalkto) mouse.SelectNextMode();
    mouse.DisableMode(eModeWalkto);
    mouse.Mode = mode;
  }
}


It is actually re-enabled when a new room is loaded, prior to the room's room_Load function being called. You can do this in the global script's on_event function and eModeWalkto will be disabled upon entering a new room instead of it being enabled. From there it won't be re-enabled by anything other than mouse.EnableMode(eModeWalkto)..unless I've overlooked some other quirk like this one. :D

This worked!

SMF spam blocked by CleanTalk