Wings of Seraphim's effect stops if healed

I'm sure not many people use the favor item Wings of Seraphim, so it's no wonder I haven't seen anyone post this bug.  Basically if you cast it and you are healed, either by a monk or Oak's Divine Justice (not sure about Sedna's heal since I haven't tested it), the effect will break as if you had taken damage.  This almost makes it useless to have as a general or once you buy priests from the citadel since the healers will likely heal you within the 10 seconds this is in effect.  Before anyone tries to make this arguement, no the effect wasn't broken because of some sort of damage that I didn't notice seeing as it also has happened when the DG was shielded with Oak's shied.  I would love to see this bug fixed because I actually have found this favor quite useful if used correctly.

6,247 views 25 replies
Reply #1 Top

You're taking negative damage(that's how healing is done in this game).

Reply #2 Top

Quoting Shade, reply 1
You're taking negative damage(that's how healing is done in this game).

I don't think so or we would have noticed this before when HoL was so popular...

Reply #3 Top

(troll removed)

what an answer. -.-

but i wonder why seraphims effect does not interupt itselfs as it heals, if healing is treatet as negative dmg? does the sedna aura interupt it too?

and it is still very surprising that this was not observed when hol was used so much.

Reply #4 Top

Quoting CelMare, reply 3

(troll removed)
what an answer. -.-

but i wonder why seraphims effect does not interupt itselfs as it heals, if healing is treatet as negative dmg? does the sedna aura interupt it too?

and it is still very surprising that this was not observed when hol was used so much.

Healing Wind is regen+, not healing.

Me and my PM tried using this with Oak's Shield and we noticed it was bugged as well, as it went off spontaneously. We didn't investigate it to healing though.

Reply #5 Top

Original:

DoTakeDamage = function(self, data)
        if self:CheckEvasion(data) then
            return
        end

        if data.Instigator:CheckMiss(self,data) then
            return
        end

        if not data.Type then
            WARN("*WARNING: No damage type specified hitting: ", self:GetUnitId())
            data.Type = 'Normal'
        end

        local isSpell = false
        if string.find(data.Type, 'Spell') then
            isSpell = true
        end

        if self.MagicImmune and isSpell then
            return
        end

        if data.CanCrit and data.Instigator.WeaponCrits then
            local damage = data.Amount
            #LOG('DEBUG: Default Damage = ' .. data.Amount)
            for abilityName,critBool in data.Instigator.WeaponCrits do
                if not data.CanCritFrom or (data.CanCritFrom and data.CanCritFrom[abilityName]) then
                    if not critBool then
                        continue
                    end

                    local critData = Ability[abilityName]

                    local critChance = critData.CritChance
                    if critData.CritChanceAbility and data.Type == 'Spell' then
                        #LOG('*DEBUG: Using Ability Crit Chance')
                        critChance = critData.CritChanceAbility
                    elseif critData.CritChanceRanged and not self.IsMelee then
                        #LOG('*DEBUG: Using Ranged Crit Chance')
                        critChance = critData.CritChanceRanged
                    end

                    if CalculateCritChance(critChance) then
                        data.Amount = CalculateCritDamage(data.Amount, critData.CritMult)
                        data.IsCrit = true

                        #LOG('DEBUG: Critical Hit! CritMult = ' .. critData.CritMult .. ', CritChance = ' .. critChance ..
                        #    ', newDamage = ' .. data.Amount .. ', CurrentTick = ' .. GetGameTick() )
                    end
                end
            end
            if data.IsCrit then
                if data.Instigator and not data.Instigator:IsDead() then
                    data.Instigator:OnCriticalHit(self, data)
                end
            end
        end

        # Absorption Check
        if self.Absorption > 0  and data.Amount > 0 then
            local unabsorbeddamage = data.Amount - self.Absorption
            if unabsorbeddamage < 0 then
                self.Absorption = self.Absorption - data.Amount
                data.Amount = 0
                FloatTextAt(table.copy(self:GetPosition()), "<LOC floattext_0003>ABSORBED!", 'DamageHealing')
            elseif unabsorbeddamage == 0 then
                self.Absorption = 0
                data.Amount = 0
                Buff.RemoveBuffsByAffect(self, 'Absorption')
                FloatTextAt(table.copy(self:GetPosition()), "<LOC floattext_0004>ABSORBED!", 'DamageHealing')
            else
                self.Absorption = 0
                data.Amount = unabsorbeddamage
                Buff.RemoveBuffsByAffect(self, 'Absorption')
            end
        end

        if data.CanMagicResist and self.MagicResistance > 0 and isSpell then
            data.Amount = CalculateMagicResistDamage(data.Amount, self.MagicResistance)
        end

        #Armor!
        if not data.ArmorImmune then
            data.Amount = CalculateArmorDamage(data.Amount, self.Sync.Armor)
        end

        if self.DamageTakenMult and data.Amount > 0 then
            data.Amount = data.Amount * (1 + self.DamageTakenMult)
        end

        if data.Amount < 0 and ((self:GetHealth() - data.Amount) > self:GetMaxHealth()) then
            local amount = data.Amount
            data.Amount = self:GetHealth() - self:GetMaxHealth()
            # The overheal amount is the amount that you would have been healed if your health was low enough
            # This value is used in the floattext
            # Ignore the health crystal so its not too spammy when you're full health shopping etc
            if(data.Amount > amount and data.DamageAction != 'HealthStatueRegen01') then
                data.OverHeal = amount
            end
        end

        if data.Amount > 0 and data.Instigator != self then
            self:DoArmorProcs()
        end

        self:OnTakeDamage(data)

        #Added in another check so that we can do things like have buffs that make you not take damage but
        #still have your instigator act like it did full damage.
        if not self.CanTakeDamage and data.Amount > 0 then
            return
        end

        if CheckOverKill(self, data) then
            self:DoOverKill(data)
        end

        local preAdjHealth = self:GetHealth()
        self:AdjustHealth(-data.Amount)

        local health = self:GetHealth()
        if( health < 0.5 ) then
            if not data.KillLocation then
                data.KillLocation = table.copy(self:GetPosition())
            end
            self.KillData = data
            self:Kill()
        end
    end,

Fix:

DoTakeDamage = function(self, data)
        if self:CheckEvasion(data) then
            return
        end

        if data.Instigator:CheckMiss(self,data) then
            return
        end

        if not data.Type then
            WARN("*WARNING: No damage type specified hitting: ", self:GetUnitId())
            data.Type = 'Normal'
        end

        local isSpell = false
        if string.find(data.Type, 'Spell') then
            isSpell = true
        end

        if self.MagicImmune and isSpell then
            return
        end

        if data.CanCrit and data.Instigator.WeaponCrits then
            local damage = data.Amount
            #LOG('DEBUG: Default Damage = ' .. data.Amount)
            for abilityName,critBool in data.Instigator.WeaponCrits do
                if not data.CanCritFrom or (data.CanCritFrom and data.CanCritFrom[abilityName]) then
                    if not critBool then
                        continue
                    end

                    local critData = Ability[abilityName]

                    local critChance = critData.CritChance
                    if critData.CritChanceAbility and data.Type == 'Spell' then
                        #LOG('*DEBUG: Using Ability Crit Chance')
                        critChance = critData.CritChanceAbility
                    elseif critData.CritChanceRanged and not self.IsMelee then
                        #LOG('*DEBUG: Using Ranged Crit Chance')
                        critChance = critData.CritChanceRanged
                    end

                    if CalculateCritChance(critChance) then
                        data.Amount = CalculateCritDamage(data.Amount, critData.CritMult)
                        data.IsCrit = true

                        #LOG('DEBUG: Critical Hit! CritMult = ' .. critData.CritMult .. ', CritChance = ' .. critChance ..
                        #    ', newDamage = ' .. data.Amount .. ', CurrentTick = ' .. GetGameTick() )
                    end
                end
            end
            if data.IsCrit then
                if data.Instigator and not data.Instigator:IsDead() then
                    data.Instigator:OnCriticalHit(self, data)
                end
            end
        end

        # Absorption Check
        if self.Absorption > 0  and data.Amount > 0 then
            local unabsorbeddamage = data.Amount - self.Absorption
            if unabsorbeddamage < 0 then
                self.Absorption = self.Absorption - data.Amount
                data.Amount = 0
                FloatTextAt(table.copy(self:GetPosition()), "<LOC floattext_0003>ABSORBED!", 'DamageHealing')
            elseif unabsorbeddamage == 0 then
                self.Absorption = 0
                data.Amount = 0
                Buff.RemoveBuffsByAffect(self, 'Absorption')
                FloatTextAt(table.copy(self:GetPosition()), "<LOC floattext_0004>ABSORBED!", 'DamageHealing')
            else
                self.Absorption = 0
                data.Amount = unabsorbeddamage
                Buff.RemoveBuffsByAffect(self, 'Absorption')
            end
        end

        if data.CanMagicResist and self.MagicResistance > 0 and isSpell then
            data.Amount = CalculateMagicResistDamage(data.Amount, self.MagicResistance)
        end

        #Armor!
        if not data.ArmorImmune then
            data.Amount = CalculateArmorDamage(data.Amount, self.Sync.Armor)
        end

        if self.DamageTakenMult and data.Amount > 0 then
            data.Amount = data.Amount * (1 + self.DamageTakenMult)
        end

        if data.Amount < 0 and ((self:GetHealth() - data.Amount) > self:GetMaxHealth()) then
            local amount = data.Amount
            data.Amount = self:GetHealth() - self:GetMaxHealth()
            # The overheal amount is the amount that you would have been healed if your health was low enough
            # This value is used in the floattext
            # Ignore the health crystal so its not too spammy when you're full health shopping etc
            if(data.Amount > amount and data.DamageAction != 'HealthStatueRegen01') then
                data.OverHeal = amount
            end
        end

        if data.Amount > 0 and data.Instigator != self then
            self:DoArmorProcs()
        end

 

        if data.Amount > 0 then

            self.OnTakeDamage(data)

        end

 

        #Added in another check so that we can do things like have buffs that make you not take damage but
        #still have your instigator act like it did full damage.
        if not self.CanTakeDamage and data.Amount > 0 then
            return
        end

        local preAdjHealth = self:GetHealth()
        self:AdjustHealth(-data.Amount)

        local health = self:GetHealth()
        if( health < 0.5 ) then
            if not data.KillLocation then
                data.KillLocation = table.copy(self:GetPosition())
            end
            self.KillData = data
            self:Kill()
        end
    end,

Changes:

- Enclosed the takeDamage callback with a check to make sure the Amount is > 0. This could cause other bugs, however. Alternate fix is:

In Achievement_Items.lua as well as Consumables.lua for HoL (it does actually happen for HoL, but it probably was rarely noticed since you use HoL while in Combat as Oak with a shield, and monks weren't nearly as popular back when HoL was everywhere)

                    Effects = 'Heal02',
                    EffectsBone = -2,
                    OnApplyBuff = function(self, unit, instigator)
                        unit.Callbacks.OnTakeDamage:Add(self.SeraphimDamaged, self)
                    end,

                    SeraphimDamaged = function(self, unit, data)

                                if data.Amount > 0 then
                           if Buff.HasBuff(unit, 'AchievementAERegen') then
                               Buff.RemoveBuff(unit, 'AchievementAERegen')
                           end
                           unit.Callbacks.OnTakeDamage:Remove(self.SeraphimDamaged)

                              end
                    end,
                    OnBuffRemove= function(self,unit)
                        unit.Callbacks.OnTakeDamage:Remove(self.SeraphimDamaged)
                    end,
                }

 

Reply #6 Top

I don't think Heart of Life has the same problem and it has the same principal.  I'm not sure why this item seems to have this issue.  Also, Abuggeredhedgie, I have no idea what's goin on in your last post as I dont intend to take my time to go through all that, lol.

Reply #7 Top

bump - STILL NOT FIXED IN 1.2

Reply #8 Top

bump

Reply #9 Top

bump

Reply #11 Top

bump

Reply #13 Top

bump

Reply #14 Top

bumpity

Reply #16 Top

bump

Reply #17 Top

bump.  although it won't do any good.. stardock doesn't care

Reply #18 Top

Still, wouldn't it be nice if someone from stardock at least acknowledged the communities efforts to bug hunt?  I mean, QA is supposed to be THEIR job...

Reply #20 Top

lol. We should

Reply #21 Top

Let's have an hourly bump-fest!

BUMP.

Reply #22 Top

bump

Reply #23 Top

doin' the rounds

Reply #24 Top

bump