Make cursor mode change over a hotspot unless an inventory item.

Started by streetcutter, Wed 28/01/2015 22:12:56

Previous topic - Next topic

streetcutter

Hey Guys.
I'm pretty new to AGS and I'm sorry if this has been posted before, but I have searched and can't seem to find anything.

I want to have a cursor mechanic like Broken Sword as in the the cursor changes to the relevant mode as it floats over an item rather then having to cycle through them.
I've done this successfully by using this script on a hotspot or object.
Code: ags

function hHallway_MouseMove()
{
    mouse.SaveCursorUntilItLeaves();
    mouse.Mode = eModeInteract;
}


But I need the exception to be if the player is using an inventory item, like a key for a door.
It's probably very very simple but I cant quiet work it out. Any help would be awesome.

Thanks Guys, Justin

monkey0506

Is simply checking the cursor mode first insufficient?

Code: ags
function hHallway_MouseMove()
{
    if (mouse.Mode != eModeUseinv)
    {
        mouse.SaveCursorUntilItLeaves();
        mouse.Mode = eModeInteract;
    }
}

Snarky

So the simple answer to your question (as monkey said while I was writing) is to put in a test for the current mouse mode, and only do it if it's not in inventory-object mode.

Code: ags

function hHallway_MouseMove()
{
    if(mouse.Mode != eModeUseinv)
    {
        mouse.SaveCursorUntilItLeaves();
        mouse.Mode = eModeInteract;
    }
}


... However, the solution you describe sounds like you're a bit on the wrong track. You definitely don't want to be writing almost identical versions of this method for every object and hotspot on every screen: it's a lot of work, it's easy to miss something somewhere, and if you need to change something it's a total pain.

What you should do instead is to write one method that can change the cursor for whatever it is you're hovering over, and just store a flag for each hotspot/object/character about which cursor to use. You can do this in the global script repeatedly_execute_always() using Hotspot/Object/Character.GetAtScreenXY() and GetLocationType(). To store the cursor for that thing, you can use a custom property.

Alternatively, there are modules that provide a Broken Sword-style UI.


strangeDetective

Quote from: Snarky on Thu 29/01/2015 00:16:13
So the simple answer to your question (as monkey said while I was writing) is to put in a test for the current mouse mode, and only do it if it's not in inventory-object mode.

Code: ags

function hHallway_MouseMove()
{
    if(mouse.Mode != eModeUseinv)
    {
        mouse.SaveCursorUntilItLeaves();
        mouse.Mode = eModeInteract;
    }
}


... However, the solution you describe sounds like you're a bit on the wrong track. You definitely don't want to be writing almost identical versions of this method for every object and hotspot on every screen: it's a lot of work, it's easy to miss something somewhere, and if you need to change something it's a total pain.

What you should do instead is to write one method that can change the cursor for whatever it is you're hovering over, and just store a flag for each hotspot/object/character about which cursor to use. You can do this in the global script repeatedly_execute_always() using Hotspot/Object/Character.GetAtScreenXY() and GetLocationType(). To store the cursor for that thing, you can use a custom property.

Alternatively, there are modules that provide a Broken Sword-style UI.

I'm fairly new to AGS and I want to use the standard Sierra interface, but I would also like the cursor to auto change modes while over a hot spot/object, ect. to eliminate the scrolling through icons. I get how to do it for each hot spot individually, but is there an example (or another thread somewhere) of how you would write a single script that would handle this throughout the entire game--and where would you put it?

Snarky

The task is similar to the one described here: http://www.adventuregamestudio.co.uk/forums/index.php?topic=54086.msg636546540#msg636546540

Scripts that apply to the entire game need to be either in GlobalScript or in a "script module" (look up "multiple scripts" in the manual).

Khris

This question is easily in the top five of "most asked beginner's questions of all time".

It's still hard to search the forum for the solution though, here's what I found after wading through search results:
http://www.adventuregamestudio.co.uk/forums/index.php?topic=52667.msg636520746#msg636520746

Note that the code I linked to changes the cursor graphic, not the mode.
To change the mode, use something like this:
Code: ags
// this function somewhere above the repeatedly_execute function
void UpdateMouseMode() {
  if (mouse.Mode == eModeUseinv) return; // do nothing
  int newMode = eModeWalkto;  // no location / walking (default)
  int lt = GetLocationType(mouse.x, mouse.y);
  if (lt == eLocationHotspot || lt == eLocationObject) newMode = eModeInteract;  // interact
  else if (lt == eLocationCharacter) newMode = eModeTalk;  // talk
  // change? (only change when required, so cursor animations aren't killed)
  if (newMode != mouse.mode) mouse.Mode = newMode;
}

// in repeatedly_execute
  UpdateMouseMode();


Edit: Thanks dayowlron, refactoring fixed :)
Edit: Useinv detection fixed

dayowlron

Kris, Just an FYI, you called your function UpdateMouseMode, but then when you called it you put UpdateMouseGraphic.
Pro is the opposite of Con                       Kids of today are so much different
This fact can clearly be seen,                  Don't you know?
If progress means to move forward         Just ask them where they are from
Then what does congress mean?             And they tell you where you can go.  --Nipsey Russell

strangeDetective

#8
Quote from: Khris on Wed 02/11/2016 11:26:03
This question is easily in the top five of "most asked beginner's questions of all time".

Edit: Thanks dayowlron, refactoring fixed :)

Thank you much appreciated.

Update: This works great until I realized that once I use an inventory item in the game, everything defaults back to the manual scrolling cursor.

The inventory item stays in the GUI window as "active" so this script gets canceled out. I'm not sure how to "de-activate" an inventory item after you've used it somewhere, so the cursor continues to change modes. :( I am missing something but not sure how to fix...

Khris

Try changing line 3 to
Code: ags
  if (mouse.Mode == eModeUseinv) return; // do nothing

strangeDetective

Quote from: Khris on Wed 02/11/2016 23:48:01
Try changing line 3 to
Code: ags
  if (mouse.Mode == eModeUseinv) return; // do nothing


Thanks, works now!

strangeDetective


??? I broke my game after trying to implement a new module in the following section of the Global Script, went back and tried to erase the changes, and now it won't run or compile.

I get this error message, but cannot see where I have left out a brace or bracket.....

GlobalScript.asc(126): Error (line 126): Nested functions not supported (you may have forgotten a closing brace)

Can anyone see what I'm missing here?

Code: ags



// Called when the game starts, before the first room is loaded
function game_start() {   
  // Put the code all in a function and then just call the function.
 

// GAME START UP ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// this function somewhere above the repeatedly_execute function

void UpdateMouseMode() {
  if (mouse.Mode == eModeUseinv) return; // do nothing
  int newMode = eModeWalkto;  // no location / walking (default)
  int lt = GetLocationType(mouse.x, mouse.y);
  if (lt == eLocationHotspot || lt == eLocationObject) newMode = eModeInteract;  // interact
  else if (lt == eLocationCharacter) newMode = eModeTalk;  // talk
  // change? (only change when required, so cursor animations aren't killed)
  if (newMode != mouse.mode) mouse.Mode = newMode;
}

}

/// GLOBAL REPEATEDLY_EXEC /////////////////////////////////////////////////////////////////////////////////////////////////////////

function repeatedly_execute() {
  
  // Put here anything you want to happen every game cycle, even when
  // the game is paused. This will not run when the game is blocked
  // inside a command like a blocking Walk()
  
  if (IsGamePaused() == 1) return;
  
  cWitch.SetIdleView(2, 150);
  
  //UpdateMouseMode();
  
 
  
  ///////////////////////////////////////////////LEARN SIGIL SPELLS AND ACTIVATE THEM HERE////////////////////////////////////////////



if (SIGIL_MOON == 1)
bSigilMoon.Enabled = true;

if (SIGIL_FIRE == 1)
bSigilFire.Enabled = true;

if (SIGIL_SPIRAL == 1)
bSigilSpiral.Enabled = true;

if (SIGIL_AIR == 1)
bSigilAir.Enabled = true;

if (SIGIL_DEATH == 1)
bSigilDeath.Enabled = true;

if (SIGIL_WATER == 1)
bSigilWater.Enabled = true;

if (SIGIL_STAR == 1)
bSigilStar.Enabled = true;

if (SIGIL_EARTH == 1)
bSigilEarth.Enabled = true;

if (SIGIL_SUN == 1)
bSigilSun.Enabled = true;

//


  
    // in repeatedly_execute
     UpdateMouseMode();


   

  // Put here anything you want to happen every game cycle, but not
  // when the game is paused.
  
  /////////////////////////////////////////////////////////////////////////SET VISIBILITY OF THE SPELL BOOK


Khris

Right at the top you're defining UpdateMouseMouse *inside* game_start.

strangeDetective

Quote from: Khris on Mon 26/12/2016 02:02:13
Right at the top you're defining UpdateMouseMouse *inside* game_start.

Thank you Khris I had no idea what to do. :-\

SMF spam blocked by CleanTalk