public override void Update() { if (Alive && Chatter.Count > 0 && DateTime.UtcNow > NextChatter) { int index = ChatterIndex % Chatter.Count; ChatterIndex++; Say(Chatter[index], 0); NextChatter = DateTime.UtcNow.AddSeconds(Program.Random(60, 90)); } var statuses = new string[Statuses.Count]; Statuses.Keys.CopyTo(statuses, 0); foreach (var status in statuses) { if (Statuses.ContainsKey(status)) { var s = Statuses[status]; if (s.RequiresCaster && s.Caster == null) { RemoveStatus(status); } else if (DateTime.UtcNow > s.NextTick) { if (s.Channeled) { Channel(s); } else if (Alive || !s.OnlyTickAlive) { s.OnTick(this); if (s.SpellAnimation != 0 && !s.SingleAnimation) { SpellAnimation(s.SpellAnimation, 100); } } if (--s.TimeLeft < 1) { RemoveStatus(status); } s.NextTick = DateTime.UtcNow.AddMilliseconds(s.Speed); } } } var characters = new Character[ThreatMeter.Count]; ThreatMeter.Keys.CopyTo(characters, 0); foreach (var c in characters) { if (c == null || c.Dead || !WithinRange(c, 12)) { ThreatMeter.Remove(c); } } var enemies = new Character[Enemies.Count]; Enemies.CopyTo(enemies, 0); foreach (var e in enemies) { if (e == null || e.Dead || !WithinRange(e, 12)) { Enemies.Remove(e); } else { foreach (var m in e.Group.Members) { this.Enemies.Add(m); m.Enemies.Add(this); } } } if (SpawnControl != null && SpawnControl.SpecificTime && SpawnControl.SpawnTime != GameServer.Time && !Dead) { LifeStatus = LifeStatus.Dead; Experience = 0; } if (CurrentHP <= 0 && Alive) { if (ShouldComa) { CurrentHP = 1; AddStatus("Spell_Coma", 1, 20, this); } else { CurrentHP = 0; LifeStatus = LifeStatus.Dead; } } switch (LifeStatus) { case LifeStatus.Alive: { if (DateTime.UtcNow > NextTick) { if (IsHostile && Target == null) { var targets = from t in from obj in Map.Objects where obj is Character && WithinRange(obj, HostileRange) select obj as Character where t.Alive && AllegianceTo(t) == Allegiance.Enemy && !t.Hidden && !t.Stealth orderby Point.DistanceFrom(t.Point) ascending select t; if (targets.Count() > 0) { var target = targets.First(); Enemies.Add(target); target.Enemies.Add(this); target.Threaten(this, 1); } } UpdateTarget(); if (IsCasting) { OnTickCasting(); } else { OnTick(); } TickCount++; NextTick = DateTime.UtcNow.AddMilliseconds(TickSpeed); } } break; case LifeStatus.Coma: { if (DateTime.UtcNow > NextTick) { OnTickComa(); TickCount++; NextTick = DateTime.UtcNow.AddMilliseconds(TickSpeed); } } break; case LifeStatus.Dying: { if (DateTime.UtcNow > NextTick) { OnTickDying(); TickCount++; NextTick = DateTime.UtcNow.AddMilliseconds(TickSpeed); } } break; case LifeStatus.Dead: { #region Remove Statuses statuses = new string[Statuses.Count]; Statuses.Keys.CopyTo(statuses, 0); foreach (var s in statuses) { RemoveStatus(s); } #endregion #region Remove Threat characters = new Character[ThreatMeter.Count]; ThreatMeter.Keys.CopyTo(characters, 0); foreach (var c in characters) { ThreatMeter.Remove(c); } #endregion #region Remove Enemies enemies = new Character[Enemies.Count]; Enemies.CopyTo(enemies, 0); foreach (var e in enemies) { Enemies.Remove(e); e.Enemies.Remove(this); } #endregion #region Give EXP / Quest Kill double highestGroupValue = 0; double highestPlayerValue = 0; Group highestGroup = null; Player highestPlayer = null; var groups = new Dictionary <Group, double>(); foreach (var attacker in Attackers) { if (attacker.Key is Player) { var player = attacker.Key as Player; if (groups.ContainsKey(player.Group)) { groups[player.Group] += attacker.Value; } else { groups.Add(player.Group, attacker.Value); } if (groups[player.Group] > highestGroupValue) { highestGroup = player.Group; highestGroupValue = groups[player.Group]; } if (attacker.Value > highestPlayerValue) { highestPlayer = player; highestPlayerValue = attacker.Value; } } } foreach (var group in groups) { if (group.Value < MaximumHP * 0.15) { continue; } long averageLevel = 0; var players = new List <Player>(); foreach (var p in group.Key.Members) { if (p.WithinRange(this, 12) && p is Player) { averageLevel += p.Level; players.Add(p as Player); } } if (players.Count > 0) { averageLevel /= players.Count; } foreach (var p in players) { var difference = Math.Abs(averageLevel - Level); if (difference < 5) { var percent = 1.0 - difference * 0.125; if (Program.Random(100) < p.ExperienceBonusChance) { percent *= p.ExperienceBonus; p.SpellAnimation(341, 100); } p.RewardExperience((long)(Experience * percent)); } foreach (var q in p.Quests) { var qs = q.Value.QuestStep; foreach (var qo in qs.Objectives.Values) { if (qo.Type == QuestObjectiveType.Kill && qo.RequiredKilledTypes.Contains(GetType().Name)) { if (qo.GroupKill || p == highestPlayer) { p.AddQuestCount(q.Key, qo.Name); } } } } } } #endregion #region Close Dialogs foreach (Client c in GameServer.Clients) { if (c.Player != null && c.Player.DialogSession.GameObject == this && c.Player.DialogSession.IsOpen) { c.Player.DialogSession.IsOpen = false; c.Player.DialogSession.Dialog = null; c.Player.DialogSession.GameObject = null; c.Player.DialogSession.Map = null; c.Enqueue(Dialog.ExitPacket()); } } #endregion #region Loot if (SpawnControl != null || CanDropLootWithoutSpawn) { var chest = new Chest(); foreach (Loot loot in Loot) { if (Program.Random(loot.MaximumValue) < loot.MinimumValue) { int value; int index = Program.Random(loot.Items.Count); var item = loot.Items[index]; Item drop = null; if (int.TryParse(item, out value)) { drop = new Gold(value); GameServer.InsertGameObject(drop); } else { drop = GameServer.CreateItem(item); } if (drop != null) { if (drop.LootRollLength > 0 || drop.BindType != BindType.None) { var chestItem = new Chest.ChestItem(); chestItem.Item = drop; chest.Items.Add(chestItem); } else { if (highestGroup != null) { foreach (var member in highestGroup.Members) { drop.ProtectionOwners.Add(member.Name); } drop.ProtectionExpireTime = DateTime.UtcNow.AddSeconds(60); } Map.InsertCharacter(drop, Point); } } } } if (chest.Items.Count > 0 && highestGroup != null) { foreach (var member in highestGroup.Members) { chest.GUIDs.Add(member.GUID); } chest.Direction = Direction.South; GameServer.InsertGameObject(chest); Map.InsertCharacter(chest, Point); } } #endregion this.OnDeath(); this.OnDeath(highestPlayer); Map.RemoveCharacter(this); GameServer.RemoveGameObject(this); } break; } if (DateTime.UtcNow.Subtract(LastHpRegen).TotalSeconds > 1) { if (Alive && CurrentHP < MaximumHP && Target == null) { CurrentHP += (long)(MaximumHP * 0.10); if (CurrentHP > MaximumHP) { CurrentHP = MaximumHP; } } LastHpRegen = DateTime.UtcNow; } if (DateTime.UtcNow.Subtract(LastMpRegen).TotalSeconds > 1) { if (Alive && CurrentMP < MaximumMP && Target == null) { CurrentMP += (long)(MaximumMP * 0.10); if (CurrentMP > MaximumMP) { CurrentMP = MaximumMP; } } LastMpRegen = DateTime.UtcNow; } }