if (attacker.Stamina >= 30) attacker.Stamina -= 30;
using System; using System.Linq; using System.Threading; using System.Collections.Generic; using KhaledMohamed.Interfaces; using KhaledMohamed.Client; using KhaledMohamed.Network.GamePackets; using System.Collections.Concurrent; using System.Diagnostics; using System.Threading.Generic; using KhaledMohamed.MaTrix; namespace KhaledMohamed.Game { public class Screen { private static TimerRule<GameState> MonsterBuffers, Guards, AliveMonsters, Items, FloorSpells, CopraMobs; public static void CreateTimerFactories() { MonsterBuffers = new TimerRule<GameState>(monsterBuffersCallback, 500); Guards = new TimerRule<GameState>(guardsCallback, 700); CopraMobs = new TimerRule<GameState>(CopraMobsCallback, 700); AliveMonsters = new TimerRule<GameState>(aliveMonstersCallback, 500); Items = new TimerRule<GameState>(itemsCallback, 1000); FloorSpells = new TimerRule<GameState>(FloorSpellsCallBack, 100); } private static void FloorSpellsCallBack(GameState client, int time) { try { if (client.Fake) { client.Screen.DisposeTimers(); return; } if (!client.Socket.IsAlive) { client.Screen.DisposeTimers(); return; } if (client.Entity == null) return; if (client.Map == null) return; Time32 Now = new Time32(time); #region ThunderCloud foreach (var Cloud in client.Map.Clouds.Values) { if (Cloud == null) continue; if (Kernel.GetDistance(Cloud.X, Cloud.Y, client.Entity.X, client.Entity.Y) > 16) continue; if (DateTime.Now > Cloud.EndTime || Cloud.Owner == null) { Cloud.DisposeCloud(client); return; } #region ThunderCloud if (!Cloud.Dead && Time32.Now > Cloud.LastCloudAttack.AddSeconds(Cloud.ThunderBolt == true ? 1 : 2)) { if (client.Entity.Cloud != null) { var spell = Database.SpellTable.GetSpell(12970, client); SpellUse suse = new SpellUse(true); suse.Attacker = client.Entity.Cloud.UID; suse.SpellID = 13190; suse.SpellLevel = 0; suse.X = client.Entity.Cloud.X; suse.Y = client.Entity.Cloud.Y; Entity attacked = null; foreach (Interfaces.IMapObject _obj in client.Screen.Objects) { if (_obj == null) continue; if (_obj.MapObjType == MapObjectType.Monster || _obj.MapObjType == MapObjectType.Entity) { Cloud.LastCloudAttack = Time32.Now; attacked = _obj as Entity; if (Kernel.GetDistance(Cloud.X, Cloud.Y, attacked.X, attacked.Y) <= 15) { Attack attack = new Attack(true); if (Game.Attacking.Handle.CanAttack(Cloud.Owner.Entity, attacked, spell, attack.AttackType == Attack.Melee)) { attack.Effect1 = Attack.AttackEffects1.None; uint damage = Game.Attacking.Calculate.Melee(Cloud.Owner.Entity, attacked, ref attack); damage = (uint)(damage * 0.200); if (Cloud.ThunderBolt) damage = Game.Attacking.Calculate.Melee(Cloud.Owner.Entity, attacked, ref attack); damage = (uint)(damage * 0.200); suse.Effect1 = attack.Effect1; Game.Attacking.Handle.ReceiveAttack(Cloud.Owner.Entity, attacked, attack, ref damage, spell); damage = (uint)(damage * 0.200); suse.AddTarget(attacked, damage, attack); break; } } } } client.SendScreen(suse, true); } } #endregion } #endregion } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void monsterBuffersCallback(GameState client, int time) { if (!client.Socket.IsAlive) { client.Screen.DisposeTimers(); return; } if (client.Entity == null) return; if (client.Map == null) return; if (client.Map.FreezeMonsters) return; #region EpicWater/Fire if (client.Entity.Class >= 100 && client.Entity.Class <= 145) { if (DateTime.Now >= client.Entity.LastGetEnergy.AddSeconds(1)) { if (client.Entity.EpicTaoist()) { if (client.Entity.Class >= 130 && client.Entity.Class <= 135) { client.Entity.Energy += 4; } else { client.Entity.Energy += 7; } client.Entity.LastGetEnergy = DateTime.Now; } else { client.Entity.RemoveFlag3((ulong)Update.Flags3.AuroraLotus); client.Entity.RemoveFlag3((ulong)Update.Flags3.FlameLotus); client.Entity.Energy = 0; } } } #endregion #region Stamina if (client.Entity.StaminaStamp.Next(500, time: time)) { if (client.Vigor < client.Entity.ExtraVigor) { client.Vigor += (ushort)(3 + (client.Entity.Action == Game.Enums.ConquerAction.Sit ? 2 : 0)); { Vigor vigor = new Vigor(true); vigor.Amount = client.Vigor; vigor.Send(client); } } if (!client.Entity.ContainsFlag(Update.Flags.Ride) && !client.Entity.ContainsFlag(Update.Flags.Fly) || client.Equipment.TryGetItem(18) != null) { int limit = 0; if (client.Spells != null) { if (client.Spells.ContainsKey(12560)) { var spell = client.Spells[12560]; var skill = Database.SpellTable.SpellInformations[12560][spell.Level]; limit += (int)skill.Power; } } if (client.Entity.HeavenBlessing > 0) limit = 50; #region Toaist if (client.Entity.Class >= 140 && client.Entity.Class <= 145) { if (!client.Entity.ContainsFlag3((ulong)Network.GamePackets.Update.Flags3.FlameLotus)) { client.Entity.AddFlag3((ulong)Network.GamePackets.Update.Flags3.FlameLotus); } if (client.Entity.Energy <= 300) { if (client.Entity.Action == Enums.ConquerAction.Sit) { if (client.Entity.Energy <= 280) { client.Entity.Energy += 4; } else { if (client.Entity.Energy != 300) client.Entity.Energy += 1; } } } } if (client.Entity.Class >= 100 && client.Entity.Class <= 135) { if (!client.Entity.ContainsFlag3((ulong)Network.GamePackets.Update.Flags3.AuroraLotus)) { client.Entity.AddFlag3((ulong)Network.GamePackets.Update.Flags3.AuroraLotus); } if (client.Entity.Energy <= 200) { if (client.Entity.Action == Enums.ConquerAction.Sit) { if (client.Entity.Energy <= 180) { client.Entity.Energy += 4; } else { if (client.Entity.Energy != 200) client.Entity.Energy += 1; } } } } #endregion #region Monk if (client.Spells != null) { if (client.Spells.ContainsKey(12560)) { var spell = client.Spells[12560]; var skill = Database.SpellTable.SpellInformations[12560][spell.Level]; limit += (int)skill.Power; } } #endregion if (client.Entity.Stamina != 100 + limit) { if (client.Entity.Action == Enums.ConquerAction.Sit) { if (client.Entity.Stamina <= 93 + limit) { client.Entity.Stamina += 7; } else { if (client.Entity.Stamina != 100 + limit) client.Entity.Stamina = (byte)(100 + limit); } } else { if (client.Entity.Stamina <= 97 + limit) { client.Entity.Stamina += 5; } else { if (client.Entity.Stamina != 100 + limit) client.Entity.Stamina = (byte)(100 + limit); } } } client.Entity.StaminaStamp = new Time32(time); } } #endregion #region WindWalker(Stomper) if (client.Entity.IsStomper2() && client.Spells != null && client.Spells.ContainsKey(12870)) { if (!client.Entity.ContainsFlag4(Update.Flags4.JusticeChant)) client.Entity.AddFlag4(Update.Flags4.JusticeChant); if (Time32.Now >= client.Entity.StomperStaminaStamp.AddSeconds(8)) { if (client.Entity.Stamina != (byte)((client.Entity.HeavenBlessing > 0) ? 150 : 100)) { _String str = new _String(true); str.Texts.Add("TSM_SXJ_HPhf"); str.TextsCount = 1; str.UID = client.Entity.UID; str.Type = 10; client.SendScreen(str, true); client.Entity.StomperStaminaStamp = Time32.Now; client.Entity.Stamina += 10; if (client.Entity.Stamina > ((client.Entity.HeavenBlessing > 0) ? 150 : 100)) client.Entity.Stamina = (byte)((client.Entity.HeavenBlessing > 0) ? 150 : 100); } } } #endregion #region WindWalker(Chaser) if (client.Entity.IsChaser2() && client.Spells != null && client.Spells.ContainsKey(12870)) { if (!client.Entity.ContainsFlag4(Update.Flags4.JusticeChant)) client.Entity.AddFlag4(Update.Flags4.JusticeChant); if (Time32.Now >= client.Entity.ChaserStaminaStamp.AddSeconds(5)) { if (client.Entity.Stamina != (byte)((client.Entity.HeavenBlessing > 0) ? 150 : 100)) { client.Entity.ChaserStaminaStamp = Time32.Now; client.Entity.Stamina += (byte)(client.Entity.Stamina / 2); if (client.Entity.Stamina > ((client.Entity.HeavenBlessing > 0) ? 150 : 100)) client.Entity.Stamina = (byte)((client.Entity.HeavenBlessing > 0) ? 150 : 100); _String str = new _String(true); str.Texts.Add("TSM_SXJ_HPhf"); str.TextsCount = 1; str.UID = client.Entity.UID; str.Type = 10; client.SendScreen(str, true); } } } #endregion foreach (IMapObject obj in client.Screen.Objects) { if (obj != null) { if (obj.MapObjType == MapObjectType.Monster) { Entity monster = obj as Entity; if (monster == null) continue; if (monster.ContainsFlag(Network.GamePackets.Update.Flags.Stigma)) { if (monster.StigmaStamp.AddSeconds(monster.StigmaTime).Next(time: time) || monster.Dead) { monster.StigmaTime = 0; monster.StigmaIncrease = 0; monster.RemoveFlag(Update.Flags.Stigma); } } if (monster.ContainsFlag(Update.Flags.Dodge)) { if (monster.DodgeStamp.AddSeconds(monster.DodgeTime).Next(time: time) || monster.Dead) { monster.DodgeTime = 0; monster.DodgeIncrease = 0; monster.RemoveFlag(Network.GamePackets.Update.Flags.Dodge); } } if (monster.ContainsFlag(Update.Flags.Invisibility)) { if (monster.InvisibilityStamp.AddSeconds(monster.InvisibilityTime).Next(time: time) || monster.Dead) { monster.RemoveFlag(Update.Flags.Invisibility); } } if (monster.ContainsFlag(Update.Flags.StarOfAccuracy)) { if (monster.StarOfAccuracyTime != 0) { if (monster.StarOfAccuracyStamp.AddSeconds(monster.StarOfAccuracyTime).Next(time: time) || monster.Dead) { monster.RemoveFlag(Update.Flags.StarOfAccuracy); } } else { if (monster.AccuracyStamp.AddSeconds(monster.AccuracyTime).Next(time: time) || monster.Dead) { monster.RemoveFlag(Update.Flags.StarOfAccuracy); } } } if (monster.ContainsFlag(Update.Flags.MagicShield)) { if (monster.MagicShieldTime != 0) { if (monster.MagicShieldStamp.AddSeconds(monster.MagicShieldTime).Next(time: time) || monster.Dead) { monster.MagicShieldIncrease = 0; monster.MagicShieldTime = 0; monster.RemoveFlag(Update.Flags.MagicShield); } } else { if (monster.ShieldStamp.AddSeconds(monster.ShieldTime).Next(time: time) || monster.Dead) { monster.ShieldIncrease = 0; monster.ShieldTime = 0; monster.RemoveFlag(Update.Flags.MagicShield); } } } if (monster.Dead || monster.Killed) { if (!monster.ContainsFlag(Update.Flags.Ghost) || monster.Killed) { monster.Killed = false; //monster.MonsterInfo.InSight = 0; monster.AddFlag(Network.GamePackets.Update.Flags.Ghost); monster.AddFlag(Network.GamePackets.Update.Flags.Dead); monster.AddFlag(Network.GamePackets.Update.Flags.FadeAway); Network.GamePackets.Attack attack = new Network.GamePackets.Attack(true); attack.Attacked = monster.UID; attack.AttackType = Network.GamePackets.Attack.Kill; attack.X = monster.X; attack.Y = monster.Y; client.Map.Floor[monster.X, monster.Y, MapObjectType.Monster, monster] = true; if (monster.Killer != null) { attack.Attacker = monster.Killer.UID; attack.KOCount = ++monster.Killer.KOCount; if (monster.Killer.EntityFlag == EntityFlag.Entity) { monster.MonsterInfo.ExcludeFromSend = monster.Killer.UID; monster.Killer.Owner.Send(attack); //monster.Killer.Owner.SendScreen(attack, true); } } monster.MonsterInfo.SendScreen(attack); monster.MonsterInfo.ExcludeFromSend = 0; } if (monster.DeathStamp.AddSeconds(1).Next(time: time)) { Data data = new Data(true); data.UID = monster.UID; data.ID = Network.GamePackets.Data.RemoveEntity; monster.MonsterInfo.SendScreen(data); } #region ThunderCloud foreach (var Cloud in client.Map.Clouds.Values) { if (Cloud == null) continue; if (Kernel.GetDistance(Cloud.X, Cloud.Y, client.Entity.X, client.Entity.Y) > 16) continue; if (DateTime.Now > Cloud.EndTime || Cloud.Owner == null) { Cloud.DisposeCloud(client); return; } #region ThunderCloud if (!Cloud.Dead && Time32.Now > Cloud.LastCloudAttack.AddSeconds(Cloud.ThunderBolt == true ? 1 : 2)) { if (client.Entity.Cloud != null) { var spell = Database.SpellTable.GetSpell(12970, client); SpellUse suse = new SpellUse(true); suse.Attacker = client.Entity.Cloud.UID; suse.SpellID = 13190; suse.SpellLevel = 0; suse.X = client.Entity.Cloud.X; suse.Y = client.Entity.Cloud.Y; Entity attacked = null; foreach (Interfaces.IMapObject _obj in client.Screen.Objects) { if (_obj == null) continue; if (_obj.MapObjType == MapObjectType.Monster || _obj.MapObjType == MapObjectType.Entity) { Cloud.LastCloudAttack = Time32.Now; attacked = _obj as Entity; if (Kernel.GetDistance(Cloud.X, Cloud.Y, attacked.X, attacked.Y) <= 15) { Attack attack = new Attack(true); if (Game.Attacking.Handle.CanAttack(Cloud.Owner.Entity, attacked, spell, attack.AttackType == Attack.Melee)) { attack.Effect1 = Attack.AttackEffects1.None; uint damage = Game.Attacking.Calculate.Melee(Cloud.Owner.Entity, attacked, ref attack); damage = (uint)(damage * 0.200); if (Cloud.ThunderBolt) damage += Game.Attacking.Calculate.Melee(Cloud.Owner.Entity, attacked, ref attack); damage = (uint)(damage * 0.200); suse.Effect1 = attack.Effect1; Game.Attacking.Handle.ReceiveAttack(Cloud.Owner.Entity, attacked, attack, ref damage, spell); suse.AddTarget(attacked.UID, damage, attack); break; } } } } client.SendScreen(suse, true); } } } #endregion #endregion } } } } } private static void guardsCallback(GameState client, int time) { if (!client.Socket.IsAlive) { client.Screen.DisposeTimers(); return; } if (client.Entity == null) return; if (client.Map == null) return; if (client.Map.FreezeMonsters) return; Time32 Now = new Time32(time); foreach (IMapObject obj in client.Screen.Objects) { if (obj != null) { if (obj.MapObjType == MapObjectType.Monster) { Entity monster = obj as Entity; if (monster.Companion) continue; if (monster.Boss == 1 || monster.MonsterInfo.Boss) continue; if (monster.Dead || monster.Killed) continue; if (monster.MonsterInfo.Guard) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.MinimumSpeed)) { if (monster.MonsterInfo.InSight == 0) { ushort xx = (ushort)Kernel.Random.Next(monster.X - 2, monster.X + 2); ushort yy = (ushort)Kernel.Random.Next(monster.Y - 2, monster.Y + 2); if (monster.X != monster.MonsterInfo.BoundX || monster.Y != monster.MonsterInfo.BoundY) { monster.X = monster.MonsterInfo.BoundX; monster.Y = monster.MonsterInfo.BoundY; TwoMovements jump = new TwoMovements(); jump.X = monster.MonsterInfo.BoundX; jump.Y = monster.MonsterInfo.BoundY; jump.EntityCount = 1; jump.FirstEntity = monster.UID; jump.MovementType = TwoMovements.Jump; client.SendScreen(jump, true); } if (client.Entity.ContainsFlag(Update.Flags.FlashingName)) monster.MonsterInfo.InSight = client.Entity.UID; } else { if (client.Entity.ContainsFlag(Update.Flags.FlashingName)) { if (monster.MonsterInfo.InSight == client.Entity.UID) { if (!client.Entity.Dead) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.AttackSpeed)) { short distance = Kernel.GetDistance(monster.X, monster.Y, client.Entity.X, client.Entity.Y); if (distance <= monster.MonsterInfo.AttackRange) { monster.MonsterInfo.LastMove = Time32.Now; new Game.Attacking.Handle(null, monster, client.Entity); } else { if (distance <= monster.MonsterInfo.ViewRange) { TwoMovements jump = new TwoMovements(); jump.X = client.Entity.X; jump.Y = client.Entity.Y; monster.X = client.Entity.X; monster.Y = client.Entity.Y; jump.EntityCount = 1; jump.FirstEntity = monster.UID; jump.MovementType = TwoMovements.Jump; client.SendScreen(jump, true); } } } } } } else { if (monster.MonsterInfo.InSight == client.Entity.UID) { monster.MonsterInfo.InSight = 0; } } } foreach (IMapObject obj2 in client.Screen.Objects) { if (obj2 == null) continue; //if (obj2.MapObjType == MapObjectType.Item) //{ // FloorItem flooritem = obj2 as FloorItem; // if (flooritem == null) continue; // if (flooritem.ValueType == FloorItem.FloorValueType.Money) // { // short distance = Kernel.GetDistance(monster.X, monster.Y, flooritem.X, flooritem.Y); // if (distance <= 15) // { // FloorItem item = new FloorItem(true); // item.Type = 3; // item.UID = client.Entity.UID; // item.X = client.Entity.X; // item.Y = client.Entity.Y; // // client.Send(Constants.PickupGold(floorItem.Value)); // monster.MonsterInfo.SendScreen(item); // flooritem.Type = 2; // client.RemoveScreenSpawn(flooritem, true); // } // } //} if (obj2.MapObjType == MapObjectType.Monster) { Entity monster2 = obj2 as Entity; if (monster2 == null) continue; if (monster2.Dead) continue; if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.AttackSpeed)) { if (!monster2.MonsterInfo.Guard && (!monster2.Companion || monster2.Owner.Entity.ContainsFlag(Update.Flags.FlashingName))) { short distance = Kernel.GetDistance(monster.X, monster.Y, monster2.X, monster2.Y); if (distance <= monster.MonsterInfo.AttackRange) { monster.MonsterInfo.LastMove = Time32.Now; new Game.Attacking.Handle(null, monster, monster2); } } } } } } } } } } } private static void aliveMonstersCallback(GameState client, int time) { if (!client.Socket.IsAlive) { client.Screen.DisposeTimers(); return; } if (client.Entity == null) return; if (client.Map == null) return; if (client.Map.FreezeMonsters) return; Time32 Now = new Time32(time); foreach (IMapObject obj in client.Screen.Objects) { if (obj != null) { if (obj.MapObjType == MapObjectType.Monster) { Entity monster = obj as Entity; if (monster == null) continue; if (monster.Name == "CasprGuard" && !monster.Dead) { if (client.Entity.Dead && !client.Entity.ContainsFlag2(Update.Flags2.SoulShackle)) { if (MyMath.Success(50.0)) { client.Entity.BringToLife(); SpellUse use = new SpellUse(true); use.Attacker = monster.UID; use.X = client.Entity.X; use.Y = client.Entity.Y; use.SpellID = 1100; use.AddTarget(client.Entity, 0, null); Kernel.SendWorldMessage(use, Program.Values, monster.MapID); if (MyMath.Success(50.0)) { use = new SpellUse(true); use.Attacker = monster.UID; use.X = client.Entity.X; use.Y = client.Entity.Y; use.SpellID = 30000; use.AddTarget(client.Entity, 0, null); Kernel.SendWorldMessage(use, Program.Values, monster.MapID); client.Entity.AzureShieldDefence = (ushort)(3000 * 4); client.Entity.AzureShieldLevel = 4; client.Entity.MagicShieldStamp = Time32.Now; client.Entity.AzureShieldStamp = DateTime.Now; client.Entity.AddFlag2(Update.Flags2.AzureShield); client.Entity.MagicShieldTime = 60; client.Entity.AzureShieldPacket(); if (client.Entity.EntityFlag == EntityFlag.Entity) client.Send(Constants.Shield(12000, client.Entity.MagicShieldTime)); } else { use = new SpellUse(true); use.Attacker = monster.UID; use.X = client.Entity.X; use.Y = client.Entity.Y; use.SpellID = 6002; use.AddTarget(client.Entity, 0, null); Kernel.SendWorldMessage(use, Program.Values, monster.MapID); client.Entity.AddFlag2(Update.Flags2.EffectBall); client.Entity.NoDrugsStamp = Time32.Now; client.Entity.NoDrugsTime = (short)60; if (client.Entity.EntityFlag == EntityFlag.Entity) client.Send(Constants.NoDrugs(60)); } } else { SpellUse use = new SpellUse(true); use.Attacker = monster.UID; use.X = client.Entity.X; use.Y = client.Entity.Y; use.SpellID = 10405; use.AddTarget(client.Entity, 0, null); Kernel.SendWorldMessage(use, Program.Values, monster.MapID); if (!client.Entity.ContainsFlag2(Update.Flags2.SoulShackle)) { client.Entity.AddFlag2(Update.Flags2.SoulShackle);//Give them shackeld effect client.Entity.ShackleStamp = Time32.Now;//Set stamp so source can remove the flag after X seconds client.Entity.ShackleTime = 35;//(short)(30 + 15 * spell.Level);//double checking here. Could be db has this wrong. Network.GamePackets.Update upgrade = new Network.GamePackets.Update(true); upgrade.UID = client.Entity.UID; upgrade.Append(Network.GamePackets.Update.SoulShackle , 111 , 35, 0, 4); client.Entity.Owner.Send(upgrade.ToArray()); if (client.Entity.EntityFlag == EntityFlag.Entity) client.Send(Constants.Shackled(client.Entity.ShackleTime)); } } } } if (monster.MonsterInfo.Guard || monster.Companion || monster.Dead) continue; if (monster.MonsterInfo.Reviver) { if (client.Entity.Dead && Now > client.Entity.DeathStamp.AddSeconds(5)) { client.Entity.BringToLife(); SpellUse use = new SpellUse(true); use.Attacker = monster.UID; use.X = client.Entity.X; use.Y = client.Entity.Y; use.SpellID = 1100; use.AddTarget(client.Entity, 0, null); Kernel.SendWorldMessage(use, Program.Values, monster.MapID); } return; } short distance = Kernel.GetDistance(monster.X, monster.Y, client.Entity.X, client.Entity.Y); if (distance > Constants.pScreenDistance) { client.Screen.Remove(obj); continue; } if (monster.MonsterInfo.InSight != 0 && monster.MonsterInfo.InSight != client.Entity.UID) { if (monster.MonsterInfo.InSight > 1000000) { GameState cl; if (Kernel.GamePool.TryGetValue(monster.MonsterInfo.InSight, out cl)) { short dst = Kernel.GetDistance(monster.X, monster.Y, cl.Entity.X, cl.Entity.Y); if (dst > Constants.pScreenDistance) monster.MonsterInfo.InSight = 0; } else monster.MonsterInfo.InSight = 0; } //else //{ // Entity companion = client.Map.Companions[monster.MonsterInfo.InSight]; // if (companion != null) // { // short dst = Kernel.GetDistance(monster.X, monster.Y, companion.X, companion.Y); // if (dst > Constants.pScreenDistance) // monster.MonsterInfo.InSight = 0; // } // else // monster.MonsterInfo.InSight = 0; //} } if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.MinimumSpeed)) { if (distance <= Constants.pScreenDistance) { #region Companions foreach (var pet in client.Pet.Pets.Values) { if (pet != null) { #region Pets if (pet.Entity.Companion && !pet.Entity.Dead) { short distance2 = Kernel.GetDistance(monster.X, monster.Y, pet.Entity.X, pet.Entity.Y); if (distance > distance2 || client.Entity.ContainsFlag(Update.Flags.Invisibility) || client.Entity.ContainsFlag(Update.Flags.Fly)) { if (monster.MonsterInfo.InSight == 0) { monster.MonsterInfo.InSight = pet.Entity.UID; } else { if (monster.MonsterInfo.InSight == pet.Entity.UID) { if (distance2 > Constants.pScreenDistance) { monster.MonsterInfo.InSight = 0; } else { if (distance2 <= monster.MonsterInfo.AttackRange) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.AttackSpeed)) { monster.MonsterInfo.LastMove = Time32.Now; new Game.Attacking.Handle(null, monster, pet.Entity); if (Time32.Now >= monster.MonsterInfo.Lastpop.AddSeconds(30)) { monster.MonsterInfo.Lastpop = Time32.Now; continue; } } } else { if (distance2 > monster.MonsterInfo.ViewRange / 2) { if (distance2 < Constants.pScreenDistance) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.RunSpeed)) { monster.MonsterInfo.LastMove = Time32.Now; Enums.ConquerAngle facing = Kernel.GetAngle(monster.X, monster.Y, pet.Entity.X, pet.Entity.Y); if (!monster.Move(facing)) { facing = (Enums.ConquerAngle)Kernel.Random.Next(7); if (monster.Move(facing)) { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; move.GroundMovementType = GroundMovement.Run; monster.MonsterInfo.SendScreen(move); continue; } } else { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; move.GroundMovementType = GroundMovement.Run; monster.MonsterInfo.SendScreen(move); continue; } } } else { monster.MonsterInfo.InSight = 0; } } else { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.MoveSpeed)) { monster.MonsterInfo.LastMove = Time32.Now; Enums.ConquerAngle facing = Kernel.GetAngle(monster.X, monster.Y, pet.Entity.X, pet.Entity.Y); if (!monster.Move(facing)) { facing = (Enums.ConquerAngle)Kernel.Random.Next(7); if (monster.Move(facing)) { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; monster.MonsterInfo.SendScreen(move); continue; } } else { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; monster.MonsterInfo.SendScreen(move); continue; } } } } } } } } } #endregion } } #endregion #region Entity if (monster.MonsterInfo.InSight == 0) { if (distance <= monster.MonsterInfo.ViewRange) { if (!client.Entity.ContainsFlag(Update.Flags.Invisibility)) { if (monster.MonsterInfo.SpellID != 0 || !client.Entity.ContainsFlag(Update.Flags.Fly)) { monster.MonsterInfo.InSight = client.Entity.UID; } } } } else { if (monster.MonsterInfo.InSight == client.Entity.UID) { if (monster.MonsterInfo.SpellID == 0 && client.Entity.ContainsFlag(Update.Flags.Fly)) { monster.MonsterInfo.InSight = 0; return; } if (client.Entity.Dead) { monster.MonsterInfo.InSight = 0; return; } if (distance > Constants.pScreenDistance) { monster.MonsterInfo.InSight = 0; } else { if (distance <= monster.MonsterInfo.AttackRange) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.AttackSpeed)) { monster.MonsterInfo.LastMove = Time32.Now; new Game.Attacking.Handle(null, monster, client.Entity); if (Time32.Now >= monster.MonsterInfo.Lastpop.AddSeconds(30)) { monster.MonsterInfo.Lastpop = Time32.Now; } } } else { if (distance > monster.MonsterInfo.ViewRange / 2) { if (distance < Constants.pScreenDistance) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.RunSpeed)) { monster.MonsterInfo.LastMove = Time32.Now; Enums.ConquerAngle facing = Kernel.GetAngle(monster.X, monster.Y, client.Entity.X, client.Entity.Y); if (!monster.Move(facing)) { facing = (Enums.ConquerAngle)Kernel.Random.Next(7); if (monster.Move(facing)) { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; move.GroundMovementType = Network.GamePackets.GroundMovement.Run; monster.MonsterInfo.SendScreen(move); } } else { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; move.GroundMovementType = Network.GamePackets.GroundMovement.Run; monster.MonsterInfo.SendScreen(move); } } } else { monster.MonsterInfo.InSight = 0; } } else { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.MoveSpeed)) { monster.MonsterInfo.LastMove = Time32.Now; Enums.ConquerAngle facing = Kernel.GetAngle(monster.X, monster.Y, client.Entity.X, client.Entity.Y); if (!monster.Move(facing)) { facing = (Enums.ConquerAngle)Kernel.Random.Next(7); if (monster.Move(facing)) { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; monster.MonsterInfo.SendScreen(move); } } else { monster.Facing = facing; GroundMovement move = new GroundMovement(true); move.Direction = facing; move.UID = monster.UID; monster.MonsterInfo.SendScreen(move); } } } } } } } #endregion } } } else if (obj.MapObjType == MapObjectType.Item) { FloorItem item = obj as FloorItem; if (item == null) continue; if (item.ItemID == FloorItem.InfernalEcho) { if (item.Owner == client) { if (item.OnFloor.AddSeconds(4).Next(time: time)) { item.UseTime = Time32.Now; var spell = Database.SpellTable.GetSpell(12550, client); var attack = new Attack(true); attack.Attacker = item.Owner.Entity.UID; attack.AttackType = Attack.Melee; foreach (var obj1 in client.Screen.Objects) { if (Kernel.GetDistance(obj1.X, obj1.Y, obj.X, obj.Y) <= 10) { if (obj1.MapObjType == MapObjectType.Entity && client.Entity.PKMode != Enums.PKMode.Capture) { var attacked = obj1 as Entity; if (Attacking.Handle.CanAttack(client.Entity, attacked, spell, false)) { uint damage = Game.Attacking.Calculate.Melee(client.Entity, attacked, spell, ref attack); damage = (uint)(damage * 0.100); attack.Damage = damage; attack.Attacked = attacked.UID; attack.X = attacked.X; attack.Y = attacked.Y; attacked.Update(_String.Effect, "twz_xldy_gj", true); Attacking.Handle.ReceiveAttack(client.Entity, attacked, attack, ref damage, spell); } } if (obj1.MapObjType == MapObjectType.Monster) { var attacked = obj1 as Entity; if (Attacking.Handle.CanAttack(client.Entity, attacked, spell, false)) { uint damage = Game.Attacking.Calculate.Melee(client.Entity, attacked, spell, ref attack); damage = (uint)(damage * 0.100); attack.Damage = damage; attack.Attacked = attacked.UID; attack.X = attacked.X; attack.Y = attacked.Y; attacked.Update(_String.Effect, "twz_xldy_gj", true); Attacking.Handle.ReceiveAttack(client.Entity, attacked, attack, ref damage, spell); } } } } } } } if (item.Type == FloorItem.Effect) { if (item.ItemID == FloorItem.RageOfWarTrap) { if (item.Owner == client) { if (item.OnFloor.AddSeconds(2).Next(time: time)) { var spell = Database.SpellTable.GetSpell(12930, client); if (spell == null) return; var attack = new Attack(true); attack.Attacker = client.Entity.UID; attack.AttackType = Attack.Melee; foreach (var obj1 in client.Screen.Objects) { if (obj1 == null) continue; var attacked = obj1 as Entity; if (attacked == null) continue; if (Kernel.GetDistance(obj1.X, obj1.Y, obj.X, obj.Y) <= 3) { if (Attacking.Handle.CanAttack(client.Entity, attacked, spell, attack.AttackType == Attack.Melee)) { uint damage = (uint)(Game.Attacking.Calculate.Melee(client.Entity, attacked, spell, ref attack)); damage = (uint)(damage * 0.100); attack.Effect1 = Attack.AttackEffects1.None; attack.Damage = damage; attack.Attacked = attacked.UID; attack.X = attacked.X; attack.Y = attacked.Y; attack.Effect1 = Attack.AttackEffects1.None; Attacking.Handle.ReceiveAttack(client.Entity, attacked, attack, ref damage, spell); } } } } } } if (item.ItemID == FloorItem.DaggerStorm || item.ItemID == FloorItem.FuryofEgg || item.ItemID == FloorItem.ShacklingIce) { if (item.Owner == client) { if (Time32.Now > item.UseTime.AddSeconds(1)) { item.UseTime = Time32.Now; var spell = Database.SpellTable.GetSpell(11600, client); var attack = new Attack(true); attack.Attacker = item.Owner.Entity.UID; attack.AttackType = Attack.Melee; foreach (var obj1 in client.Screen.Objects) { if (Kernel.GetDistance(obj1.X, obj1.Y, obj.X, obj.Y) <= 3) { if (obj1.MapObjType == MapObjectType.Monster || obj1.MapObjType == MapObjectType.Entity) { var attacked = obj1 as Entity; if (Attacking.Handle.CanAttack(client.Entity, attacked, spell, false)) { uint damage = Game.Attacking.Calculate.Melee(client.Entity, attacked, spell, ref attack); damage = (uint)(damage * 0.100); attack.Damage = damage; attack.Attacked = attacked.UID; attack.X = attacked.X; attack.Y = attacked.Y; Attacking.Handle.ReceiveAttack(client.Entity, attacked, attack, ref damage, spell); } } else if (obj1.MapObjType == MapObjectType.SobNpc) { var attacked = obj1 as SobNpcSpawn; if (Attacking.Handle.CanAttack(client.Entity, attacked, spell)) { uint damage = Game.Attacking.Calculate.Melee(client.Entity, attacked, ref attack); damage = (uint)(damage * 0.100); attack.Damage = damage; attack.Attacked = attacked.UID; attack.X = attacked.X; attack.Y = attacked.Y; Attacking.Handle.ReceiveAttack(client.Entity, attacked, attack, damage, spell); } } } } } } } } } } } } private static void itemsCallback(GameState client, int time) { if (!client.Socket.IsAlive) { client.Screen.DisposeTimers(); return; } if (client.Entity == null) return; if (client.Map == null) return; if (client.Map.FreezeMonsters) return; Time32 Now = new Time32(time); foreach (IMapObject obj in client.Screen.Objects) { if (obj != null) { if (obj.MapObjType == MapObjectType.Item) { FloorItem item = obj as FloorItem; if (item == null) continue; if (item.Type == FloorItem.Effect) { if (item.ItemID == FloorItem.RageOfWarTrap) { if (item.OnFloor.AddSeconds(3).Next(time: time)) { item.Type = Network.GamePackets.FloorItem.RemoveEffect; client.Map.RemoveFloorItem(item); client.RemoveScreenSpawn(item, true); } } #region Aurora-Flame Lotus if (item.ItemID == FloorItem.FlameLotus || item.ItemID == FloorItem.AuroraLotus) { if (item.OnFloor.AddSeconds(8).Next(time: time)) { List<Game.Entity> array = new List<Entity>(); #region FlameLotus if (item.ItemID == FloorItem.FlameLotus) { foreach (var client2 in Kernel.GamePool.Values.Where(x => Kernel.GetDistance(x.Entity.X, x.Entity.Y, item.X, item.Y) <= 5 && x.Entity.Dead == false)) { array.Add(client2.Entity); } foreach (var monster in client.Map.Entities.Values.Where(x => Kernel.GetDistance(x.X, x.Y, item.X, item.Y) <= 5 && x.Dead == false)) { array.Add(monster); } var attack = new Attack(true); var spell = Database.SpellTable.GetSpell(12380, item.Owner); attack.Attacker = item.UID; SpellUse suse = new SpellUse(true); suse.Attacker = item.UID; suse.SpellID = spell.ID; suse.SpellLevel = spell.Level; suse.X = item.X; suse.Y = item.Y; foreach (Entity pClient in array) { if (pClient == null) return; if (pClient.UID != item.Owner.Entity.UID) { if (Game.Attacking.Handle.CanAttack(item.Owner.Entity, pClient, null, false)) { uint damage = Game.Attacking.Calculate.Magic(item.Owner.Entity, pClient, spell, ref attack); damage = (uint)(damage * 0.100); attack.Damage = damage; Game.Attacking.Handle.ReceiveAttack(item.Owner.Entity, pClient, attack, ref damage, spell); suse.AddTarget(pClient, damage, attack); } } } Kernel.SendWorldMessage(suse, Kernel.GamePool.Values.Where(i => i.Entity.MapID == item.MapID && Kernel.GetDistance(item.X, item.Y, i.Entity.X, i.Entity.Y) < 16).ToArray()); } #endregion #region AuroraLotus if (item.ItemID == FloorItem.AuroraLotus) { if (item.Owner.Team != null) { foreach (var client2 in Kernel.GamePool.Values.Where(x => (Kernel.GetDistance(x.Entity.X, x.Entity.Y, item.X, item.Y) <= 16 && x.Entity.Dead) && (item.Owner.Team.IsTeammate(x.Entity.UID) || (item.Owner.Guild != null && item.Owner.Guild.Members.ContainsKey(x.Entity.UID))))) { array.Add(client2.Entity); } } SpellUse suse = new SpellUse(true); suse.Attacker = item.UID; suse.SpellID = 1100; suse.SpellLevel = 0; suse.X = item.X; suse.Y = item.Y; foreach (Entity pClient in array) { if (pClient == null) return; if (pClient.UID != item.Owner.Entity.UID && !pClient.ContainsFlag2(Network.GamePackets.Update.Flags2.SoulShackle)) { suse.AddTarget(pClient, 0, null); pClient.BringToLife(); var attacked = pClient; var attacker = item.Owner.Entity; if (attacker.Owner.Spells.ContainsKey(12390)) { var spell = Database.SpellTable.GetSpell(12390, item.Owner); if (Kernel.Rate(spell.Percent)) { SpellUse susee = new SpellUse(true); susee.Attacker = attacker.UID; susee.SpellID = spell.ID; susee.SpellLevel = spell.Level; susee.X = attacked.X; susee.Y = attacked.Y; attacked.Owner.SendScreen(susee, true); attacked.AddFlag(Update.Flags.Stigma); attacked.StigmaStamp = Time32.Now; attacked.StigmaIncrease = 15; attacked.StigmaTime = 45; attacked.MagicShieldStamp = Time32.Now; attacked.MagicShieldIncrease = 15; attacked.MagicShieldTime = 60; attacked.AddFlag(Update.Flags.MagicShield); } } } } Kernel.SendWorldMessage(suse, Kernel.GamePool.Values.Where(i => i.Entity.MapID == item.MapID && Kernel.GetDistance(item.X, item.Y, i.Entity.X, i.Entity.Y) < 16).ToArray()); } #endregion item.Type = Network.GamePackets.FloorItem.RemoveEffect; client.Map.RemoveFloorItem(item); client.RemoveScreenSpawn(item, true); } } #endregion if (item.ItemID == FloorItem.ShadowofChaser) { if (item.OnFloor.AddMilliseconds(1000).Next(time: time)) { Game.Attacking.Handle.ShadowofChaser(item.ShadowofChaserAttacker, item.ShadowofChaserAttacked, item.Attack as Attack, 2); client.Map.RemoveFloorItem(item); item.Type = Network.GamePackets.FloorItem.RemoveEffect; client.RemoveScreenSpawn(item, true); } } if (item.ItemID == 1397) { if (item.OnFloor.AddSeconds(7).Next(time: time)) { if (!item.Owner.Spells.ContainsKey(12550)) return; var spell = Database.SpellTable.GetSpell(item.Owner.Spells[12550].ID, item.Owner.Spells[12550].Level); var attack = new Attack(true); attack.Attacker = item.Owner.Entity.UID; attack.X = item.X; attack.Y = item.Y; attack.Damage = spell.ID; attack.AttackType = Attack.Magic; SpellUse suse = new SpellUse(true); suse.Attacker = item.Owner.Entity.UID; suse.SpellID = spell.ID; suse.SpellLevel = spell.Level; suse.X = item.X; suse.Y = item.Y; suse.SpellEffect = 1; foreach (var _Ob in item.Owner.Screen.Objects) { if (_Ob == null) continue; if (_Ob.MapObjType == MapObjectType.Monster || _Ob.MapObjType == MapObjectType.Entity) { var attacked = _Ob as Entity; if (Kernel.GetDistance(item.X, item.Y, attacked.X, attacked.Y) <= spell.Range) { if (Game.Attacking.Handle.CanAttack(item.Owner.Entity, attacked, spell, attack.AttackType == Attack.Ranged)) { uint damage = Game.Attacking.Calculate.Melee(item.Owner.Entity, attacked, ref attack); damage = (uint)(damage * 0.100); // damage = (uint)(damage * .95); suse.Effect1 = attack.Effect1; Game.Attacking.Handle.ReceiveAttack(item.Owner.Entity, attacked, attack, ref damage, spell); suse.AddTarget(attacked, damage, attack); } } } } item.Owner.SendScreen(suse, true); item.Type = FloorItem.Effect; client.Map.RemoveFloorItem(item); client.RemoveScreenSpawn(item, true); } if (item.OnFloor.AddSeconds(3).Next(time: time)) { if (!item.Owner.Spells.ContainsKey(12550)) return; var spell = Database.SpellTable.GetSpell(item.Owner.Spells[12550].ID, item.Owner.Spells[12550].Level); var attack = new Attack(true); attack.Attacker = item.Owner.Entity.UID; attack.X = item.X; attack.Y = item.Y; attack.Damage = spell.ID; attack.AttackType = Attack.Magic; SpellUse suse = new SpellUse(true); suse.Attacker = item.Owner.Entity.UID; suse.SpellID = spell.ID; suse.SpellLevel = spell.Level; suse.X = item.X; suse.Y = item.Y; suse.SpellEffect = 1; foreach (var _Ob in item.Owner.Screen.Objects) { if (_Ob == null) continue; if (_Ob.MapObjType == MapObjectType.Monster || _Ob.MapObjType == MapObjectType.Entity) { var attacked = _Ob as Entity; if (Kernel.GetDistance(item.X, item.Y, attacked.X, attacked.Y) <= spell.Range) { if (Game.Attacking.Handle.CanAttack(item.Owner.Entity, attacked, spell, attack.AttackType == Attack.Ranged)) { uint damage = Game.Attacking.Calculate.Melee(item.Owner.Entity, attacked, ref attack); damage = (uint)(damage * 0.100); suse.Effect1 = attack.Effect1; Game.Attacking.Handle.ReceiveAttack(item.Owner.Entity, attacked, attack, ref damage, spell); suse.AddTarget(attacked, damage, attack); } } } } item.Owner.SendScreen(suse, true); item.Type = FloorItem.Effect; client.Map.RemoveFloorItem(item); client.RemoveScreenSpawn(item, true); } } if (item.ItemID == FloorItem.DaggerStorm || item.ItemID == FloorItem.FuryofEgg || item.ItemID == FloorItem.ShacklingIce) { if (item.OnFloor.AddSeconds(4).Next(time: time)) { item.Type = Network.GamePackets.FloorItem.RemoveEffect; client.Map.RemoveFloorItem(item); client.RemoveScreenSpawn(item, true); } } if (item.ItemID == FloorItem.Twilight) { if (item.OnFloor.AddMilliseconds(500).Next(time: time)) { item.Type = Network.GamePackets.FloorItem.RemoveEffect; //client.SendScreen(item, true); client.Map.RemoveFloorItem(item); client.RemoveScreenSpawn(item, true); } } } else { if (item.OnFloor.AddSeconds(Constants.FloorItemSeconds).Next(time: time)) { item.Type = Network.GamePackets.FloorItem.Remove; foreach (Interfaces.IMapObject _obj in client.Screen.Objects) if (_obj != null) if (_obj.MapObjType == MapObjectType.Entity) (_obj as Entity).Owner.Send(item); client.Map.RemoveFloorItem(item); client.Screen.Remove(item); } } } } } } private static void CopraMobsCallback(GameState client, int time) { if (!client.Socket.IsAlive) { client.Screen.DisposeTimers(); return; } if (client.Entity == null) return; if (client.Map == null) return; if (client.Map.FreezeMonsters) return; Time32 Now = new Time32(time); foreach (IMapObject obj in client.Screen.Objects) { if (obj != null) { if (obj.MapObjType == MapObjectType.Monster) { Entity monster = obj as Entity; if (monster.Companion) continue; if (monster.Dead || monster.Killed) continue; if (monster.MonsterInfo.Type == 2 || monster.Mesh == 482) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.MinimumSpeed)) { if (monster.MonsterInfo.InSight == 0) { ushort xx = (ushort)Kernel.Random.Next(monster.X - 10, monster.X + 10); ushort yy = (ushort)Kernel.Random.Next(monster.Y - 10, monster.Y + 10); if (monster.X != xx || monster.Y != yy) { monster.X = xx; monster.Y = yy; TwoMovements jump = new TwoMovements(); jump.X = xx; jump.Y = yy; jump.EntityCount = 1; jump.FirstEntity = monster.UID; jump.MovementType = TwoMovements.Jump; client.SendScreen(jump, true); } // if (client.Entity.ContainsFlag(Update.Flags.FlashingName)) // monster.MonsterInfo.InSight = client.Entity.UID; } else { // if (client.Entity.ContainsFlag(Update.Flags.FlashingName)) { if (monster.MonsterInfo.InSight == client.Entity.UID) { if (!client.Entity.Dead) { if (Now >= monster.MonsterInfo.LastMove.AddMilliseconds(monster.MonsterInfo.AttackSpeed)) { short distance = Kernel.GetDistance(monster.X, monster.Y, client.Entity.X, client.Entity.Y); if (distance <= monster.MonsterInfo.AttackRange) { monster.MonsterInfo.LastMove = Time32.Now; new Game.Attacking.Handle(null, monster, client.Entity); if (Time32.Now >= monster.MonsterInfo.Lastpop.AddSeconds(30)) { monster.MonsterInfo.Lastpop = Time32.Now; } } else { if (distance <= monster.MonsterInfo.ViewRange) { TwoMovements jump = new TwoMovements(); jump.X = client.Entity.X; jump.Y = client.Entity.Y; monster.X = client.Entity.X; monster.Y = client.Entity.Y; jump.EntityCount = 1; jump.FirstEntity = monster.UID; jump.MovementType = TwoMovements.Jump; client.SendScreen(jump, true); } } } } } } } } } } } } } private IDisposable[] TimerSubscriptions; private object DisposalSyncRoot; private Interfaces.IMapObject[] _objects; private static ConcurrentDictionary<uint, PokerTable> PokerTables; public Interfaces.IMapObject[] Objects { get { return _objects; } } private ConcurrentDictionary<uint, Interfaces.IMapObject> _objectDictionary; public ConcurrentDictionary<uint, Game.Statue> Statue = new ConcurrentDictionary<uint, Statue>(); public Client.GameState Owner; public Screen(Client.GameState client) { Owner = client; _objects = new Interfaces.IMapObject[0]; PokerTables = new ConcurrentDictionary<uint, PokerTable>(); _objectDictionary = new ConcurrentDictionary<uint, IMapObject>(); TimerSubscriptions = new IDisposable[] { MonsterBuffers.Add(client), Guards.Add(client), AliveMonsters.Add(client), FloorSpells.Add(client), Items.Add(client), CopraMobs.Add(client) }; DisposalSyncRoot = new object(); } ~Screen() { DisposeTimers(); Clear(); _objects = null; _objectDictionary = null; Owner = null; } public void DisposeTimers() { lock (DisposalSyncRoot) { if (TimerSubscriptions == null) return; for (int i = 0; i < TimerSubscriptions.Length; i++) { if (TimerSubscriptions[i] != null) { TimerSubscriptions[i].Dispose(); TimerSubscriptions[i] = null; } } } } private void updateBase() { _objects = _objectDictionary.Values.ToArray(); } public bool Add(Interfaces.IMapObject _object) { try { if (_object == null) return false; var allobject = _objectDictionary; if (allobject.ContainsKey(_object.UID)) if (allobject[_object.UID] == null) allobject.Remove(_object.UID); if (!allobject.ContainsKey(_object.UID)) { if (Kernel.GetDistance(_object.X, _object.Y, Owner.Entity.X, Owner.Entity.Y) <= Constants.pScreenDistance) { allobject[_object.UID] = _object; updateBase(); return true; } } } catch { return false; } return false; } public bool Remove(Interfaces.IMapObject _object) { if (_object == null) return false; if (_objectDictionary.Remove(_object.UID)) { updateBase(); if (_object.MapObjType == MapObjectType.Item) { FloorItem item = _object as FloorItem; if (item.Type >= FloorItem.Effect) { item.Type = FloorItem.RemoveEffect; Owner.Send(item); } else { item.Type = FloorItem.Remove; Owner.Send(item); item.Type = FloorItem.Drop; } } else if (_object.MapObjType == MapObjectType.Entity) { Owner.Send(new Data(true) { UID = _object.UID, ID = Network.GamePackets.Data.RemoveEntity }); } else if (_object.MapObjType == MapObjectType.StaticEntity) { Owner.Send(new Data(true) { UID = _object.UID, ID = Network.GamePackets.Data.RemoveEntity }); } return true; } return false; } public bool TryGetValue(uint uid, out Entity entity) { entity = null; Interfaces.IMapObject imo = null; if (_objectDictionary.TryGetValue(uid, out imo)) { if (imo == null) { _objectDictionary.Remove(uid); updateBase(); return false; } if (imo is Entity) { entity = imo as Entity; return true; } } return false; } public bool GetRaceObject(Func<IMapObject, bool> predicate, out StaticEntity entity) { entity = null; foreach (var obj in Objects) if (obj is StaticEntity) if (predicate(obj)) entity = obj as StaticEntity; return entity != null; } public bool TryGetSob(uint uid, out SobNpcSpawn sob) { sob = null; Interfaces.IMapObject imo = null; if (_objectDictionary.TryGetValue(uid, out imo)) { if (imo == null) { _objectDictionary.Remove(uid); updateBase(); return false; } if (imo is SobNpcSpawn) { sob = imo as SobNpcSpawn; return true; } } return false; } public bool TryGetFloorItem(uint uid, out FloorItem item) { item = null; Interfaces.IMapObject imo = null; if (_objectDictionary.TryGetValue(uid, out imo)) { if (imo == null) { _objectDictionary.Remove(uid); updateBase(); return false; } if (imo is FloorItem) { item = imo as FloorItem; return true; } } return false; } public IEnumerable<T> Select<T>(MapObjectType type) where T : class { foreach (var obj in Objects) if (obj != null) if (obj.MapObjType == type) yield return obj as T; } public IEnumerable<T> Where<T>(Func<IMapObject, bool> predicate) where T : class { foreach (var obj in Objects) if (obj != null) if (predicate(obj)) yield return obj as T; } public IEnumerable<T> SelectWhere<T>(MapObjectType type, Func<T, bool> predicate) where T : class { foreach (var obj in Objects) if (obj != null) if (obj.MapObjType == type) if (predicate(obj as T)) yield return obj as T; } public bool Contains(Interfaces.IMapObject _object) { if (_object == null) return false; return _objectDictionary.ContainsKey(_object.UID); } public bool Contains(uint uid) { return _objectDictionary.ContainsKey(uid); } public void CleanUp(Interfaces.IPacket spawnWith) { bool remove; try { foreach (IMapObject Base in Objects) { if (Base == null) continue; remove = false; if (Base.MapObjType == MapObjectType.Monster) { if ((Base as Entity).Dead) { if (Time32.Now > (Base as Entity).DeathStamp.AddSeconds(8)) remove = true; else remove = false; } if (Kernel.GetDistance(Owner.Entity.X, Owner.Entity.Y, Base.X, Base.Y) >= Constants.remScreenDistance) remove = true; if (remove) { if ((Base as Entity).MonsterInfo.InSight == Owner.Entity.UID) (Base as Entity).MonsterInfo.InSight = 0; } } else if (Base.MapObjType == MapObjectType.Entity) { if (remove = (Kernel.GetDistance(Owner.Entity.X, Owner.Entity.Y, Base.X, Base.Y) >= Constants.pScreenDistance)) { GameState pEntity = Base.Owner as GameState; pEntity.Screen.Remove(Owner.Entity); } } else if (Base.MapObjType == MapObjectType.Item) { remove = (Kernel.GetDistance(Owner.Entity.X, Owner.Entity.Y, Base.X, Base.Y) >= 22); } else { remove = (Kernel.GetDistance(Owner.Entity.X, Owner.Entity.Y, Base.X, Base.Y) >= Constants.remScreenDistance); } if (Base.MapID != Owner.Map.ID) remove = true; if (remove) { Remove(Base); } } } catch (Exception e) { Program.SaveException(e); } } public void FullWipe() { foreach (IMapObject Base in Objects) { if (Base == null) continue; Data data = new Data(true); data.UID = Base.UID; data.ID = Network.GamePackets.Data.RemoveEntity; Owner.Send(data); if (Base.MapObjType == Game.MapObjectType.Entity) { GameState pEntity = Base.Owner as GameState; pEntity.Screen.Remove(Owner.Entity); } } Clear(); } public void Clear() { _objectDictionary.Clear(); _objects = new IMapObject[0]; } public ConcurrentDictionary<uint, Game.BotShop> BOTSTALL = new ConcurrentDictionary<uint, BotShop>(); public void Reload(Interfaces.IPacket spawnWith = null) { try { var Map = Owner.Map; #region ThunderCloud foreach (var Cloud in Map.Clouds.Values) { if (Cloud == null) continue; if (Kernel.GetDistance(Cloud.X, Cloud.Y, Owner.Entity.X, Owner.Entity.Y) > 16) continue; Cloud.SendSpawn(Owner, false); } #endregion #region Npcs foreach (Interfaces.INpc npc in Map.Npcs.Values) { if (npc == null) continue; if (Kernel.GetDistance(npc.X, npc.Y, Owner.Entity.X, Owner.Entity.Y) > 16) continue; if (Contains(npc.UID)) continue; npc.SendSpawn(Owner, false); } foreach (var npc in Database.GuildCondutors.GuildConductors.Values) { if (npc == null) continue; if (npc.npc.MapID == Owner.Entity.MapID) { if (Kernel.GetDistance(npc.npc.X, npc.npc.Y, Owner.Entity.X, Owner.Entity.Y) > 16) continue; if (Contains(npc.npc.UID)) continue; npc.npc.SendSpawn(Owner, false); } } #endregion #region Items + map effects foreach (var item in Map.FloorItems.Values) { if (item == null) continue; if (Kernel.GetDistance(item.X, item.Y, Owner.Entity.X, Owner.Entity.Y) > 16) continue; if (Contains(item.UID)) continue; if (item.Type == FloorItem.Effect) { if (item.ItemID == FloorItem.DaggerStorm || item.ItemID == FloorItem.FuryofEgg || item.ItemID == FloorItem.ShacklingIce || item.ItemID == 31 || item.ItemID == 1397 || item.ItemID == FloorItem.RageOfWar || item.ItemID == FloorItem.ShadowofChaser) { if (item.OnFloor.AddSeconds(4).Next(time: Time32.Now.AllMilliseconds())) { item.Type = FloorItem.RemoveEffect; foreach (Interfaces.IMapObject _obj in Objects) if (_obj != null) if (_obj.MapObjType == MapObjectType.Entity) (_obj as Entity).Owner.Send(item); Map.RemoveFloorItem(item); } else item.SendSpawn(Owner, false); }//Done else item.SendSpawn(Owner, false); } else { if ((Time32.Now > item.OnFloor.AddSeconds(Constants.FloorItemSeconds)) || item.PickedUpAlready) { item.Type = Network.GamePackets.FloorItem.Remove; Map.RemoveFloorItem(item); } } item.SendSpawn(Owner); if (item.ItemID == FloorItem.AuroraLotus) { if (item.OnFloor.AddSeconds(7).Next(time: Time32.Now.AllMilliseconds())) { item.Type = Network.GamePackets.FloorItem.RemoveEffect; foreach (Interfaces.IMapObject _obj in Objects) if (_obj != null) if (_obj.MapObjType == MapObjectType.Entity) (_obj as Entity).Owner.Send(item); Map.RemoveFloorItem(item); //Attacking.Handle.AuroraLotus(item); } else item.SendSpawn(Owner, false); } else if (item.ItemID == FloorItem.FlameLotus) { if (item.OnFloor.AddSeconds(7).Next(time: Time32.Now.AllMilliseconds())) { item.Type = Network.GamePackets.FloorItem.RemoveEffect; foreach (Interfaces.IMapObject _obj in Objects) if (_obj != null) if (_obj.MapObjType == MapObjectType.Entity) (_obj as Entity).Owner.Send(item); Map.RemoveFloorItem(item); //Attacking.Handle.FlameLotus(item); } else item.SendSpawn(Owner, false); } else if (item.ItemID == FloorItem.TwilightDance) { if (item.OnFloor.AddSeconds(1).Next(time: Time32.Now.AllMilliseconds())) { item.Type = Network.GamePackets.FloorItem.RemoveEffect; foreach (Interfaces.IMapObject _obj in Objects) if (_obj != null) if (_obj.MapObjType == MapObjectType.Entity) (_obj as Entity).Owner.Send(item); Map.RemoveFloorItem(item); } else item.SendSpawn(Owner, false); } } #endregion AI.CheckScreen(Owner, spawnWith); foreach (Game.Entity monster in Map.Entities.Values) { if (monster == null) continue; if (Kernel.GetDistance(monster.X, monster.Y, Owner.Entity.X, Owner.Entity.Y) <= 16 && !Contains(monster.UID)) { if (!monster.Dead) { monster.SendSpawn(Owner, false); if (monster.MaxHitpoints > 65535) { Update upd = new Update(true) { UID = monster.UID }; // upd.Append(Update.MaxHitpoints, monster.MaxHitpoints); upd.Append(Update.Hitpoints, monster.Hitpoints); Owner.Send(upd); } } } } if (Owner.Map.ID == Copra.Roulette.Database.Roulettes.RouletteTable.MapID) { foreach (var R in Copra.Roulette.Database.Roulettes.RoulettesPoll.Values) { if (Kernel.GetDistance(R.SpawnPacket.X, R.SpawnPacket.Y, Owner.Entity.X, Owner.Entity.Y) <= Constants.nScreenDistance && !Contains(R.SpawnPacket.UID)) { Owner.Send(R.SpawnPacket); } } } #region RaceItems if (Owner.Map.StaticEntities.Count != 0) { foreach (var item in Owner.Map.StaticEntities.Values) { if (item == null) continue; if (!item.Viable) continue; if (Kernel.GetDistance(item.X, item.Y, Owner.Entity.X, Owner.Entity.Y) > 16) continue; if (Contains(item.UID)) continue; item.SendSpawn(Owner); } } #endregion #region Entitys CleanUp(spawnWith); if (Owner.Entity.MapID == 1002) { foreach (var statue in Game.Statue.Statues.Values) { if (statue > Owner) { Statue.TryAdd(statue.UID, statue); } else if (statue < Owner) { Game.Statue astatue; Statue.TryRemove(statue.UID, out astatue); } } } else { if (Statue.Count > 0) Statue.Clear(); } foreach (GameState pClient in Kernel.GamePool.Values) { if (pClient == null) return; if (pClient.Entity == null) return; if (Owner == null) return; if (Owner.Entity == null) return; if (pClient.Entity.UID != Owner.Entity.UID) { if (pClient.Map.ID == Owner.Map.ID) { short dist = Kernel.GetDistance(pClient.Entity.X, pClient.Entity.Y, Owner.Entity.X, Owner.Entity.Y); if (dist <= Constants.pScreenDistance && !Contains(pClient.Entity)) { if (pClient.Guild != null) pClient.Guild.SendName(Owner); if (Owner.Guild != null) Owner.Guild.SendName(pClient); if (pClient.Entity.InteractionInProgress && pClient.Entity.InteractionWith != Owner.Entity.UID && pClient.Entity.InteractionSet) { if (pClient.Entity.Body == 1003 || pClient.Entity.Body == 1004) { if (pClient.Entity.InteractionX == pClient.Entity.X && pClient.Entity.Y == pClient.Entity.InteractionY) { Network.GamePackets.Attack atak = new KhaledMohamed.Network.GamePackets.Attack(true); atak.Attacker = pClient.Entity.UID; atak.Attacked = pClient.Entity.InteractionWith; atak.X = pClient.Entity.X; atak.Y = pClient.Entity.Y; atak.AttackType = 49; atak.Damage = pClient.Entity.InteractionType; Owner.Send(atak); } } else { if (KhaledMohamed.Kernel.GamePool.ContainsKey(pClient.Entity.InteractionWith)) { Client.GameState Cs = KhaledMohamed.Kernel.GamePool[pClient.Entity.InteractionWith] as Client.GameState; if (Cs.Entity.X == pClient.Entity.InteractionX && pClient.Entity.Y == pClient.Entity.InteractionY) { Network.GamePackets.Attack atak = new KhaledMohamed.Network.GamePackets.Attack(true); atak.Attacker = pClient.Entity.UID; atak.Attacked = pClient.Entity.InteractionWith; atak.X = pClient.Entity.X; atak.Y = pClient.Entity.Y; atak.AttackType = 49; atak.Damage = pClient.Entity.InteractionType; Owner.Send(atak); } } } } if (pClient.Map.BaseID == 700) { if (Owner.InQualifier()) { if (pClient.InQualifier()) { Owner.Entity.SendSpawn(pClient); pClient.Entity.SendSpawn(Owner); if (pClient.Guild != null) Owner.Entity.SendSpawn(pClient, false); if (Owner.Guild != null) pClient.Entity.SendSpawn(Owner, false); if (spawnWith != null) pClient.Send(spawnWith); } else { Owner.Entity.SendSpawn(pClient); if (pClient.Guild != null) Owner.Entity.SendSpawn(pClient, false); Add(pClient.Entity); if (spawnWith != null) pClient.Send(spawnWith); } } else { if (pClient.InQualifier()) { pClient.Entity.SendSpawn(Owner); if (Owner.Guild != null) pClient.Entity.SendSpawn(Owner, false); pClient.Screen.Add(Owner.Entity); if (spawnWith != null) Owner.Send(spawnWith); } else { Owner.Entity.SendSpawn(pClient); pClient.Entity.SendSpawn(Owner); if (pClient.Guild != null) Owner.Entity.SendSpawn(pClient, false); if (Owner.Guild != null) pClient.Entity.SendSpawn(Owner, false); if (spawnWith != null) pClient.Send(spawnWith); } } } else { Owner.Entity.SendSpawn(pClient); pClient.Entity.SendSpawn(Owner); if (pClient.Guild != null) Owner.Entity.SendSpawn(pClient, false); if (Owner.Guild != null) pClient.Entity.SendSpawn(Owner, false); if (spawnWith != null) pClient.Send(spawnWith); } #region Other Pet & Clones if (pClient.Entity.MyClones.Count > 0) { foreach (var clone in pClient.Entity.MyClones.Values) { if (clone == null) continue; if (Kernel.GetDistance(clone.X, clone.Y, Owner.Entity.X, Owner.Entity.Y) <= 18 && !Contains(clone.UID)) { if (!clone.Dead) clone.SendSpawn(Owner); } } } if (pClient.Pet.Pets.Count > 0) { foreach (var pet in pClient.Pet.Pets.Values) { if (pet == null) continue; if (pet.Entity == null) continue; if (Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, Owner.Entity.X, Owner.Entity.Y) <= 18 && !Contains(pet.Entity.UID)) { if (!pet.Entity.Dead) pet.Entity.SendSpawn(Owner); } } } #endregion } } } } #region My Pet & Clones if (Owner.Entity.MyClones.Count > 0) { foreach (var clone in Owner.Entity.MyClones.Values) { if (clone == null) continue; if (Kernel.GetDistance(clone.X, clone.Y, Owner.Entity.X, Owner.Entity.Y) <= 18 && !Contains(clone.UID)) { if (!clone.Dead) clone.SendSpawn(Owner); } } } if (Owner.Pet.Pets.Count > 0) { foreach (var pet in Owner.Pet.Pets.Values) { if (pet == null) continue; if (pet.Entity == null) continue; if (Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, Owner.Entity.X, Owner.Entity.Y) <= 18/* && !Contains(pet.Entity.UID)*/) { if (!pet.Entity.Dead) Owner.Send(pet.Entity.SpawnPacket); // pet.Entity.SendSpawn(Owner, false); } } } #endregion #endregion } catch { } } public void SendScreen(Interfaces.IPacket buffer, bool self) { foreach (Interfaces.IMapObject _obj in Objects) { if (_obj != null) { if (_obj.UID != Owner.Entity.UID) { if (_obj.MapObjType == Game.MapObjectType.Entity) { GameState client = _obj.Owner as GameState; if (Owner.WatchingGroup != null && client.WatchingGroup == null) continue; if (Owner.TeamWatchingGroup != null && client.TeamWatchingGroup == null) continue; client.Send(buffer); } } } } if (self) Owner.Send(buffer); } public bool TryGetNpc(uint uid, out INpc sob) { sob = null; Interfaces.IMapObject imo = null; if (_objectDictionary.TryGetValue(uid, out imo)) { if (imo == null) { _objectDictionary.Remove(uid); updateBase(); return false; } if (imo is NpcSpawn) { sob = imo as NpcSpawn; return true; } } return false; } } }