SOLVED: Changing cursor graphic when hovering over objects

Started by TurduckenMan, Fri 11/09/2015 17:00:19

Previous topic - Next topic

TurduckenMan

Hello everyone! I've recently started using AGS and I'm working on a project which uses a single mouse format rather than the multiple verb style a lot of adventure games go for. I've  read a few threads on the subject and found this one which seemed to give me the best luck so far: http://www.adventuregamestudio.co.uk/forums/index.php?topic=46511.0

I've tried using the code Khris posted there, however I'm having an issue.
The movement works perfectly, and the interaction works perfectly, however I'm finding that left clicking on inventory items isn't setting them to my active inventory. Is this because my Inventory is always on screen?
And lastly, I'd like to change what the mouse looks like based on what is under it. Is this something I should do in repeatedly execute? If so, how would I go about it?

Here's the function I'm currently handling this in.

Code: ags

int lt = GetLocationType(mouse.x, mouse.y);
  InventoryItem*ai = player.ActiveInventory, ia = inventory[game.inv_activated];
 
  if (button == eMouseLeft) {
    if (lt == eLocationNothing) ProcessClick(mouse.x, mouse.y, eModeWalkto);
    else if (ai) ProcessClick(mouse.x, mouse.y, eModeUseinv);
    else ProcessClick(mouse.x, mouse.y, eModeInteract);
  }
  else if (button == eMouseRight) {
    if (ai) player.ActiveInventory = null;
    else ProcessClick(mouse.x, mouse.y, eModeLookat);
  }
  else if (button == eMouseLeftInv) {
    if (ai) ia.RunInteraction(eModeUseinv);
    else player.ActiveInventory = ia;
  }
  else if (button == eMouseRightInv) {
    if (ai) player.ActiveInventory = null;
    else ia.RunInteraction(eModeLookat);
  }int lt = GetLocationType(mouse.x, mouse.y);
  InventoryItem*ai = player.ActiveInventory, ia = inventory[game.inv_activated];
 
  if (button == eMouseLeft) {
    if (lt == eLocationNothing) ProcessClick(mouse.x, mouse.y, eModeWalkto);
    else if (ai) ProcessClick(mouse.x, mouse.y, eModeUseinv);
    else ProcessClick(mouse.x, mouse.y, eModeInteract);
  }
  else if (button == eMouseRight) {
    if (ai) player.ActiveInventory = null;
    else ProcessClick(mouse.x, mouse.y, eModeLookat);
  }
  else if (button == eMouseLeftInv) {
    if (ai) ia.RunInteraction(eModeUseinv);
    else player.ActiveInventory = ia;
  }
  else if (button == eMouseRightInv) {
    if (ai) player.ActiveInventory = null;
    else ia.RunInteraction(eModeLookat);
  }


Any help would be very much appreciated!


[EDIT]
As for the not being able to select inventory items, I've solved the issue. I feel a bit foolish, but all I had to do was set "Override built-in inventory window click handling" in general settings.
I am still trying to make the cursor graphic change when hovering over a hotspot, object, or inventory object though, so I've changed the title of the thread, but I'll leave the previous stuff just in case anyone else has the same issue. Any help would again be very appreciated.

Khris

Hi, the basic idea is to use a single cursor mode during the entire game (commonly eModeInteract), since the different types of interactions are already handled by the on_mouse_click code, and change its graphic in repeatedly_execute depending on the current location type.

Code: ags
void UpdateMouseGraphic() {
  if (player.ActiveInventory != null) return; // do nothing
  int newGraphic = 123;  // no location / walking
  int lt = GetLocationType(mouse.x, mouse.y);
  if (lt == eLocationHotspot || lt == eLocationObject) newGraphic = 124;  // interact
  else if (lt == eLocationCharacter) newGraphic = 125;  // talk
  // change?
  if (newGraphic != mouse.GetModeGraphic(mouse.Mode)) mouse.ChangeModeGraphic(mouse.Mode, newGraphic);
}

// in repeatedly_execute
  UpdateMouseGraphic();


This will also work with animated cursors (mouse.ChangeModeView), since the graphic/view is only switched when necessary and the animation won't start over 40 times per second that way.

Edit: fixed code

TurduckenMan

Thanks a lot for taking the time to reply! I've implemented the code you've posted and for some reason the cursor defaults to the graphic used for interact no matter where on the screen it is. So a couple of questions on my end:
1. Am I supposed to set the default graphics as blank for my cursor modes?
2. May have been a faulty assumption on my end, but the number used in this code for each graphic is supposed to be the number that goes with the sprite when viewing all of my sprites, correct?

Thanks again

Khris

1. Not necessary
2. Exactly

The code uses only one cursor for everything, just set mouse.Mode to eModeInteract in game_start.

So are you saying that the code basically does nothing at all? Did you add line 12 to your GlobalScript.asc's repeatedly_execute?
Because while I didn't test this, the cursor should at least change in some way, unless I'm missing a bad error in the code.

TurduckenMan

Right, my bad I didn't mention the difference.
Now, the cursor changes to the cursor I've set for location and hotspots immediately, rather than when I hover over them. Hovering somewhere other than there does nothing. Basically the interact sprite is always being used, and never the no location sprite.
And yes I have added the function call to repeatedly_execute, and I've also set the mouse mode to interact in game_start.





Khris

I'm sorry, there's a really stupid error in my code. Replace line 5 with this:
Code: ags
  if (lt == eLocationHotspot || lt == eLocationObject) newGraphic = 6;  // interact


TurduckenMan

Aha, it works perfectly!

Thanks so much for the time spent helping, I really appreciate it.

SMF spam blocked by CleanTalk