Xalzar's WML Headaches
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.
Re: Xalzar's WML Headaches
So...the event
Now I need to link these events to another one which is normally evoked during recruitment; ok no problem, another linked custom event fired from the first one. The problem is that this event needs to be fed variables normally obtained during side turns, and the unit_placed event triggers in prestart.
How can I work around this?
P.S.: I've already tried "side X turn 1" and "start" events, and they would work, if not for the fact that the events through which I insert the variables into the leader have values defined by a macro which I've put inside the unit cfg file (and that macro cannot be moved from there). If only I could add variables directly inside [unit_type]!
Code: Select all
unit_placed
I needed to cram some variable into all the leaders of the various sides (every leader has different variables depending on its unit type), this I have already solved with this event "linked" other, custom events.wiki wrote:Leaders and units placed in side definitions (fired once for every unit right before prestart events)
Now I need to link these events to another one which is normally evoked during recruitment; ok no problem, another linked custom event fired from the first one. The problem is that this event needs to be fed variables normally obtained during side turns, and the unit_placed event triggers in prestart.
How can I work around this?
P.S.: I've already tried "side X turn 1" and "start" events, and they would work, if not for the fact that the events through which I insert the variables into the leader have values defined by a macro which I've put inside the unit cfg file (and that macro cannot be moved from there). If only I could add variables directly inside [unit_type]!
- Pentarctagon
- Project Manager
- Posts: 5564
- Joined: March 22nd, 2009, 10:50 pm
- Location: Earth (occasionally)
Re: Xalzar's WML Headaches
If the variables you need aren't set yet, then you could perhaps use defaults in that case? If the only case you'd need to do that for would be the prestart event, then you'd only need to account for side 1 turn 1.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
take one down, patch it around
-2,147,483,648 little bugs in the code
Re: Xalzar's WML Headaches
The major problem is that I have lots of events in my code, and I wanted to remove some of them via [remove_event] when they are no longer needed.Pentarctagon wrote: ↑July 11th, 2019, 12:12 am If the variables you need aren't set yet, then you could perhaps use defaults in that case? If the only case you'd need to do that for would be the prestart event, then you'd only need to account for side 1 turn 1.
And guess what? The event with the predefined variables (which is brought by the units themselves) has the same id for all units so when I remove it for the first leader the other leaders lack half of the variables.
So I've tried to give an unique id for that event (linked to the unit id), and now neither the event nor the remove_event work anymore apparently. Maybe they do not appreciate substitutions very much.
More testing required...
Re: Xalzar's WML Headaches
Sometimes the best approach to a complex debugging problem is pen, paper, pizza and not sitting in front of the PC. Don't focus on where you're getting stuck, instead write an overview of the desired behaviour. Doodle a bit and avoid thinking about the current implementation, the aim is that an easier overall design will appear.
How the pizza helps this process is unclear, but it does seem to do so.
How the pizza helps this process is unclear, but it does seem to do so.
Re: Xalzar's WML Headaches
Instructions unclear: I have a ball o' paper in my throat and I've scribbled on my pizza. Each anchovy stands for a variable.octalot wrote: ↑July 11th, 2019, 12:28 pm Sometimes the best approach to a complex debugging problem is pen, paper, pizza and not sitting in front of the PC. Don't focus on where you're getting stuck, instead write an overview of the desired behaviour. Doodle a bit and avoid thinking about the current implementation, the aim is that an easier overall design will appear.
How the pizza helps this process is unclear, but it does seem to do so.
Jokes aside, solid advice.
Right now, the structure is like this:
Code: Select all
Inside the units: {MACRO OF THE VARIABLES' VALUES}, unique for every unit type
Code: Select all
Indipendent Events: Unit Placed event (for the leaders) with generic variables and fire_event=Variables event
Start event which deletes the previous event (I don't need it any more) and the Variables event (since it is renewed every recruitment)
Events Dependent on the unit macro: Prerecruit event (for recruits) with dependent variables and fire_event=Variables event
Custom Variables event with unique id and the majority of dependent variables and fire_event=Store event
Code: Select all
Custom Store event with some store_x
Custom Menu event with the message and its options
Then...While writing on pizza I've come up with an idea: using the macro values in separate, general variable instead of "unit" variables like now (like unit_stored.variables.x value={MACRO VALUE}) and then transfer those values into the latter ones, so I should be able to delete generic variables instead of whole events, and I wouldn't need to give an unique id to the event itself and keep it in the game. On to more testing!
Re: Xalzar's WML Headaches
If you want to trigger unit placed event, you could just [fire_event] with that unit.
Re: Xalzar's WML Headaches
I've quite re-ordered my code for those events, but I still have a major problem. Let me explain better (my last post was quite unclear on rereading).
The obstacle I face is an event included as macro inside unit files, which has variable with variables set by said macro.
It's all fine and dandy when I fire it from a recruit event, but at the start I have all the different side leaders which creates it at the same time (even if I set the trigger to each side turn 1 start), and since it has an id (for removing purposes), it gains the values of the first macro (in the first unit) only.
So it's good for the first leader, e.g.:
But then the second leader which should get e.g.:
doesn't get the expected value, instead it gets "John".
I know the logic of the problem but I cannot find a workaround, since trying to making the events unique by setting the event id for example as "renaming_$leadername.side" (after a store_unit variable=leadername) it causes the event to not work. Same if I use this trick on variable names.
I cannot refresh the values of that event unless maybe I store_unit kill=yes and unstore_unit each leader at the start of their turn, but then the game ends in defeat for that faction (death of the leader).
I'm now thinking the solution is removing that event from unit files, but doing that would cause the code to bloat since it's not evoked only when the unit is first appearing in the game; I would have to write a macro (so an event) with values for every single unit (they are many) and try to lighten the code using a lot of filters (which don't delete events though, so the "weight" of the written code remains.
So, before going forward, have you any more advice to resolve this conundrum without resorting to the alternative option?
The obstacle I face is an event included as macro inside unit files, which has variable with variables set by said macro.
It's all fine and dandy when I fire it from a recruit event, but at the start I have all the different side leaders which creates it at the same time (even if I set the trigger to each side turn 1 start), and since it has an id (for removing purposes), it gains the values of the first macro (in the first unit) only.
So it's good for the first leader, e.g.:
Code: Select all
[set_variable]
name=new_name
value=_"John"
[/set_variable]
Code: Select all
[set_variable]
name=new_name
value=_"Arnold"
[/set_variable]
I know the logic of the problem but I cannot find a workaround, since trying to making the events unique by setting the event id for example as "renaming_$leadername.side" (after a store_unit variable=leadername) it causes the event to not work. Same if I use this trick on variable names.
I cannot refresh the values of that event unless maybe I store_unit kill=yes and unstore_unit each leader at the start of their turn, but then the game ends in defeat for that faction (death of the leader).
I'm now thinking the solution is removing that event from unit files, but doing that would cause the code to bloat since it's not evoked only when the unit is first appearing in the game; I would have to write a macro (so an event) with values for every single unit (they are many) and try to lighten the code using a lot of filters (which don't delete events though, so the "weight" of the written code remains.
So, before going forward, have you any more advice to resolve this conundrum without resorting to the alternative option?
Re: Xalzar's WML Headaches
I understand original issue is slow performance then.
Do you have code in form I could try out in game?
Do you have code in form I could try out in game?
Re: Xalzar's WML Headaches
More like "preempively avoiding slow performances in the future". I have many more events to add still, I'm testing with only few units to make sure everything works before adding more.
The code is like this:
Code: Select all
{PREDEFINED (yes) (yes) (sword,bow) (sword) (crown) (5) (20)}
Code: Select all
#define PREDEFINED HERO CANRECRUIT BASE LOADOUT UPGRADES SQUADS MORALE
## Recruits Storage
[event]
name=prerecruit
id=predef_prerecr
first_time_only=no
[store_unit]
[filter]
id=$unit.id
[/filter]
variable=predef
[/store_unit]
[if]
[variable]
name=predef.canrecruit
equals=yes
[/variable]
[or]
[variable]
name=predef.variables.hero
equals=yes
[/variable]
[/or]
[then]
[object]
silent=yes
duration=forever
[filter]
id=$predef.id
[/filter]
[effect]
apply_to=ellipse
ellipse="misc/ellipse-hero"
[/effect]
[/object]
[if]
[variable]
name=predef.canrecruit
equals=yes
[/variable]
[then]
[unit_overlay]
id=$predef.id
image=misc/hero-icon.png
[/unit_overlay]
[/then]
[else]
[unit_overlay]
id=$predef.id
image=misc/loyal-icon.png
[/unit_overlay]
[/else]
[/if]
[/then]
[/if]
[fire_event]
id=predef_variables
[/fire_event]
[/event]
## Predefined Variables
[event]
name=unit_variables
id=predef_variables
first_time_only=no
[set_variable]
name=predef_hero
value={HERO}
[/set_variable]
[set_variable]
name=predef_canrecruit
value={CANRECRUIT}
[/set_variable]
[set_variable]
name=predef_base
value={BASE}
[/set_variable]
[set_variable]
name=predef_loadout
value={LOADOUT}
[/set_variable]
[set_variable]
name=predef_upgrades
value={UPGRADES}
[/set_variable]
[set_variable]
name=predef_squads
value={SQUADS}
[/set_variable]
[set_variable]
name=predef_morale
value={MORALE}
[/set_variable]
[unstore_unit]
variable=predef
[/unstore_unit]
{CLEAR_VARIABLE "predef"}
[fire_event]
id=modstore #ignore this since the problem isn't there, just know it sets variables inside the unit and there is a {CLEAR_VARIABLE} which cleans up all the general variables set here
[/fire_event]
[remove_event]
id=predef_prerecr,predef_variables
[/remove_event]
[/event]
#enddef
Code: Select all
[event]
name=side turn 1
id=commander_mod
first_time_only=no
[store_unit]
[filter]
canrecruit=yes
side=$side_number
[/filter]
variable=predef
[/store_unit]
[set_variable]
name=storing_id
value=$predef.id
[/set_variable]
[set_variable]
name=predef.name
value=_"$predef.name| Commander"
[/set_variable]
[set_variable]
name=predef.variables.commander
value=yes
[/set_variable]
[set_variable]
name=predef_hero
value=yes
[/set_variable]
[fire_event]
id=predef_variables
[/fire_event]
[/event]
Re: Xalzar's WML Headaches
I put the parts together as https://github.com/ProditorMagnus/Xalzar. What is the expected behavior, and what happens instead with this code?
Re: Xalzar's WML Headaches
Thank you, you are doing too much!
The macro {PREDEFINED} is to be inserted in a unit file, the rest in modifications. I'm very sorry.
The results?
So, since I have multiple, different leaders, I can have for example:
Leader 1
Leader 2
...and then the event would only take the values from the first unit. That's one of the reasons to delete events, to erase the values (since the event is created - and takes the values - when the unit first appears, not when triggers following its conditions). Sadly the event can't be created anymore from a leader (since it's already in the game).
As a result I would have both units with variables values taken from the first macro. I'm saying "units" because those general variables (e.g. predef_base) are first converted in unit.variables in a later event, and then deleted. It seems a step too much but I was trying to find a workaround, pity that the event substitutes macro values on creation and not on activation.
Expected behaviour would be having the correct values for each leader unit. Forget the prerecruit event for now, the relevant ones are the side turn 1 and the unit_variables ones.
Rats! I've realized only now that typing "[ code=in UNIT FILES ]" in the forum post does not work. I wrote where to put the code but alas.Ravana wrote: ↑July 14th, 2019, 2:25 pm I put the parts together as https://github.com/ProditorMagnus/Xalzar. What is the expected behavior, and what happens instead with this code?
The macro {PREDEFINED} is to be inserted in a unit file, the rest in modifications. I'm very sorry.
The results?
So, since I have multiple, different leaders, I can have for example:
Leader 1
Code: Select all
{PREDEFINED (yes) (yes) (sword,bow) (sword) (crown) (5) (20)}
Code: Select all
{PREDEFINED (no) (yes) (sword,gun) (gun) (eagle eye) (1) (30)}
As a result I would have both units with variables values taken from the first macro. I'm saying "units" because those general variables (e.g. predef_base) are first converted in unit.variables in a later event, and then deleted. It seems a step too much but I was trying to find a workaround, pity that the event substitutes macro values on creation and not on activation.
Expected behaviour would be having the correct values for each leader unit. Forget the prerecruit event for now, the relevant ones are the side turn 1 and the unit_variables ones.
Re: Xalzar's WML Headaches
Assuming you want to store arbitrary data with unit type, and do not want Lua, I suggest using ability. I pushed the example.
Though if you intend to have them as constant instead of variable, the mapping event is not even needed.
Though if you intend to have them as constant instead of variable, the mapping event is not even needed.
Re: Xalzar's WML Headaches
Either I don't understand what you want to do, or there's a much simpler way to do it.
I think you want a side to have several leaders, all recruited units to get a buff based on which leader recruits them, and each recruit to know who their squad leader is. That can be done like this:
I think you want a side to have several leaders, all recruited units to get a buff based on which leader recruits them, and each recruit to know who their squad leader is. That can be done like this:
Code: Select all
#text_domain wesnoth-Xalzar_WML_Headaches
[scenario]
current_time=0
description=""
experience_modifier=70
id="01_Squad_Leaders"
map_data="{multiplayer/maps/4p_Castle_Hopping_Isle.map}"
name= _ "Squad Leaders"
random_start_time=no
victory_when_enemies_defeated=no
carryover_percentage=0
next_scenario="null"
{DEFAULT_SCHEDULE}
[side]
controller="human"
fog=no
gold=10000
hidden=no
income=4
no_leader=no
share_vision="all"
shroud=no
side=1
team_name=Heroes
user_team_name= _ "Squad Leaders"
id=Methor
name= _ "General Methor"
unrenamable=yes
facing="ne"
type="General"
recruit="Bowman, Cavalryman, Heavy Infantryman, Horseman, Mage, Spearman, Footpad, Poacher, Thief, Thug"
[/side]
# This is a standard 4-player map, so fill in the unused sides
[side]
controller="null"
[/side]
[side]
controller="null"
[/side]
[side]
controller="null"
[/side]
[event]
name=prestart
[unit]
x,y=14,8
side=1
type=Longbowman
canrecruit=yes
[variables]
recruit_boost="bow"
[/variables]
[/unit]
[unit]
x,y=24,8
side=1
type=Swordsman
canrecruit=yes
[variables]
recruit_boost="sword"
[/variables]
[/unit]
[unit]
x,y=14,13
side=1
type="White Mage"
canrecruit=yes
[variables]
recruit_boost="holy_mace"
[/variables]
[/unit]
[/event]
[event]
name=recruit
first_time_only=no
[modify_unit]
[filter]
x,y=$x1,$y1
[/filter]
[trait]
name=_ "recruited"
description= "The unit was recruited by $second_unit.name"
[/trait]
[/modify_unit]
[switch]
variable=second_unit.variables.recruit_boost
[case]
value="bow"
[object]
silent=yes
duration=forever
[effect]
apply_to=new_attack
name="extra_bow"
description=_ "Bow"
damage=8
number=3
range="ranged"
type="pierce"
[/effect]
[/object]
[/case]
[case]
value="sword"
[object]
silent=yes
duration=forever
[effect]
apply_to=new_attack
name="extra sword"
description=_ "Sword"
damage=9
number=3
range="melee"
type="blade"
[/effect]
[/object]
[/case]
[case]
value="holy_mace"
[object]
silent=yes
duration=forever
[effect]
apply_to=new_attack
name="holy_mace"
description=_ "Holy Mace"
damage=8
number=2
range="melee"
type="arcane"
[/effect]
[/object]
[/case]
[/switch]
[/event]
[/scenario]
Re: Xalzar's WML Headaches
octalot wrote: ↑July 14th, 2019, 8:14 pm Either I don't understand what you want to do, or there's a much simpler way to do it.
I think you want a side to have several leaders, all recruited units to get a buff based on which leader recruits them, and each recruit to know who their squad leader is. That can be done like this:
I don't know how to express my ideas properly, I'm sorry!
Let's try again :
-no, no side with multiple leaders;
-no buffs to recruits dependent on leader;
-no necessity to identify the squad leader.
When I talk of multiple leaders, I mean that every side has its own at the start of the game (obviously). The problem is that each of them have events incorporated, and they overwrite themselves (actually the first one is the one who overwrites the others). This is because every side leader spawns simultaneously.
The leaders need to have some variables stored inside them, which I use for some general events or for filtering some options in some event-message-options; my objective is letting the player select some weapons/abilities for their leaders (and each leader has some, predefined options for this). These things happen in events I've not reported here, because they function properly for now.
The same happens to every recruited unit, and this works wonderfully because they do not spawn simultaneously (only one recruit at a time, obviously, and then their events would be deleted by event so there is no overlap).
To answer about squads, let me explain summarily what each variable does:
-Hero: it should change ellipse and crown, opens the option to equip them with some specific upgrades (I still need to make this work properly, a question for the future maybe - if I can't resolve the problem myself);
-Canrecruit: ok, this gives the side multiple leaders, it depends primarily on what type of unit do you recruit (the Commander is the first and proper leader, other Leaders can recruit but are otherwise no different from other Heroes);
-Base: specifies the standard equipment for the unit, while modifying the unit you can choose to keep it as it is and this is how the message gives the player information about its standard weapons;
-Loadout: specifies the obligatory weapons, the ones which cannot be changed;
-Upgrades: same but with upgrades, which are normally abilities and weapon specials;
-Squads: some units can have e.g. size 3,6,9 squads - this means you can recruit them 3,6,9 of the same (modified or not) unit at the same time (cost is multiplied obviously), Heroes are normally size 1 squad. Additionally, this squad units must remain adjacent to their squad mates to form chains/blocks of at least the minimum size lest they incur in penalties to movement and attack;
-Morale: the higher the better, every time an adjacent allied unit dies it loses 1 morale, at 0 they get maluses to movement and attack.
TL;DR: these variables are used in filtering options for unit modification or for general gameplay events.
Also, I'm using modifications so I can use this Era in any map. If I used a specific scenario, I'd have resolved my problem with the leaders' variables long ago!
Re: Xalzar's WML Headaches
Quick update: AFAIK my problem was unsolvable, so I brute-forced the solution and manually wrote the unit parameters inside [modification]. It will be a long list (the units to modify are quite a number), but macros help a lot at least visually (coding-wise, maybe I have a solution for that too).
I'm not exactly unhappy with the resolution since the more I thought about the matter, the more I realized that I was overcomplicating the code with no real benefit.
I'm not exactly unhappy with the resolution since the more I thought about the matter, the more I realized that I was overcomplicating the code with no real benefit.