public override void Die() { if (Dead) { return; } explosionDie(); HP = 0; Dead = true; //DeadTime = Envir.Time + DeadDelay; DeadTime = 0; Broadcast(new S.ObjectDied { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = (byte)2 }); if (EXPOwner != null && Master == null && EXPOwner.Race == ObjectType.Player) { EXPOwner.WinExp(Experience); } if (Respawn != null) { Respawn.Count--; } PoisonList.Clear(); Envir.MonsterCount--; CurrentMap.MonsterCount--; }
public override void PoisonDamage(int damage, MapObject attacker) { damage = damage * (-1); if (attacker == null || (attacker is MonsterObject && attacker.Master == null)) { return; } if (_currentAttacker != null && (_currentAttacker != attacker || _currentAttacker != attacker.Master)) { //OutputAverage(); //ResetStats(); } if (_currentAttacker == null) { _StartTime = Envir.Time; } _currentAttacker = attacker is MonsterObject ? (PlayerObject)attacker.Master : (PlayerObject)attacker; _hitCount++; _totalDamage += damage; _lastAttackTime = Envir.Time; long timespend = Math.Max(1000, (Envir.Time - _StartTime));//avoid division by 0 if (_StartTime == 0) { timespend = 1000; } double Dps = _totalDamage / (timespend * 0.001); _currentAttacker.ReceiveChat(string.Format("{1} 造成 {0} 伤害, 秒均伤害: {2:#.00}.", damage, attacker is MonsterObject ? "你宠物的毒" : "你的毒", Dps), ChatType.Trainer); //Poisoned = true; PoisonList.Clear(); }
protected override void ProcessAI() { //狂暴计算 if (!Dead && Envir.Time > ProcessTime) { ProcessTime = Envir.Time + 1000; byte __stage = _stage; if (Envir.Time > fireTime) { _stage = 0; } // if (Envir.Time > AttackTime && _stage == 0 && RandomUtils.Next(100) < 10) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); PoisonList.Clear(); _stage = 1; fireTime = Envir.Time + RandomUtils.Next(5, 12) * 1000; ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); } if (__stage != _stage) { Broadcast(GetInfo()); } } base.ProcessAI(); }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 500; //50 MS per Step DelayedAction action = null; int rd = RandomUtils.Next(100); if (rd < 65) { //吸血 Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MAC); ActionList.Add(action); } else if (rd < 80 && PoisonList.Count > 0) { //治愈 Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Target = Target.CurrentLocation, Location = CurrentLocation, Type = 2 }); PoisonList.Clear(); //血量恢复 ChangeHP(damage * 2); //5-10秒内无法中毒 _stage = 1; fireTime = Envir.Time + RandomUtils.Next(5, 15) * 1000; } else { //毒云 Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Target = Target.CurrentLocation, Location = CurrentLocation, Type = 1 }); action = new DelayedAction(DelayedType.RangeDamage, Envir.Time + 1000, Target, damage * 3 / 2, DefenceType.MAC, Target.CurrentLocation); ActionList.Add(action); action = new DelayedAction(DelayedType.RangeDamage, Envir.Time + 1800, Target, damage * 3 / 2, DefenceType.MAC, Target.CurrentLocation); ActionList.Add(action); action = new DelayedAction(DelayedType.RangeDamage, Envir.Time + 2500, Target, damage * 3 / 2, DefenceType.MAC, Target.CurrentLocation); ActionList.Add(action); } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
public override int Attacked(PlayerObject attacker, int damage, DefenceType type = DefenceType.ACAgility, bool damageWeapon = true) { int armour = 0; switch (type) { case DefenceType.ACAgility: if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0; armour = GetDefencePower(MinAC, MaxAC); break; case DefenceType.AC: armour = GetDefencePower(MinAC, MaxAC); break; case DefenceType.MACAgility: if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0; armour = GetDefencePower(MinMAC, MaxMAC); break; case DefenceType.MAC: armour = GetDefencePower(MinAC, MaxAC); break; case DefenceType.Agility: if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0; break; } if (armour >= damage) return 0; if (damageWeapon) attacker.DamageWeapon(); ShockTime = 0; for (int i = PoisonList.Count - 1; i >= 0; i--) { if (PoisonList[i].PType != PoisonType.LRParalysis) continue; PoisonList.RemoveAt(i); OperateTime = 0; } if (Master != null && Master != attacker) if (Envir.Time > Master.BrownTime && Master.PKPoints < 200) attacker.BrownTime = Envir.Time + Settings.Minute; if (EXPOwner == null || EXPOwner.Dead) EXPOwner = attacker; if (EXPOwner == attacker) EXPOwnerTime = Envir.Time + EXPOwnerDelay; Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation }); attacker.GatherElement(); ChangeHP(-1); return 1; }
private void ResetStats() { _currentAttacker = null; _hitCount = 0; _totalDamage = 0; _lastAttackTime = 0; _StartTime = 0; Poisoned = false; PoisonList.Clear(); }
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 = GetDefencePower(MinAC, MaxAC); break; case DefenceType.AC: armour = GetDefencePower(MinAC, MaxAC); break; case DefenceType.MACAgility: if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0; armour = GetDefencePower(MinMAC, MaxMAC); break; case DefenceType.MAC: armour = GetDefencePower(MinAC, MaxAC); break; case DefenceType.Agility: if (Envir.Random.Next(Agility + 1) > attacker.Accuracy) return 0; break; } if (armour >= damage) return 0; ShockTime = 0; for (int i = PoisonList.Count - 1; i >= 0; i--) { if (PoisonList[i].PType != PoisonType.LRParalysis) continue; PoisonList.RemoveAt(i); OperateTime = 0; } if (attacker.Info.AI == 6) EXPOwner = null; else if (attacker.Master != null) { 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(-1); return 1; }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 500; //50 MS per Step DelayedAction action = null; if (RandomUtils.Next(100) < 65) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MAC); ActionList.Add(action); if (RandomUtils.Next(Settings.PoisonResistWeight) >= Target.PoisonResist && RandomUtils.Next(100) < 40) { Target.ApplyPoison(new Poison { Owner = this, Duration = damage / 10, PType = PoisonType.Green, Value = damage / 10, TickSpeed = 2000 }, this); } } else { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); PoisonList.Clear(); if (Target.PoisonList.Count > 0) { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage * 2, DefenceType.MAC); ActionList.Add(action); } else { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MAC); ActionList.Add(action); } } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 750; //50 MS per Step int rd = 10; if (HP < MaxHP / 2) { rd = 4; } if (PoisonList != null && PoisonList.Count > 0) { rd = 3; } if (RandomUtils.Next(rd) == 0) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); //攻击并回血,解毒 DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.ACAgility); ActionList.Add(action); //血量恢复 ChangeHP(damage / 2); //解除中毒 PoisonList.Clear(); } else { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); DelayedAction action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.ACAgility); ActionList.Add(action); } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
public override void Process() { base.Process(); if (Dead || SEnvir.Now < ShockTime) { return; } if (SEnvir.Now <= VisibleTime) { return; } VisibleTime = SEnvir.Now.AddSeconds(3); bool visible = Target != null && (Functions.InRange(Target.CurrentLocation, CurrentLocation, Visible ? HideRange : FindRange) || (Visible && InAttackRange())); if (!Visible && visible) { Visible = true; CellTime = SEnvir.Now.AddMilliseconds(500); ActionTime = SEnvir.Now.AddSeconds(1); AddAllObjects(); Broadcast(new S.ObjectShow { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation }); } if (Visible && !visible && CanAttack) { Visible = false; VisibleTime = SEnvir.Now.AddSeconds(4); Broadcast(new S.ObjectHide { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation }); ActionList.Add(new DelayedAction(SEnvir.Now.AddMilliseconds(3000), ActionType.Function)); SetHP(MaximumHP); PoisonList.Clear(); } }
public override void UpdateMoveTime() { if (!Visible) { MoveTime = SEnvir.Now.AddMilliseconds(20); ActionTime = SEnvir.Now.AddMilliseconds(20); } else { MoveTime = SEnvir.Now.AddMilliseconds(MoveDelay); ActionTime = SEnvir.Now.AddMilliseconds(Math.Min(MoveDelay - 100, AttackDelay)); Poison poison = PoisonList.FirstOrDefault(x => x.Type == PoisonType.Slow); if (poison != null) { AttackTime += TimeSpan.FromMilliseconds(poison.Value * 100); ActionTime += TimeSpan.FromMilliseconds(poison.Value * 100); } } }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); if (_stage == 1) { damage = damage * 13 / 10; } int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 500; //50 MS per Step DelayedAction action = null; _actime++; if (_actime > 1000) { _actime = 1; } byte p_atype = atype;//上一次攻击的类型 atype = 0; if (distance <= 2) { if (RandomUtils.Next(100) < 70) { atype = 1; } else { atype = 2; } } else { atype = 6; } //护盾 if (this.HP < this.MaxHP * 3 / 5 && RandomUtils.Next(100) < 20 && Envir.Time > protectTime) { atype = 4; } //瞬移 if (this.HP < this.MaxHP / 5 && RandomUtils.Next(100) < 30 && Envir.Time > protectTime && _TeleportTime < MaxTeleportTime) { atype = 5; } //放完鬼头后,下次攻击放麻痹或者减速 if (_actime % 10 == 0) { atype = 3; } if (p_atype == 3) { if (distance > 3) { atype = 6; } else { atype = 2; } } //1.普通攻击 if (atype == 1) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.ACAgility); ActionList.Add(action); } //2.脉冲,范围麻痹 if (atype == 2) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); Point movepoint = Functions.PointMove(CurrentLocation, Direction, 2); List <MapObject> listtargets = CurrentMap.getMapObjects(movepoint.X, movepoint.Y, 2); for (int o = 0; o < listtargets.Count; o++) { MapObject ob = listtargets[o]; if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) { continue; } if (!ob.IsAttackTarget(this)) { continue; } if (ob.Race == ObjectType.Monster) { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage * 2, DefenceType.MAC); ActionList.Add(action); } else { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage, DefenceType.MAC); ActionList.Add(action); } if (RandomUtils.Next(Settings.PoisonResistWeight) >= ob.PoisonResist && RandomUtils.Next(100) < 60) { ob.ApplyPoison(new Poison { Owner = this, Duration = RandomUtils.Next(4, 8), PType = PoisonType.Frozen, Value = damage, TickSpeed = 1000 }, this); } } } //3.撒花,放鬼头 if (atype == 3) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 2 }); if (RandomUtils.Next(100) < 50) { //放火圈 List <Point> list = new List <Point>(); list.Add(new Point(CurrentLocation.X, CurrentLocation.Y + 5)); list.Add(new Point(CurrentLocation.X, CurrentLocation.Y - 5)); list.Add(new Point(CurrentLocation.X + 5, CurrentLocation.Y + 5)); list.Add(new Point(CurrentLocation.X + 5, CurrentLocation.Y)); list.Add(new Point(CurrentLocation.X + 5, CurrentLocation.Y - 5)); list.Add(new Point(CurrentLocation.X - 5, CurrentLocation.Y - 5)); list.Add(new Point(CurrentLocation.X - 5, CurrentLocation.Y)); list.Add(new Point(CurrentLocation.X - 5, CurrentLocation.Y + 5)); //一次放6个鬼头,随机放,如果重复了,就不放 for (int i = 0; i < list.Count; i++) { Point p = list[i]; if (!CurrentMap.Valid(p.X, p.Y)) { continue; } SpellObject spellObj = new SpellObject { Spell = Spell.MonGhostHead, Value = damage * 3, ExpireTime = Envir.Time + 15000, TickSpeed = 3000, Caster = null, MonCaster = this, CurrentLocation = p, CurrentMap = CurrentMap, Direction = MirDirection.Up }; action = new DelayedAction(DelayedType.Spawn, Envir.Time + 500, spellObj); CurrentMap.ActionList.Add(action); } } else { int rcount = RandomUtils.Next(5, 10); //一次放3-6个毒,随机放,如果重复了,就不放 for (int i = 0; i < rcount; i++) { Point p = CurrentMap.RandomValidPoint(CurrentLocation.X, CurrentLocation.Y, 6, 1); //随机抽取5个点,放毒 SpellObject spellObj = new SpellObject { Spell = Spell.MonGhostHead, Value = damage * 2, ExpireTime = Envir.Time + 15000, TickSpeed = 3000, Caster = null, MonCaster = this, CurrentLocation = p, CurrentMap = CurrentMap, Direction = MirDirection.Up }; action = new DelayedAction(DelayedType.Spawn, Envir.Time + 500, spellObj); CurrentMap.ActionList.Add(action); } } } //4.无敌,护盾 if (atype == 4) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 3 }); protectTime = Envir.Time + 1000 * RandomUtils.Next(15, 30); PoisonTime = Envir.Time + 1000 * RandomUtils.Next(5, 12); PoisonList.Clear(); ProcessTime = Envir.Time + 500; } //5.闪现,瞬移 if (atype == 5) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 4 }); PoisonList.Clear(); action = new DelayedAction(DelayedType.RangeDamage, Envir.Time + 700, Target, damage, DefenceType.MACAgility, 5); ActionList.Add(action); _TeleportTime++; } //6.远程单体雷电,减速 if (atype == 6) { Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MACAgility); ActionList.Add(action); if (RandomUtils.Next(Settings.PoisonResistWeight) >= Target.PoisonResist && RandomUtils.Next(100) < 70) { Target.ApplyPoison(new Poison { Owner = this, Duration = RandomUtils.Next(6, 16), PType = PoisonType.Slow, Value = damage / 2, TickSpeed = 2000 }, this); } } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 550; //50 MS per Step int rd = RandomUtils.Next(100); // if (distance > 2) { if (rd < 60) { attType = 3; } else { attType = 4; } } else { if (rd < 40) { attType = 1; } else if (rd < 70) { attType = 3; } else { attType = 4; } } if (distance == 1 && RandomUtils.Next(3) == 0) { attType = 0; } //如果中毒了,几率解毒 if (PoisonList != null && PoisonList.Count > 0 && RandomUtils.Next(5) == 0) { attType = 2; } //如果血量过少,则加血哦 if (HP < MaxHP / 3 && RandomUtils.Next(5) == 0) { attType = 2; } DelayedAction action = null; List <MapObject> listtargets; switch (attType) { case 0: Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.ACAgility); ActionList.Add(action); break; case 1: Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); //抖花粉 封印技能 listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 2); for (int o = 0; o < listtargets.Count; o++) { MapObject ob = listtargets[o]; if (ob.Race == ObjectType.Monster || ob.Race == ObjectType.Player) { if (!ob.IsAttackTarget(this)) { continue; } action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage, DefenceType.MAC); ActionList.Add(action); if (RandomUtils.Next(Settings.PoisonResistWeight) >= ob.PoisonResist) { ob.ApplyPoison(new Poison { Owner = this, Duration = RandomUtils.Next(5, 15), PType = PoisonType.Stun, Value = damage, TickSpeed = 1000 }, this); } } } break; case 2: Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 2 }); //血量恢复 ChangeHP(damage * 3); //解除中毒 PoisonList.Clear(); break; case 3: //放追踪技能 Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MAC); ActionList.Add(action); break; case 4: Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 1 }); listtargets = CurrentMap.getMapObjects(Target.CurrentLocation.X, Target.CurrentLocation.Y, 2); for (int o = 0; o < listtargets.Count; o++) { MapObject ob = listtargets[o]; if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) { continue; } if (!ob.IsAttackTarget(this)) { continue; } action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage * 2 / 3, DefenceType.MAC); ActionList.Add(action); if (RandomUtils.Next(Settings.PoisonResistWeight) >= ob.PoisonResist && RandomUtils.Next(100) < 50) { ob.ApplyPoison(new Poison { Owner = this, Duration = RandomUtils.Next(4, 8), PType = PoisonType.Frozen, Value = damage, TickSpeed = 1000 }, this); } } break; } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
public override int Attacked(MonsterObject attacker, int damage, DefenceType type = DefenceType.ACAgility) { int armour = 0; switch (type) { case DefenceType.ACAgility: if (Envir.Random.Next(Stats[Stat.Agility] + 1) > attacker.Stats[Stat.Accuracy]) { return(0); } armour = GetAttackPower(Stats[Stat.MinAC], Stats[Stat.MaxAC]); break; case DefenceType.AC: armour = GetAttackPower(Stats[Stat.MinAC], Stats[Stat.MaxAC]); break; case DefenceType.MACAgility: if (Envir.Random.Next(Stats[Stat.Agility] + 1) > attacker.Stats[Stat.Accuracy]) { return(0); } armour = GetAttackPower(Stats[Stat.MinMAC], Stats[Stat.MaxMAC]); break; case DefenceType.MAC: armour = GetAttackPower(Stats[Stat.MinMAC], Stats[Stat.MaxMAC]); break; case DefenceType.Agility: if (Envir.Random.Next(Stats[Stat.Agility] + 1) > attacker.Stats[Stat.Accuracy]) { return(0); } break; } if (armour >= damage) { return(0); } ShockTime = 0; for (int i = PoisonList.Count - 1; i >= 0; i--) { if (PoisonList[i].PType != PoisonType.LRParalysis) { continue; } PoisonList.RemoveAt(i); OperateTime = 0; } if (attacker.Info.AI == 6) { EXPOwner = null; } else if (attacker.Master != null) { if (EXPOwner == null || EXPOwner.Dead) { EXPOwner = attacker.Master switch { HeroObject hero => hero.Owner, _ => attacker.Master } } ; if (EXPOwner == attacker.Master) { EXPOwnerTime = Envir.Time + EXPOwnerDelay; } } Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation }); ChangeHP(-1); return(1); }
public override int Attacked(HumanObject attacker, int damage, DefenceType type = DefenceType.ACAgility, bool damageWeapon = true) { int armour = 0; switch (type) { case DefenceType.ACAgility: if (Envir.Random.Next(Stats[Stat.Agility] + 1) > attacker.Stats[Stat.Accuracy]) { return(0); } armour = GetAttackPower(Stats[Stat.MinAC], Stats[Stat.MaxAC]); break; case DefenceType.AC: armour = GetAttackPower(Stats[Stat.MinAC], Stats[Stat.MaxAC]); break; case DefenceType.MACAgility: if (Envir.Random.Next(Stats[Stat.Agility] + 1) > attacker.Stats[Stat.Accuracy]) { return(0); } armour = GetAttackPower(Stats[Stat.MinMAC], Stats[Stat.MaxMAC]); break; case DefenceType.MAC: armour = GetAttackPower(Stats[Stat.MinMAC], Stats[Stat.MaxMAC]); break; case DefenceType.Agility: if (Envir.Random.Next(Stats[Stat.Agility] + 1) > attacker.Stats[Stat.Accuracy]) { return(0); } break; } if (armour >= damage) { return(0); } if (damageWeapon) { attacker.DamageWeapon(); } ShockTime = 0; for (int i = PoisonList.Count - 1; i >= 0; i--) { if (PoisonList[i].PType != PoisonType.LRParalysis) { continue; } PoisonList.RemoveAt(i); OperateTime = 0; } if (Master != null && Master != attacker) { if (Envir.Time > Master.BrownTime && Master.PKPoints < 200) { attacker.BrownTime = Envir.Time + Settings.Minute; } } if (EXPOwner == null || EXPOwner.Dead) { EXPOwner = GetAttacker(attacker); } if (EXPOwner == attacker) { EXPOwnerTime = Envir.Time + EXPOwnerDelay; } Broadcast(new S.ObjectStruck { ObjectID = ObjectID, AttackerID = attacker.ObjectID, Direction = Direction, Location = CurrentLocation }); attacker.GatherElement(); ChangeHP(-1); return(1); }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } int atype = 1; Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 500; //50 MS per Step DelayedAction action = null; if (distance <= 1 && RandomUtils.Next(100) < 30) { atype = 1; } else { if (RandomUtils.Next(100) < 60) { atype = 2; } else { atype = 3; } } if (atype == 1) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); if (Target.Race == ObjectType.Monster) { damage = damage * 2; } action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage * 4 / 3, DefenceType.ACAgility); ActionList.Add(action); } if (atype == 2) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); List <MapObject> listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 3); for (int o = 0; o < listtargets.Count; o++) { MapObject ob = listtargets[o]; if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) { continue; } if (!ob.IsAttackTarget(this)) { continue; } if (ob.Race == ObjectType.Monster) { damage = damage * 2; } action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage, DefenceType.MAC); ActionList.Add(action); if (RandomUtils.Next(Settings.PoisonResistWeight) >= ob.PoisonResist && RandomUtils.Next(100) < 30) { ob.ApplyPoison(new Poison { Owner = this, Duration = damage / 30, PType = PoisonType.Green, Value = damage / 5, TickSpeed = 2000 }, this); } } } if (atype == 3) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 2 }); PoisonList.Clear(); PoisonTime = Envir.Time + RandomUtils.Next(2, 5) * 1000; action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MACAgility); ActionList.Add(action); int rcount = RandomUtils.Next(2, 6); //一次放2-4个毒,随机放,如果重复了,就不放 for (int i = 0; i < rcount; i++) { Point p = CurrentMap.RandomValidPoint(CurrentLocation.X, CurrentLocation.Y, 6, 1); //随机抽取5个点,放毒 SpellObject spellObj = new SpellObject { Spell = Spell.MonPoisonFog, Value = damage, ExpireTime = Envir.Time + 1000 * RandomUtils.Next(20, 30), TickSpeed = 2000, Caster = null, MonCaster = this, CurrentLocation = p, CurrentMap = CurrentMap, Direction = MirDirection.Up }; action = new DelayedAction(DelayedType.Spawn, Envir.Time + 500, spellObj); CurrentMap.ActionList.Add(action); } } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
public override void Die() { if (SpecialMode.HasFlag(SpecialItemMode.Revival) && Envir.Time > LastRevivalTime) { LastRevivalTime = Envir.Time + 300000; for (var i = (int)EquipmentSlot.RingL; i <= (int)EquipmentSlot.RingR; i++) { var item = Info.Equipment[i]; if (item == null) { continue; } if (!(item.Info.Unique.HasFlag(SpecialItemMode.Revival)) || item.CurrentDura < 1000) { continue; } SetHP(Stats[Stat.HP]); item.CurrentDura = (ushort)(item.CurrentDura - 1000); Enqueue(new S.DuraChanged { UniqueID = item.UniqueID, CurrentDura = item.CurrentDura }); RefreshStats(); ReceiveChat("You have been given a second chance at life", ChatType.System); return; } } for (int i = Pets.Count - 1; i >= 0; i--) { if (Pets[i].Dead) { continue; } Pets[i].Die(); } RemoveBuff(BuffType.MagicShield); RemoveBuff(BuffType.ElementalBarrier); if (!InSafeZone) { DeathDrop(LastHitter); } HP = 0; Dead = true; LogTime = Envir.Time; BrownTime = Envir.Time; Broadcast(new S.ObjectDied { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation }); Owner.Enqueue(new S.UpdateHeroSpawnState { State = HeroSpawnState.Dead }); for (int i = 0; i < Buffs.Count; i++) { Buff buff = Buffs[i]; if (!buff.Properties.HasFlag(BuffProperty.RemoveOnDeath)) { continue; } RemoveBuff(buff.Type); } PoisonList.Clear(); InTrapRock = false; }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 500; //50 MS per Step DelayedAction action = null; int rd = RandomUtils.Next(100); byte AttackType = 3; if (rd < 70) { //3.远程噬血(范围攻击) AttackType = 3; } else if (rd < 85) { //1.无敌 if (Envir.Time > unmatchedTime + 2000) { AttackType = 1; } else { AttackType = 3; } } else { //2.范围减速,范围攻击,范围治疗 AttackType = 2; } //1.无敌 if (AttackType == 1) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); unmatchedTime = Envir.Time + RandomUtils.Next(3, 6) * 1000; } //2.范围减速,范围攻击,范围治疗 if (AttackType == 2) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); List <MapObject> listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 3); for (int o = 0; o < listtargets.Count; o++) { MapObject ob = listtargets[o]; if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) { continue; } if (ob.IsAttackTarget(this)) { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage, DefenceType.MAC); ActionList.Add(action); if (RandomUtils.Next(Settings.PoisonResistWeight) >= ob.PoisonResist && RandomUtils.Next(100) < 40) { ob.ApplyPoison(new Poison { Owner = this, Duration = 3, PType = PoisonType.Slow, Value = damage / 10, TickSpeed = 2000 }, this); } } else { //解除中毒 PoisonList.Clear(); ob.PoisonList.Clear(); //血量恢复 ob.HealAmount = (ushort)Math.Min(ushort.MaxValue, ob.HealAmount + damage * 2); } } } //3.远程噬血(范围攻击) if (AttackType == 3) { Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MAC); ActionList.Add(action); //血量恢复 ChangeHP(damage / 5); } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 500; //50 MS per Step DelayedAction action = null; AttackType = 0; if (_stage == 0) { if (PoisonList.Count > 0) { if (RandomUtils.Next(100) < 20) { AttackType = 3; } } else { if (RandomUtils.Next(100) < 10) { AttackType = 3; } } } else { if (AttackedCount > 10) { AttackedCount = 0; AttackType = 4; } } if (AttackType == 0) { if (distance > 1) { AttackType = 2; } else { int rd = RandomUtils.Next(100); if (rd < 50) { AttackType = 0; } else if (rd < 80) { AttackType = 1; } else { AttackType = 2; } } } switch (AttackType) { case 0: Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.ACAgility); ActionList.Add(action); break; case 1: Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage * 2, DefenceType.AC); ActionList.Add(action); break; case 2: Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MACAgility); ActionList.Add(action); if (RandomUtils.Next(Settings.PoisonResistWeight) >= Target.PoisonResist && RandomUtils.Next(100) < 50) { Target.ApplyPoison(new Poison { Owner = this, Duration = RandomUtils.Next(5, 10), PType = PoisonType.Slow, Value = damage, TickSpeed = 1000 }, this); } break; case 3: Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 2 }); _stage = 1; Broadcast(GetInfo()); //清除状态 PoisonList.Clear(); //血量恢复 ChangeHP(damage * 3); break; case 4: Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 3 }); List <MapObject> listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 3); for (int o = 0; o < listtargets.Count; o++) { MapObject ob = listtargets[o]; if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) { continue; } if (!ob.IsAttackTarget(this)) { continue; } action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage * 2, DefenceType.MAC); ActionList.Add(action); } _stage = 0; Broadcast(GetInfo()); break; } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }
protected override void Attack() { if (!Target.IsAttackTarget(this)) { Target = null; return; } Direction = Functions.DirectionFromPoint(CurrentLocation, Target.CurrentLocation); int damage = GetAttackPower(MinDC, MaxDC); int distance = Functions.MaxDistance(CurrentLocation, Target.CurrentLocation); int delay = distance * 50 + 500; //50 MS per Step DelayedAction action = null; int rd = RandomUtils.Next(100); byte attacktype = 1; if (_stage == 0) { if (rd < 50) { attacktype = 1; if (distance >= 2) { attacktype = 6; } } else if (rd < 80) { attacktype = 6; } else { if (Envir.Time > fireTime) { attacktype = 2; fireTime = Envir.Time + 4000; } else { attacktype = 6; } } } else { damage = damage * 3 / 2; if (rd < 40) { attacktype = 4; if (distance >= 3) { attacktype = 7; } } else if (rd < 80) { attacktype = 7; } else { if (Envir.Time > fireTime) { attacktype = 3; fireTime = Envir.Time + 12000; } else { attacktype = 7; } } } //普通攻击 if (attacktype == 1) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.ACAgility); ActionList.Add(action); } //2.放鬼头 if (attacktype == 2) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 1 }); if (distance < 3) { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.ACAgility); ActionList.Add(action); } int rcount = RandomUtils.Next(6, 12); //一次放6个鬼头,随机放,如果重复了,就不放 for (int i = 0; i < rcount; i++) { Point p = CurrentMap.RandomValidPoint(CurrentLocation.X, CurrentLocation.Y, 6, 1); //随机抽取5个点,放鬼头 SpellObject spellObj = new SpellObject { Spell = Spell.MonKITO, Value = damage * 3 / 2, ExpireTime = Envir.Time + 5000, TickSpeed = 2500, Caster = null, MonCaster = this, CurrentLocation = p, CurrentMap = CurrentMap, Direction = MirDirection.Up }; action = new DelayedAction(DelayedType.Spawn, Envir.Time + 500, spellObj); CurrentMap.ActionList.Add(action); } } //3.举刀 解毒,强化,放火圈 if (attacktype == 3) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 2 }); //血量恢复 ChangeHP(damage); //解除中毒 PoisonList.Clear(); PoisonTime = Envir.Time + RandomUtils.Next(5, 10) * 1000; //放火圈 List <Point> list = new List <Point>(); list.Add(new Point(CurrentLocation.X, CurrentLocation.Y + 5)); list.Add(new Point(CurrentLocation.X, CurrentLocation.Y - 5)); list.Add(new Point(CurrentLocation.X + 5, CurrentLocation.Y + 5)); list.Add(new Point(CurrentLocation.X + 5, CurrentLocation.Y)); list.Add(new Point(CurrentLocation.X + 5, CurrentLocation.Y - 5)); list.Add(new Point(CurrentLocation.X - 5, CurrentLocation.Y - 5)); list.Add(new Point(CurrentLocation.X - 5, CurrentLocation.Y)); list.Add(new Point(CurrentLocation.X - 5, CurrentLocation.Y + 5)); //一次放6个鬼头,随机放,如果重复了,就不放 for (int i = 0; i < list.Count; i++) { Point p = list[i]; if (!CurrentMap.Valid(p.X, p.Y)) { continue; } SpellObject spellObj = new SpellObject { Spell = Spell.MonFireCircle, Value = damage * 3 / 2, ExpireTime = Envir.Time + 12000, TickSpeed = 2000, Caster = null, MonCaster = this, CurrentLocation = p, CurrentMap = CurrentMap, Direction = MirDirection.Up }; action = new DelayedAction(DelayedType.Spawn, Envir.Time + 500, spellObj); CurrentMap.ActionList.Add(action); } } //4.砸地板 if (attacktype == 4) { Broadcast(new S.ObjectAttack { ObjectID = ObjectID, Direction = Direction, Location = CurrentLocation, Type = 3 }); List <MapObject> listtargets = CurrentMap.getMapObjects(CurrentLocation.X, CurrentLocation.Y, 3); for (int o = 0; o < listtargets.Count; o++) { MapObject ob = listtargets[o]; if (ob.Race != ObjectType.Player && ob.Race != ObjectType.Monster) { continue; } if (!ob.IsAttackTarget(this)) { continue; } if (ob.Race == ObjectType.Monster) { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage * 2, DefenceType.MAC); } else { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, ob, damage, DefenceType.MAC); } ActionList.Add(action); } } //6.小火球(r1) if (attacktype == 6) { damage += damage * distance / 30; Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 0 }); action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MAC); ActionList.Add(action); } //7.大火球(r2) if (attacktype == 7) { damage += damage * distance / 30; Broadcast(new S.ObjectRangeAttack { ObjectID = ObjectID, Direction = Direction, TargetID = Target.ObjectID, Location = CurrentLocation, Type = 1 }); if (Target.Race == ObjectType.Monster) { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage * 2, DefenceType.MAC); } else { action = new DelayedAction(DelayedType.Damage, Envir.Time + delay, Target, damage, DefenceType.MAC); } ActionList.Add(action); } ShockTime = 0; ActionTime = Envir.Time + 500; AttackTime = Envir.Time + (AttackSpeed); }