Runaway-type cursor? *Finally solved!*

Started by Bulbapuck, Mon 08/12/2008 11:56:41

Previous topic - Next topic

Bulbapuck

Hi!
I'm trying to create a game with a 'Runaway' cursor, i.e. a cursor that changes depending on what it's over.
for example: 'talk to' when it's over a character and 'pick up' when it's over an object.
Does anyone know how to do this?

p.s. Is there any way to change the cursor to 'look at' if you press the right mouse button?

/Bulbapuck

Ghost

In the game's global script there's a function "on_mouse_click", and this is where you'll want to make your changes...

if (button == eMouseRight)
{
  mouse.Mode = whatever mode you need
}

Akatosh

For the cursor automatically changing, you could make clever use of the repeatedly_execute function, mouse.x, mouse.y, and Custom Properties.

Wonkyth

Thats the way I did it in one of the games I ,made when i was just fooling aroun, and it seemed to work.
"But with a ninja on your face, you live longer!"

Ghost

#4
Yes, I use a similar method for my SCUMM ripoff (  :P ) - basically a custom string to store "look", "get", "use", talk" that is read in repeatedly_execute.

I think you could also create a temporary hotspot/object/character object and check against that, since it's sensible to always talk to a character/examine a hotspot and use an object. If you always want to have the same interactions, you won't need the (more flexible) custom property at all.

Bulbapuck

Thanks for the quick response ;D!
However, a problem came up.

The cursor seems to be flicking back and forth between the eMode I set it to in repeatedly_execute and the cursor I start with.

Any idea what I should do?

Ghost

#6
Put this somewhere on top of your script:
Code: ags

function myUpdateCursor() {
  bool stop;
  stop = false;
  
  if (GetLocationType(mouse.x, mouse.y) == eLocationNothing
  {
      mouse.Mode = eModeWalkto;
      stop = true;
  }
  
  if (!stop && GetLocationType(mouse.x, mouse.y) == eLocationHotspot) 
  {
     mouse.Mode = eModeLookAt;
     stop = true;
  }

  if (!stop && GetLocationType(mouse.x, mouse.y) == eLocationObject) {
    mouse.Mode = eModeInteract;
    stop = true;
  }

  if (!stop && GetLocationType(mouse.x, mouse.y) == eLocationCharacter) {
    mouse.Mode = eModeTalkTo;
    stop = true;
  }
}


Put this in repeatedly_execute:
Code: ags

myUpdateCursor();


And in on_mouse_click you write:
Code: ags

else if (button == eMouseLeft) 
  {
    ProcessClick(mouse.x, mouse.y, mouse.Mode);
    myUpdateCursor(); 
  }


This *should* work...

Bulbapuck

Good gravy that was fast!

Thanks Ghost (and Akatosh and wonkyth)
You saved my day :D

Bulbapuck

BUMP!

Okay, I am still using the cursor that you guys helped me with in this thread.

What I'm now trying to do is add an inventory that you don't have to press a button to open, a GUI that is constantly visible (I'm bad at explaining these things)  :P

But with this cursor I don't know how you can use that inventory since the cursor's eMode is "WalkTo" when it's over the inventory window.

Need help!


Trent R

Multiple ways:

1) Add another condition to the myUpdateCursor() function, using something like
Code: ags
if (gInventory.GetAtScreenXY(mouse.x, mouse.y) mouse.mode=eModeInteract;


2) You could turn 'Handle inventory clicks in script' to True, and script the interactions yourself. (hence not need it to be in Interact mode)



~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

monkey0506

gInventory.GetAtScreenXY(mouse.x, mouse.y)? I think you might mean:

Code: ags
if (GUI.GetAtScreenXY(mouse.x, mouse.y) == gInventory) mouse.Mode = eModeInteract;


In addition to doing this, I also store a global variable, something like bool walkmode. Then when I check for the inventory I first set the walkmode flag to (mouse.Mode == eModeWalkto). I also add an additional clause:

Code: ags
else if (walkmode) mouse.Mode = eModeWalkto;

Bulbapuck

Thanks guys :D I knew it was something simple all along.

Before I posted here I did infact give the manual a guick glance, and GetAtScreenXY was one of the things I looked at ::) Guess I was tired or something.

Thanks again Trent and monkey!

monkey0506

Glad to hear you got it sorted out. Of course things could even be made simpler if mouse.SaveCursorUntilItLeaves supported inventory items....but that's another story entirely. Best of luck with your game.

Trent R

Quote from: monkey_05_06 on Mon 27/04/2009 19:04:29
I think you might mean:
Indeed, I forgot it was a static function. Good to hear it worked for you Bulbapuck.

~Trent
To give back to the AGS community, I can get you free, full versions of commercial software. Recently, Paint Shop Pro X, and eXPert PDF Pro 6. Please PM me for details.


Current Project: The Wanderer
On Hold: Hero of the Rune

Bulbapuck

Well, this is embarresing...

I thought it was solved but it wasn't. You see, it was a sort of optical illusion...
The cursor seemed to change to the inventory item but what really happened was that it dissapered :=

Here's my code:
Code: ags

function repeatedly_execute() 
{
  
 
  if (IsGamePaused() == 1) return;

  if (GetLocationType(mouse.x,mouse.y) == eLocationCharacter && stop == 1 && mouse.Mode != eModeUseinv)
  {
      mouse.Mode = eModeTalkto;
      stop = 3;
  } 
  
  if (GetLocationType(mouse.x,mouse.y) == eLocationHotspot && stop == 1 && mouse.Mode != eModeUseinv)
  {
      mouse.Mode = eModeInteract;
      stop = 0;
  }

  if (GetLocationType(mouse.x,mouse.y) == eLocationObject && stop == 1 && mouse.Mode != eModeUseinv)
  {
      mouse.Mode = eModeInteract;
      stop = 0;
  }

  if (GetLocationType(mouse.x,mouse.y) == eLocationNothing && stop != 1 && mouse.Mode != eModeUseinv)
  {
      mouse.Mode = eModeWalkto;
      stop = 1;
  }
  if (stop!=6)
  {
    if (GUI.GetAtScreenXY(mouse.x, mouse.y) == gGui2 && mouse.Mode != eModeUseinv)
    {
    mouse.Mode = eModeInteract;
    stop = 5;
    }
  }
}


Code: ags


function on_mouse_click(MouseButton button) {
  // called when a mouse button is clicked. button is either LEFT or RIGHT
  if (IsGamePaused() == 1) {
    // Game is paused, so do nothing (ie. don't allow mouse click)
  }
  else if (button == eMouseLeft) {
    if(mouse.Mode==eModeWalkto)
    {
       ProcessClick(mouse.x, yvalue, mouse.Mode );
    }
    else
    {
    ProcessClick(mouse.x, mouse.y, mouse.Mode );
    }
  }
  /*else if (button == eMouseRight || button == eMouseWheelSouth){
    // right-click our mouse-wheel down, so cycle cursor
    mouse.SelectNextMode();
  }*/
    else if (button == eMouseRight && mouse.Mode == eModeUseinv && GetLocationType(mouse.x,mouse.y) == eLocationNothing)
  {
      mouse.Mode = eModeWalkto;
      
  }
  else if (button == eMouseRight && mouse.Mode == eModeUseinv && GetLocationType(mouse.x,mouse.y) == eLocationCharacter)
  {
      mouse.Mode = eModeTalkto;
  }
  else if (button == eMouseRight && mouse.Mode == eModeUseinv)
  {
      mouse.Mode = eModeInteract;
  }      
  else if (button == eMouseRight && stop == 0)
  {
      mouse.Mode=eModeLookat;
      stop = 2;
  }
  else if (button == eMouseRight && stop == 2)
  {
      mouse.Mode=eModeInteract;
      stop = 0;
  }
  else if (button == eMouseRight && stop == 3)
  {
      mouse.Mode=eModeLookat;
      stop = 4;
  }
  else if (button == eMouseRight && stop == 4)
  {
      mouse.Mode=eModeTalkto;
      stop = 3;
  }
  else if (button == eMouseLeft && stop == 5)
  {
    stop = 6;
  }
  
  ...




Sorry for asking again but I just can't seem to figure it out.
[desperate] I need help again [/desperate] :P

Khris

Code: ags
function repeatedly_execute()  {
  
  if (IsGamePaused()) return;

  int lt = GetLocationType(mouse.x,mouse.y);
  InventoryItem*i = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  InventoryItem*ai = player.ActiveInventory;
  int nmm; // new mouse mode
  String action;

  if (mouse.Mode == eModeUseinv) {
    if (i != ai) action = String.Format("Use %s on @OVERHOTSPOT@", ai.name);
    else action = i.Name;
  }
  else if (i != null) {
    nmm = eModePointer;
    action = i.Name;
  }
  else {
    if (lt == eLocationCharacter) {
      nmm = eModeTalkto;
      action = String.Format("Talk to @OVERHOTSPOT@");
    }
    if (lt == eLocationHotspot || lt == eLocationObject) {
      nmm = eModeInteract;
      action = String.Format("Interact with @OVERHOTSPOT@");
    }
    if (lt == eLocationNothing) {
      nmm = eModeWalkto;
      action = "";
    }
  }

  if (nmm != mouse.Mode) mouse.Mode = nmm;
  // lAction.Text = action;   // uncomment if needed
  
}

function on_mouse_click(MouseButton button) {
  // called when a mouse button is clicked. button is either LEFT or RIGHT

  if (IsGamePaused()) return; // Game is paused, so do nothing (ie. don't allow mouse click)

  InventoryItem*i = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  InventoryItem*ai = player.ActiveInventory;

  if (button == eMouseLeft) {
    if(mouse.Mode==eModeWalkto) ProcessClick(mouse.x, yvalue, mouse.Mode );
    else ProcessClick(mouse.x, mouse.y, mouse.Mode );
  }
  else if (button == eMouseRight) {
    if (mouse.Mode == eModeUseinv) player.ActiveInventory == null;
    else ProcessClick(mouse.x, mouse.y, eModeLookat);
  }
  else if (button == eMouseLeftInv) {
    if (ai == null) player.ActiveInventory = i;
    else if (i == ai) return;
    else i.RunInteraction(eModeUseinv);
  }
  else if (button == eMouseRightInv) {
    if (mouse.Mode == eModeUseinv) player.ActiveInventory == null;
    else i.RunInteraction(eModeLookat);
  }
}


Not tested!

Bulbapuck

Thanks KhrisMUC  :D Really appreciate your help.

Even though your code didn't quite work it gave me some intresting ideas on how to solve this.

I'll try to solve it myself for now since I need some practice in scripting. I'll update soon!

Bulbapuck

I found a solution!  :D

thank you all so much for your help, I've learned a lot ;D

SMF spam blocked by CleanTalk