Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Ultra Magnus on Fri 06/08/2010 16:31:08

Title: ProcessClick / hotspot detection glitching [solved]
Post by: Ultra Magnus on Fri 06/08/2010 16:31:08
Hey people.
I'm having trouble with clicking on some hotspots. Here's the code I'm using...


function on_mouse_click(MouseButton button)
{
 if (IsGamePaused()==1) { }
 else if (gInventory.Visible==true && GUI.GetAtScreenXY(mouse.x, mouse.y)==null) {gInventory.Visible=false;}
 else if (button==eMouseLeft) {
   if (cCharacter.Room==cEgo.Room && GUIControl.GetAtScreenXY(mouse.x, mouse.y)==null) {
     cCharacter.Walk(mouse.x, mouse.y, eBlock, eWalkableAreas);
     cCharacter.FaceLocation(mouse.x, cCharacter.y, eNoBlock);
   }
   ProcessClick(mouse.x, mouse.y, eModeInteract);
 }
<snipped>
}


Now, the problem is on the screens where cCharacter is in the same room as cEgo.
Most of the time it works as it should, but sometimes the character just walks over to the hotspot and it doesn't process the click afterwards. I've also got rep_exec telling the cursor to change its graphic when over a hotspot, so I know the game knows there's a hotspot there, it just sometimes chooses to ignore it. Furthermore, from what I can tell, the closer the mouse is to the centre of the hotspot, the more likely it is to not register.

Any ideas on why this is happening and maybe how to stop it?
Thanks in advance.
Title: Re: ProcessClick / hotspot detection glitching
Post by: Khris on Fri 06/08/2010 17:11:51
I was stumped for a bit, but then it hit me.
The problem is that due to the character doing a blocking walk, a considerable amount of time may pass until ProcessClick is called. The thing is, it uses the current mouse coordinates, not necessarily the ones you clicked at.

It's an easy fix though:

function on_mouse_click(MouseButton button)
{

  int mx = mouse.x, my = mouse.y;

  if (IsGamePaused()==1) { }
  else if (gInventory.Visible==true && GUI.GetAtScreenXY(mx, my)==null) {gInventory.Visible=false;}
  else if (button==eMouseLeft) {
    if (cCharacter.Room==cEgo.Room && GUIControl.GetAtScreenXY(mx, my)==null) {
      cCharacter.Walk(mx, my, eBlock, eWalkableAreas);
      cCharacter.FaceLocation(mx, cCharacter.y, eNoBlock);
    }
    ProcessClick(mx, my, eModeInteract);
  }
<snipped>
}
Title: Re: ProcessClick / hotspot detection glitching
Post by: Ultra Magnus on Fri 06/08/2010 17:41:07
Hey, thanks for the help, but it didn't work. It's still not processing the click even if I'm really careful not to move the mouse. And as I said, it only seems to happen when the cursor's right in (or close to) the centre of the hotspot.

But typing that did just make me realise something. When the mouse is clicked in the centre of a hotspot that makes the character walk and stand right in front of it, whereas clicking slightly to either side makes him stand next to it. So this probably means that by the time ProcessClick is called, the mouse isn't over the hotspot anymore because it's over the character instead (because he's standing between them).
By this theory, the reason why your suggested fix didn't work is because it's not just the mouse's coordinates that are the problem, but their relation to the character. It's still clicking the same spot, but the character's still in the way.

So, now (I think) I know what the problem is, is there an easy way to work around it, or do I just need to go through the game manually setting the walk-to point for every hotspot?
Title: Re: ProcessClick / hotspot detection glitching
Post by: Khris on Fri 06/08/2010 18:39:43
Just make the character not clickable.
If he's supposed to stay clickable, use this:

  // at time of click
  Hotspot*h = Hotspot.GetAtScreen(mx, my);
  int lt = GetLocationType(mx, my);

  // instead of ProcessClick(...)
  if (lt == eLocationHotspot) {
    if (h != hotspot[0]) h.RunInteraction(eModeInteract);
  }
  else ProcessClick(mx, my, eModeInteract);


This could get messy quickly, though.
An alternative is to turn the character not clickable immediately before ProcessClick, then turn him back in the rep_ex.
  if (!cCharacter.Clickable) cCharacter.Clickable = true;
should do it.
Title: Re: ProcessClick / hotspot detection glitching [solved]
Post by: Ultra Magnus on Fri 06/08/2010 18:54:21
Excellent stuff. Thanks a lot.