Ejemplo n.º 1
0
        /// <summary>
        /// Does spell-damage to this Unit
        /// </summary>
        public DamageAction DealSpellDamage(Unit attacker, SpellEffect effect, int dmg, bool addDamageBonuses = true, bool mayCrit = true, bool forceCrit = false, bool clearAction = true)
        {
            EnsureContext();
            if (!IsAlive)
            {
                return(null);
            }
            if (attacker != null && !attacker.IsInContext)
            {
                attacker = null;
            }
            if (attacker is NPC)
            {
                dmg = (int)(dmg * NPCMgr.DefaultNPCDamageFactor + 0.999999f);
            }

            DamageSchool school;

            if (effect != null)
            {
                school = GetLeastResistantSchool(effect.Spell);
            }
            else
            {
                school = DamageSchool.Physical;
            }

            if (IsEvading || IsImmune(school) || IsInvulnerable || !IsAlive)
            {
                // cannot deal damage to this guy
                return(null);
            }

            var action = GetUnusedAction();

            // reset values
            action.Attacker    = attacker;
            action.HitFlags    = 0;
            action.VictimState = 0;
            action.Weapon      = null;

            if (effect != null)
            {
                // Some kind of spell is involved
                action.UsedSchool = school;
                action.Schools    = effect.Spell.SchoolMask;
                action.IsDot      = effect.IsPeriodic;
            }
            else
            {
                // pure white melee damage
                action.UsedSchool = DamageSchool.Physical;
                action.Schools    = DamageSchoolMask.Physical;
                action.IsDot      = false;
            }

            action.Damage = dmg;
            var deffence   = (Asda2MagicDefence + Asda2Defence) / 2;
            var atackerChr = action.Attacker as Character;

            if (atackerChr != null)
            {
                switch (atackerChr.Archetype.ClassId)
                {
                case ClassId.OHS:
                    deffence = Asda2Defence;
                    break;

                case ClassId.THS:
                    deffence = Asda2Defence;
                    break;

                case ClassId.Spear:
                    deffence = Asda2Defence;
                    break;

                case ClassId.Bow:
                    deffence = Asda2Defence;
                    break;

                case ClassId.Crossbow:
                    deffence = Asda2Defence;
                    break;

                case ClassId.Balista:
                    deffence = Asda2Defence;
                    break;

                case ClassId.AtackMage:
                    deffence = Asda2MagicDefence;
                    break;

                case ClassId.HealMage:
                    deffence = Asda2MagicDefence;
                    break;

                case ClassId.SupportMage:
                    deffence = Asda2MagicDefence;
                    break;
                }
            }
            action.ResistPct   = DamageAction.CalcResistPrc(deffence, action.Damage, GetResistChancePct(this, action.UsedSchool));
            action.Absorbed    = 0;
            action.SpellEffect = effect;


            action.Victim = this;
            if (attacker != null)
            {
                attacker.DeathPrevention++;
            }

            DeathPrevention++;
            try
            {
                if (attacker != null)
                {
                    // the damage is caused by someone else (i.e. not environmental damage etc)

                    var random    = Utility.Random(1, 10000);
                    var hitChance = action.CalcHitChance();
                    if (random > hitChance)
                    {
                        // missed the target
                        action.Miss();
                    }
                    else
                    {
                        var block = action.CalcBlockChance();
                        if (random > (hitChance - block))
                        {
                            // block
                            action.Block();
                        }
                        else
                        {
                            var critical = action.CalcCritChance();
                            if (forceCrit || random > (hitChance - critical - block))
                            {
                                // critical hit
                                action.StrikeCritical();
                            }
                        }
                        if (addDamageBonuses)
                        {
                            action.AddDamageMods();
                        }
                    }

                    // add mods and call events

                    OnDefend(action);
                    attacker.OnAttack(action);
                }

                action.Resisted = (int)Math.Round(action.Damage * action.ResistPct / 100);

                DoRawDamage(action);
            }
            finally
            {
                DeathPrevention--;
                if (attacker != null)
                {
                    attacker.DeathPrevention--;
                }
                if (clearAction)
                {
                    action.OnFinished();
                }
            }
            if (clearAction)
            {
                return(null);
            }
            return(action);
        }