cant disable walkto mode

Started by Rocco, Sun 01/05/2011 22:10:50

Previous topic - Next topic

Rocco

well the actual cursormode management is a pain in the ass.

ok i have several functions to prevent some modes to show up, but it wont work without problems:

Code: ags
 
function Interface_Interact()
{
    mouse.DisableMode(eModeTalkto);
    mouse.DisableMode(eModeUseinv);
    mouse.DisableMode(eModeWalkto);
    mouse.DisableMode(eModeLookat);
    
    mouse.Mode = eModeInteract;
}

I call this function for example on room_load,
but when i click the right button or turn the mousewheel, the first mode eModeWalkto appears and further rightclicking changes between the interact and walkto mode, which is an undesired behavior, cause i disabled the walkto mode explicit.

It obiviously is related to this line(s) in the global script:
Code: ags

else if (button == eMouseRight || button == eMouseWheelSouth){
    // right-click our mouse-wheel down, so cycle cursor

    if (mouse.Mode == eModeUseinv) {
      player.ActiveInventory = null;
      mouse.Mode = eModeWalkto;
    }
    else mouse.SelectNextMode();

..

else if (button == eMouseWheelNorth) { 
    // Mouse-wheel up, cycle cursors 
    // If mode isn't WALK, set the previous mode (notice usage of numbers instead
    // of eNums, when it suits us)...
    if (mouse.Mode>0) mouse.Mode=mouse.Mode-1; 

.....
if (player.ActiveInventory!=null) 
      {
        //...and the player has a selected inventory item, set mouse mode to UseInv. 
        mouse.Mode=eModeUseinv; 
      }
      else 
      {
        // If they don't, however, just set it to mode TALK (change this line if you add more cursor modes)
        mouse.Mode=eModeTalkto; 


is there another solution beside to operate in this code sections?

Sephiroth

#1
If the disable works with other modes, and it should, then SelectNextMode should skip the disabled modes. Here I can see that the interface behaviour is chosing 'eModeWalkTo' as the default next mode for 'eModeUseinv' when you right-click. You would just need to change that line to a mode like eModeInteract, like you did in the room load. Or have I missed something?

Also the line:

Code: ags

if (mouse.Mode>0) mouse.Mode=mouse.Mode-1;


It will probably not care about disabled modes.

Rocco

there is no eModeUseinv in use so this isnt the mainproblem,
unfortunatly this line mouse.SelectNextMode();
switch to the walkto mode - maybe why its the first in the list,
regardless if this mode is switched off or not.

Sephiroth

#3
This could work as a SelectPreviousMode, while skipping disabled ones.

Code: ags


//global-outside functions

bool is_enabled[10];

//game_start

int i = 0;
while(i < 10)
{
  is_enabled[i] = true;
  i++;
}

//on_mouse_south_wheel - the number 3 represents the last mousemode

if(mouse.Mode == 0)
 mouse.Mode = 3;
else
 mouse.Mode--;
 
while(!is_enabled[mouse.Mode])
{
  if(mouse.Mode == 0)
    mouse.Mode = 3; //last mode number
  else
   mouse.Mode--;
}

//when you want to disable a mode

is_enabled[eModeWalkto] = false;
mouse.DisableMode(eModeWalkTo);



This will hang if all the modes are disabled at the same time and you try to switch.

Edit: I have confirmed SelectNextMode() will skip modes you have disabled via mouse.DisableMode();  

I think the problem comes from the mouse.Mode = mouse.Mode - 1; Or another part of the code, because setting the current mouse.Mode to a disabled one will make the cursor reset to 0 (walkto). This doesn't happen with SelectNextMode(), only when you set it directly like this.

If you used the code I wrote, then you could check if the mode is enabled before changing it in other parts of the code as well.

Code: ags

if(is_enabled[eModeTalkto])
 mouse.Mode = eModeTalkto;


Sorry for the long post.

monkey0506

I've actually written some (unreleased) code for things like checking whether a mouse mode is enabled, whether it is a standard mode, etc.

I would like to note that you cannot set the mouse to a disabled mode, ever. So if the mouse mode is being set to eModeWalkto, then eModeWalkto is never being disabled. Try this:

Code: ags
mouse.Mode = eModeInteract;
mouse.DisableMode(eModeWalkto);
mouse.Mode = eModeWalkto;
if (mouse.Mode == eModeWalkto) AbortGame("eModeWalkto not disabled!");


I bet you it doesn't crash if you put that into game_start.

Even if eModeWalkto was the current mouse mode, you can still disable it just fine.

So somewhere between disabling eModeWalkto and the reported problem, you are re-enabling eModeWalkto.

Sephiroth

#5
Quoteyou cannot set the mouse to a disabled mode, ever. So if the mouse mode is being set to eModeWalkto, then eModeWalkto is never being disabled.

If you use :

Code: ags

mouse.DisableMode(eModeTalkTo);
mouse.Mode = eModeTalkTo;


It will reset the cursor to 0 (walkto) by default, if it's not disabled as well. So you need to check if the mode is enabled before changing it with something else than SelectNextMode().

I have just tested (inside on_mouse_click) with all the mouse modes disabled, setting the mouse mode to anything will just reset to walkto, I'm using AGS 3.2.

monkey0506

#6
No it doesn't. It selects the next available, enabled, standard mode.

Open up the default game. Change eModePickup to standard. Now do this:

Code: ags
function game_start()
{
  mouse.Mode = eModeUsermode1;
  mouse.DisableMode(eModeTalkto);
  mouse.Mode = eModeTalkto;
  AbortGame("mouse.Mode: %d", mouse.Mode);
}


It aborts at mouse mode 5, which, given the setup I described, is the next enabled standard mode. It doesn't reset to eModeWalkto. It also doesn't abort at eModeUseinv which is 4, but is not a standard mode.

As far as checking if any cursor mode is currently enabled, the following always works:

Code: ags
bool enabled = false;
CursorMode prevMode = mouse.Mode;
mouse.Mode = MODE_TO_TEST;
enabled = (mouse.Mode == MODE_TO_TEST);
mouse.Mode = prevMode;
//...use ENABLED as needed..


It is possible to disable eModeWalkto, and it will not be re-enabled until you do so yourself.

Edit: You said that with every cursor mode disabled that trying to change it will change it to eModeWalkto. That is not correct:

Code: ags
function game_start()
{
  mouse.Mode = eModeInteract;
  int i = 0;
  while (i < Game.MouseCursorCount)
  {
    if (i != eModeInteract) mouse.DisableMode(i);
    i++;
  }
  CursorMode modeAfterLoop = mouse.Mode;
  mouse.DisableMode(eModeInteract);
  CursorMode modeAfterAllDisabled = mouse.Mode;
  mouse.SelectNextMode();
  CursorMode modeAfterSelectNext = mouse.Mode;
  mouse.Mode = eModeWalkto;
  AbortGame("modeAfterLoop: %d, modeAfterAllDisabled: %d, modeAfterSelectNext: %d, finalMode: %d", modeAfterLoop, modeAfterAllDisabled, modeAfterSelectNext, mouse.Mode);
}


This shows 2 for every check we perform. That's eModeInteract, not eModeWalkto.

It is impossible to disable the last cursor mode. If every other cursor mode is disabled, you cannot disable the last one. It won't work. The mouse mode will not be able to change from that mode. It won't work. You will always have at least one cursor mode enabled, at all times, regardless of what you might do. No cursor mode enables itself. Cursor modes are only enabled when you call mouse.EnableMode. Period. ..or, you know..any time you're switching to a new room apparently. :=

Sephiroth

#7
Arf no, that's not what I meant, maybe I didn't explain well, can you try to open the default game (clean) and put this instead of selectnexmode inside (on_mouse_right_click):

Code: ags

    mouse.DisableMode(eModeTalkto);
    mouse.Mode = eModeTalkto;


Or any other mode, can you tell me what happens?

Also I mentionned the problem only happens when you're assigning the value directly and not with SlectNextMode. So no offense, but your last post's edit makes no sense.

monkey0506

#8
It's not a problem. This is by design.

When you try to set mouse.Mode to a disabled mode, AGS will, by design, automatically change it to the next available, enabled, standard mode. This is on purpose.

If eModeWalkto is disabled, the only way it will be re-enabled is if you call mouse.EnableMode(eModeWalkto). It doesn't re-enable itself if you successfully disable it. I say "if you successfully disable it" because if it is the only enabled mode it is impossible to disable it.

If there are no standard modes available, other modes may be selected as an alternative to a disabled mode. But no disabled mode will be re-enabled just because you tried to set the mouse to that mode.

It's also important to note that mouse.DisableMode(mouse.Mode) does not change mouse.Mode. It does disable it from future use, but it does not change the current mode.

Sephiroth

#9
QuoteWhen you try to set mouse.Mode to a disabled mode, AGS will, by design, automatically change it to the next available, enabled, standard mode. This is on purpose.

Standard mode is what I was missing. I was confused.

QuoteIf eModeWalkto is disabled, the only way it will be re-enabled is if you call mouse.EnableMode(eModeWalkto). It doesn't re-enable itself if you successfully disable it. I say "if you successfully disable it" because if it is the only enabled mode it is impossible to disable it.

I think the mode is (re-)enabled after game_start, this is what made me think that:

Code: ags

//game_start
mouse.DisableMode(eModeWalkto);

//mouse_right_click
mouse.Mode = eModeWalkto;



This will set the cursor to walkto, like it was never disabled.

monkey0506

#10
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

Rocco

#11
ok, my observation brings this facts. (the same as yours.)

my function Interface_Interact() works only if i put it in room_load, and only for this particular room.
after a roomchange, (and i didn't enable the walkmode in this roomchange explizit) i got the behavior mentioned above,
mouse_cursor starts on interact and with rightclick it switches to walkto.
the same if i put this code in game_start, it wont work without the walkto,
so my solution is to put this code in every room_load regardless if i need it 3 rooms in a row,
have to put it in every room_load, cause the room_change will do something (strange?) with mouse.modes.

so i suggest a
Code: ags
mouse.Mode = eModeInteract_only;

for the editor wishlist, who will automatically make this mode the only available.


thx for the help.  :)

monkey0506

#12
That's not an editor wish, that's an engine wish. Anything to do with the run-time of your game is engine. :P

It would actually be perfectly possible to do this via a script module though.

Oh, I also wanted to mention that there's no need to duplicate code in multiple room scripts for the room_Load functions. Just use the on_event function in the global script with the eEventEnterRoomBeforeFadein function.

In any case, you should check out the MousePlus module. It implements a mouse.DisableModeEvenOnRoomChange function that should fix your issues with disabling eModeWalkto. Just use it in place of mouse.DisableMode.

SMF spam blocked by CleanTalk