undefined token

Started by Gius, Wed 08/07/2009 17:39:28

Previous topic - Next topic

Gius

Hi,
I have one click automatic
room_a function () (
   / / Script for Room: Repeatedly execute



timer + +;
   if (timer> GetGameSpeed () * 5) (/ / 5 seconds
     timer = 0;
   on_mouse_click (eMouseLeft);
)

gives me the following error:
undefined token "on_mouse_click"
how I can solve?
thanks

Gilbert

Do you have the on_mouse_click() function in that room's script?

Gius

#2
I have not on_mouse_click() function in room's script

GuyAwesome

You can't call the global on_mouse_click like that unless you've made it a global function (imported into the Global script header). And, if you did that, I don't think you'd be able to have room-based on_mouse_clicks when you need them.

Depending on what you're after, ProcessClick might be the way to go. It'll work with Characters, Objects and Hotspots - just not with GUIs. Otherwise, you'll need to copy the relevant bits of the global on_mouse_click into the room script... (I don't think that'll work with GUIs either, however.)

Gius

I forgot to add in Script Header
import function on_mouse_click (MouseButton button);

I apologize...

monkey0506

#5
You do not want to import your global script's on_mouse_click function at all! This will make things go wonky and not work the way they should, i.e. if you try to use a local on_mouse_click function (as Guy said).

What you should be doing is, as Guy said, using ProcessClick.

Code: ags
function on_event(EventType event, int data) {
  if (event == eEventGUIMouseDown) {
    if (data == gSomegui.ID) {
      GUIControl *gcat = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
      if (gcat == null) {
        // the user did not click a control, just the GUI...
        return; // stop executing this function
      }
      // here you would need to import the GUI control event handlers, i.e. btnSomebutton_Click()
      if ((gcat.AsButton != null) && (gcat.AsButton == btnSomebutton)) btnSomebutton_Click();
      // etc.
    }
  }
}

function room_a() {
  // Script for Room: Repeatedly execute
  timer++;
  if (timer > GetGameSpeed() * 5) { // 5 seconds
    timer = 0;
    GUI *gat = GUI.GetAtScreenXY(mouse.x, mouse.y);
    InventoryItem *iat = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
    if (iat != null) iat.RunInteraction(mouse.Mode);
    else if (gat != null) on_event(eEventGUIMouseDown, gat.ID);
    else ProcessClick(mouse.x, mouse.y, mouse.Mode);
  }
}


The on_event here is serving solely as a sorting function and isn't necessarily a necessary step. The idea is just that if you've clicked on a GUI you then need to figure out if it was a click on a control or not, and if it was, what control was clicked. InventoryItem.RunInteraction allows you to simulate a mouse-click on an inventory item. ProcessClick allows you to simulate a mouse-click on the currently visible screen, any GUIs (and thereby any controls, or inventory items) ignored. So ProcessClick will still detect Characters, Objects, and Hotspots that you need to interact with. The only items that don't have simulate-click functions are GUIs and GUIControls.

So if you need to simulate a GUI/GUIControl-click then it's okay to import that event handler since it is a very specific handler that will only appear in one script. on_mouse_click is a generic handler that could appear in every script! So again...don't import on_mouse_click. :=

Khris

Quote from: monkey_05_06 on Wed 08/07/2009 23:46:08So again...don't import on_mouse_click. :=

That really depends on the type of game.
If you're never going to use a room's on_mouse_click, things won't go wonky at all.

A better way IMO though is to move the left click code to a custom function and import that.

Code: ags
// header

import left_click();

// global script

function left_click() {
  ...
}

function on_mouse_click(MouseButton button) {
  ...
  if (button = eMouseLeft) {
    left_click();
  }
  ...
}

monkey0506

#7
Well when I said things would go wonky what would happen is this. If there was more than one on_mouse_click function (in any script) then the import would make the very first on_mouse_click function the global version which would override all other functions. This could be extremely difficult to diagnose, especially if working off any sort of template/module.

For example if in SomeScript.asc you have:

Code: ags
function on_mouse_click(MouseButton button) {
  if (button != eMouseLeftInv) return; // only work with inventory-clicks
  // ...
}


And then in GlobalScript.ash you have:

Code: ags
import function on_mouse_click(MouseButton button);


And in GlobalScript.asc you have:

Code: ags
function on_mouse_click(MouseButton button) {
  if (button == eMouseLeft) ProcessClick(mouse.x, mouse.y, mouse.Mode);
  else mouse.SelectNextMode();
}


The on_mouse_click code in GlobalScript.asc will never be run. This is exactly what was happening with SSH's BackwardsCompatibility module where IIRC he was trying to update some local variable or some such in his version of a deprecated function he was trying to make available again...yet it wasn't working at all. I did some digging and what was happening was that the function he was declaring was being completely ignored. The function was still defined with AGS it just wasn't imported, so when he was importing the function it was grabbing that copy globally.

How it would react if you tried to call on_mouse_click directly in the GlobalScript.asc I'm not sure.

So yes, it's arguable that "I'm not using on_mouse_click anywhere else..." however this is precisely why it's bad programming practice and I said not to do it. Because when you try and debug that...you're going to drive yourself effing crazy man. :=

As far as your suggestion goes, if there's a lot of complicated workings going on there that's a great way of doing it. Of course eMouseLeft is never used for GUIs, GUIControls, or InventoryItems, but you could still throw checks into the left_click function to make these accessible.

The primary point of my post was to display though that you can use InventoryItem.RunInteraction and ProcessClick to simulate mouse-clicks. Now if only we had GUI.Click and GUIControl.Click we'd have a fully simulated mouse! :D

SMF spam blocked by CleanTalk