[SOLVED] Save unit level and restore after rebuild

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
User avatar
Toranks
Translator
Posts: 168
Joined: October 21st, 2022, 8:59 pm
Location: Sevilla
Contact:

[SOLVED] Save unit level and restore after rebuild

Post by Toranks »

Here is an event that increases the level number every time a unit levels up AMLA, not only to keep track of how many times it has leveled up, but also to increase its upkeep cost, leadership skill, and experience enemies receive by attacking or killing him.

Code: Select all

[event]
    name=post_advance
    id=aww_15_trigger_post_advance_amla_inc
    first_time_only=no
    [filter_condition]
        {AWW_ENABLED_FEATURE_15}
        {AWW_TEST_WAS_AMLA}
    [/filter_condition]

    {VARIABLE_OP unit.level add 1}

    [unstore_unit]
        variable=unit
    [/unstore_unit]

    {CLEAR_VARIABLE inc_level}
[/event]
However, every time a unit receives a temporary [object] and loses it (usually at the end of the turn), it rebuilds and reduces his level to the maximum base unit level, according to the manual:
"Modifications are permanent changes to a unit; however using an [object] with a limited duration to apply an [effect] will cause the unit to be rebuilt without the effect's effects when the duration expires."
My idea is to save the level value of each unit in this post_advance event, and create another event after the rebuild, which restores the lost level. I don't know when this rebuild happens (at the end of the map, right when you lose the object...?), since it depends on the type of object.
Is there a simple way to do this? I'm still learning WML and maybe I'm asking for something complicated.

Note: I can't create a permanent level up item with [object], that it would be a simpler solution and that I am using to preserve almost all the statistics that I raise to the units with bonuses (movement, damage, attacks...), because the [effect] tag doesn't support any way to level up AFAIK (and confirmed to me on Discord).
Last edited by Toranks on October 30th, 2022, 5:06 pm, edited 2 times in total.
User avatar
beetlenaut
Developer
Posts: 2825
Joined: December 8th, 2007, 3:21 am
Location: Washington State
Contact:

Re: Save unit level and restore after rebuild

Post by beetlenaut »

Toranks wrote: October 30th, 2022, 6:11 am My idea is to save the level value of each unit in this post_advance event...
You can actually save a variable inside the unit that holds whatever data you want. You can do it with [set_variable] on a stored unit or use [modify_unit]. (Use :inspect to see the variable in the unit data.) Setting it looks like this:

Code: Select all

[modify_unit]
    [filter]
        id=harold
    [/filter]
    [set_variable]
        name=my_level
        value=5  # for example
    [/set_variable]
[/modify_unit]

# OR

[set_variable]
    name=unit.variables.my_level
    value=5
[/set_variable]
Toranks wrote: October 30th, 2022, 6:11 am ...and create another event after the rebuild, which restores the lost level.
Objects with duration=turn are rebuilt during the turn_refresh event. scenario and end_turn objects will be rebuilt shortly before that. In other words, a turn_refresh event should take care of everything:

Code: Select all

[event]
    name=turn_refresh
    first_time_only=no
    
    [modify_unit]
        [filter]
            side=1-99
        [/filter]
        level=$this_unit.variables.my_level
    [/modify_unit]
[/event]
This works, presumably because setting the level fails if the variable doesn't exist. However, it would be more robust if it did each unit one at a time checking to see whether or not the variable exists first. (Use [foreach] to go through the units, and compare the value of my_level to the value of a variable that you know doesn't exist.)
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
User avatar
Toranks
Translator
Posts: 168
Joined: October 21st, 2022, 8:59 pm
Location: Sevilla
Contact:

Re: Save unit level and restore after rebuild

Post by Toranks »

EDIT: SOLVED

Once these two variables are saved inside the unit (checked with inspect, it is saved only in the units that level up above AMLA as I intend)

Code: Select all

	[set_variable]
		name=unit.variables.my_level
		value=$unit.level
	[/set_variable]

	[set_variable]
		name=unit.variables.leveled
		value=yes
	[/set_variable]
Inside the unit i see this with inspect:

Code: Select all

[variables]
	leveled=yes
	my_level=3
[/variables]
I have created this event:

Code: Select all

[event]
    name=turn_refresh
    first_time_only=no

    [filter_condition]
        {AWW_ENABLED_FEATURE_15}
        {AWW_TEST_WAS_AMLA}
    [/filter_condition]
	
    [store_unit]
        variable=level_check
		[filter]
			[filter_wml]
				[variables]
					leveled=yes
				[/variables]
			[/filter_wml]
		[/filter]
    [/store_unit]
	
   {FOREACH level_check i}

		{VARIABLE level_check[$i].level $level_check[$i].variables.my_level}
        [unstore_unit]
            variable=level_check[$i]
        [/unstore_unit]

    {NEXT i}
    {CLEAR_VARIABLE level_check}

[/event]
And finally works! Thanks!

(My previous mistake is using $unit.variables.my_level and $this_unit.variables.my_level instead of $level_check[$i].variables.my_level. The last is the correct sintax)
User avatar
beetlenaut
Developer
Posts: 2825
Joined: December 8th, 2007, 3:21 am
Location: Washington State
Contact:

Re: [SOLVED] Save unit level and restore after rebuild

Post by beetlenaut »

OK, I'm glad it works. You do still have a problem in that {FOREACH} is deprecated and will be removed soon. (There is a note in data/core/macros/deprecated-utils.cfg.) You should definitely use [foreach] instead.
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
User avatar
Celtic_Minstrel
Developer
Posts: 2222
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: [SOLVED] Save unit level and restore after rebuild

Post by Celtic_Minstrel »

I think it might be easier to use a custom effect for this?

Then you could put this in your AMLA definition:

Code: Select all

[effect]
	apply_to=level
	increase=1
[/effect]
Making that actually work needs some Lua coding. It would look something like this (just put this tag in your _main.cfg or an equivalent location):

Code: Select all

[lua]
	code=<<
		function wesnoth.effects.level(unit, cfg)
			unit.level = unit.level + cfg.increase
		end
	>>
[/lua]
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
beetlenaut
Developer
Posts: 2825
Joined: December 8th, 2007, 3:21 am
Location: Washington State
Contact:

Re: [SOLVED] Save unit level and restore after rebuild

Post by beetlenaut »

Celtic_Minstrel wrote: November 1st, 2022, 4:16 am I think it might be easier to use a custom effect for this?
The OP originally tried to do this with [effect], but found it to be impossible since apply_to=level doesn't exist. I didn't realize how easy it would be to add though. If it's that easy, it should be added to the core.
Campaigns: Dead Water,
The Founding of Borstep,
Secrets of the Ancients,
and WML Guide
User avatar
Celtic_Minstrel
Developer
Posts: 2222
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: [SOLVED] Save unit level and restore after rebuild

Post by Celtic_Minstrel »

Note that if it were to be added to core, you'd want to expand on that code a bit more to make it more foolproof and probably also support set. I kept it to the bare minimum needed for the original poster's needs.
Author of The Black Cross of Aleron campaign and Default++ era.
Former maintainer of Steelhive.
User avatar
Toranks
Translator
Posts: 168
Joined: October 21st, 2022, 8:59 pm
Location: Sevilla
Contact:

Re: [SOLVED] Save unit level and restore after rebuild

Post by Toranks »

Spoiler:
This works too, thanks! More simple. Now I can set the unit level with an object, much more manageable and instantly instead to create another event.
It also allows me to combine it with other level dependent effects. It should definitely be a native function of [effect], as it makes handling RPG maps and campaigns a bit easier.
Post Reply