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; }
public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility) { throw new NotSupportedException(); }
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; }
public virtual void Add(MonsterObject monster) { }
public virtual void Remove(MonsterObject monster) { }
private void ProcessSegment(MonsterObject monster, NPCPage page, NPCSegment segment) { segment.Check(monster); }
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; }
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; }
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; }
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; } }
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); }
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(); }
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; }
public void KilledMonster(MonsterObject obj, string info = "", [CallerMemberName] string source = "") { string message = $"Killed Monster {obj.Name} {info}"; LogMessage(message, source); }
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); }
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); } } } }
public abstract bool IsAttackTarget(MonsterObject attacker);
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; }
public override bool IsAttackTarget(MonsterObject attacker) { return(false); }
public override bool IsFriendlyTarget(MonsterObject ally) { throw new NotSupportedException(); }
public override bool IsFriendlyTarget(MonsterObject ally) { return(true); }
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; } } } } } }
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; }
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; }
public override bool IsAttackTarget(MonsterObject attacker) { throw new NotSupportedException(); }
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); }
public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility) { throw new NotSupportedException(); }
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; }
public override bool IsFriendlyTarget(MonsterObject ally) { throw new NotSupportedException(); }
public PetInfo(MonsterObject ob) { MonsterIndex = ob.Info.Index; HP = ob.HP; Experience = ob.PetExperience; Level = ob.PetLevel; MaxPetLevel = ob.MaxPetLevel; }
public virtual void Remove(MonsterObject monster) { }
public abstract int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility);
public virtual void Add(MonsterObject monster) { }
public abstract bool IsFriendlyTarget(MonsterObject ally);
public abstract bool IsAttackTarget(MonsterObject attacker);
public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility) { return 0; }
public abstract int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility);
public override bool IsFriendlyTarget(MonsterObject ally) { return true; }
public abstract bool IsFriendlyTarget(MonsterObject ally);
public override bool IsAttackTarget(MonsterObject attacker) { throw new NotSupportedException(); }
public override void Remove(MonsterObject monster) { Enqueue(new S.ObjectRemove { ObjectID = monster.ObjectID }); }
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); }
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; }
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; } }