• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a faction for Warcraft 3 and enter Hive's 19th Techtree Contest: Co-Op Commanders! Click here to enter!
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 21st Texturing Contest: Upgrade is now concluded, time to vote for your favourite set of icons! Click here to vote!

CR - Buffs Engine

JASS:
library BuffsEngine initializer Init requires Main, MISC, BuffsDatabase
// globals
    private MyBuffData BuffStack[]
    private int Stack = 0

    struct MyBuffData
        real duration, tick = 0.
        int cell, level, state, total = 0, slc = 0
        bool Unpause = false
        unit source, victim
    endstruct

// func
    string Parameter2String (int value_type, real value, bool f){
        string s 
            if f { s = "+" }
            else { s = "-" }
        if (value_type == PHYSICAL_ATTACK_TYPE_1) { return "Phys Damage " + s + R2S(value) + "%" }
        elseif (value_type == PHYSICAL_DEFENCE_TYPE_1) { return "Defence " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_ATTACK_TYPE_1) { return "Mag Attack " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_SUPPRESSION_TYPE_1) { return "Suppress. " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_RESIST_TYPE_1) { return "Resist " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_ACCURACY_TYPE_1) { return "Mag Acc. " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == ACCURACY_TYPE_1) { return "Accuracy " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == EVADE_TYPE_1) { return "Evade " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == PARRY_TYPE_1) { return "Parry " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == BLOCK_TYPE_1) { return "Block " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == HP_TYPE_1) { return "Hp " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == MP_TYPE_1) { return "Mp " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == SPEED_TYPE_1) { return "Speed " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == ATTACK_SPEED_TYPE_1) { return "Atk Speed " + s + I2S(R2I(value)) + "%" }

        if (value_type == PHYSICAL_ATTACK_TYPE_2) { return "Damage " + s + I2S(R2I(value)) }
        elseif (value_type == PHYSICAL_DEFENCE_TYPE_2) { return "Defence " + s + I2S(R2I(value))}
        elseif (value_type == PHYSICAL_CRITICAL_CHANCE_TYPE_2 ) { return "Crit " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == PHYSICAL_CRITICAL_MULT_TYPE_2 ) { return "Crit Mult " + s + I2S(R2I(value)) }
        elseif (value_type == PHYSICAL_CRITICAL_DAMAGE_RESIST ) { return "Crit Res. " + s + I2S(R2I(value)) }
        elseif (value_type == MAGICAL_ATTACK_TYPE_2 ) { return "Mag Attack " + s + I2S(R2I(value)) }
        elseif (value_type == MAGICAL_SUPPRESSION_TYPE_2 ) { return "Supress. " + s + I2S(R2I(value)) }
        elseif (value_type == MAGICAL_RESIST_TYPE_2) { return "Resist " + s + I2S(R2I(value)) }
        elseif (value_type == MAGICAL_ACCURACY_TYPE_2) { return "Mag Acc " + s + I2S(R2I(value)) }
        elseif (value_type == MAGICAL_CRITICAL_CHANCE_TYPE_2 ) { return "Mag Crit " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_CRITICAL_MULT_TYPE_2 ) { return "Mag Crit Mult " + s + I2S(R2I(value)) }
        elseif (value_type == MAGICAL_CRITICAL_DAMAGE_RESIST ) { return "Mag Crit Res " + s + I2S(R2I(value)) }
        elseif (value_type == ACCURACY_TYPE_2) { return "Accuracy " + s + I2S(R2I(value)) }
        elseif (value_type == EVADE_TYPE_2) { return "Evade " + s + I2S(R2I(value)) }
        elseif (value_type == PARRY_TYPE_2) { return "Parry " + s + I2S(R2I(value)) }
        elseif (value_type == BLOCK_TYPE_2) { return "Block " + s + I2S(R2I(value)) }
        elseif (value_type == HP_TYPE_2) { return "Hp " + s + I2S(R2I(value)) }
        elseif (value_type == MP_TYPE_2) { return "Mp " + s + I2S(R2I(value)) }
        elseif (value_type == SPEED_TYPE_2) { return "Speed " + s + I2S(R2I(value)) }
        elseif (value_type == HEAL_RATE_TYPE_2) { return "Healing " + s + I2S(R2I(value)) }
        elseif (value_type == VAMPIRIC_DAMAGE_TYPE_2) { return "Draining " + s + I2S(R2I(value)) }
        
        if (value_type == STUN_RESIST) { return "Stun Res " + s + I2S(R2I(value)) }
        elseif (value_type == BLEED_RESIST) { return "Bleed Res " + s + I2S(R2I(value)) }
        elseif (value_type == POISON_RESIST) { return "Poison Res " + s + I2S(R2I(value)) }
        elseif (value_type == ROOT_RESIST) { return "Root Res " + s + I2S(R2I(value)) }
        elseif (value_type == SLEEP_RESIST) { return "Sleep Res " + s + I2S(R2I(value)) }
        elseif (value_type == PARALYZE_RESIST) { return "Paralyze Res " + s + I2S(R2I(value)) }
        elseif (value_type == MISC_RESIST) { return "Resistance " + s + I2S(R2I(value)) }
        
        if (value_type == FIRE_RESIST) { return "Fire Res " + s + I2S(R2I(value)) }
        elseif (value_type == AQUA_RESIST) { return "Water Res " + s + I2S(R2I(value)) }
        elseif (value_type == WIND_RESIST) { return "Wind Res " + s + I2S(R2I(value)) }
        elseif (value_type == EARTH_RESIST) { return "Earth Res " + s + I2S(R2I(value)) }
        elseif (value_type == HOLY_RESIST) { return "Light Res " + s + I2S(R2I(value)) }
        elseif (value_type == DARKNESS_RESIST ) { return "Darkness Res " + s + I2S(R2I(value)) }
        elseif (value_type == NATURE_RESIST ) { return "Nature Res " + s + I2S(R2I(value)) }
        elseif (value_type == BLOOD_RESIST ) { return "Blood Res " + s + I2S(R2I(value)) }
        
        if (value_type == FIRE_BONUS) { return "Fire Power " + s + I2S(R2I(value)) }
        elseif (value_type == AQUA_BONUS) { return "Water Power " + s + I2S(R2I(value)) }
        elseif (value_type == WIND_BONUS) { return "Wind Power " + s + I2S(R2I(value)) }
        elseif (value_type == EARTH_BONUS) { return "Earth Power " + s + I2S(R2I(value)) }
        elseif (value_type == HOLY_BONUS) { return "Light Power " + s + I2S(R2I(value)) }
        elseif (value_type == DARKNESS_BONUS ) { return "Darkness Power " + s + I2S(R2I(value)) }
        elseif (value_type == NATURE_BONUS ) { return "Nature Power " + s + I2S(R2I(value)) }
        elseif (value_type == BLOOD_BONUS ) { return "Blood Power " + s + I2S(R2I(value)) }
        
        if (value_type == PHYSICAL_REFLECT_AMOUNT) { return "Phys Damage Reflect " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == PHYSICAL_REFLECT_CHANCE) { return "Phys Dam. Reflect Chance " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == PHYSICAL_BUFFS_REFLECT_CHANCE) { return "Phys Debuff Reflect " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_REFLECT_AMOUNT) { return "Magic Damage Reflect " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_REFLECT_CHANCE) { return "Mag Dam. Reflect Chance " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == MAGICAL_BUFFS_REFLECT_CHANCE) { return "Magic Debuff Reflect " + s + I2S(R2I(value)) + "%" }
        
        if (value_type == BOW_RESIST) { return "Bow Resist " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == BLUNT_RESIST) { return "Mace Resist " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == GREATBLUNT_RESIST) { return "Greatmace Resist " + s + I2S(R2I(value)) + "%" }
        elseif (value_type == SWORD_RESIST) { return "Sword Resist " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == GREATSWORD_RESIST) { return "Greatsword Resist " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == AXE_RESIST) { return "Axe Resist " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == GREATAXE_RESIST) { return "Greataxe Resist " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == DAGGER_RESIST) { return "Dagger Resist " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == STAFF_RESIST) { return "Staff Resist " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == POLE_RESIST) { return "Pole Resist " + s + I2S(R2I(value)) + "%"  }
        
        if (value_type == SIDE_DAMAGE_BONUS) { return "Side damage " + s + I2S(R2I(value)) + "%"  }
        elseif (value_type == BACK_DAMAGE_BONUS) { return "Back damage " + s + I2S(R2I(value)) + "%" }
        
        if value_type == FIRE_DAMAGE { return "Fire damage" }
        elseif value_type == AQUA_DAMAGE { return "Water damage" }
        elseif value_type == WIND_DAMAGE { return "Wind damage" }
        elseif value_type == EARTH_DAMAGE { return "Earth damage" }
        elseif value_type == HOLY_DAMAGE { return "Light damage" }
        elseif value_type == DARKNESS_DAMAGE { return "Darkness damage" }
        elseif value_type == BLOOD_DAMAGE { return "Blood damage" }
        elseif value_type == NATURE_DAMAGE { return "Nature damage" }
        
        return "MissingString"
    }


    void SetStat(int value_type, real value, bool logic, UD src ){
        if logic {
            if (value_type == PHYSICAL_ATTACK_TYPE_1) { src.MultiplyPatk(value, true); return }
            elseif (value_type == PHYSICAL_DEFENCE_TYPE_1) { src.MultiplyPhysDef(value, true); return }
            elseif (value_type == MAGICAL_ATTACK_TYPE_1) { src.MultiplyMatk(value, true); return }
            elseif (value_type == MAGICAL_SUPPRESSION_TYPE_1) { src.MultiplyMsupp(value, true); return }
            elseif (value_type == MAGICAL_RESIST_TYPE_1) { src.MultiplyResist(value, true); return }
            elseif (value_type == MAGICAL_ACCURACY_TYPE_1) { src.MultiplyMagAcc(value, true); return }
            elseif (value_type == ACCURACY_TYPE_1) { src.MultiplyAcc(value, true); return }
            elseif (value_type == EVADE_TYPE_1) { src.MultiplyEvade(value, true); return }
            elseif (value_type == PARRY_TYPE_1) { src.MultiplyParry(value, true); return }
            elseif (value_type == BLOCK_TYPE_1) { src.MultiplyBlock(value, true); return }
            elseif (value_type == HP_TYPE_1) { src.MultiplyHpBonus(value, true); return }
            elseif (value_type == MP_TYPE_1) { src.MultiplyMpBonus(value, true); return }
            elseif (value_type == SPEED_TYPE_1) { src.SetSpeedType1(value, true); return }
            elseif (value_type == ATTACK_SPEED_TYPE_1) { src.SetAttackSpeed(value); return }
            
            if (value_type == PHYSICAL_ATTACK_TYPE_2) {  src.SetPatk(value); return }
            elseif (value_type == PHYSICAL_DEFENCE_TYPE_2) { src.SetPhysDef(value); return }
            elseif (value_type == PHYSICAL_CRITICAL_CHANCE_TYPE_2 ) { src.SetPCrit(value); return }
            elseif (value_type == PHYSICAL_CRITICAL_MULT_TYPE_2 ) { src.SetPhysCritMult(value); return }
            elseif (value_type == PHYSICAL_CRITICAL_DAMAGE_RESIST ) { src.physical_critical_damage_resist += value ; return }
            elseif (value_type == MAGICAL_ATTACK_TYPE_2 ) { src.SetMatk(value); return }
            elseif (value_type == MAGICAL_SUPPRESSION_TYPE_2 ) { src.SetMsupp(value); return }
            elseif (value_type == MAGICAL_RESIST_TYPE_2) { src.SetResist(value); return }
            elseif (value_type == MAGICAL_ACCURACY_TYPE_2) { src.SetMagAcc(value); return }
            elseif (value_type == MAGICAL_CRITICAL_CHANCE_TYPE_2 ) { src.SetMCrit(value); return }
            elseif (value_type == MAGICAL_CRITICAL_MULT_TYPE_2 ) { src.SetMagCritMult(value); return }
            elseif (value_type == MAGICAL_CRITICAL_DAMAGE_RESIST ) { src.magical_critical_damage_resist += value; return }
            elseif (value_type == ACCURACY_TYPE_2) { src.SetAcc(value); return }
            elseif (value_type == EVADE_TYPE_2) { src.SetEvade(value); return }
            elseif (value_type == PARRY_TYPE_2) { src.SetParry(value); return }
            elseif (value_type == BLOCK_TYPE_2) { src.SetBlock(value); return }
            elseif (value_type == HP_TYPE_2) { src.SetHpBonus(value); return }
            elseif (value_type == MP_TYPE_2) { src.SetMpBonus(value); return }
            elseif (value_type == SPEED_TYPE_2) { src.SetSpeedType2(value); return }
            elseif (value_type == HEAL_RATE_TYPE_2) { src.healing_rate += value ; return }
            elseif (value_type == VAMPIRIC_DAMAGE_TYPE_2) { src.vampiric += value ; return }
            
            if (value_type == STUN_RESIST) { src.resist[STUN] += value ; return }
            elseif (value_type == BLEED_RESIST) { src.resist[BLEED] += value ; return }
            elseif (value_type == POISON_RESIST) { src.resist[POISON] += value ; return }
            elseif (value_type == ROOT_RESIST) { src.resist[ROOT] += value ; return }
            elseif (value_type == SLEEP_RESIST) { src.resist[SLEEP] += value ; return }
            elseif (value_type == PARALYZE_RESIST) { src.resist[PARALYZE] += value ; return }
            elseif (value_type == MISC_RESIST) { src.resist[MISCL] += value ; return }
            
            if (value_type == FIRE_RESIST) { src.element_resist[FIRE] += R2I(value); return }
            elseif (value_type == AQUA_RESIST) { src.element_resist[AQUA] += R2I(value); return }
            elseif (value_type == WIND_RESIST) { src.element_resist[WIND] += R2I(value); return }
            elseif (value_type == EARTH_RESIST) { src.element_resist[EARTH] += R2I(value); return }
            elseif (value_type == HOLY_RESIST) { src.element_resist[HOLY] += R2I(value); return }
            elseif (value_type == DARKNESS_RESIST ) { src.element_resist[DARKNESS] += R2I(value); return }
            elseif (value_type == NATURE_RESIST ) { src.element_resist[NATURE] += R2I(value); return }
            elseif (value_type == BLOOD_RESIST ) { src.element_resist[BLOOD] += R2I(value); return }
            
            if (value_type == FIRE_BONUS) { src.element_bonus[FIRE] += R2I(value); return }
            elseif (value_type == AQUA_BONUS) { src.element_bonus[AQUA] += R2I(value); return }
            elseif (value_type == WIND_BONUS) { src.element_bonus[WIND] += R2I(value); return }
            elseif (value_type == EARTH_BONUS) { src.element_bonus[EARTH] += R2I(value); return }
            elseif (value_type == HOLY_BONUS) { src.element_bonus[HOLY] += R2I(value); return }
            elseif (value_type == DARKNESS_BONUS ) { src.element_bonus[DARKNESS] += R2I(value); return }
            elseif (value_type == NATURE_BONUS ) { src.element_bonus[NATURE] += R2I(value); return }
            elseif (value_type == BLOOD_BONUS ) { src.element_bonus[BLOOD] += R2I(value); return }
            
            if (value_type == PHYSICAL_REFLECT_AMOUNT) { src.phys_damage_reflect_amount += value ; return }
            elseif (value_type == PHYSICAL_REFLECT_CHANCE) { src.phys_damage_reflect_chance += value ; return }
            elseif (value_type == PHYSICAL_BUFFS_REFLECT_CHANCE) { src.phys_debuff_reflect_chance += value ; return }
            elseif (value_type == MAGICAL_REFLECT_AMOUNT) { src.magical_damage_reflect_amount += value ; return }
            elseif (value_type == MAGICAL_REFLECT_CHANCE) { src.magical_damage_reflect_chance += value ; return }
            elseif (value_type == MAGICAL_BUFFS_REFLECT_CHANCE) { src.magical_debuff_reflect_chance += value ; return }
            
            if (value_type == BOW_RESIST) { src.weapons_resist[BOW] -= value ; return }
            elseif (value_type == BLUNT_RESIST) { src.weapons_resist[BLUNT] -= value ; return }
            elseif (value_type == GREATBLUNT_RESIST) { src.weapons_resist[GREATBLUNT] -= value ; return }
            elseif (value_type == SWORD_RESIST) { src.weapons_resist[SWORD] -= value ; return }
            elseif (value_type == GREATSWORD_RESIST) { src.weapons_resist[GREATSWORD] -= value ; return }
            elseif (value_type == AXE_RESIST) { src.weapons_resist[AXE] -= value ; return }
            elseif (value_type == GREATAXE_RESIST) { src.weapons_resist[GREATAXE] -= value ; return }
            elseif (value_type == DAGGER_RESIST) { src.weapons_resist[DAGGER] -= value ; return }
            elseif (value_type == STAFF_RESIST) { src.weapons_resist[STAFF] -= value ; return }
            elseif (value_type == POLE_RESIST) { src.weapons_resist[POLE] -= value ; return }
            
            if (value_type == SIDE_DAMAGE_BONUS) { src.side_damage_bonus += value ; return }
            elseif (value_type == BACK_DAMAGE_BONUS) { src.back_damage_bonus += value ; return }
            
            if (value_type == BLINDNESS) { src.blind_chance += value ; return }
        }
        elseif not logic {
        
            if (value_type == PHYSICAL_ATTACK_TYPE_1) { src.MultiplyPatk(value, false) ; return }
            elseif (value_type == PHYSICAL_DEFENCE_TYPE_1) { src.MultiplyPhysDef(value, false) ; return }
            elseif (value_type == MAGICAL_ATTACK_TYPE_1) { src.MultiplyMatk(value, false); return }
            elseif (value_type == MAGICAL_SUPPRESSION_TYPE_1) { src.MultiplyMsupp(value, false); return }
            elseif (value_type == MAGICAL_RESIST_TYPE_1) { src.MultiplyResist(value, false); return }
            elseif (value_type == MAGICAL_ACCURACY_TYPE_1) { src.MultiplyMagAcc(value, false); return }
            elseif (value_type == ACCURACY_TYPE_1) { src.MultiplyAcc(value, false); return }
            elseif (value_type == EVADE_TYPE_1) { src.MultiplyEvade(value, false); return }
            elseif (value_type == PARRY_TYPE_1) { src.MultiplyParry(value, false); return }
            elseif (value_type == BLOCK_TYPE_1) { src.MultiplyBlock(value, false); return }
            elseif (value_type == HP_TYPE_1) { src.MultiplyHpBonus(value, false); return }
            elseif (value_type == MP_TYPE_1) { src.MultiplyMpBonus(value, false); return }
            elseif (value_type == SPEED_TYPE_1) { src.SetSpeedType1(value, false); return }
            elseif (value_type == ATTACK_SPEED_TYPE_1) { src.SetAttackSpeed(-value) ; return }
            
            if (value_type == PHYSICAL_ATTACK_TYPE_2) { src.SetPatk(-value); return }
            elseif (value_type == PHYSICAL_DEFENCE_TYPE_2) { src.SetPhysDef(-value); return }
            elseif (value_type == PHYSICAL_CRITICAL_CHANCE_TYPE_2 ) { src.SetPCrit(-value); return }
            elseif (value_type == PHYSICAL_CRITICAL_MULT_TYPE_2 ) { src.SetPhysCritMult(-value); return }
            elseif (value_type == PHYSICAL_CRITICAL_DAMAGE_RESIST ) { src.physical_critical_damage_resist -= value ; return }
            elseif (value_type == MAGICAL_ATTACK_TYPE_2 ) { src.SetMatk(-value); return }
            elseif (value_type == MAGICAL_SUPPRESSION_TYPE_2 ) { src.SetMsupp(-value); return }
            elseif (value_type == MAGICAL_RESIST_TYPE_2) { src.SetResist(-value); return }
            elseif (value_type == MAGICAL_ACCURACY_TYPE_2) { src.SetMagAcc(-value); return }
            elseif (value_type == MAGICAL_CRITICAL_CHANCE_TYPE_2 ) { src.SetMCrit(-value); return }
            elseif (value_type == MAGICAL_CRITICAL_MULT_TYPE_2 ) { src.SetMagCritMult(-value); return }
            elseif (value_type == MAGICAL_CRITICAL_DAMAGE_RESIST ) { src.magical_critical_damage_resist -= value ; return }
            elseif (value_type == ACCURACY_TYPE_2) { src.SetAcc(-value); return }
            elseif (value_type == EVADE_TYPE_2) { src.SetEvade(-value); return }
            elseif (value_type == PARRY_TYPE_2) { src.SetParry(-value) ; return}
            elseif (value_type == BLOCK_TYPE_2) { src.SetBlock(-value); return }
            elseif (value_type == HP_TYPE_2) { src.SetHpBonus(-value); return }
            elseif (value_type == MP_TYPE_2) { src.SetMpBonus(-value); return }
            elseif (value_type == SPEED_TYPE_2) { src.SetSpeedType2(-value); return }
            elseif (value_type == HEAL_RATE_TYPE_2) { src.healing_rate -= value; return }
            elseif (value_type == VAMPIRIC_DAMAGE_TYPE_2) { src.vampiric -= value; return }
            
            if (value_type == STUN_RESIST) { src.resist[STUN] -= value; return }
            elseif (value_type == BLEED_RESIST) { src.resist[BLEED] -= value; return }
            elseif (value_type == POISON_RESIST) { src.resist[POISON] -= value; return }
            elseif (value_type == ROOT_RESIST) { src.resist[ROOT] -= value; return }
            elseif (value_type == SLEEP_RESIST) { src.resist[SLEEP] -= value; return }
            elseif (value_type == PARALYZE_RESIST) { src.resist[PARALYZE] -= value; return }
            elseif (value_type == MISC_RESIST) { src.resist[MISCL] -= value; return }
            
            if (value_type == FIRE_RESIST) { src.element_resist[FIRE] -= R2I(value); return }
            elseif (value_type == AQUA_RESIST) { src.element_resist[AQUA] -= R2I(value); return }
            elseif (value_type == WIND_RESIST) { src.element_resist[WIND] -= R2I(value); return }
            elseif (value_type == EARTH_RESIST) { src.element_resist[EARTH] -= R2I(value); return }
            elseif (value_type == HOLY_RESIST) { src.element_resist[HOLY] -= R2I(value); return }
            elseif (value_type == DARKNESS_RESIST ) { src.element_resist[DARKNESS] -= R2I(value); return }
            elseif (value_type == NATURE_RESIST ) { src.element_resist[NATURE] -= R2I(value); return }
            elseif (value_type == BLOOD_RESIST ) { src.element_resist[BLOOD] -= R2I(value); return }
            
            if (value_type == FIRE_BONUS) { src.element_bonus[FIRE] -= R2I(value); return }
            elseif (value_type == AQUA_BONUS) { src.element_bonus[AQUA] -= R2I(value); return }
            elseif (value_type == WIND_BONUS) { src.element_bonus[WIND] -= R2I(value); return }
            elseif (value_type == EARTH_BONUS) { src.element_bonus[EARTH] -= R2I(value); return }
            elseif (value_type == HOLY_BONUS) { src.element_bonus[HOLY] -= R2I(value); return }
            elseif (value_type == DARKNESS_BONUS ) { src.element_bonus[DARKNESS] -= R2I(value); return }
            elseif (value_type == NATURE_BONUS ) { src.element_bonus[NATURE] -= R2I(value); return }
            elseif (value_type == BLOOD_BONUS ) { src.element_bonus[BLOOD] -= R2I(value); return }
            
            if (value_type == PHYSICAL_REFLECT_AMOUNT) { src.phys_damage_reflect_amount -= value; return }
            elseif (value_type == PHYSICAL_REFLECT_CHANCE) { src.phys_damage_reflect_chance -= value; return }
            elseif (value_type == PHYSICAL_BUFFS_REFLECT_CHANCE) { src.phys_debuff_reflect_chance -= value; return }
            elseif (value_type == MAGICAL_REFLECT_AMOUNT) { src.magical_damage_reflect_amount -= value; return}
            elseif (value_type == MAGICAL_REFLECT_CHANCE) { src.magical_damage_reflect_chance -= value; return }
            elseif (value_type == MAGICAL_BUFFS_REFLECT_CHANCE) { src.magical_debuff_reflect_chance -= value }
            
            if (value_type == BOW_RESIST) { src.weapons_resist[BOW] += value; return }
            elseif (value_type == BLUNT_RESIST) { src.weapons_resist[BLUNT] += value; return }
            elseif (value_type == GREATBLUNT_RESIST) { src.weapons_resist[GREATBLUNT] += value; return }
            elseif (value_type == SWORD_RESIST) { src.weapons_resist[SWORD] += value; return }
            elseif (value_type == GREATSWORD_RESIST) { src.weapons_resist[GREATSWORD] += value; return }
            elseif (value_type == AXE_RESIST) { src.weapons_resist[AXE] += value; return }
            elseif (value_type == GREATAXE_RESIST) { src.weapons_resist[GREATAXE] += value; return }
            elseif (value_type == DAGGER_RESIST) { src.weapons_resist[DAGGER] += value; return}
            elseif (value_type == STAFF_RESIST) { src.weapons_resist[STAFF] += value; return }
            elseif (value_type == POLE_RESIST) { src.weapons_resist[POLE] += value; return }
            
            if (value_type == SIDE_DAMAGE_BONUS) { src.side_damage_bonus -= value; return }
            elseif (value_type == BACK_DAMAGE_BONUS) { src.back_damage_bonus -= value; return }
            
            if (value_type == BLINDNESS) { src.blind_chance -= value; return }
        }
    }

    bool IsDebuff(int base_state, real base_rate, real resist) {
        real debuff_chance
            if base_rate == -1. { return true }
            debuff_chance = (base_rate / (base_state * 0.09)) / resist
            if debuff_chance >= 90. { debuff_chance = 90. }
            elseif debuff_chance <= 10. { debuff_chance = 10. }
        return Chance(debuff_chance)
    }
    
    void RemoveBuff(int id, unit A){
        UD src = GetData(A)
        int index = 0, C1 = 1
            while (index++ < Stack) {
                if BuffId[BuffStack[index].cell][1] == id and BuffStack[index].victim == A {
                    if BuffStack[index].level == 1 {
                        while (WhichState_1[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_1[BuffStack[index].cell][C1], WhichStateValue_1[BuffStack[index].cell][C1], true, GetData(BuffStack[index].victim))
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 2 {
                        while (WhichState_2[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_2[BuffStack[index].cell][C1], WhichStateValue_2[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 3 {
                        while (WhichState_3[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_3[BuffStack[index].cell][C1], WhichStateValue_3[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 4 {
                        while (WhichState_4[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_4[BuffStack[index].cell][C1], WhichStateValue_4[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 5 {
                        while (WhichState_5[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_5[BuffStack[index].cell][C1], WhichStateValue_5[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    if BuffAbsorbDamageAmount[BuffStack[index].cell][BuffStack[index].level] > 0. {
                        src.absorb_amount = 0
                        src.absorb_perc = 0.
                        src.absorb_chance = 0.
                        src.absorb_type = 0
                        src.absorb_buff = 0
                    }
                    if BuffStack[index].slc == PHYSICAL_SILENCE { src.silence[1] = false }
                    elseif BuffStack[index].slc == MAGICAL_SILENCE { src.silence[2] = false }
                    elseif BuffStack[index].slc == BOTH_SILENCE { src.silence[1] = false; src.silence[2] = false }
                    src.alternate_effect = 0
                    SetUnitTimeScale(src.Owner, 1.)
                    if DebuffState[BuffStack[index].cell] == SLEEPING { src.sleep_buff = 0 }
                    if BuffStack[index].Unpause { PauseUnit(BuffStack[index].victim, false) }
                    UnitRemoveAbility(BuffStack[index].victim, BuffId[BuffStack[index].cell][1])
                    UnitRemoveAbility(BuffStack[index].victim, BuffId[BuffStack[index].cell][2])
                    BuffStack[index].victim = null
                    BuffStack[index].source = null
                    BuffStack[index].destroy()
                    BuffStack[index] = BuffStack[Stack]
                    Stack--
                    break
                }
            }
    }
    
    private void BuffsUpdate(){
        int index = 0, C1 = 1
        UD src
            while(index++ < Stack){
                src = GetData(BuffStack[index].victim)
                if (BuffStack[index].duration <= 0. or GetHp(BuffStack[index].victim) <= 0.045 or GetUnitAbilityLevel(BuffStack[index].victim, BuffId[BuffStack[index].cell][2]) == 0) {
                    if BuffStack[index].level == 1 {
                        while (WhichState_1[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_1[BuffStack[index].cell][C1], WhichStateValue_1[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 2 {
                        while (WhichState_2[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_2[BuffStack[index].cell][C1], WhichStateValue_2[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 3 {
                        while (WhichState_3[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_3[BuffStack[index].cell][C1], WhichStateValue_3[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 4 {
                        while (WhichState_4[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_4[BuffStack[index].cell][C1], WhichStateValue_4[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    elseif BuffStack[index].level == 5 {
                        while (WhichState_5[BuffStack[index].cell][C1] > 0) {
                            SetStat(WhichState_5[BuffStack[index].cell][C1], WhichStateValue_5[BuffStack[index].cell][C1], false, src)
                            C1++
                        }
                    }
                    if BuffAbsorbDamageAmount[BuffStack[index].cell][BuffStack[index].level] > 0. {
                        src.absorb_amount = 0
                        src.absorb_perc = 0.
                        src.absorb_chance = 0.
                        src.absorb_type = 0
                        src.absorb_buff = 0
                    }
                    if BuffStack[index].slc == PHYSICAL_SILENCE { src.silence[1] = false }
                    elseif BuffStack[index].slc == MAGICAL_SILENCE { src.silence[2] = false }
                    elseif BuffStack[index].slc == BOTH_SILENCE { src.silence[1] = false; src.silence[2] = false }
                    if DebuffState[BuffStack[index].cell] == SLEEPING { src.sleep_buff = 0 }
                    src.alternate_effect = 0
                    SetUnitTimeScale(src.Owner, 1.)
                    if BuffStack[index].Unpause { PauseUnit(BuffStack[index].victim, false) }
                    UnitRemoveAbility(BuffStack[index].victim, BuffId[BuffStack[index].cell][1])
                    UnitRemoveAbility(BuffStack[index].victim, BuffId[BuffStack[index].cell][2])
                    BuffStack[index].victim = null
                    BuffStack[index].source = null
                    BuffStack[index].destroy()
                    BuffStack[index] = BuffStack[Stack]
                    Stack--
                }
                else {
                    // fear effect
                    if DebuffState[BuffStack[index].cell] == FEARING {
                        IssuePointOrderById(BuffStack[index].victim, order_move, Gx(BuffStack[index].victim) + Rx(110., (ABU(BuffStack[index].victim, BuffStack[index].source) + GetRandomReal(-5.,5.))), Gx(BuffStack[index].victim) + Ry(110., (ABU(BuffStack[index].victim, BuffStack[index].source) + GetRandomReal(-5.,5.))))
                    }
                    //==============Effect over time==============
                        if EffectOverTimeValue[BuffStack[index].cell][BuffStack[index].level] > 0 {
                            BuffStack[index].tick += 0.1
                            if BuffStack[index].tick == EffectOverTimeDelay[BuffStack[index].cell][BuffStack[index].level] {
                                if StringLength(EffectOverTimeEffect[BuffStack[index].cell][1]) > 1 
                                { DestroyEffect(AddSpecialEffectTarget(EffectOverTimeEffect[BuffStack[index].cell][1], BuffStack[index].victim, EffectOverTimeEffect[BuffStack[index].cell][2])) }
                                if EffectOverTimeType[BuffStack[index].cell] {
                                    UnitDamageTarget(BuffStack[index].source, BuffStack[index].victim, EffectOverTimeValue[BuffStack[index].cell][BuffStack[index].level], true, false, null, null, WEAPON_TYPE_WHOKNOWS)
                                    TextUp(I2S(R2I(EffectOverTimeValue[BuffStack[index].cell][BuffStack[index].level])), BuffStack[index].victim, 10.,100.00, 20.00, 20.00)
                                }
                                else {
                                    SetHp(BuffStack[index].victim,(GetHp(BuffStack[index].victim) + (EffectOverTimeValue[BuffStack[index].cell][BuffStack[index].level] * src.healing_rate)))
                                    TextUp(I2S(R2I(EffectOverTimeValue[BuffStack[index].cell][BuffStack[index].level] * src.healing_rate)), BuffStack[index].victim, 10.,0.00, 100.00, 0.00)
                                }
                            BuffStack[index].tick = 0.
                            }
                        BuffStack[index].total = 0
                        }
                        else {
                            BuffStack[index].total++
                        }
                    BuffStack[index].duration -= 0.1
                }
            }
    }
    
    
    
    int AddBuffToUnit(unit target, unit caster, int buff_id, int level) {
        int c = 0, C1 = 1, finder_val = -1
        int NBS
        real reflect_chance
        UD trg = GetData(target)
        UD src = GetData(caster)
        MyBuffData new_buff = MyBuffData.create()
        new_buff.level = level
        new_buff.source = caster
        new_buff.victim = target
        new_buff.cell = GetBuffCell(buff_id)
            // exist
            if new_buff.cell > 0 {
                // buff
                if BuffPolar[new_buff.cell] {
                    bj_forLoopAIndex = 1
                    while (BuffReplacer[new_buff.cell][bj_forLoopAIndex] > 0 ){
                        RemoveBuff(BuffReplacer[new_buff.cell][bj_forLoopAIndex], target)
                        bj_forLoopAIndex++
                    }
                    RemoveBuff(BuffId[new_buff.cell][1], target)
                    UnitAddAbility(target, BuffId[new_buff.cell][1])
                        if level == 1 {
                            while (WhichState_1[new_buff.cell][C1] > 0) {
                                SetStat(WhichState_1[new_buff.cell][C1], WhichStateValue_1[new_buff.cell][C1], true, trg)
                                C1++
                            }
                        }
                        elseif level == 2 {
                            while (WhichState_2[new_buff.cell][C1] > 0) {
                                SetStat(WhichState_2[new_buff.cell][C1], WhichStateValue_2[new_buff.cell][C1], true, trg)
                                C1++
                            }
                        }
                        elseif level == 3 {
                            while (WhichState_3[new_buff.cell][C1] > 0) {
                                SetStat(WhichState_3[new_buff.cell][C1], WhichStateValue_3[new_buff.cell][C1], true, trg)
                                C1++
                            }
                        }
                        elseif level == 4 {
                            while (WhichState_4[new_buff.cell][C1] > 0) {
                                SetStat(WhichState_4[new_buff.cell][C1], WhichStateValue_4[new_buff.cell][C1], true, trg)
                                C1++
                            }
                        }
                        elseif level == 5 {
                            while (WhichState_5[new_buff.cell][C1] > 0) {
                                SetStat(WhichState_5[new_buff.cell][C1], WhichStateValue_5[new_buff.cell][C1], true, trg)
                                C1++
                            }
                        }
                        if BuffAbsorbDamageAmount[new_buff.cell][level] > 0. {
                            if trg.absorb_buff > 0 { RemoveBuff(BuffId[new_buff.cell][1], target) }
                            trg.absorb_amount = BuffAbsorbDamageAmount[new_buff.cell][level]
                            trg.absorb_perc = BuffAbsorbDamagePerc[new_buff.cell][level]
                            trg.absorb_chance = BuffAbsorbDamageChance[new_buff.cell][level]
                            trg.absorb_type = BuffAbsorbDamageType[new_buff.cell][level]
                            trg.absorb_buff = BuffId[new_buff.cell][1]
                        }
                    new_buff.duration = BuffTime[new_buff.cell][level]
                }
                // debuff
                else {
                    if BuffType[new_buff.cell] { reflect_chance = trg.phys_debuff_reflect_chance }
                    else { reflect_chance = trg.magical_debuff_reflect_chance }
                    
                    if reflect_chance > 100. { reflect_chance = 100. }
                    elseif reflect_chance < 0. { reflect_chance = 0. }
                    
                    if Chance(reflect_chance) {
                        new_buff.source = target
                        new_buff.victim = caster
                        caster = target
                        target = new_buff.victim
                        trg = GetData(target)
                        src = GetData(caster)
                            if BuffType[new_buff.cell] { NBS = trg.STD }
                            else { NBS = trg.WIL }
                    }
                        if BuffType[new_buff.cell] { NBS = trg.STD }
                        else { NBS = trg.WIL }
                    // success chances
                    if IsDebuff(NBS, DebuffChance[new_buff.cell][level], trg.resist[DebuffResist[new_buff.cell]]) {
                        if trg.alternate_effect > 0 {
                            if (BuffRank[trg.alternate_effect] < BuffRank[new_buff.cell] and BuffRank[new_buff.cell] > 0) {
                                RemoveBuff(BuffId[trg.alternate_effect][1], target)
                            }
                            else {
                                new_buff.destroy()
                                return 0
                            }
                        }
                            bj_forLoopAIndex = 1
                                while (BuffReplacer[new_buff.cell][bj_forLoopAIndex] > 0 ){
                                    RemoveBuff(BuffReplacer[new_buff.cell][bj_forLoopAIndex], target)
                                    bj_forLoopAIndex++
                                }
                            RemoveBuff(BuffId[new_buff.cell][1], target)
                            UnitAddAbility(target, BuffId[new_buff.cell][1])
                            new_buff.duration = BuffTime[new_buff.cell][level]
                                if level == 1 {
                                    while (WhichState_1[new_buff.cell][C1] > 0) {
                                        SetStat(WhichState_1[new_buff.cell][C1], WhichStateValue_1[new_buff.cell][C1], true, trg)
                                        C1++
                                    }
                                }
                                elseif level == 2 {
                                    while (WhichState_2[new_buff.cell][C1] > 0) {
                                        SetStat(WhichState_2[new_buff.cell][C1], WhichStateValue_2[new_buff.cell][C1], true, trg)
                                        C1++
                                    }
                                }
                                elseif level == 3 {
                                    while (WhichState_3[new_buff.cell][C1] > 0) {
                                        SetStat(WhichState_3[new_buff.cell][C1], WhichStateValue_3[new_buff.cell][C1], true, trg)
                                        C1++
                                    }
                                }
                                elseif level == 4 {
                                    while (WhichState_4[new_buff.cell][C1] > 0) {
                                        SetStat(WhichState_4[new_buff.cell][C1], WhichStateValue_4[new_buff.cell][C1], true, trg)
                                        C1++
                                    }
                                }
                                elseif level == 5 {
                                    while (WhichState_5[new_buff.cell][C1] > 0) {
                                        SetStat(WhichState_5[new_buff.cell][C1], WhichStateValue_5[new_buff.cell][C1], true, trg)
                                        C1++
                                    }
                                }
                                
                                if DebuffState[new_buff.cell] == STUNING {
                                    trg.alternate_effect = new_buff.cell
                                    new_buff.Unpause = true
                                    IssueImmediateOrderById(target, order_stop)
                                    PT(trg.damage_delay_timer)
                                    PT(trg.back_delay_timer)
                                    PauseUnit(target, true)
                                }
                                if DebuffState[new_buff.cell] == PARALYZING {
                                    trg.alternate_effect = new_buff.cell
                                    new_buff.Unpause = true
                                    IssueImmediateOrderById(target, order_stop)
                                    PT(trg.damage_delay_timer)
                                    PT(trg.back_delay_timer)
                                    PauseUnit(target, true)
                                    SetUnitTimeScale(trg.Owner, 0.)
                                }
                                if DebuffState[new_buff.cell] == FEARING {
                                    trg.alternate_effect = new_buff.cell
                                    IssueImmediateOrderById(target, order_stop) 
                                    PT(trg.damage_delay_timer)
                                    PT(trg.back_delay_timer)
                                }
                                if DebuffState[new_buff.cell] == SLEEPING { 
                                    trg.alternate_effect = new_buff.cell
                                    new_buff.Unpause = true
                                    IssueImmediateOrderById(target, order_stop)
                                    PT(trg.back_delay_timer)
                                    PT(trg.damage_delay_timer)
                                    PauseUnit(target, true)
                                    trg.sleep_buff = buff_id 
                                }
                    }
                    // fail
                    else {
                        new_buff.destroy()
                        return 0
                    }
                }
            }
            else {
                new_buff.destroy()
                return 0
            }
            Stack++
            BuffStack[Stack] = new_buff
        return new_buff
    }
    
    
    private void Init(){
        TimerStart(CT, 0.1, true, function BuffsUpdate)
    }

endlibrary
Top