[SOLVED] How to modify pre-defined common abilities like "ABILITY_CURES" ?

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
Zatiranyk
Posts: 12
Joined: May 4th, 2018, 8:00 pm

[SOLVED] How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Zatiranyk »

Hey people,

I’m building a modification add-on to make heal cumulative but less effective. I was thinking of +8 health from village or regeneration ability and we add +6 for each adjacent "lvl2 healers" and +3 from "lvl1 healers". Do you have any tips ?

Using WML, I tried these but none of them seem to work :
  1. Somehow modify the macros from data/core/macros/abilities.cfg. I put the following code directly in the add-on’s _main.cfg outside and inside the [modification] tag:

    Code: Select all

    #undefine ABILITY_HEALS
    #define ABILITY_HEALS
        [heals]
            value=3
            id=healing
            affect_allies=yes
            name= "heals +3"
            female_name= "heals +3"
            description=  "awesome description"
            affect_self=no
            poison=slowed
            [affect_adjacent]
            [/affect_adjacent]
        [/heals]
    #enddef
    
    # Result: Nothing changed
    
  2. Write accessing the unit type with [store_unit_type] and [set_variable] but it seems it’s read-only:

    Code: Select all

    [event]
        name=preload
        
        [store_unit_type]
            type=Elvish Druid
            variable=unit_type_druid
        [/store_unit_type]
         
        [chat]
            message="Druid Hitpoints before: $unit_type_druid.hitpoints"
        [/chat]
            
        {VARIABLE unit_type_druid.hitpoints 60}
            
        [chat]
            message="Druid Hitpoints after: $unit_type_druid.hitpoints"
        [/chat]
    [/event]
    
    # Result: Printing correct before and after max health but does nothing to the recruited druid.
    
  3. I saw the [modify_unit_type] tag inside [modification] but it looks like it isn’t useful in our case.
The easiest way I can think of now is to create an [event] named recruit, filter the abilities of the unit and change it. Also recoding the heal in WML with events, filters… I could also create a new era but it’s not really the goal here…

Thanks for reading !
Last edited by Zatiranyk on January 2nd, 2021, 5:30 pm, edited 4 times in total.
User avatar
Pentarctagon
Project Manager
Posts: 4648
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Pentarctagon »

Rather than modifying the core ability macro it would probably be better to check for it and replace it using a unit placed event.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
Helmet
Posts: 331
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Helmet »

Zatiranyk wrote: December 28th, 2020, 8:49 pmI was thinking of +8 health from village or regeneration ability and we add +6 for each adjacent "lvl2 healers" and +3 from "lvl1 healers". Do you have any tips ?
So if a unit is in a village and six allied +8 healing units are standing next to the village, you want the unit in the village to heal 44 damage?

I would let the village heal the unit as normal. I would focus on the healers.

I would probably try to use [filter_adjacent] -- or some other method, if that won't work. My goal would be to count the various allied healers adjacent to the target unit, one hex at a time. Then I would have a complicated IF/THEN routine do the healing math. Each adjacent Elvish Shaman would add 4 to the heal_this_guy variable, etc. When all 6 adjacent hexes had been inspected for healers, I would use modify_unit to add the value of heal_this_guy to the unit's hitpoints.
vghetto
Posts: 356
Joined: November 2nd, 2019, 5:12 pm

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by vghetto »

To un-define a macro, use #undef
User avatar
Ravana
Forum Moderator
Posts: 2482
Joined: January 29th, 2012, 12:49 am
Location: Estonia
Contact:

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Ravana »

Undef only affects WML which is loaded after that line. Core is loaded before addons.
Zatiranyk
Posts: 12
Joined: May 4th, 2018, 8:00 pm

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Zatiranyk »

Thank you all for your answers !
Pentarctagon wrote: December 28th, 2020, 9:13 pm Rather than modifying the core ability macro it would probably be better to check for it and replace it using a unit placed event.
I used this, it works very well. It seems i couldn’t use [modify_unit] for abilities so I rather used [store_unit]:

Code: Select all

[event]
    name="unit placed"
    first_time_only=no
    [filter]
        ability=healing
    [/filter]
    
    [store_unit]
        [filter]
            id=$unit.id
        [/filter]
        variable=healer
    [/store_unit]

    [foreach] 
        array=healer[0].abilities.heals
        [do]
        [if]  
            [variable]  
                name=this_item.id
                equals="healing"
            [/variable]  
            [then]
                {VARIABLE this_item.description "my new awesome ability description"}
            [/then] 
        [/if] 
        [/do] 
    [/foreach]

    [unstore_unit]
        variable=healer
    [/unstore_unit]
[/event]
Zatiranyk
Posts: 12
Joined: May 4th, 2018, 8:00 pm

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Zatiranyk »

Here I am, back to give you some updates :D

So, unfortunately, there is a small case where this method fails. The following quote is a description of the [remove_object] from the wiki :
[remove_object]
...
Note that remove_object worked the following way: Step1) remove thos objects from the unit wml, Step2) Rebuild the unit to make the changes effective. Step2 implies that changes done for example via [modify_unit] (or via the [store_unit] + [set_variable] + [unstore_unit] technique) will be reset if those changes change a property that is a property of the unit type.
Indeed, when [remove_object] is called on some unit, its modified abilities are erased and replaced by the old ones !
In my case, I would like to catch when an object is being removed on a unit so I can reset the abilities on that unit. Do you have any idea ?

I found a "dirty bypass". I just reset the abilities of all the healers each turn, before they heal… that’s a bit too much and maybe not really optimised but yeah :D

Thanks !
User avatar
Helmet
Posts: 331
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Helmet »

Zatiranyk wrote: December 29th, 2020, 9:52 pm It seems i couldn’t use [modify_unit] for abilities so I rather used [store_unit]...
It sounds like you found a solution. Anyhow, this is how you add a new ability to a unit upon creation, employing modifications, object and a macro.

Code: Select all

	[unit]
		type=Elvish Shaman
#		etc.
        	[modifications]
				{CUSTOM_HEALING}
        	[/modifications]
	[/unit]

Code: Select all

#define ABILITY_CUSTOM_HEALING
	[object]
		[effect]
			apply_to=new_ability
			[abilities]
    				[heals]
    					name= _ "mega-heal"
#					stuff
   				[/heals]						
			[/abilities]
		[/effect]
	[/object]
#enddef
There is also a tag called remove_ability.
Zatiranyk
Posts: 12
Joined: May 4th, 2018, 8:00 pm

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Zatiranyk »

Hello ! I found the solution :D

Helmet: I’m not sure you’ve read my last reply but you were right to bring me this other method using objects :).

My last attempt to modify ability with [store_unit] is in conflict with [remove_object]. When this last tag is called, the modified abilities are erased and replaced by the ones defined in the unit type. As a result, my add-on was in conflict with maybe half of all the other add-ons that use this remove tag.

So if you want to modify permanently a pre-defined ability, you should use [object] with remove_ability and new_ability effects. Don’t forget to manage the advancements and scenario ending (for campaigns…) !

Here an example where the heal is multiplied by 2 !

Code: Select all

[event]
    name= "pre advance"
    first_time_only= no

    [remove_object]
        id= $unit.id
        ability= healing
        object_id= modify_healing
    [/remove_object]
[/event]


[event]
    name= "unit placed,post advance"
    first_time_only= no

    [foreach]
        array= unit.abilities.heals
        variable= this_ability
        [do]
        [if]
            {VARIABLE_CONDITIONAL this_ability.id equals healing}
            [then]
                [set_variable] 
                    name= healing_value
                    formula= "$this_ability.value * 2"
                [/set_variable]
            [/then]
        [/if]
        [/do]
    [/foreach]

    [object]
        id= modify_healing
        take_only_once= no
        [filter]
            id= $unit.id
            ability= healing
        [/filter]

        [effect]
            apply_to= remove_ability
            [abilities]
                [heals]
                    id= healing
                [/heals]
            [/abilities]
        [/effect]
        
        [effect]
            apply_to= new_ability
            [abilities]
                [heals]
                    id= healing
                    name= "heal +$healing_value"
                    description= "it's super powerful ! :D"
                    value= $healing_value
                [/heals]
            [/abilities]
        [/effect]
    [/object]
    
    {CLEAR_VARIABLE healing_value} 
[/event]


[event]
    name= scenario_end

    [remove_object]
        ability= healing
        object_id= modify_healing
    [/remove_object]
[/event]
Last edited by Zatiranyk on January 3rd, 2021, 2:12 pm, edited 12 times in total.
User avatar
Helmet
Posts: 331
Joined: December 19th, 2006, 5:28 pm
Location: Florida, USA

Re: How to modify pre-defined common abilities like "ABILITY_CURES" ?

Post by Helmet »

Zatiranyk wrote: January 2nd, 2021, 5:30 pm Hello ! I found the solution :D

Helmet: I’m not sure you’ve read my last reply but you were right to bring me this other method using objects.
I'm glad the information was useful. There are big gaps in my WML knowledge, but there are also areas where I know how to get things done. Thanks for posting the solution.
Post Reply