zealvurte / SimSimMissionWin

WoW addon for the Shadowlands command table
GNU General Public License v3.0
4 stars 2 forks source link

Effect.Points logic #4

Closed zealvurte closed 3 years ago

zealvurte commented 3 years ago

Effect.Types and Effect.Flags can change the behaviour of Effect.Points as described below.

When Effect.Flags doesn't have 2^0 -- USE_ATTACK_FOR_POINTS:

{
    [0]="Do nothing to",    -- NONE (effect.points unused)
    [1]="Damage",   -- DAMAGE (effect.points)
    [2]="Heal", -- HEAL (effect.points)
    [3]="Damage",   -- DAMAGE_PCT (effect.points as %)
    [4]="Heal", -- HEAL_PCT (effect.points as %)
    [5]="Damage (tick)",    -- DOT (effect.points)
    [6]="Heal (tick)",  -- HOT (effect.points)
    [7]="Damage (tick)",    -- DOT_PCT (effect.points as %)
    [8]="Heal (tick)",  -- HOT_PCT (effect.points as %)
    [9]="Taunt",    -- TAUNT (effect.points unused)
    [10]="Detaunt", -- DETAUNT (effect.points unused)
    [11]="Mod damage done of",  -- MOD_DAMAGE_DONE (effect.points)
    [12]="Mod damage done of",  -- MOD_DAMAGE_DONE_PCT (effect.points as %)
    [13]="Mod damage taken of", -- MOD_DAMAGE_TAKEN (effect.points)
    [14]="Mod damage taken of", -- MOD_DAMAGE_TAKEN_PCT (effect.points as %)
    [15]="Damage attacker of",  -- DEAL_DAMAGE_TO_ATTACKER (effect.points)
    [16]="Damage attacker of",  -- DEAL_DAMAGE_TO_ATTACKER_PCT (effect.points as %)
    [17]="Mod max health of",   -- INCREASE_MAX_HEALTH (effect.points)
    [18]="Mod max health of",   -- INCREASE_MAX_HEALTH_PCT (effect.points as %)
    [19]="Mod damage done of",  -- MOD_DAMAGE_DONE_PCT_OF_FLAT (effect.points as %)
    [20]="Mod damage taken of"  -- MOD_DAMAGE_TAKEN_PCT_OF_FLAT (effect.points as %)
}

When Effect.Flags has 2^0 -- USE_ATTACK_FOR_POINTS:

{
    [0]="Do nothing to",    -- NONE (effect.points unused)
    [1]="Damage",   -- DAMAGE (use source.attack instead)
    [2]="Heal", -- HEAL (use source.attack instead)
    [3]="Damage",   -- DAMAGE_PCT (effect.points*source.attack)
    [4]="Heal", -- HEAL_PCT (effect.points*source.attack)
    [5]="Damage (tick)",    -- DOT (use source.attack instead)
    [6]="Heal (tick)",  -- HOT (use source.attack instead)
    [7]="Damage (tick)",    -- DOT_PCT (effect.points*source.attack)
    [8]="Heal (tick)",  -- HOT_PCT (effect.points*source.attack)
    [9]="Taunt",    -- TAUNT (effect.points unused)
    [10]="Detaunt", -- DETAUNT (effect.points unused)
    [11]="Mod damage done of",  -- MOD_DAMAGE_DONE (use source.attack instead)
    [12]="Mod damage done of",  -- MOD_DAMAGE_DONE_PCT (effect.points as %)
    [13]="Mod damage taken of", -- MOD_DAMAGE_TAKEN (use source.attack instead)
    [14]="Mod damage taken of", -- MOD_DAMAGE_TAKEN_PCT (effect.points as %)
    [15]="Damage attacker of",  -- DEAL_DAMAGE_TO_ATTACKER (use source.attack instead)
    [16]="Damage attacker of",  -- DEAL_DAMAGE_TO_ATTACKER_PCT (effect.points*source.attack)
    [17]="Mod max health of",   -- INCREASE_MAX_HEALTH (use source.attack instead)
    [18]="Mod max health of",   -- INCREASE_MAX_HEALTH_PCT (effect.points*source.attack)
    [19]="Mod damage done of",  -- MOD_DAMAGE_DONE_PCT_OF_FLAT (effect.points*source.attack)
    [20]="Mod damage taken of"  -- MOD_DAMAGE_TAKEN_PCT_OF_FLAT (effect.points*source.attack)
}

As you can see, Effect.Type 19 and 20 only exist because 12 and 14 ignore this flag in the game.

I've implemented this logic as a pair of functions. The first mutates the effect with the correct flags value when first processing the spell effect info, and second returns a new effect with the correct effect.type and effect.points values whenever it is cast:

{
    [2^0]={ -- USE_ATTACK_FOR_POINTS
        info=function (spell,effect)
            if effect.type == 12 or effect.type == 14 then
                effect.flags = bit.band(effect.flags,bit.bnot(2^0)) -- Flag is never used
                if effect.flags = 0 then effect.flags = nil end
            end
        end,
        cast=function (spell,effect,source,target)
            e = {}
            for k, v in pairs(effect)
                e[k] = v
            end
            if e.type == 1 or e.type == 2 or e.type == 5 or e.type == 11 or e.type == 13 e.type == 6 or e.type == 15 then
                e.points = source.attack    -- Points is the source's attack
            else
                e.points = e.points*source.attack   -- Points is modified by the source's attack
            end
            return e
        end,
    },
    -- ...
}