SOLVED: If (GUI.Visible==true) doesn't trigger when it's clearly visible - why?

Started by Tamanegi, Mon 29/11/2010 20:24:40

Previous topic - Next topic

Tamanegi

This is what I want to have:

Left-click on an inventory item selects it, displaying it in a window on screen (gActiveItem). If another item is left-clicked, a bool will be checked, and if it's on then use those two together as usual, if it's off change the selected item to the second one (by de-selecting the first one before the click is handled).
gInventory is the name of my inventory GUI.

I put this in the global script area:

Code: ags

bool usewith = false; // no code to toggle this anywhere yet

function update_activeinv_window()
{
  if (player.ActiveInventory!=null) { // If an item is selected, display it as button graphic
    bActiveItem.NormalGraphic=player.ActiveInventory.Graphic;
    bActiveItem.Visible=true;
    } else {
      bActiveItem.NormalGraphic=0;
      bActiveItem.Visible=false;
    }

}

#sectionstart repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() 
  {
  // put anything you want to happen every game cycle here
  update_activeinv_window();
  }

#sectionend repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE

#sectionstart on_mouse_click  // DO NOT EDIT OR REMOVE THIS LINE
function on_mouse_click(MouseButton button) // called when a mouse button is clicked. button is either LEFT or RIGHT
  {
  if (gInventory.Visible==true) { // If inventory-GUI is there do...
      lLookatbox.Text=(""); // clear the messagebox in GUI after any click
      InventoryItem *item = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
      // above: which item was clicked?
      if ((button==eMouseLeft)&&(usewith==false)&&(item!=null)) {
      // Left button + usewith false + there actually was an item clicked, then
        player.ActiveInventory=null; // de-select current item
        update_activeinv_window(); // refresh display-GUI
        }
      if ((button==eMouseRight)&&(item!=null)) {
        item.RunInteraction(1); // if right-click: look at clicked item
        }
    }
  if (IsGamePaused() == 1) // Game is paused, so do nothing (ie. don't allow mouse click)
// following the usual stuff


This works for the first item, but after that, the de-selection won't trigger... The idea is that when the interaction script is triggered, the item is no longer selected so the usual "no item selected".
I found out via breakpoints that the "if (gInventory.Visible==true) { // If inventory-GUI is there do..." part never becomes true... and I have no clue why.

gInventory is set to "pause game when shown", in case that's relevant, but changing that doesn't do anything else.
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

Khris

First of all you need to get your indentations straight; your code is hard to read.

Everybody has their own style, here's mine:

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

  if (gInventory.Visible==true) { // If inventory-GUI is there do...

    lLookatbox.Text = ""; // clear the messagebox in GUI after any click
    // which item was clicked?
    InventoryItem *item = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);

    if (button == eMouseLeft && usewith == false && item != null) {
      // Left button + usewith false + there actually was an item clicked, then
      player.ActiveInventory = null; // de-select current item
      update_activeinv_window(); // refresh display-GUI
    }
    if (button == eMouseRight && item != null) {
      item.RunInteraction(eModeLook); // if right-click: look at clicked item
    }
  }

  ...
}


Not sure where you set the breakpoint; the reason why the code doesn't get executed is you're using eMouseLeft, not eMouseLeftInv.

I'm pretty sure that you're making things more complicated than necessary; how/when is usewith set?
When I know that, I can give you some pointers about how best to simplify things.

Tamanegi

Sorry about the indentations - I'm still not used to them...

Interesting, that eMouseLeftInv()... That doesn't solve my problem though, because I set the breakpoint directly at the If-statement and another in the line after it, and the script never reaches this line, which is before the check for eMouseLeft. And eMouseLeftInv() only catches clicks in the inventory window, not the whole GUI.

If I change "if (gInventory.Visible==true)" to "if (gInventory.Visible==false)", the script actually executes.

I can only imagine that On_Mouse_Click() is not called when clicking inside the inventory window, but it must also be the case that it's not called inside the whole GUI, because when I click completely outside the GUI,
Code: ags
lLookatbox.Text = "";
is executed, but anywhere inside the GUI doesn't execute it.
So what is called up when I click inside the inventory GUI?

"usewith" will be toggled by a button inside the inventory GUI that is not yet created  ::)

EDIT

I solved the problem! It came mostly from the fact that I started the game three years ago, and back then the "On_Event" wasn't there yet, which is now automatically inserted when a new game is created. I just had to make it myself and put this into it:
Code: ags

#sectionstart on_event  // DO NOT EDIT OR REMOVE THIS LINE
function on_event (EventType event, int data)
{
  if ((event==eEventGUIMouseDown) && (data==gInventory.ID)) {
    lLookatbox.Text=("");
    InventoryItem *item = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
    if ((mouse.IsButtonDown(eMouseLeft))&&(usewith==false)&&(item!=null)) {
      selectedanitem=true;
      player.ActiveInventory=null;
      mouse.Mode = eModeInteract;			// switch to the Use cursor (to select items with)
      mouse.UseModeGraphic(eModePointer);	// But, override the appearance to look like the arrow
      update_activeinv_window();
    }
  }
}
#sectionend on_event  // DO NOT EDIT OR REMOVE THIS LINE


I had to use IsButtonDown() to check the mouse button status because the function doesn't retreive the button argument that on_mouse_click gets.
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

Khris

Right, on_mouse_click isn't called when you click on a GUI. Instead, the GUI's OnClick function is executed, if it is linked in the GUI's event pane.
The only exception is a click on an inventory item, provided that the relevant option is set in the General settings pane. In that case, on_mouse_click is called with the button parameter being one of the eMouse...Invs.

In other words, you don't have to check for the GUI's visibility because it must be visible if button is e.g. eMouseLeftInv.

Btw, if I may: the way you want to implement combining inventory items seems a bit weird, usually a left click selects the item and a right click examines it while when there's an active inv item, a left click uses it with something else and a right click deselects it.
By making a right click do two things you don't need a button that changes a variable that determines what happens and so on.

Tamanegi

You may  ;)

Is that the way it is usually done, or the way it's already working by default?

The funny thing is, I wanted to examine the item with a right click without knowing what you just wrote, so I wrote a script for it and was confused that it "worked" although the if-statement was never processed ;)

I guess I wanted to be able to examine items while having an item selected, and change selections without de-selecting first... but as it won't change the way I have to script everything else, I guess the final decision about that can wait until later.

I tried it with on_click, but something didn't work, so I read into it more and found the solution with on_event that I'm using now.
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

Khris

The default game uses several cursors (walk, look, interact, talk), when an inv item is active, that becomes the fifth (like the 90's Sierra games).

What I suggested is known as the BASS or Broken Sword interface since one of the first games to use it was Beneath a Steel Sky, and later Broken Sword, by the same company.
I'll go out on a limb and say that it's the favorite interface of the average player, and 90% of the interface questions here in the forum are on how to implement it.
I'll stop talking about game design now though, that's not what this forum is for :)
As you said, the interface can easily be adjusted at a later point.

Regarding on_event, I assume you're using eEventGUIMouseUp in combination with InventoryItem.GetAtScreenXY; like I said, clicks on inventory items can be handled using eMouseLeftInv and eMouseRightInv; I use this all the time and it should work for you. You don't actually need the GUI's OnClick event, I just mentioned it for completeness' sake.

Tamanegi

No, I'm just using eEventGUIMouseDown for checking clicks inside the GUI in general to deselect and clear the info box, the item selection itself is still internally handled by AGS.

Thank you for all your help! You got me thinking into the right direction  :)
Don't Look! MAGS 12-2010
Mediocre Expectations Current development blog

SMF spam blocked by CleanTalk