inferno8 / wesnoth-Era_of_Magic

add-on for Battle for Wesnoth
GNU General Public License v2.0
10 stars 4 forks source link

Review fight and kill experience in multitarget attacks #30

Closed ProditorMagnus closed 1 year ago

ProditorMagnus commented 3 years ago

1) Decide and comment for each multitarget ability what should happen with experience 2) Test each ability and make sure it works that way

Re https://github.com/inferno8/wesnoth-Era_of_Magic/issues/29#issuecomment-900631828

ProditorMagnus commented 3 years ago

Points to answer, when

Attacker damages third party

  1. Damager gets fight xp?
  2. Damager gets kill xp?
  3. Third party gets fight xp?

Defender damages third party, for abilities where it can happen

  1. Damager gets fight xp?
  2. Damager gets kill xp?
  3. Third party gets fight xp?

Exceptions

  1. Some abilities do not inflict damage to third party while defending. Some do. In case it should differ based on ability, describe which ones.
  2. Any other exceptions?
ProditorMagnus commented 3 years ago

Goal of this task is to simplify multitarget damage logic and reduce code duplication to cover use cases for

It would also provide place for unified handling for interaction with awake in case it is desired.

inferno8 commented 3 years ago

Here are (probably) all weapon specials and abilities inflicting area of effect (AoE) damage in EoMa + my comments and suggestions.

  1. area effect {WEAPON_SPECIAL_EOMA_AREAEFFECT} abilities.cfg:218 “When this attack is used, all units adjacent to the target (except the attacker) receive half of the attack's damage. Does not work on defense.” Used by: Guru Notes: should be replaced with “random area effect” (see below) with a chance to hit set to 100% (that way all adjacent units are affected = no randomness).

  2. random area effect {WEAPON_SPECIAL_EOMA_AREAEFFECTRANDOM (CHANCE_TO_HIT)} abilities.cfg:367 “When this attack is used, random units adjacent to the target (except the attacker) get half of the basic damage. Does not work on defense.” Used by: Great Efreeti, Master of War Notes: the macro should have an additional DMG_PERCENT parameter set in this case to 50% or 0.5 depending on the syntax. Experience: When attacker damages third party:

    • damager should NOT get fight xp (this is to prevent attacker from leveling up too fast)
    • damager should get kill xp
    • third party should get fight xp (to compensate for loss of hp and lack of retaliation)

    When defender damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp
  3. all around {WEAPON_SPECIAL_EOMA_ALLAROUND (CHANCE_TO_HIT)} allaround.cfg: 68 “This attack can hit some of adjacent enemy units (or even all depending on your luck) Works only on offense. This ability does not work on defense.” Used by: Abaddon, Obliterator, Omen, Punisher, Child of Light, Mistress of Light, Master of Fire, Air God Notes: This one is very similar to the ‘random area effect’ described above except the filter in [harm_unit] is different and full damage is inflicted. Experience: When attacker damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp

    When defender damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp
  4. cleave {WEAPON_SPECIAL_EOMA_CLEAVE} cleave.cfg:120 “A unit with this ability can hurt units that are adjacent to the attacker and the defender at the same time.” Used by: Chaos Wyvern Notes: should be replaced with “cleave + 100%” (see below).

  5. cleave + #% {WEAPON_SPECIAL_EOMA_CLEAVE_CUSTOM (VALUE) (DISPLAY_VALUE)} cleave.cfg:279 “A unit with this ability can hurt units that are adjacent to the attacker and the defender at the same time. The damage dealt equals {DISPLAYVALUE}% of the base damage.” Used by: Cyclops Goliath, Cyclops Warmonger, Master of Fire, Earth God Notes: this weapon special has a random chance to hit target’s bystanders set to 50%. Designed with melee attacks in mind, it should take targets’ terrain defense into consideration, but the 50% workaround still works pretty well. Experience: When attacker damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp

    When defender damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp
  6. cleave 50% {WEAPON_SPECIAL_EOMA_CLEAVEHALF} cleave.cfg:440 “A unit with this ability can hurt units that are adjacent to the attacker and the defender at the same time. The damage dealt equals 50% of the base damage.” Used by: - Notes: should be removed

  7. triple strike {WEAPON_SPECIAL_EOMA_TRIPLESTRIKE} triplestrike.cfg:1 “This attack can hit some enemy units adjacent to a target (up to 3 harmed units total - depending on your luck).” Used by: Hydra, Great Hydra, Chaos Hydra Notes: this weapon special has a random chance to hit target’s bystanders set to 40%, which is 10% less than ‘cleave’. Designed with melee attacks in mind, it should take targets’ terrain defense into consideration, but it’s optional. Probably the main difference between this and ‘cleave’ is that ‘triple strike’ drains opponent’s health and 100% of damage is inflicted. Experience: When attacker damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp

    When defender damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp
  8. damage aura {ABILITY_EOMA_DAMAGEAURA (VALUE) (TYPE) (ALIGNMENT)} abilities.cfg:755 “This unit harms all adjacent enemies at the start of each turn by a certain amount of damage (affected by the ToD bonus), giving the unit experience for each enemy harmed/killed.” Used by: Dark Portal, Infernal Vortex Notes: adjacent enemy units cannot avoid the effects of this ability. Experience: harmed units should NOT receive experience

  9. furious death {ABILITY_EOMA_FURIOUSDEATH (DMG) (TYPE)} abilities.cfg:92 “Moments before this unit's death, it flies into a fury, dealing {DMG} damage to adjacent units, friend or foes alike. When a harmed adjacent unit goes to or below 0 HP, its HP are set to 1 instead of being killed.” Used by: Cyclops Warmonger, Cyclops Goliath Notes: all adjacent units cannot dodge this. (maybe it should be better to take units’ terrain defense into consideration or go with the 50% chance to hit). Experience: all harmed units should receive experience, even allied (currently they do not)

  10. hard landing {ABILITY_EOMA_HARDLANDING (DMG) (TYPE)} “When this large unit is destroyed, it falls on a ground dealing damage to all adjacent units. When a harmed adjacent unit goes to or below 0 HP, its HP are set to 1 instead of being killed.” Used by: Heavy Balloon, Flying Fortress, Mechanical Dragon Notes: same as above. Experience: all harmed units should receive experience, even allied (currently they do not)

  11. dragon breath {WEAPON_SPECIAL_EOMA_DRAGON_BREATH} dragon_breath.cfg:3 “A unit with this ability can hurt 3 adjacent units standing behind the defender. Only works on offense.” Used by: Mechanical Dragon Notes: this weapon special has a random chance to hit target’s bystanders set to 60%, which is 10% more than ‘cleave’. Experience: When attacker damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp

    When defender damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp
  12. beam {WEAPON_SPECIAL_EOMA_BEAM} beam.cfg:78 “When this attack is used, the attacker can hurt a unit behind his primary target and a unit behind that unit (3 units total). Damage dealt to the second target equals to 2/3 of raw firepower. Damage dealt to the third target equals to 1/3 of raw firepower. This effect works only on offence.” Experience: When attacker damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp

    When defender damages third party:

    • damager should NOT get fight xp
    • damager should get kill xp
    • third party should get fight xp
ProditorMagnus commented 1 year ago

Added reminder to fix it during next ageless release if the issue is still happening.

ProditorMagnus commented 1 year ago

Started with first in list, guru. Test confirms xp is not given. https://github.com/inferno8/wesnoth-Era_of_Magic/commit/567bda970cbd0756ad0b053d49aa701af82c7714 https://i.vgy.me/bR43JB.png

ProditorMagnus commented 1 year ago

@inferno8 WEAPON_SPECIAL_EOMA_AREAEFFECTRANDOM and WEAPON_SPECIAL_EOMA_AREAEFFECT both have id=eoma_areaeffect_event, so one of them never works. However, in addition to that I see WEAPON_SPECIAL_EOMA_AREAEFFECTRANDOM is supposed to damage every time attacker hits, while WEAPON_SPECIAL_EOMA_AREAEFFECT is supposed to damage every time chance is rolled over value, no matter if main attack hits or misses.

In the Guru note you said

should be replaced with “random area effect” (see below) with a chance to hit set to 100% (that way all adjacent units are affected = no randomness).

Should WEAPON_SPECIAL_EOMA_AREAEFFECTRANDOM be changed to not work with misses? Or allow it as buff to guru?

inferno8 commented 1 year ago

@ProditorMagnus Let's allow it as a buff to Guru.

WEAPON_SPECIAL_EOMA_AREAEFFECT is marked for removal, so once it is gone, the 'same event id in use' issue should no longer be a problem in this case.

ProditorMagnus commented 1 year ago

Beam had unique issue where every hit gave xp to both attacker and defender. Solved that, and then results are

$ run_all_tests()
fail EoMa_Guru attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Guru attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Guru attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Guru attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Great_Efreeti attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Great_Efreeti attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Great_Efreeti attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Great_Efreeti attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Omen attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Omen attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Omen attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Omen attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Chaos_Rider attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Chaos_Rider attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Chaos_Rider attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Chaos_Rider attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Chaos_Hydra attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Chaos_Hydra attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Chaos_Hydra attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Chaos_Hydra attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Mechanical_Dragon attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Mechanical_Dragon attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Mechanical_Dragon attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Mechanical_Dragon attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Kirios attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Kirios attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Kirios attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Kirios attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Kirios attacker xp if cfg.defender_dies and cfg.thirdparty_dies expected 48 but was 24
pass EoMa_Kirios attacker xp if cfg.defender_dies and not cfg.thirdparty_dies is 24
pass thirdparty xp if cfg.defender_dies and not cfg.thirdparty_dies is 3
fail EoMa_Kirios attacker xp if not cfg.defender_dies and cfg.thirdparty_dies expected 27 but was 3
pass defender xp if not cfg.defender_dies and cfg.thirdparty_dies is 3
pass EoMa_Kirios attacker xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass defender xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
pass thirdparty xp if not cfg.defender_dies and not cfg.thirdparty_dies is 3
ProditorMagnus commented 1 year ago

Underlying issue was that storing units for xp considerations was done after they were already dead.

ProditorMagnus commented 1 year ago
        name= _ "awaken"
        description=_"If a friendly adjacent unit with more than one hitpoint dies, it is resurrected, gets +6 experience and remains in battle with one hitpoint. If it dies again (having one hitpoint), it will be killed for sure.
Doesn't work on units attacked indirectly e.g. by area weapons."

Was "on units attacked indirectly" just for easier coding or also for balance? Since I already work with pain absorber started thinking of awaken too.

inferno8 commented 1 year ago

Was "on units attacked indirectly" just for easier coding or also for balance?

Balance. Having it working on units attacked indirectly would make Inspired (unit) too powerful imo. That's why I introduced this limitation. Changing this behavior would probably require rebalancing the unit from scratch. I will consult IPS on that matter, but for now I would keep this limitation as it is for now.

ProditorMagnus commented 1 year ago

Getting concerned why cleave is the only one disabled in rpg when triplestrikes is almost the same.

inferno8 commented 1 year ago

Getting concerned why cleave is the only one disabled in rpg when triplestrikes is almost the same.

Well, I just briefly discussed this with IPS and here's the conclusion: "Regarding cleave if you hit a unit that is at very low defense (20%) you have more chances harming other secondary target instead of directly attacking that unit." That was probably the main reason why it was disabled in RPG. I believe the decision was made more than a year ago, so I don't remember all the details.

If you know how to combine these two specials into one or have some other ideas, I am all ears.

ProditorMagnus commented 1 year ago

Cleave has 50% chance to hit, no matter what main target chance is. I would add rpg condition to all the area specials I focused on during this task. It is higher than triplestrike with its 40%, but triplestrike is also full damage instead of half like cleave.

inferno8 commented 1 year ago

I would add rpg condition to all the area specials I focused on during this task.

Ok. Go ahead.