Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Tenacious Stu on Thu 14/02/2013 01:19:41

Title: Unhandled Events - Not triggering during the game [SOLVED]
Post by: Tenacious Stu on Thu 14/02/2013 01:19:41
Hi everyone

I'm trying to get the unhandled event function to work properly, but everything I've tried just seems to have no effect in-game. I'm not getting any errors with my code, but whatever I seem to try, when I right click or left click on an object/character/hotspot that has no events scripted, none of the unhandled events seem to trigger and nothing happens.

Here's the code I've tried:

Code (AGS) Select
function unhandled_event(int what, int type) {

   //  Unhandled Hotspot
   if (what == 1) {         // Hotspot     
      if (type==1) {         // 1    1   Look at hotspot
      }
      else if (type==2) {  //  1    2   Interact with hotspot
      }
      else if (type==3) {  //  1    3   Use inventory on hotspot
      }
      else  {                     //  Undefined
      }
   }
     
   //  Unhandled Object
   else if (what== 2) {   
      //
      if (type==0) {         //  2    0   Look at object
         Display("It looks fine.");
      }
      else if (type==1) {  //  2    1   Interact with object
          Display ("You have more important things to worry about at the moment.");
      }
      else if (type==3) {  //  2    3   Use inventory on object
      }
      else  {                     //  Undefined
      }
   }

   //  Unhandled Character
   else if (what==3)  { 
   //
      if (type==0) {  //  3    0   Look at character
      cBoy.Say ("Looking good.");
      }
      else if (type==1) {  //  3    1   Interact with character
      cBoy.Say ("I don't want to interact with him/her.");
      }
      else if (type==3) {  //  3    3   Use inventory on character
      }
      else  {                     //  Undefined
      }
   }
     
   // Unhandled Inventory
   else if (what==5) {
     //
      if (type==0) {  //  5    0   Look at inventory
      }
      else if (type==1) {  //  5    1   Interact with inventory (currently not possible)
      }
      else if (type==3) {  //  5    3   Use an inventory item on another
      }
      else  {                     //  Undefined
      }     
   }

  // Unhandled Undefined
   else {
      // This isn't supposed to happen
   }
}


I also tried this:

Code (AGS) Select

function unhandled_event(int what, int type) {

if ((what==1)&&(type==1)) { //Look at Hotspot
cBoy.Say ("Nice Hotspot.");
}
else if ((what==1)&&(type==2)) { //Interact with Hotspot
cBoy.Say("I'm not touching that.");
}
else if ((what==1)&&(type==3)) { //Use Inventory on Hotspot
cBoy.Say("I don't want to.");     
}
else if ((what==2)&&(type==0)) { //Look at Object
cBoy.Say("Nice Object.");
}
else if ((what==2)&&(type==1)) { //Interact with Object
cBoy.Say("I don't want that Object");
}
else if ((what==2)&&(type==3)) { //Use Inventory on Object
cBoy.Say("Those two objects won't work together.");     
}
else if ((what==3)&&(type==0)) { //Look at Character
cBoy.Say("Looking good.");
}
else if ((what==3)&&(type==1)) { //Interact with Character
cBoy.Say("I don't want to touch them.");
}
else if ((what==3)&&(type==3)) { //Use Inventory on Character
cBoy.Say("I'm not giving my stuff away.");     
}
}


I've also tried just having this:

Code (AGS) Select
function unhandled_event (int what, int type) {

  if (what == 2) {  // object
    if (type == 0) {  // look at object
      cBoy.Say ("Wow, nice object.");
    }
  }
}


But whatever I seem to try nothing works. It's making me think that it may have something to do with the way I'm interacting with things on mouse click. My code for that is here:

Code (AGS) Select
function on_mouse_click(MouseButton button) {
  CursorMode mode = eModeInteract;
  if ((button == eMouseRight) || (button == eMouseRightInv)) mode = eModeLookat;
  else if (player.ActiveInventory != null) mode = eModeUseinv;
  if ((button == eMouseLeftInv) || (button == eMouseRightInv))
  {
    InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
    if (iat) {
      if (iat.IsInteractionAvailable(mode)) iat.RunInteraction(mode);
      else if ((button == eMouseLeftInv) && (player.ActiveInventory == null)) player.ActiveInventory = iat;
      else if ((button == eMouseRightInv) && (player.ActiveInventory != null)) player.ActiveInventory = null;
    }
  }
  else if (IsInteractionAvailable(mouse.x, mouse.y, mode)) ProcessClick(mouse.x, mouse.y, mode);
  else if ((button == eMouseLeft) && (player.ActiveInventory == null))
  {
    ProcessClick(mouse.x, mouse.y, eModeWalkto);
  }
  else if ((button == eMouseRight) && (player.ActiveInventory != null))
  {
    player.ActiveInventory = null;
  }
}


Or perhaps, there is some setting that I have wrong that won't let me use the unhandled event function?

I hope you guys can help me out. Thanks in advance  :smiley:
Title: Re: Unhandled Events - Not triggering during the game
Post by: geork on Thu 14/02/2013 10:38:14
The problem may lie in this line:
Code (AGS) Select
else if (IsInteractionAvailable(mouse.x, mouse.y, mode)) ProcessClick(mouse.x, mouse.y, mode);
From the manual:
Quote[isInteractionAvailable] is very similar to ProcessClick, except that rather than carry out any interactions it encounters, it simply returns 1 if something would have happened, or 0 if unhandled_event would have been run.
Therefore, you are only calling ProcessClick when an interaction IS available, and never when it would carry over to an unhandled event.
You could try changing it to this:
Code (AGS) Select
//from the bottom half
  else if ((button == eMouseLeft) && (player.ActiveInventory == null) && (GetLocationType(mouse.x, mouse.y) == eLocationNothing))
  {
    ProcessClick(mouse.x, mouse.y, eModeWalkto);
  }
  else if ((button == eMouseRight) && (player.ActiveInventory != null))
  {
    player.ActiveInventory = null;
  }
  else ProcessClick(mouse.x, mouse.y, mode);


The GetLocationType check in line 2 means that clause is executed when the cursor is not over a hotspot, object or character.

Hope this helps! :)
Title: Re: Unhandled Events - Not triggering during the game
Post by: Khris on Thu 14/02/2013 11:10:43
Indeed.
To quote the manual:
Quoteunhandled_event (int what, int type)
    Called when an event occurs, but no handler is set up in the Events list.

Instead of rewriting unhandled_event (twice) when it didn't work, why didn't you simply put a Display command at the start of the function? That way you would have noticed immediately that it isn't called at all.
Title: Re: Unhandled Events - Not triggering during the game
Post by: Tenacious Stu on Thu 14/02/2013 12:54:08
@Khris

Thanks Khris, to be honest I've never used a Display command to check code when in game. I'm not sure how to place one? In this instance would it have shown that nothing was happening, rather than running through the unhandled event code, allowing me to see that the problem lay elsewhere? I'll try to use this with future issues.

@geork

Thanks. Your code seems to work, but is there a tweak I can make to allow unhandled events to be called when an inventory is clicked? So that when you look at an inventory item or use an item with another item it triggers unhandled events? I think I understand that it isn't working because the same reason, in the fist half of the code it says

Code (AGS) Select
if (iat.IsInteractionAvailable(mode)) iat.RunInteraction(mode);

which will run the interaction if one is available, but what if there isn't one available? I'm not sure how to rejigger the code, so that it uses unhandled events. Would it be something similar to what you did with the second half of the code?

This is how my code looks at the minute (excuse all the comments, I was trying to gain a better understanding of the whole thing)

Code (AGS) Select
function on_mouse_click(MouseButton button) {
  CursorMode mode = eModeInteract;
  if ((button == eMouseRight) || (button == eMouseRightInv)) mode = eModeLookat; //If the player right clicks or right clicks on an inventory item, it will Look at what is being clicked on
  else if (player.ActiveInventory != null) mode = eModeUseinv; //if the player has an active inventory item it will use inventory
  if ((button == eMouseLeftInv) || (button == eMouseRightInv)) //if the player right or left clicks on inventory
  {
    InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); // "iat" is whether there is an inventory item being clicked on
    if (iat) { // If there is an inventory item being clicked on:
      if (iat.IsInteractionAvailable(mode)) iat.RunInteraction(mode); // if there is an interaction available then run it
      else if ((button == eMouseLeftInv) && (player.ActiveInventory == null)) player.ActiveInventory = iat; //If Player Left Clicks and currently does not have an inventory item selected then it will select one
      else if ((button == eMouseRightInv) && (player.ActiveInventory != null)) player.ActiveInventory = null; //If Player Right Clicks and has an inventory item selected, it will deselct the item
    }
  }
    else if ((button == eMouseLeft) && (player.ActiveInventory == null) && (GetLocationType(mouse.x, mouse.y) == eLocationNothing))
  { // If the player left clicks and has no inventory selected and the mouse is not over a Hotspot, Object or Character, then...
    ProcessClick(mouse.x, mouse.y, eModeWalkto); // The player will walk to mouse coordinates
  }
    else if ((button == eMouseRight) && (player.ActiveInventory != null))
  { // If the player right clicks and has an inventory item selected, then...
    player.ActiveInventory = null; //The player will deselect the inventory item
  }
    else ProcessClick(mouse.x, mouse.y, mode); // else process the click
}


Thanks guys
Title: Re: Unhandled Events - Not triggering during the game
Post by: Khris on Thu 14/02/2013 21:21:02
Quote from: Tenacious Stu on Thu 14/02/2013 12:54:08to be honest I've never used a Display command to check code when in game. I'm not sure how to place one?

All you need to do is put Display("unhandled"); at the very start of unhandled_event().
As soon as it's supposed to be called, if you don't get to see the text displayed, something's wrong. Plus, you'll know that the fault isn't within its contents, at least not only there, but there's something wrong elsewhere already because the function isn't called.

You can also do something like this:
Code (ags) Select
  if (player.ActiveInventory == null) Display("ActiveInventory is null");
  else Display("ActiveInventory: %s", player.ActiveInventory.Name);

Stuff like that is extremely useful to troubleshoot complex code.
Title: Re: Unhandled Events - Not triggering during the game
Post by: Tenacious Stu on Thu 28/02/2013 10:19:24
Hi Guys

I'm still having issues with the unhandled events not triggering when an inventory item is looked at or another inventory item is used on an item.

As I said in my previous post I believe it has something to do with this line of code:

Code (AGS) Select
if (iat.IsInteractionAvailable(mode)) iat.RunInteraction(mode);

But after staring at it for some time, I can't seem to figure out how to fix this. Here is how the code looks right now:

Code (AGS) Select
function on_mouse_click(MouseButton button) {
  CursorMode mode = eModeInteract;
  if ((button == eMouseRight) || (button == eMouseRightInv)) mode = eModeLookat; //If the player right clicks or right clicks on an inventory item, it will Look at what is being clicked on
  else if (player.ActiveInventory != null) mode = eModeUseinv; //if the player has an active inventory item it will use inventory
  if ((button == eMouseLeftInv) || (button == eMouseRightInv)) //if the player right or left clicks on inventory
  {
    InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); // "iat" is whether there is an inventory item being clicked on
    if (iat) { // If there is an inventory item being clicked on:
      if (iat.IsInteractionAvailable(mode)) iat.RunInteraction(mode); // if there is an interaction available then run it
      else if ((button == eMouseLeftInv) && (player.ActiveInventory == null)) player.ActiveInventory = iat; //If Player Left Clicks and currently does not have an inventory item selected then it will select one
      else if ((button == eMouseRightInv) && (player.ActiveInventory != null)) player.ActiveInventory = null; //If Player Right Clicks and has an inventory item selected, it will deselct the item
    }
  }
    else if ((button == eMouseLeft) && (player.ActiveInventory == null) && (GetLocationType(mouse.x, mouse.y) == eLocationNothing))
  { // If the player left clicks and has no inventory selected and the mouse is not over a Hotspot, Object or Character, then...
    ProcessClick(mouse.x, mouse.y, eModeWalkto); // The player will walk to mouse coordinates
  }
    else if ((button == eMouseRight) && (player.ActiveInventory != null))
  { // If the player right clicks and has an inventory item selected, then...
    player.ActiveInventory = null; //The player will deselect the inventory item
  }
    else ProcessClick(mouse.x, mouse.y, mode); // else process the click
}


Thanks in advance for any suggestions
Title: Re: Unhandled Events - Not triggering during the game
Post by: Khris on Thu 28/02/2013 12:16:51
The problem is still exactly the same as before: you're not triggering the event if there's no handler, and wondering why unhandled isn't called.

To put it another way: in order for unhandled_event to be called, a mouse click after which nothing happens is not enough! Because AGS isn't HAL or Edi; it cannot detect this situation. You HAVE to call .RunInteraction(), regardless of whether there's one available or not, in order to make AGS call unhandled_event (if the latter is the case).
But again, just like before, you're actively making sure that unhandled_event is never called by not calling .RunInteraction if .IsInteractionAvailable returns 0.

      .RunInteraction()
              |
              |
              V
   .IsInteractionAvailabe()?
      |                |
     YES               NO
      |                |
      V                V
  event_x()        unhandled_event()
Title: Re: Unhandled Events - Not triggering during the game
Post by: Tenacious Stu on Fri 30/08/2013 00:13:55
Hi

Sorry for reviving this old thread, but I've been away from working on the game and have come back to it with this problem still. I realised that this was never resolved here on the forums and so I thought I would complete it in case it would help anyone in the future. I've tried to make sense of it all and think I now understand why it wasn't working for Inventory stuff:

Code (AGS) Select
if (iat.IsInteractionAvailable(mode)) iat.RunInteraction(mode);

Basically, I was telling AGS that if there is an interaction available, then run it, but at no point do I say if there isn't an interaction available then to run interaction anyway (which would call the unhandled event). Also I was under the impression that processclick was what would call an unhandled event, but I think this is just for walking to a location?

This is how my code looks now:

Code (AGS) Select
function on_mouse_click(MouseButton button) {
CursorMode mode = eModeInteract;
  if ((button == eMouseRight) || (button == eMouseRightInv)) mode = eModeLookat; //If the player right clicks or right clicks on an inventory item, it will Look at what is being clicked on
  else if (player.ActiveInventory != null) mode = eModeUseinv; //if the player has an active inventory item it will use inventory
if ((button == eMouseLeftInv) || (button == eMouseRightInv)) //if the player right or left clicks on inventory
  {
    InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y); // "iat" is whether there is an inventory item being clicked on
    if (iat) { // If there is an inventory item being clicked on:
 
     if (iat.IsInteractionAvailable(mode)) iat.RunInteraction(mode); // if there is an interaction available then run it

      else if ((button == eMouseLeftInv) && (player.ActiveInventory == null)) player.ActiveInventory = iat; //If Player Left Clicks and currently does not have an inventory item selected then it will select one
     else if ((button == eMouseRightInv) && (player.ActiveInventory != null)) player.ActiveInventory = null; //If Player Right Clicks and has an inventory item selected, it will deselct the item
      //else if ((button == eMouseRightInv) && (player.ActiveInventory == null)) ProcessClick(mouse.x, mouse.y, mode);//If Player Right Clicks and Doesn't have inv selected,
     else iat.RunInteraction(mode); //Run Interactions - If none, then calls Unhandled Event
    }

}
   else if ((button == eMouseLeft) && (player.ActiveInventory == null) && (GetLocationType(mouse.x, mouse.y) == eLocationNothing))
  { // If the player left clicks and has no inventory selected and the mouse is not over a Hotspot, Object or Character, then...
    ProcessClick(mouse.x, mouse.y, eModeWalkto); // The player will walk to mouse coordinates
  }
   else if ((button == eMouseRight) && (player.ActiveInventory != null))
  { // If the player right clicks and has an inventory item selected, then...
   player.ActiveInventory = null; //The player will deselect the inventory item
  }
    else ProcessClick(mouse.x, mouse.y, mode); // else process the click
}


So, by adding in the
Code (AGS) Select
else iat.RunInteraction(mode); the game now knows to run interaction if there is no other option, which will call the unhandled event.

Thank you Khris and geork for helping me get to grips with the issue and apologies for my lack of understanding.