how fire_event works?

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
Bozenka
Posts: 11
Joined: March 17th, 2023, 7:28 pm

how fire_event works?

Post by Bozenka »

hoy there,
I am wondering how fire_event works...
Can I fire events that have been added to game recently? Maybe even in the same actionwml tag?
User avatar
Atreides
Posts: 1075
Joined: March 30th, 2019, 10:38 pm
Location: On the 2nd story of the centre village of Merwuerdigliebe turning the lights on and off

Re: how fire_event works?

Post by Atreides »

This works so it seems the order isn't that important.

Code: Select all

[event]
    name=movethrough
    [filter_condition]
        [have_location]
            x=$x2
            y=$y2
            [and]
                x=$hero_store.x
                y=$hero_store.y
                radius=2
            [/and]
        [/have_location]
    [/filter_condition]
    [fire_event]
        name=reveal_hero
    [/fire_event]
[/event]

[event]
    name=reveal_hero
    first_time_only=no
User avatar
beetlenaut
Developer
Posts: 2827
Joined: December 8th, 2007, 3:21 am
Location: Washington State
Contact:

Re: how fire_event works?

Post by beetlenaut »

Bozenka wrote: February 8th, 2024, 8:52 pm Can I fire events that have been added to game recently?
Every event provided with the game has a defined trigger that comes from the game or a player's action, so you don't need [fire_event] for those. It is almost always used to fire custom events, which are mainly used to avoid duplicating sections of code that can be reached in different ways. (Macros seem to do the same thing, but they only hide the duplication. They don't remove it.)
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
Bozenka
Posts: 11
Joined: March 17th, 2023, 7:28 pm

Re: how fire_event works?

Post by Bozenka »

Ok so if I make custom event and fire it in one action, for example another event, it should work right? Thats great!
The other thing is...
I understand, that when i am expanding lots of macros, for certain actions it can make the game slower.
So lets say that I have a piece of code that perform actions that are very simmilar but not completely the same. Lets say i want to change one number in it. but i would not like to copy/paste. Is it an option to create macro, that will add event with those different numbers as arg? Or is another way to trigger the same event with different parameter...maybe [insert_tag] or is that generaly just bad idea?
User avatar
Ravana
Forum Moderator
Posts: 3016
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: how fire_event works?

Post by Ravana »

You can create variable before you fire event.

You can use [data] (historically [primary_attack]) to send data to event.
User avatar
Spannerbag
Posts: 538
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: how fire_event works?

Post by Spannerbag »

I'd appreciate a bit of enlightenment regarding [data] inside [fire_event].

For custom data, is there any advantage over using [set_variable] ... [fire_event] ... [clear_variable]?
Also, what is the syntax for custom data?
Do you still need [set_variable] or can you simply use variable_name=value?
And when the event is finished, are the [data] values automatically cleared?

I had a brief skim through the campaigns but couldn't find any examples there and there are no syntax examples (that I could find anyway) in the wiki.

Tried code to stumble across how to assign custom data solution but no joy. (v1.17.25).

Code: Select all

  [event]
    name=data_test
    first_time_only=no
    [message]
      speaker=narrator
      message=_"In data_test and value sent = $data_sent."
    [/message]
  [/event]

  [event]
    name=side 1 turn 1

    {VARIABLE data_sent (_"Hello World!")}
    [fire_event]				# --- Existing method (works)
      name=data_test
    [/fire_event]
{DEBUG_MSG (_"Method 1: fired data_test, data_sent=$data_sent")}

   [fire_event]
      name=data_test				# --- First guess at [data] syntax (doesn't work)
      [data]
        {VARIABLE data_sent (_"Stop the world I wamnt to get off!")}
      [/data]
    [/fire_event]
{DEBUG_MSG (_"Method 2: fired data_test, data_sent=$data_sent")}

    [fire_event]
      name=data_test				# --- Second guess at [data] syntax (doesn't work)
      [data]
        data_sent=_"Goodbye and thanks for all the fish!"
      [/data]
    [/fire_event]
{DEBUG_MSG (_"Method 3: fired data_test, data_sent=$data_sent")}
  [/event]
$data_sent was never assigned either value specified inside [data].

What am I missing or misunderstanding?

Any clarification greatly appreciated.

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
User avatar
Celtic_Minstrel
Developer
Posts: 2236
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: how fire_event works?

Post by Celtic_Minstrel »

I think the [data] support is missing a piece. It probably should be exposed either as something like $event_data or by injecting its contents as temporary variables. Your second attempt used the correct syntax, so if $event_data existed, you should've been able to access the sent variable as $event_data.data_sent. If the contents were injected as temporary variables, your example would've worked as-is.

However, in actual fact the data can currently only be accessed from the Lua API via wesnoth.current.event_context.data.

I think the following (untested) approach should work if you want to expose it to WML. It should make your second example work as-is. You could put it into a macro and just dump it at the top of any function that you need to fire with data:

Code: Select all

[lua]
	code=<<
		local tag_indices = {}
		for key, value in pairs(wesnoth.current.event_context.data) do
			if type(key) == 'number' then
				-- Container variable
				if tag_indices[value.tag] == nil then
					tag_indices[value.tag] = 0
				else
					tag_indices[value.tag] = tag_indices[value.tag] + 1
				end
				local var_path = ("%s[%d]"):format(value.tag, tag_indices[value.tag])
				wml.variables[var_path] = value.contents
			else
				-- Scalar variable
				wml.variables[key] = value
			end
		end
	>>
[/lua]
That code doesn't clean up after itself though, so it'll leave all those variables littering the global scope when it's done. I don't know of any way to make it clean up after itself in pure Lua. Each event will need to clear the variables that were passed through to it – each toplevel key or tag in the [data] tag.

Note: In 1.16, value.tag would need to be replaced with value[1], and value.contents would need to be replaced with value[2].
Spannerbag wrote: February 20th, 2024, 2:24 pm For custom data, is there any advantage over using [set_variable] ... [fire_event] ... [clear_variable]?
Yes – that approach places the data in the global scope, where it needs to be careful not to conflict with other things. Using [data], it's completely private to the event. Three different events could use the same data variable in completely different ways without worry, if you really wanted.
Spannerbag wrote: February 20th, 2024, 2:24 pm Also, what is the syntax for custom data?
Do you still need [set_variable] or can you simply use variable_name=value?
The second is correct. You can put any key or tag you want for arbitrarily complicated data.
Spannerbag wrote: February 20th, 2024, 2:24 pm And when the event is finished, are the [data] values automatically cleared?
The data is stored as part of the event, so it's never placed in a global scope. If we exposed it properly to WML, the variables would be automatically cleared.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Ravana
Forum Moderator
Posts: 3016
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: how fire_event works?

Post by Ravana »

Seems 1.18 should keep using [primary_attack] -> $weapon for custom data then.
User avatar
Spannerbag
Posts: 538
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: how fire_event works?

Post by Spannerbag »

Hi Celtic_Minstrel, many thanks, as ever, for the very helpful and detailed reply.

Just a couple of thoughts/comments...
Celtic_Minstrel wrote: February 20th, 2024, 2:52 pm I think the [data] support is missing a piece. It probably should be exposed either as something like $event_data or by injecting its contents as temporary variables. Your second attempt used the correct syntax,...
Yay! I got something right!

Celtic_Minstrel wrote: February 20th, 2024, 2:52 pm ...so if $event_data existed, you should've been able to access the sent variable as $event_data.data_sent. If the contents were injected as temporary variables, your example would've worked as-is.

However, in actual fact the data can currently only be accessed from the Lua API via wesnoth.current.event_context.data.
Ah.
Celtic_Minstrel wrote: February 20th, 2024, 2:52 pm I think the following (untested) approach should work if you want to expose it to WML...
...That code doesn't clean up after itself though, so it'll leave all those variables littering the global scope when it's done. I don't know of any way to make it clean up after itself in pure Lua. Each event will need to clear the variables that were passed through to it – each toplevel key or tag in the [data] tag.
Err... seems to me that for now at least, this approach adds no benefit over regular WML (unless I've missed something - quite possible)?

Sorry to be dim here but I don't know lua and have found mapping out the lua API challenging.
I am not clear about the relationship between lua variables and WML variables, namely that as I see it there are two kinds of lua variables from a WML perspective (maybe more, it's quite possible I've missed something out here).

First there are those lua variables that are simply the lua incarnations of WML variables/values (wml.variables and maybe wesnoth.current.event_context.data if it worked as I expected?).

Then there are the internal "working variables" used by lua to reference/manipulate the WML values/variables such as (I guess, really out of my depth here) tag_indices[value.tag] that (I infer) identifies a specific WML array element?
So, for example, in $my_array[$i], tag_indices[value.tag] does the same job as $i?

Celtic_Minstrel wrote: February 20th, 2024, 2:52 pm
Spannerbag wrote: February 20th, 2024, 2:24 pm For custom data, is there any advantage over using [set_variable] ... [fire_event] ... [clear_variable]?
Yes – that approach places the data in the global scope, where it needs to be careful not to conflict with other things. Using [data], it's completely private to the event. Three different events could use the same data variable in completely different ways without worry, if you really wanted.
Cool, I can see that the reduced variable scope/visibility is inherently superior.
However I am consufed because previously, re. the lua method, you said:
That code doesn't clean up after itself though, so it'll leave all those variables littering the global scope when it's done.

I'm not clear what you mean (sorry to be dim). By all those variables do you mean:
  1. These are WML variables so must be cleared at WML level using [clear_variable]?
  2. These are lua "working variables" (assuming they even exist, my original supposition may have been wrong) that cannot be cleared by WML so will hang around in (lua) global scope until (I guess) the player quits the game?
    (I would've thought that these would be cleared by internal housekeeping when the lua routine exits?)
  3. Something entirely different and I have utterly misunderstood what you were saying (most likely option IMHO).
Celtic_Minstrel wrote: February 20th, 2024, 2:52 pm
Spannerbag wrote: February 20th, 2024, 2:24 pm And when the event is finished, are the [data] values automatically cleared?
The data is stored as part of the event, so it's never placed in a global scope. If we exposed it properly to WML, the variables would be automatically cleared.
Well, that helps with my list item 1 above so I guess the variables in global scope would be what I call "working variables"?

Again, sorry to be dim but really not sure which variables are in what scope!
Thanks again for your reply, much appreciated!

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
User avatar
Celtic_Minstrel
Developer
Posts: 2236
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: how fire_event works?

Post by Celtic_Minstrel »

Spannerbag wrote: February 21st, 2024, 11:54 am However I am consufed because previously, re. the lua method, you said:
That code doesn't clean up after itself though, so it'll leave all those variables littering the global scope when it's done.

I'm not clear what you mean (sorry to be dim). By all those variables do you mean:
  1. These are WML variables so must be cleared at WML level using [clear_variable]?
This is the correct option. The Lua code I posted exposes everything in [data] as WML variables, but does not clean those variables up, so you would need to use [clear_variable] if you use that code. A proper solution in the engine would work mostly the same as that Lua code, but would also clean up the variables after the event runs.

Lua automatically cleans up variables, as long as you declare them as local. It's possible to arrange things so that Lua's local variable cleanup process will also clean up the WML variables, but I didn't do that because it ends up looking rather weird and awkward – you would need to put all your WML code inside the Lua tag (in [args]), which I thought would be confusing.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Spannerbag
Posts: 538
Joined: December 18th, 2016, 6:14 pm
Location: Yes

Re: how fire_event works?

Post by Spannerbag »

Thanks for your time and patience, it actually all makes sense to me! :shock:

Celtic_Minstrel wrote: February 21st, 2024, 6:40 pm
Spannerbag wrote: February 21st, 2024, 11:54 am ...I'm not clear what you mean (sorry to be dim). By all those variables do you mean:
  1. These are WML variables so must be cleared at WML level using [clear_variable]?
This is the correct option... It's possible to arrange things so that Lua's local variable cleanup process will also clean up the WML variables... you would need to put all your WML code inside the Lua tag (in [args]), which I thought would be confusing.
And you'd be right, at least in my case. :)

Again, thanks ever so much for explaining this, much appreciated.

Cheers!
-- Spannerbag
SP Campaigns: After EI (v1.14) Leafsea Burning (v1.17, v1.16)
I suspect the universe is simpler than we think and stranger than we can know.
Also, I fear that beyond a certain point more intelligence does not necessarily benefit a species...
Post Reply