Beispiel #1
0
        public void MagicAttack(MonsterObject _target)
        {
            if (_target == null) return;
            if (!uniqueAI.IgnorePets)
                MagicAttackDamage += DamageToPets;
            else
                FindTarget();

            AttackTime = Envir.Time + AttackSpeed + 500;

            if (MagicAttackDamage == 0) return;
            switch (uniqueAI.MagicAttackEffect)
            {
                case 1:
                    Broadcast(new S.ObjectEffect { ObjectID = _target.ObjectID, Effect = SpellEffect.Entrapment });
                    break;
                case 2:
                    Broadcast(new S.ObjectEffect { ObjectID = _target.ObjectID, Effect = SpellEffect.GreatFoxSpirit });
                    break;
                default:
                    break;
            }

            DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 500, _target, MagicAttackDamage, DefenceType.MAC);
            ActionList.Add(action);
        }
        private void ElectricShock(MonsterObject target, UserMagic magic)
        {
            if (target == null || !target.IsAttackTarget(this)) return;

            if (Envir.Random.Next(4 - magic.Level) > 0)
            {
                if (Envir.Random.Next(2) == 0) LevelMagic(magic);
                return;
            }

            LevelMagic(magic);

            if (target.Master == this)
            {
                target.ShockTime = Envir.Time + (magic.Level * 5 + 10) * 1000;
                target.Target = null;
                return;
            }

            if (Envir.Random.Next(2) > 0)
            {
                target.ShockTime = Envir.Time + (magic.Level * 5 + 10) * 1000;
                target.Target = null;
                return;
            }

            if (target.Level > Level + 2 || !target.Info.CanTame) return;

            if (Envir.Random.Next(Level + 20 + magic.Level * 5) <= target.Level + 10)
            {
                if (Envir.Random.Next(5) > 0 && target.Master == null)
                {
                    target.RageTime = Envir.Time + (Envir.Random.Next(20) + 10) * 1000;
                    target.Target = null;
                }
                return;
            }

            if (Pets.Count(t => !t.Dead) >= magic.Level + 2) return;
            int rate = (int)(target.MaxHP / 100);
            if (rate <= 2) rate = 2;
            else rate *= 2;

            if (Envir.Random.Next(rate) != 0) return;
            //else if (Envir.Random.Next(20) == 0) target.Die();

            if (target.Master != null)
            {
                target.SetHP(target.MaxHP / 10);
                target.Master.Pets.Remove(target);
            }
            else if (target.Respawn != null)
            {
                target.Respawn.Count--;
                Envir.MonsterCount--;
                CurrentMap.MonsterCount--;
                target.Respawn = null;
            }

            target.Master = this;
            //target.HealthChanged = true;
            target.BroadcastHealthChange();
            Pets.Add(target);
            target.Target = null;
            target.RageTime = 0;
            target.ShockTime = 0;
            target.OperateTime = 0;
            target.MaxPetLevel = (byte)(1 + magic.Level * 2);

            target.Broadcast(new S.ObjectName { ObjectID = target.ObjectID, Name = target.Name });
        }
        public override bool IsFriendlyTarget(MonsterObject ally)
        {
            if (ally.Race != ObjectType.Monster) return false;
            if (ally.Master == null) return false;

            switch (ally.Master.Race)
            {
                case ObjectType.Player:
                    if (!ally.Master.IsFriendlyTarget(this)) return false;
                    break;
                case ObjectType.Monster:
                    return false;
            }

            return true;
        }
Beispiel #4
0
 public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
 {
     throw new NotSupportedException();
 }
Beispiel #5
0
        public override bool IsFriendlyTarget(MonsterObject ally)
        {
            if (Master != null) return false;
            if (ally.Race != ObjectType.Monster) return false;
            if (ally.Master != null) return false;

            return true;
        }
Beispiel #6
0
 public virtual void Add(MonsterObject monster)
 {
 }
Beispiel #7
0
 public virtual void Remove(MonsterObject monster)
 {
 }
Beispiel #8
0
 private void ProcessSegment(MonsterObject monster, NPCPage page, NPCSegment segment)
 {
     segment.Check(monster);
 }
Beispiel #9
0
        public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
        {
            int armour = 0;
            switch (type)
            {
                case DefenceType.ACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.AC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.MACAgility:
                    if (Envir.Random.Next(Settings.MagicResistWeight) < MagicResist) return 0;
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinMAC, MaxMAC);
                    break;
                case DefenceType.MAC:
                    if (Envir.Random.Next(Settings.MagicResistWeight) < MagicResist) return 0;
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.Agility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    break;
            }

            if (Envir.Random.Next(100) < Reflect)
            {
                attacker.Attacked(this, damage, type, false);
                CurrentMap.Broadcast(new S.ObjectEffect { ObjectID = ObjectID, Effect = SpellEffect.Reflect },CurrentLocation);
                return 0;
            }

            if (MagicShield)
                damage -= damage * (MagicShieldLv + 2) / 10;

            if (armour >= damage) return 0;

            MagicShieldTime -= (damage - armour) * 60;

            LastHitter = attacker.Master ?? attacker;
            LastHitTime = Envir.Time + 10000;
            RegenTime = Envir.Time + RegenDelay;

            DamageDura();
            ActiveBlizzard = false;

            Enqueue(new S.Struck { AttackerID = attacker.ObjectID });
            Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation });
            //
            ChangeHP(armour - damage);
            return damage - armour;
        }
Beispiel #10
0
        public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
        {
            int armour = 0;

            if (Hidden)
            {
                for (int i = 0; i < Buffs.Count; i++)
                {
                    switch (Buffs[i].Type)
                    {
                        //case BuffType.Hiding:
                        case BuffType.MoonLight:
                        case BuffType.DarkBody:
                            Buffs[i].ExpireTime = 0;
                            break;
                    }
                }
            }

            switch (type)
            {
                case DefenceType.ACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.AC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.MACAgility:
                    if (Envir.Random.Next(Settings.MagicResistWeight) < MagicResist) return 0;
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinMAC, MaxMAC);
                    break;
                case DefenceType.MAC:
                    if (Envir.Random.Next(Settings.MagicResistWeight) < MagicResist) return 0;
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.Agility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    break;
            }

            if (Envir.Random.Next(100) < Reflect)
            {
                attacker.Attacked(this, damage, type, false);
                CurrentMap.Broadcast(new S.ObjectEffect { ObjectID = ObjectID, Effect = SpellEffect.Reflect }, CurrentLocation);
                return 0;
            }

            armour = (int)Math.Max(int.MinValue, (Math.Min(int.MaxValue, (decimal)(armour * ArmourRate))));
            damage = (int)Math.Max(int.MinValue, (Math.Min(int.MaxValue, (decimal)(damage * DamageRate))));

            if (MagicShield)
                damage -= damage * (MagicShieldLv + 2) / 10;

            if (ElementalBarrier)
                damage -= damage * (ElementalBarrierLv +1 ) / 10;

            if (EnergyShield)
            {
                int shieldDamage = damage * (EnergyShieldLv + 1) / 10;
                damage -= shieldDamage;

                if (attacker.IsAttackTarget(this))
                {
                    attacker.Attacked(this, shieldDamage, type, false);
                }
            }

            if (armour >= damage) return 0;

            MagicShieldTime -= (damage - armour) * 60;

            ElementalBarrierTime -= (damage - armour) * 60;

            EnergyShieldTime -= (damage - armour) * 60;

            LastHitter = attacker.Master ?? attacker;
            LastHitTime = Envir.Time + 10000;
            RegenTime = Envir.Time + RegenDelay;
            LogTime = Envir.Time + Globals.LogDelay;

            DamageDura();
            ActiveBlizzard = false;
            ActiveReincarnation = false;

            CounterAttackCast(GetMagic(Spell.CounterAttack), LastHitter);

            Enqueue(new S.Struck { AttackerID = attacker.ObjectID });
            Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation });
            //
            ChangeHP(armour - damage);
            return damage - armour;
        }
Beispiel #11
0
        public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
        {
            int armour = 0;

            switch (type)
            {
                case DefenceType.ACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.AC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.MACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinMAC, MaxMAC);
                    break;
                case DefenceType.MAC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.Agility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    break;
            }

            if (MagicShield)
                damage -= damage * (MagicShieldLv + 2) / 10;

            if (armour >= damage) return 0;

            MagicShieldTime -= (damage - armour) * 60;

            LastHitter = attacker.Master ?? attacker;
            LastHitTime = Envir.Time + 10000;
            RegenTime = Envir.Time + RegenDelay;

            DamageDura();

            Enqueue(new S.Struck { AttackerID = attacker.ObjectID });
            Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation });
            //
            ChangeHP(armour - damage);
            return damage - armour;
        }
Beispiel #12
0
        public override void Process()
        {
            if (Decoration)
            {
                return;
            }

            if (Caster != null && Caster.Node == null)
            {
                Caster = null;
            }

            if (Envir.Time > ExpireTime || ((Spell == Spell.FireWall || Spell == Spell.Portal || Spell == Spell.ExplosiveTrap || Spell == Spell.Reincarnation) && Caster == null) || (Spell == Spell.TrapHexagon && Target != null) || (Spell == Spell.Trap && Target != null))
            {
                if (Spell == Spell.TrapHexagon && Target != null || Spell == Spell.Trap && Target != null)
                {
                    MonsterObject ob = (MonsterObject)Target;

                    if (Envir.Time < ExpireTime && ob.ShockTime != 0)
                    {
                        return;
                    }
                }

                if (Spell == Spell.Reincarnation && Caster != null)
                {
                    Caster.ReincarnationReady      = true;
                    Caster.ReincarnationExpireTime = Envir.Time + 6000;
                }

                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Spell == Spell.Reincarnation && !Caster.ActiveReincarnation)
            {
                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Spell == Spell.ExplosiveTrap && FindObject(Caster.ObjectID, 20) == null && Caster != null)
            {
                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Envir.Time < TickTime)
            {
                return;
            }
            TickTime = Envir.Time + TickSpeed;
            Tick++;
            //范围伤害
            if (Spell == Spell.MonKITO || Spell == Spell.MonFireCircle || Spell == Spell.MonRotateAxe || Spell == Spell.MonGhostFlag1 || Spell == Spell.MonGhostHead)
            {
                //范围伤害
                ProcessSpell(null);
            }
            else
            {
                //单体伤害
                for (int i = 0; i < CurrentMap.Objects[CurrentLocation.X, CurrentLocation.Y].Count; i++)
                {
                    ProcessSpell(CurrentMap.Objects[CurrentLocation.X, CurrentLocation.Y][i]);
                }
            }

            //Cell cell = CurrentMap.GetCell(CurrentLocation);
            for (int i = 0; i < CurrentMap.Objects[CurrentLocation.X, CurrentLocation.Y].Count; i++)
            {
                ProcessSpell(CurrentMap.Objects[CurrentLocation.X, CurrentLocation.Y][i]);
            }

            if ((Spell == Spell.MapLava) || (Spell == Spell.MapLightning))
            {
                Value = 0;
            }
        }
Beispiel #13
0
        public override void UseItem(ulong id)
        {
            S.UseItem p = new S.UseItem {
                UniqueID = id, Grid = MirGridType.HeroInventory, Success = false
            };

            UserItem item  = null;
            int      index = -1;

            for (int i = 0; i < Info.Inventory.Length; i++)
            {
                item = Info.Inventory[i];
                if (item == null || item.UniqueID != id)
                {
                    continue;
                }
                index = i;
                break;
            }

            if (item == null || index == -1 || !CanUseItem(item))
            {
                Owner.Enqueue(p);
                return;
            }

            if (Dead && !(item.Info.Type == ItemType.Scroll && item.Info.Shape == 6))
            {
                Owner.Enqueue(p);
                return;
            }

            switch (item.Info.Type)
            {
            case ItemType.Potion:
                switch (item.Info.Shape)
                {
                case 0:         //NormalPotion
                    PotHealthAmount = (ushort)Math.Min(ushort.MaxValue, PotHealthAmount + item.Info.Stats[Stat.HP]);
                    PotManaAmount   = (ushort)Math.Min(ushort.MaxValue, PotManaAmount + item.Info.Stats[Stat.MP]);
                    break;

                case 1:         //SunPotion
                    ChangeHP(item.Info.Stats[Stat.HP]);
                    ChangeMP(item.Info.Stats[Stat.MP]);
                    break;

                case 2:         //MysteryWater
                    if (UnlockCurse)
                    {
                        ReceiveChat("You can already unequip a cursed item.", ChatType.Hint);
                        Owner.Enqueue(p);
                        return;
                    }
                    ReceiveChat("You can now unequip a cursed item.", ChatType.Hint);
                    UnlockCurse = true;
                    break;

                case 3:         //Buff
                {
                    int time = item.Info.Durability;

                    if (item.GetTotal(Stat.MaxDC) > 0)
                    {
                        AddBuff(BuffType.Impact, this, time * Settings.Minute, new Stats {
                                [Stat.MaxDC] = item.GetTotal(Stat.MaxDC)
                            });
                    }

                    if (item.GetTotal(Stat.MaxMC) > 0)
                    {
                        AddBuff(BuffType.Magic, this, time * Settings.Minute, new Stats {
                                [Stat.MaxMC] = item.GetTotal(Stat.MaxMC)
                            });
                    }

                    if (item.GetTotal(Stat.MaxSC) > 0)
                    {
                        AddBuff(BuffType.Taoist, this, time * Settings.Minute, new Stats {
                                [Stat.MaxSC] = item.GetTotal(Stat.MaxSC)
                            });
                    }

                    if (item.GetTotal(Stat.AttackSpeed) > 0)
                    {
                        AddBuff(BuffType.Storm, this, time * Settings.Minute, new Stats {
                                [Stat.AttackSpeed] = item.GetTotal(Stat.AttackSpeed)
                            });
                    }

                    if (item.GetTotal(Stat.HP) > 0)
                    {
                        AddBuff(BuffType.HealthAid, this, time * Settings.Minute, new Stats {
                                [Stat.HP] = item.GetTotal(Stat.HP)
                            });
                    }

                    if (item.GetTotal(Stat.MP) > 0)
                    {
                        AddBuff(BuffType.ManaAid, this, time * Settings.Minute, new Stats {
                                [Stat.MP] = item.GetTotal(Stat.MP)
                            });
                    }

                    if (item.GetTotal(Stat.MaxAC) > 0)
                    {
                        AddBuff(BuffType.Defence, this, time * Settings.Minute, new Stats {
                                [Stat.MaxAC] = item.GetTotal(Stat.MaxAC)
                            });
                    }

                    if (item.GetTotal(Stat.MaxMAC) > 0)
                    {
                        AddBuff(BuffType.MagicDefence, this, time * Settings.Minute, new Stats {
                                [Stat.MaxMAC] = item.GetTotal(Stat.MaxMAC)
                            });
                    }

                    if (item.GetTotal(Stat.BagWeight) > 0)
                    {
                        AddBuff(BuffType.BagWeight, this, time * Settings.Minute, new Stats {
                                [Stat.BagWeight] = item.GetTotal(Stat.BagWeight)
                            });
                    }
                }
                break;

                case 4:         //Exp
                {
                    int time = item.Info.Durability;
                    AddBuff(BuffType.Exp, this, Settings.Minute * time, new Stats {
                            [Stat.ExpRatePercent] = item.GetTotal(Stat.Luck)
                        });
                }
                break;

                case 5:         //Drop
                {
                    int time = item.Info.Durability;
                    AddBuff(BuffType.Drop, this, Settings.Minute * time, new Stats {
                            [Stat.ItemDropRatePercent] = item.GetTotal(Stat.Luck)
                        });
                }
                break;
                }
                break;

            case ItemType.Scroll:
                UserItem temp;
                switch (item.Info.Shape)
                {
                case 3:         //BenedictionOil
                    if (!TryLuckWeapon())
                    {
                        Owner.Enqueue(p);
                        return;
                    }
                    break;

                case 4:         //RepairOil
                    temp = Info.Equipment[(int)EquipmentSlot.Weapon];
                    if (temp == null || temp.MaxDura == temp.CurrentDura)
                    {
                        Owner.Enqueue(p);
                        return;
                    }
                    if (temp.Info.Bind.HasFlag(BindMode.DontRepair))
                    {
                        Owner.Enqueue(p);
                        return;
                    }
                    temp.MaxDura = (ushort)Math.Max(0, temp.MaxDura - Math.Min(5000, temp.MaxDura - temp.CurrentDura) / 30);

                    temp.CurrentDura = (ushort)Math.Min(temp.MaxDura, temp.CurrentDura + 5000);
                    temp.DuraChanged = false;

                    ReceiveChat("Your weapon has been partially repaired", ChatType.Hint);
                    Owner.Enqueue(new S.ItemRepaired {
                        UniqueID = temp.UniqueID, MaxDura = temp.MaxDura, CurrentDura = temp.CurrentDura
                    });
                    break;

                case 5:         //WarGodOil
                    temp = Info.Equipment[(int)EquipmentSlot.Weapon];
                    if (temp == null || temp.MaxDura == temp.CurrentDura)
                    {
                        Owner.Enqueue(p);
                        return;
                    }
                    if (temp.Info.Bind.HasFlag(BindMode.DontRepair) || (temp.Info.Bind.HasFlag(BindMode.NoSRepair)))
                    {
                        Owner.Enqueue(p);
                        return;
                    }
                    temp.CurrentDura = temp.MaxDura;
                    temp.DuraChanged = false;

                    ReceiveChat("Your weapon has been completely repaired", ChatType.Hint);
                    Owner.Enqueue(new S.ItemRepaired {
                        UniqueID = temp.UniqueID, MaxDura = temp.MaxDura, CurrentDura = temp.CurrentDura
                    });
                    break;

                case 6:         //ResurrectionScroll
                    if (CurrentMap.Info.NoReincarnation)
                    {
                        ReceiveChat(string.Format("Cannot use on this map"), ChatType.System);
                        Owner.Enqueue(p);
                        return;
                    }
                    if (Dead)
                    {
                        MP = Stats[Stat.MP];
                        Revive(MaxHealth, true);
                    }
                    break;
                }
                break;

            case ItemType.Book:
                UserMagic magic = new UserMagic((Spell)item.Info.Shape);

                if (magic.Info == null)
                {
                    Owner.Enqueue(p);
                    return;
                }

                Info.Magics.Add(magic);
                SendMagicInfo(magic);
                RefreshStats();
                break;

            case ItemType.Food:
                temp = Info.Equipment[(int)EquipmentSlot.Mount];
                if (temp == null || temp.MaxDura == temp.CurrentDura)
                {
                    Owner.Enqueue(p);
                    return;
                }

                switch (item.Info.Shape)
                {
                case 0:
                    temp.MaxDura = (ushort)Math.Max(0, temp.MaxDura - Math.Min(1000, temp.MaxDura - (temp.CurrentDura / 30)));
                    break;

                case 1:
                    break;
                }

                temp.CurrentDura = (ushort)Math.Min(temp.MaxDura, temp.CurrentDura + item.CurrentDura);
                temp.DuraChanged = false;

                ReceiveChat("Your mount has been fed.", ChatType.Hint);
                Owner.Enqueue(new S.ItemRepaired {
                    UniqueID = temp.UniqueID, MaxDura = temp.MaxDura, CurrentDura = temp.CurrentDura
                });

                RefreshStats();
                break;

            case ItemType.Transform:     //Transforms
            {
                AddBuff(BuffType.Transform, this, (Settings.Second * item.Info.Durability), new Stats(), values: item.Info.Shape);
            }
            break;

            case ItemType.Deco:

                DecoObject decoOb = new DecoObject
                {
                    Image           = item.Info.Shape,
                    CurrentMap      = CurrentMap,
                    CurrentLocation = CurrentLocation,
                };

                CurrentMap.AddObject(decoOb);
                decoOb.Spawned();

                Owner.Enqueue(decoOb.GetInfo());

                break;

            case ItemType.MonsterSpawn:

                var monsterID    = item.Info.Stats[Stat.HP];
                var spawnAsPet   = item.Info.Shape == 1;
                var conquestOnly = item.Info.Shape == 2;

                var monsterInfo = Envir.GetMonsterInfo(monsterID);
                if (monsterInfo == null)
                {
                    break;
                }

                MonsterObject monster = MonsterObject.GetMonster(monsterInfo);
                if (monster == null)
                {
                    break;
                }

                if (spawnAsPet)
                {
                    if (Pets.Count(t => !t.Dead && t.Race != ObjectType.Creature) >= Globals.MaxPets)
                    {
                        ReceiveChat("Maximum number of pets already reached.", ChatType.Hint);
                        Owner.Enqueue(p);
                        return;
                    }

                    monster.Master      = this;
                    monster.PetLevel    = 0;
                    monster.MaxPetLevel = 7;

                    Pets.Add(monster);
                }

                if (conquestOnly)
                {
                    var con = CurrentMap.GetConquest(CurrentLocation);
                    if (con == null)
                    {
                        ReceiveChat(string.Format("{0} can only be spawned during a conquest.", monsterInfo.GameName), ChatType.Hint);
                        Owner.Enqueue(p);
                        return;
                    }
                }

                monster.Direction  = Direction;
                monster.ActionTime = Envir.Time + 5000;

                if (!monster.Spawn(CurrentMap, Front))
                {
                    monster.Spawn(CurrentMap, CurrentLocation);
                }
                break;

            case ItemType.SiegeAmmo:
                //TODO;
                break;

            default:
                return;
            }

            if (item.Count > 1)
            {
                item.Count--;
            }
            else
            {
                Info.Inventory[index] = null;
            }
            RefreshBagWeight();

            Report?.ItemChanged(item, 1, 1);

            p.Success = true;
            Owner.Enqueue(p);
        }
Beispiel #14
0
        public override void GainExp(uint amount)
        {
            if (!CanGainExp)
            {
                return;
            }

            if (amount == 0)
            {
                return;
            }

            if (Stats[Stat.ExpRatePercent] > 0)
            {
                amount += (uint)Math.Max(0, (amount * Stats[Stat.ExpRatePercent]) / 100);
            }

            Experience += amount;

            Owner.Enqueue(new S.GainHeroExperience {
                Amount = amount
            });

            for (int i = 0; i < Pets.Count; i++)
            {
                MonsterObject monster = Pets[i];
                if (monster.CurrentMap == CurrentMap && Functions.InRange(monster.CurrentLocation, CurrentLocation, Globals.DataRange) && !monster.Dead)
                {
                    monster.PetExp(amount);
                }
            }

            if (Experience < MaxExperience)
            {
                return;
            }
            if (Level >= ushort.MaxValue)
            {
                return;
            }

            //Calculate increased levels
            var experience = Experience;

            while (experience >= MaxExperience)
            {
                Level++;
                experience -= MaxExperience;

                RefreshLevelStats();

                if (Level >= ushort.MaxValue)
                {
                    break;
                }
            }

            Experience = experience;

            LevelUp();
        }
Beispiel #15
0
        public void RangeAttack(MonsterObject _target)
        {
            if (_target == null) return;
            if (!uniqueAI.IgnorePets) RangeAttackDamage += DamageToPets;
            else FindTarget();
            Direction = Functions.DirectionFromPoint(CurrentLocation, _target.CurrentLocation);

            AttackTime = Envir.Time + AttackSpeed + 500;
            Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation });
            if (RangeAttackDamage == 0) return;
            switch (uniqueAI.RangeAttackEffect)
            {
                case 1: // needs to be changed
                    Broadcast(new S.ObjectEffect { ObjectID = _target.ObjectID, Effect = SpellEffect.Entrapment });
                    break;
                case 2: // FireWorks
                    Broadcast(new S.ObjectEffect { ObjectID = _target.ObjectID, Effect = SpellEffect.GreatFoxSpirit });
                    break;
                default:
                    break;
            }

            DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + 500, _target, RangeAttackDamage, DefenceType.AC);
            ActionList.Add(action);
            RangeAttackDamage = uniqueAI.RangeAttackDamage;
        }
Beispiel #16
0
        public void KilledMonster(MonsterObject obj, string info = "", [CallerMemberName] string source = "")
        {
            string message = $"Killed Monster {obj.Name} {info}";

            LogMessage(message, source);
        }
Beispiel #17
0
        public void KilledMonster(string source, MonsterObject obj, string info = "")
        {
            string task = string.Format("Killed Monster {0}", obj.Name);

            Action action = new Action { Source = source, Task = task, AddedInfo = info };

            RecordAction(action);
        }
Beispiel #18
0
        public void BroadcastHealthChange()
        {
            if (Race != ObjectType.Player && Race != ObjectType.Monster)
            {
                return;
            }

            byte   time = Math.Min(byte.MaxValue, (byte)Math.Max(5, (RevTime - Envir.Time) / 1000));
            Packet p    = new S.ObjectHealth {
                ObjectID = ObjectID, Percent = PercentHealth, Expire = time
            };

            if (Envir.Time < RevTime)
            {
                CurrentMap.Broadcast(p, CurrentLocation);
                return;
            }



            if (Race == ObjectType.Monster)
            {
                MonsterObject monster = (MonsterObject)this;

                if (monster.Info.Class == MonsterClass.Boss)
                {
                    CurrentMap.Broadcast(p, CurrentLocation);
                }
            }

            if (Race == ObjectType.Monster && !AutoRev && Master == null)
            {
                return;
            }

            if (Race == ObjectType.Player)
            {
                if (GroupMembers != null) //Send HP to group
                {
                    for (int i = 0; i < GroupMembers.Count; i++)
                    {
                        PlayerObject member = GroupMembers[i];

                        if (this == member)
                        {
                            continue;
                        }
                        if (member.CurrentMap != CurrentMap || !Functions.InRange(member.CurrentLocation, CurrentLocation, Globals.DataRange))
                        {
                            continue;
                        }
                        member.Enqueue(p);
                    }
                }

                return;
            }

            if (Master != null && Master.Race == ObjectType.Player)
            {
                PlayerObject player = (PlayerObject)Master;

                player.Enqueue(p);

                if (player.GroupMembers != null) //Send pet HP to group
                {
                    for (int i = 0; i < player.GroupMembers.Count; i++)
                    {
                        PlayerObject member = player.GroupMembers[i];

                        if (player == member)
                        {
                            continue;
                        }

                        if (member.CurrentMap != CurrentMap || !Functions.InRange(member.CurrentLocation, CurrentLocation, Globals.DataRange))
                        {
                            continue;
                        }
                        member.Enqueue(p);
                    }
                }
            }


            if (EXPOwner != null && EXPOwner.Race == ObjectType.Player)
            {
                PlayerObject player = (PlayerObject)EXPOwner;

                if (player.IsMember(Master))
                {
                    return;
                }

                player.Enqueue(p);

                if (player.GroupMembers != null)
                {
                    for (int i = 0; i < player.GroupMembers.Count; i++)
                    {
                        PlayerObject member = player.GroupMembers[i];

                        if (player == member)
                        {
                            continue;
                        }
                        if (member.CurrentMap != CurrentMap || !Functions.InRange(member.CurrentLocation, CurrentLocation, Globals.DataRange))
                        {
                            continue;
                        }
                        member.Enqueue(p);
                    }
                }
            }
        }
Beispiel #19
0
 public abstract bool IsAttackTarget(MonsterObject attacker);
Beispiel #20
0
        public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
        {
            if (Target == null && attacker.IsAttackTarget(this))
                Target = attacker;

            int armour = 0;

            switch (type)
            {
                case DefenceType.ACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.AC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.MACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    armour = GetAttackPower(MinMAC, MaxMAC);
                    break;
                case DefenceType.MAC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.Agility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0;
                    break;
            }

            armour = (int)(armour * PoisonRate);

            if (armour >= damage) return 0;

            if (Target != this && attacker.IsAttackTarget(this))
                Target = attacker;

            ShockTime = 0;

            if (attacker.Info.AI == 6)
                EXPOwner = null;

            else if (attacker.Master != null)
            {
                if (!Functions.InRange(attacker.CurrentLocation, attacker.Master.CurrentLocation, Globals.DataRange))
                    EXPOwner = null;
                else
                {

                    if (EXPOwner == null || EXPOwner.Dead)
                        EXPOwner = attacker.Master;

                    if (EXPOwner == attacker.Master)
                        EXPOwnerTime = Envir.Time + EXPOwnerDelay;
                }

            }

            Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation });

            ChangeHP(armour - damage);
            return damage - armour;
        }
 public override bool IsAttackTarget(MonsterObject attacker)
 {
     return false;
 }
Beispiel #22
0
 public override bool IsAttackTarget(MonsterObject attacker)
 {
     return(false);
 }
Beispiel #23
0
 public override bool IsFriendlyTarget(MonsterObject ally)
 {
     throw new NotSupportedException();
 }
Beispiel #24
0
 public override bool IsFriendlyTarget(MonsterObject ally)
 {
     return(true);
 }
Beispiel #25
0
        protected virtual void FindTarget()
        {
            Map Current = CurrentMap;

            for (int d = 0; d <= ViewRange; d++)
            {
                for (int y = CurrentLocation.Y - d; y <= CurrentLocation.Y + d; y++)
                {
                    if (y < 0)
                    {
                        continue;
                    }
                    if (y >= Current.Height)
                    {
                        break;
                    }

                    for (int x = CurrentLocation.X - d; x <= CurrentLocation.X + d; x += Math.Abs(y - CurrentLocation.Y) == d ? 1 : d * 2)
                    {
                        if (x < 0)
                        {
                            continue;
                        }
                        if (x >= Current.Width)
                        {
                            break;
                        }
                        Cell cell = Current.Cells[x, y];
                        if (cell.Objects == null || !cell.Valid)
                        {
                            continue;
                        }
                        for (int i = 0; i < cell.Objects.Count; i++)
                        {
                            MapObject ob = cell.Objects[i];
                            switch (ob.Race)
                            {
                            case ObjectType.Monster:
                            case ObjectType.Hero:
                                if (ob is TownArcher)
                                {
                                    continue;
                                }
                                if (!ob.IsAttackTarget(Owner))
                                {
                                    continue;
                                }
                                if (ob.Hidden && (!CoolEye || Level < ob.Level))
                                {
                                    continue;
                                }
                                if (ob.Master != null && Target != ob)
                                {
                                    continue;
                                }
                                if (Owner.Info.HeroBehaviour == HeroBehaviour.CounterAttack && ob.Target != this && ob.Target != Owner)
                                {
                                    continue;
                                }

                                Target = ob;
                                return;

                            case ObjectType.Player:
                                PlayerObject playerob = (PlayerObject)ob;
                                if (!ob.IsAttackTarget(Owner))
                                {
                                    continue;
                                }
                                if (playerob.GMGameMaster || ob.Hidden && (!CoolEye || Level < ob.Level))
                                {
                                    continue;
                                }
                                if (Target != ob && Owner.LastHitter != ob && ob.LastHitter != Owner)
                                {
                                    continue;
                                }

                                Target = ob;

                                if (Owner != null)
                                {
                                    for (int j = 0; j < playerob.Pets.Count; j++)
                                    {
                                        MonsterObject pet = playerob.Pets[j];

                                        if (!pet.IsAttackTarget(this))
                                        {
                                            continue;
                                        }
                                        Target = pet;
                                        break;
                                    }
                                }
                                return;

                            default:
                                continue;
                            }
                        }
                    }
                }
            }
        }
Beispiel #26
0
 public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
 {
     return(0);
 }
        public override bool IsAttackTarget(MonsterObject attacker)
        {
            if (attacker == null || attacker.Node == null) return false;
            if (Dead || attacker.Master == this || GMGameMaster) return false;
            if (attacker.Info.AI == 6 || attacker.Info.AI == 58) return PKPoints >= 200;
            if (attacker.Master == null) return true;
            if (InSafeZone || attacker.Master.InSafeZone) return false;

            if (LastHitter != attacker.Master && attacker.Master.LastHitter != this)
            {
                bool target = false;

                for (int i = 0; i < attacker.Master.Pets.Count; i++)
                {
                    if (attacker.Master.Pets[i].Target != this) continue;

                    target = true;
                    break;
                }

                if (!target)
                    return false;
            }

            switch (attacker.Master.AMode)
            {
                case AttackMode.All:
                    return true;
                case AttackMode.Group:
                    return GroupMembers == null || !GroupMembers.Contains(attacker.Master);
                case AttackMode.Guild:
                    return true;
                case AttackMode.EnemyGuild:
                    return false;
                case AttackMode.Peace:
                    return false;
                case AttackMode.RedBrown:
                    return PKPoints >= 200 || Envir.Time < BrownTime;
            }

            return true;

        }
Beispiel #28
0
        public override void Process()
        {
            if (Decoration)
            {
                return;
            }

            if (Caster != null && Caster.Node == null)
            {
                Caster = null;
            }

            if (Envir.Time > ExpireTime || ((Spell == Spell.FireWall || Spell == Spell.Portal || Spell == Spell.ExplosiveTrap || Spell == Spell.Reincarnation) && Caster == null) || (Spell == Spell.TrapHexagon && Target != null) || (Spell == Spell.Trap && Target != null))
            {
                if (Spell == Spell.TrapHexagon && Target != null || Spell == Spell.Trap && Target != null)
                {
                    MonsterObject ob = (MonsterObject)Target;

                    if (Envir.Time < ExpireTime && ob.ShockTime != 0)
                    {
                        return;
                    }
                }

                if (Spell == Spell.Reincarnation && Caster != null)
                {
                    Caster.ReincarnationReady      = true;
                    Caster.ReincarnationExpireTime = Envir.Time + 6000;
                }

                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Spell == Spell.Reincarnation && !Caster.ActiveReincarnation)
            {
                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Spell == Spell.ExplosiveTrap && Caster != null && !Functions.InRange(CurrentLocation, Caster.CurrentLocation, 15))
            {
                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Envir.Time < TickTime)
            {
                return;
            }
            TickTime = Envir.Time + TickSpeed;

            Cell cell = CurrentMap.GetCell(CurrentLocation);

            for (int i = 0; i < cell.Objects.Count; i++)
            {
                ProcessSpell(cell.Objects[i]);
            }

            if ((Spell == Spell.MapLava) || (Spell == Spell.MapLightning))
            {
                Value = 0;
            }
        }
        public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
        {
            int armour = 0;

            if (Hidden)
            {
                for (int i = 0; i < Buffs.Count; i++)
                {
                    switch (Buffs[i].Type)
                    {
                        //case BuffType.Hiding:
                        case BuffType.MoonLight:
                        case BuffType.DarkBody:
                            Buffs[i].ExpireTime = 0;
                            break;
                        case BuffType.EnergyShield:
                            int rate = Buffs[i].Values[0];

                            if (Envir.Random.Next(rate < 2 ? 2 : rate) == 0)
                            {
                                if (HP + ((ushort)Buffs[i].Values[1]) >= MaxHP)
                                    SetHP(MaxHP);
                                else
                                    ChangeHP(Buffs[i].Values[1]);
                            }
                            break;
                    }
                }
            }

            switch (type)
            {
                case DefenceType.ACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy)
                    {
                        BroadcastDamageIndicator(DamageType.Miss);
                        return 0;
                    }
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.AC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.MACAgility:
                    if (Envir.Random.Next(Settings.MagicResistWeight) < MagicResist)
                    {
                        BroadcastDamageIndicator(DamageType.Miss);
                        return 0;
                    }
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy)
                    {
                        return 0;
                    }
                    armour = GetAttackPower(MinMAC, MaxMAC);
                    break;
                case DefenceType.MAC:
                    if (Envir.Random.Next(Settings.MagicResistWeight) < MagicResist)
                    {
                        BroadcastDamageIndicator(DamageType.Miss);
                        return 0;
                    }
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.Agility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy)
                    {
                        BroadcastDamageIndicator(DamageType.Miss);
                        return 0;
                    }
                    break;
            }

            if (Envir.Random.Next(100) < Reflect)
            {
                attacker.Attacked(this, damage, type, false);
                CurrentMap.Broadcast(new S.ObjectEffect { ObjectID = ObjectID, Effect = SpellEffect.Reflect }, CurrentLocation);
                return 0;
            }

            armour = (int)Math.Max(int.MinValue, (Math.Min(int.MaxValue, (decimal)(armour * ArmourRate))));
            damage = (int)Math.Max(int.MinValue, (Math.Min(int.MaxValue, (decimal)(damage * DamageRate))));

            if (MagicShield)
                damage -= damage * (MagicShieldLv + 2) / 10;

            if (ElementalBarrier)
                damage -= damage * (ElementalBarrierLv + 1) / 10;

            if (armour >= damage)
            {
                BroadcastDamageIndicator(DamageType.Miss);
                return 0;
            }

            if (MagicShield)
            {
                MagicShieldTime -= (damage - armour) * 60;
                AddBuff(new Buff { Type = BuffType.MagicShield, Caster = this, ExpireTime = MagicShieldTime });
            }

            ElementalBarrierTime -= (damage - armour) * 60;

            for (int i = PoisonList.Count - 1; i >= 0; i--)
            {
                if (PoisonList[i].PType != PoisonType.LRParalysis) continue;

                PoisonList.RemoveAt(i);
                OperateTime = 0;
            }

            LastHitter = attacker.Master ?? attacker;
            LastHitTime = Envir.Time + 10000;
            RegenTime = Envir.Time + RegenDelay;
            LogTime = Envir.Time + Globals.LogDelay;

            DamageDura();
            ActiveBlizzard = false;
            ActiveReincarnation = false;

            CounterAttackCast(GetMagic(Spell.CounterAttack), LastHitter);

            Enqueue(new S.Struck { AttackerID = attacker.ObjectID });
            Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation });

            BroadcastDamageIndicator(DamageType.Hit, armour - damage);

            ChangeHP(armour - damage);
            return damage - armour;
        }
Beispiel #30
0
 public override bool IsAttackTarget(MonsterObject attacker)
 {
     throw new NotSupportedException();
 }
Beispiel #31
0
 public void MassAttack(MonsterObject _target)
 {
     if (_target == null) return;
     switch (uniqueAI.MassAttackEffect)
     {
         case 2:
             Broadcast(new S.ObjectEffect { ObjectID = _target.ObjectID, Effect = SpellEffect.GreatFoxSpirit });
             break;
         default:
             break;
     }
     _target.Attacked(this, MassAttackDamage, DefenceType.None);
 }
Beispiel #32
0
 public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
 {
     throw new NotSupportedException();
 }
Beispiel #33
0
        public void MeleeAttack(MonsterObject _target)
        {
            if (_target == null) return;
            if (!uniqueAI.IgnorePets)
                MeleeAttackDamage += DamageToPets;
            else
                return;
            Direction = Functions.DirectionFromPoint(CurrentLocation, _target.CurrentLocation);
            Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation });
            if (MeleeAttackDamage == 0) return;

            if (uniqueAI != null && uniqueAI.MeleeAttackEffect > 0)
            {
                switch (uniqueAI.MeleeAttackEffect)
                {
                    case 1: // Effect 1
                        Broadcast(new S.ObjectEffect { ObjectID = _target.ObjectID, Effect = SpellEffect.Entrapment });
                        break;
                    case 2: // Effect 2
                        Broadcast(new S.ObjectEffect { ObjectID = _target.ObjectID, Effect = SpellEffect.GreatFoxSpirit });
                        break;
                    default:
                        break;
                }
            }

            _target.Attacked(this, MeleeAttackDamage, DefenceType.ACAgility);
            if (_target.Dead)
                FindTarget();
            MeleeAttackDamage = uniqueAI.MeleeAttackDamage;
        }
Beispiel #34
0
 public override bool IsFriendlyTarget(MonsterObject ally)
 {
     throw new NotSupportedException();
 }
Beispiel #35
0
 public PetInfo(MonsterObject ob)
 {
     MonsterIndex = ob.Info.Index;
     HP = ob.HP;
     Experience = ob.PetExperience;
     Level = ob.PetLevel;
     MaxPetLevel = ob.MaxPetLevel;
 }
Beispiel #36
0
 public virtual void Remove(MonsterObject monster)
 {
 }
Beispiel #37
0
 public abstract int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility);
Beispiel #38
0
 public virtual void Add(MonsterObject monster)
 {
 }
Beispiel #39
0
 public abstract bool IsFriendlyTarget(MonsterObject ally);
Beispiel #40
0
 public abstract bool IsAttackTarget(MonsterObject attacker);
 public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
 {
     return 0;
 }
Beispiel #42
0
 public abstract int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility);
 public override bool IsFriendlyTarget(MonsterObject ally)
 {
     return true;
 }
Beispiel #44
0
 public abstract bool IsFriendlyTarget(MonsterObject ally);
Beispiel #45
0
 public override bool IsAttackTarget(MonsterObject attacker)
 {
     throw new NotSupportedException();
 }
 public override void Remove(MonsterObject monster)
 {
     Enqueue(new S.ObjectRemove { ObjectID = monster.ObjectID });
 }
Beispiel #47
0
        public override bool IsAttackTarget(MonsterObject attacker)
        {
            if (attacker == null || attacker.Node == null) return false;
            if (Dead || attacker == this) return false;

            if (attacker.Info.AI == 6) // Guard
            {
                if (Info.AI != 1 && Info.AI != 2 && Info.AI != 3 && (Master == null || Master.PKPoints >= 200)) //Not Dear/Hen/Tree/Pets or Red Master
                    return true;
            }
            else if (attacker.Info.AI == 58) // Tao Guard - attacks Pets
            {
                if (Info.AI != 1 && Info.AI != 2 && Info.AI != 3) //Not Dear/Hen/Tree
                    return true;
            }
            else if (Master != null) //Pet Attacked
            {
                if (attacker.Master == null) //Wild Monster
                    return true;

                //Pet Vs Pet
                if (Master == attacker.Master)
                    return false;

                if (Envir.Time < ShockTime) //Shocked
                    return false;

                if (Master.Race == ObjectType.Player && attacker.Master.Race == ObjectType.Player && (Master.InSafeZone || attacker.Master.InSafeZone)) return false;

                switch (attacker.Master.AMode)
                {
                    case AttackMode.Group:
                        if (Master.GroupMembers != null && Master.GroupMembers.Contains((PlayerObject)attacker.Master)) return false;
                        break;
                    case AttackMode.Guild:
                        break;
                    case AttackMode.EnemyGuild:
                        break;
                    case AttackMode.RedBrown:
                        if (attacker.Master.PKPoints < 200 || Envir.Time > attacker.Master.BrownTime) return false;
                        break;
                    case AttackMode.Peace:
                        return false;
                }

                for (int i = 0; i < Master.Pets.Count; i++)
                    if (Master.Pets[i].EXPOwner == attacker.Master) return true;

                return Master.LastHitter == attacker.Master;
            }
            else if (attacker.Master != null) //Pet Attacking Wild Monster
            {
                if (Envir.Time < ShockTime) //Shocked
                    return false;

                for (int i = 0; i < attacker.Master.Pets.Count; i++)
                {
                    MonsterObject ob = attacker.Master.Pets[i];
                    if (ob == Target || ob.Target == this) return true;
                }

                if (Target == attacker.Master )
                    return true;
            }

            if (Envir.Time < attacker.HallucinationTime) return true;

            return Envir.Time < attacker.RageTime;
        }
        public override void Add(MonsterObject monster)
        {
            Enqueue(monster.GetInfo());

            monster.SendHealth(this);
        }
Beispiel #49
0
        public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility)
        {
            if (Target == null && attacker.IsAttackTarget(this))
                Target = attacker;

            int armour = 0;

            switch (type)
            {
                case DefenceType.ACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy)
                    {
                        BroadcastDamageIndicator(DamageType.Miss);
                        return 0;
                    }
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.AC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.MACAgility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy)
                    {
                        BroadcastDamageIndicator(DamageType.Miss);
                        return 0;
                    }
                    armour = GetAttackPower(MinMAC, MaxMAC);
                    break;
                case DefenceType.MAC:
                    armour = GetAttackPower(MinAC, MaxAC);
                    break;
                case DefenceType.Agility:
                    if (Envir.Random.Next(Agility + 1) > attacker.Accuracy)
                    {
                        BroadcastDamageIndicator(DamageType.Miss);
                        return 0;
                    }
                    break;
            }

            armour = (int)Math.Max(int.MinValue, (Math.Min(int.MaxValue, (decimal)(armour * ArmourRate))));
            damage = (int)Math.Max(int.MinValue, (Math.Min(int.MaxValue, (decimal)(damage * DamageRate))));

            if (armour >= damage)
            {
                BroadcastDamageIndicator(DamageType.Miss);
                return 0;
            }

            if (Target != this && attacker.IsAttackTarget(this))
                Target = attacker;

            if (BindingShotCenter) ReleaseBindingShot();
            ShockTime = 0;

            if (attacker.Info.AI == 6 || attacker.Info.AI == 58)
                EXPOwner = null;

            else if (attacker.Master != null)
            {
                if (!Functions.InRange(attacker.CurrentLocation, attacker.Master.CurrentLocation, Globals.DataRange))
                    EXPOwner = null;
                else
                {

                    if (EXPOwner == null || EXPOwner.Dead)
                        EXPOwner = attacker.Master;

                    if (EXPOwner == attacker.Master)
                        EXPOwnerTime = Envir.Time + EXPOwnerDelay;
                }

            }

            Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation });

            BroadcastDamageIndicator(DamageType.Hit, armour - damage);

            ChangeHP(armour - damage);
            return damage - armour;
        }
Beispiel #50
0
        public override void Process()
        {
            if (Decoration)
            {
                return;
            }
            if (LMS_Circle)
            {
                if (Envir.Time > ExpireTime)
                {
                    CurrentMap.RemoveObject(this);
                    Despawn();
                }
                return;
            }
            if (Caster == null && MobCaster == null)
            {
                return;
            }
            if (Caster != null && Caster.Node == null)
            {
                Caster = null;
            }
            if (MobCaster != null && MobCaster.Node == null)
            {
                MobCaster = null;
            }
            if (
                (
                    MobCaster == null && Caster == null
                    &&
                    (
                        Spell == Spell.FireWall ||
                        Spell == Spell.HealingCircle ||
                        Spell == Spell.Portal ||
                        Spell == Spell.ExplosiveTrap ||
                        Spell == Spell.Reincarnation ||
                        Spell == Spell.MobFireWall ||
                        Spell == Spell.MobBlizzard ||
                        Spell == Spell.MobMeteorStrike ||
                        Spell == Spell.MobPoisonCloud ||
                        Spell == Spell.MeteorStrike ||
                        Spell == Spell.LavaKing ||
                        Spell == Spell.Blizzard ||
                        Spell == Spell.FrozenRains ||
                        Spell == Spell.MoonMist
                    )
                )
                ||
                (Envir.Time > ExpireTime) || (Spell == Spell.Trap && Target != null))
            {
                if (Spell == Spell.TrapHexagon && Target != null || Spell == Spell.Trap && Target != null)
                {
                    MonsterObject ob = (MonsterObject)Target;

                    if (Envir.Time < ExpireTime && ob.ShockTime != 0)
                    {
                        return;
                    }
                }
                if (MobCaster is HeroObject tmp)
                {
                    if (tmp != null)
                    {
                        tmp.LavaKingCasting = false;
                    }
                }
                if (Spell == Spell.Reincarnation && Caster != null)
                {
                    Caster.ReincarnationReady      = true;
                    Caster.ReincarnationExpireTime = Envir.Time + 6000;
                }

                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }


            if (Spell == Spell.Reincarnation && !Caster.ActiveReincarnation)
            {
                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Spell == Spell.ExplosiveTrap && FindObject(Caster.ObjectID, 20) == null && Caster != null)
            {
                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Spell == Spell.FireWall && FindObject(Caster.ObjectID, 12) == null && Caster != null)  // Ice Firewall last time.
            {
                CurrentMap.RemoveObject(this);
                Despawn();
                return;
            }

            if (Envir.Time < TickTime)
            {
                return;
            }
            TickTime = Envir.Time + TickSpeed;

            Cell cell = CurrentMap.GetCell(CurrentLocation);

            for (int i = 0; i < cell.Objects.Count; i++)
            {
                ProcessSpell(cell.Objects[i]);
            }

            if ((Spell == Spell.MapLava) || (Spell == Spell.MapLightning))
            {
                Value = 0;
            }
        }