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:
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:
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:
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:
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:
The problem may lie in this line:
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:
//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! :)
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.
@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
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)
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
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:
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.
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:
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:
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
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()
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:
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:
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 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.