Give experience to the attacker unit on a [harm_unit] event

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:

Give experience to the attacker unit on a [harm_unit] event

Post by Toranks »

I have an event here that recreates a surprise attack on ambushes. It does a fixed damage to the ambushed unit relative to the attacks it could have done by subtracting a percentage equal to the defense of the terrain. After the calculations, and once the corresponding value is obtained, a [harm_unit] is executed.
The attacked unit receives experience correctly, but the attacker is restored to the initial state before the attack and loses experience due to the [unstore_unit] being executed at the end to update the unit variables that have changed during the event (needed to avoid another surprise attack the same turn, reveal it, and add a cooldown counter).
Initially I thought of adding the experience in the same way as the other variables using formula, and I did a basic test to see if it would work, like this (where says # saving unit variable : )

Code: Select all

[set_variable]
    name=ambushers[$a].experience
    add=20
[/set_variable]
But then I ran into a problem. In normal play, there's no difference, but if the unit levels up at that moment, you see it animate for the level up, all the pre_advance, post_advance, etc events are executed, and THEN when unstore_unit is executed and retrieves the unit with updated experience, the previous unit spawns without leveling up and immediately levels up again, running all of the above events again. That twice in a row.
So I need some idea to avoid this problem, can anybody guide me on a possible method to give that experience without that visual error?

Code: Select all

## manage surprises attacks
[event]
    name=moveto
    id=aww_13_trigger_ambush_moveto
    first_time_only=no
    [filter_condition]
        {AWW_ENABLED_FEATURE_13}
    [/filter_condition]
    [filter]
        [filter_adjacent]
            is_enemy=yes
            find_in=hidden_units
            [filter_wml]
                [variables]
                    preambush=yes
                [/variables]
            [/filter_wml]
        [/filter_adjacent]
    [/filter]


    ### getting victim terrain defense to reduce damages taken by surprise attack : (value will be between 20-80):

    [store_unit_defense_on]
        variable=def_ratio
        loc_x,loc_y=$x1,$y1
    [/store_unit_defense_on]
    ## it return like 30 for a terrain defense of 70%. We divide by 100 to get 0.3, and use this as damage ratio in harm_unit :
    {VARIABLE_OP def_ratio divide 100}

    {AWW_VARIABLE_VALUE_OP ambush_cooldown_turn $turn_number add 2}

    ### getting all ambushers enemies :

    [store_unit]
        variable=ambushers
        [filter]
            find_in=hidden_units
            [filter_wml]
                [variables]
                    preambush=yes
                [/variables]
            [/filter_wml]
            [filter_adjacent]
                id=$unit.id
                is_enemy=yes
            [/filter_adjacent]
        [/filter]
    [/store_unit]

    {FOREACH ambushers a}
        [if]
            {AWW_NOT_ISSET_VARIABLE ambushers[$a].variables.aww_ambush_cooldown_turn}
            [or]
                {VARIABLE_CONDITIONAL ambushers[$a].variables.aww_ambush_cooldown_turn less_than_equal_to $turn_number}
            [/or]
            [then]
                ### disable  attack of ambushed victims :

                [modify_unit]
                    [filter]
                        {AWW_EVENT_UNIT}
                    [/filter]
                    attacks_left=0
                [/modify_unit]

                ## Most of the time weapon 2 is a faster / ranger weapon, so more coherent it's used for surprise attack :
                [if]
                    {VARIABLE_CONDITIONAL ambushers[$a].attack[1].damage greater_than 0}
                    {VARIABLE_CONDITIONAL ambushers[$a].attack[1].number greater_than 0}
                    [then]
                        {VARIABLE ambusher_w_name $ambushers[$a].attack[1].name}
                        {VARIABLE ambusher_w_type $ambushers[$a].attack[1].type}
                        {VARIABLE ambusher_w_damage $ambushers[$a].attack[1].damage}
                        {VARIABLE ambusher_w_number $ambushers[$a].attack[1].number}
                    [/then]
                    [else]
                        {VARIABLE ambusher_w_name $ambushers[$a].attack[0].name}
                        {VARIABLE ambusher_w_type $ambushers[$a].attack[0].type}
                        {VARIABLE ambusher_w_damage $ambushers[$a].attack[0].damage}
                        {VARIABLE ambusher_w_number $ambushers[$a].attack[0].number}
                    [/else]
                [/if]

                [if]
                    {VARIABLE_CONDITIONAL ambusher_w_damage greater_than 0}
                    {VARIABLE_CONDITIONAL ambusher_w_number greater_than 0}
                    [then]
                        {AWW_VARIABLE_VALUE_OP ambush_damage $ambusher_w_damage multiply $ambusher_w_number}
       
                        ## max damage : half of ambushed unit max_hp
                        {AWW_VARIABLE_VALUE_OP max_damage $unit.max_hitpoints divide 2}
                        [if]
                            {VARIABLE_CONDITIONAL ambush_damage greater_than $max_damage}
                            [or]
                                {VARIABLE_CONDITIONAL ambush_damage less_than 1}
                            [/or]
                            [then]
                                {VARIABLE ambush_damage $max_damage}
                            [/then]
                        [/if]

                        ### surprise attack on ambushed victims :

                        [message]
                            speaker=$ambushers[$a].id
                            message=_"Surprise!"
                            side_for=$side_number,$ambushers[$a].side
                        [/message]

                        {AWW_VARIABLE_VALUE_OP ambush_damage $ambusher_w_damage multiply $ambusher_w_number}
                        [harm_unit]
                            [filter]
                                id=$unit.id
                            [/filter]
                            [filter_second]
                                id=$ambushers[$a].id
                            [/filter_second]
                            amount=$ambush_damage
                            damage_type=$ambusher_w_type
                            alignment=$ambushers[$a].alignment
                            fire_event=yes
                            animate=yes
                            [primary_attack]
                                name=$ambusher_w_name
                            [/primary_attack]
                            [secondary_attack]
                                name=$unit.attack[0].name
                            [/secondary_attack]
                            experience=yes
                            resistance_multiplier=$(1-$def_ratio)
                        [/harm_unit]
                    [/then]
                [/if]

                # saving unit variable :
                {VARIABLE ambushers[$a].variables.aww_ambush_cooldown_turn $ambush_cooldown_turn}
                {VARIABLE ambushers[$a].variables.preambush no}
                {VARIABLE ambushers[$a].status.uncovered yes}

                [unstore_unit]
                    variable=ambushers[$a]
                [/unstore_unit]
            [/then]
        [/if]

        {CLEAR_VARIABLE ambush_damage,max_damage,ambusher_w_damage,ambusher_w_number,ambusher_w_type,ambusher_w_name}
    {NEXT a}

    {CLEAR_VARIABLE ambushers,def_ratio,ambush_cooldown_turn,hidden_units,firstmove}
[/event]
User avatar
Celtic_Minstrel
Developer
Posts: 2166
Joined: August 3rd, 2012, 11:26 pm
Location: Canada
Contact:

Re: Give experience to the attacker unit on a [harm_unit] event

Post by Celtic_Minstrel »

I'm not sure if this helps with your issue, but you can use [set_variable] inside [modify_unit]. If you use [modify_unit] then there's no need to unstore the unit.

Code: Select all

[modify_unit]
	[filter]
		id=$ambushers[$a].id # or whatever other filter fits
	[/filter]
	# saving unit variable :
	{VARIABLE aww_ambush_cooldown_turn $ambush_cooldown_turn}
	{VARIABLE preambush no}
	[status]
		uncovered=yes
	[/status]
[/modify_unit]
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: Give experience to the attacker unit on a [harm_unit] event

Post by Toranks »

Yeah! This works. Actually it should have occurred to me as I constantly use [modify_unit]. I now have a much better understanding of the function of [unstore_unit] and why it is not recommended to use it simply to update units.
Post Reply