Dugy / Legend_of_the_Invincibles

An add-on campaign for the Battle for Wesnoth game
GNU General Public License v3.0
40 stars 22 forks source link

Making leaders fight more #246

Open dalong76 opened 5 years ago

dalong76 commented 5 years ago

It really bothers me that super nasty demon leaders don't attack. Seal Guardians sit on their recruitment spot and summon wimpy minions instead of personally wrecking havoc. This is to collect some ideas on changing that. Today I'm going to try to change the Seal Guardians into non-leaders who are restricted to their keeps and make their minions auto-spawn.

dalong76 commented 5 years ago

I've been messing with the Chapter 9 Grim Port scenario as a starting point. After the Demon Lord spends his money (his recruits cost 180), he loses the ability to recruit and cannot leave his castle. But each turn, after he collects income, he will regain recruitment if he has enough money. The movement adjustment gives him a chance to return to his keep if he somehow gets knocked out. This is done with the below events. The RecruitMore event is removed when the lord dies.

What does anyone think? I will spend the time to refactor and apply this to the 8 Seal Guardian scenarios if people like it.

    [event]
        name=recruit
        first_time_only=no
        [filter]
            side=4
        [/filter]
        [store_gold]
            side=$side_number
            variable=GoldToConsider
        [/store_gold]
        [if]
            [variable]
                name=GoldToConsider
                less_than=180
            [/variable]
            [then]
                {VARIABLE second_unit.canrecruit no}
                {VARIABLE second_unit.movement_costs.flat 99}
                [unstore_unit]
                    variable=second_unit 
                [/unstore_unit]
            [/then]
        [/if]
        {CLEAR_VARIABLE GoldToConsider}
    [/event]
    [event]
        name=side 4 turn refresh
        id=RecruitMore
        first_time_only=no
        [store_gold]
            side=$side_number
            variable=GoldToConsider
        [/store_gold]
        [if]
            [variable]
                name=GoldToConsider
                greater_than_equal_to=180
            [/variable]
            [then]
                [store_unit]
                    [filter]
                        id=se_lord
                    [/filter]
                    variable=Leader
                [/store_unit]
                {VARIABLE Leader.canrecruit yes}
                {VARIABLE Leader.movement_costs.flat 2}
                [unstore_unit]
                    variable=Leader 
                [/unstore_unit]
            [/then]
        [/if]
        {CLEAR_VARIABLE GoldToConsider,Leader}
    [/event]
Dugy commented 5 years ago

The idea is good, but there are some technical issues:

dalong76 commented 5 years ago

How about this? I didn't do teleport, although maybe I should.

#define LEADER_RECRUIT_FIGHT_IN_KEEP LEADER_ID SIDE
    [event]
        name=start
        [object]
            [filter]
                id={LEADER_ID}
            [/filter]
            id=restrict_to_keep
            [effect]
                apply_to=movement_costs
                replace="yes"
                [movement_costs]
                    frozen={UNREACHABLE}
                    shallow_water={UNREACHABLE}
                    deep_water={UNREACHABLE}
                    reef={UNREACHABLE}
                    flat={UNREACHABLE}
                    castle=1
                    village={UNREACHABLE}
                    forest={UNREACHABLE}
                    cave={UNREACHABLE}
                    hills={UNREACHABLE}
                    mountains={UNREACHABLE}
                    forest={UNREACHABLE}
                    fungus={UNREACHABLE}
                    swamp_water={UNREACHABLE}
                    sand={UNREACHABLE}
                    unwalkable={UNREACHABLE}
                    impassable={UNREACHABLE}
                [/movement_costs]
            [/effect]
        [/object]
    [/event]
    [event]
        name=recruit
        first_time_only=no
        [filter]
            side={SIDE}
        [/filter]
        [store_gold]
            side=$side_number
            variable=gold_to_consider
        [/store_gold]
        [if]
            [variable]
                name=gold_to_consider
                less_than=180
            [/variable]
            [then]
                {VARIABLE second_unit.canrecruit no}
                [unstore_unit]
                    variable=second_unit 
                [/unstore_unit]
            [/then]
        [/if]
        {CLEAR_VARIABLE gold_to_consider}
    [/event]
    [event]
        name=side {SIDE} turn refresh
        id=recruit_more
        first_time_only=no
        [store_gold]
            side=$side_number
            variable=gold_to_consider
        [/store_gold]
        [if]
            [variable]
                name=gold_to_consider
                greater_than_equal_to=180
            [/variable]
            [then]
                [store_unit]
                    [filter]
                        id={LEADER_ID}
                    [/filter]
                    variable=temp_leader
                [/store_unit]
                {VARIABLE temp_leader.canrecruit yes}
                [unstore_unit]
                    variable=temp_leader 
                [/unstore_unit]
            [/then]
        [/if]
        {CLEAR_VARIABLE gold_to_consider,temp_leader}
    [/event]
#enddef
Dugy commented 5 years ago

Better. An silent=yes attribute is missing, but otherwise, it should do the trick.

Though I would still have him teleport to a keep after gaining the recruitment ability.

konecnyjakub commented 5 years ago

@Dugy silent defaults to yes on 1.14 if no description is provided: https://wiki.wesnoth.org/DirectActionsWML#.5Bobject.5D.

Dugy commented 5 years ago

Aha, that change was pretty useful. Thanks for updating me.

dalong76 commented 5 years ago

I left out the teleport intentionally. I figure you should be rewarded by doing something to knock him out of position. Plus, recruits after the first wave are fairly insignificant anyway.

I'll turn this into a real github submission that covers all 4 seal guardians.

Dugy commented 5 years ago

Luring leaders out of their keeps and blocking their way is generally a convenient way to defeat them, they have lowered terrain defence outside their keeps and furthermore can't recruit. This would cause the leaders to get really far from their keeps, making it unlikely for them ever to return. Also, they would attack at places where players don't expect them, while the teleporting would keep them at several turns' ranges from their keeps. Breaking encirclement by teleporting away could add some interesting aspect to the fights.

I find it unlikely that doing it without teleportation could be a better option.

dalong76 commented 5 years ago

The above code prevents the leader from moving outside the castle because all terrain except castle is unwalkable. He might move off the recruitment spot and then be blocked from going back, but recruitment after the first wave is about one demon every other turn, so that isn't significant. If the player somehow moves him out of the castle entirely (shockwave or knockback), he does get stuck, but that's where I feel the player should be rewarded for doing something interesting.

That said ... when/where would you add teleportation?

Dugy commented 5 years ago

Oops, I forgot about that part. If he teleported to the keep after getting enough gold, he might be actually able to leave the keep without too much risk... Well, let's better keep it that way.

Though I wonder how much advantage would a player gain by using shockwave or knockback on him.

dalong76 commented 5 years ago

I found a problem that I'm not sure how to solve - when they die, they cannot recruit, so they don't always drop an item. Any suggestions? Brainstorming ...

Dugy commented 5 years ago

You can turn them into leaders in last breath events, so that they would be leaders when the die events that make them drop kick in.

If they get special drops, they would drop them only when they are not leaders or drop both the special item and a regular item on death when they are leaders.

However, always turning them into non-leaders before death and having them drop special one-of-a-kind items is the preferable option for me. I will add some items for them if you don't want to make some yourself.

dalong76 commented 5 years ago

First thoughts on new items then: (I really don't like my attack name, but its late and I'm not creative)

Demon Stomper (boots) defence=6 melee_damage_plus=2 spell_suck=1 cold_resist=15 New ranged attack named "Order", 3-6 fire, {WEAPON_SPECIAL_MAGICAL}, {WEAPON_SPECIAL_UNHOLYBANE}

Demon Strangler (gloves) defence=6 magic=10 fire_resist=15 fire_penetrate=10 {ABILITY_REGROWING} increase damage on the "Order" attack by 15% Set bonus, 1 other item, {ABILITY_CAREFUL 10}

Demon Destroyer (helm) defence=12 magic=15 arcane_resist=15 {ABILITY_WEAK_REFLECT} increase damage on the "Order" attack by 15% Set bonus, 1 other item, {ABILITY_KILLHUNGER}

Seraph's Power (ring) magic=20 cold_resist=10 fire_resist=10 increase damage on the "Order" attack by 10% Set bonus, all items, +1 base attack

Dugy commented 5 years ago

Adding a new attack causes problems with animations, furthermore, these items would very strongly depend on the order they are placed on the unit.

dalong76 commented 5 years ago

I modeled my new attack and increasing its damage on the Violent Mage set. Why would order matter here when it doesn't there? There are already items and amlas that add animation attacks, so that doesn't seem a huge problem. Copying Forestburner for the animation would work.

Dugy commented 5 years ago

The problem is that the [effect] tags are applied in the order the items were equipped. Set effects behave like regular [effect] tags if their conditions are met. Only some item properties were implemented differently, mainly because their behaviour is intentionally different to what [effect] tags can do. New attacks are regular [effect] tags. The bonus attack thing is added in LotI and its improvements were programmed to scan all possible bonuses, even backwards.

Of course, it is possible to modify stats.cfg to add almost any item property thinkable.