public void Cleanup() { bool remove; lock (PlayerDictionary) { foreach (Entity Entity in ScreenPlayers) { remove = ConquerMath.CalculateDistance(Client.Entity.Location, Entity.Location) > Kernel.ScreenView; if (remove) { GameClient Owner = Entity.Owner; Owner.Screen.Remove(Client.Entity); Remove(Entity); } } } lock (NPCDictionary) { foreach (NonPlayerCharacter NPC in ScreenNPCs) { remove = ConquerMath.CalculateDistance(Client.Entity.Location, NPC.Location) > Kernel.ScreenView; if (remove) { NPCDictionary.Remove(NPC.UID); } } } }
public void Teleport(ushort MapID, ushort X, ushort Y) { if (Kernel.IsWalkable(MapID, X, Y)) { GeneralData *Packet = PacketHelper.AllocGeneral(); if (Entity.Location.MapID == MapID && ConquerMath.CalculateDistance(X, Y, Entity.Location.X, Entity.Location.Y, true) < Kernel.ScreenView) { // Teleporting within Kernel.ScreenView distance. Don't remove entity from other players. Send "Jump" packet instead Packet->DataID = GeneralDataID.Jump; Packet->UID = Entity.UID; Packet->ValueA = Entity.Location.X; Packet->ValueB = Entity.Location.Y; Packet->ValueD_High = X; Packet->ValueD_Low = Y; Entity.Location.MapID = MapID; Entity.Location.X = X; Entity.Location.Y = Y; SendScreen(Packet, Packet->Size, true); } else { Packet->UID = Entity.UID; Packet->DataID = GeneralDataID.RemoveEntity; SendScreen(Packet, Packet->Size); } Packet = PacketHelper.ReAllocGeneral(Packet); Packet->UID = Entity.UID; Packet->DataID = GeneralDataID.ChangeMap; Packet->ValueA = X; Packet->ValueB = Y; Packet->ValueD_High = MapID; Entity.Location.MapID = MapID; Entity.Location.X = X; Entity.Location.Y = Y; Send(Packet, Packet->Size); Memory.Free(Packet); } else { Message(string.Format("Can't teleport to MapID: {0} X {1} Y {2}.", MapID, X, Y), ChatType.Center, Color.White); return; } }
private void HandleJumping(GameClient Client, GeneralData *Packet) { ushort X1 = Packet->ValueA; ushort Y1 = Packet->ValueB; if ((X1 != Client.Entity.Location.X) || (Y1 != Client.Entity.Location.Y)) { Client.Disconnect(); } else { ushort X2 = Packet->ValueD_High; ushort Y2 = Packet->ValueD_Low; Client.Entity.Angle = ConquerMath.GetAngle(Client.Entity.Location, new Location() { X = X2, Y = Y2 }); Client.Entity.Location.X = X2; Client.Entity.Location.Y = Y2; if (!Kernel.IsWalkable(Client.Entity.Location.MapID, Client.Entity.Location.X, Client.Entity.Location.Y)) { Client.Disconnect(); } else { Client.Send(Packet, Packet->Size); Client.SendScreen(Packet, Packet->Size); Kernel.GetScreen(Client, ConquerCallbackKernel.GetScreenReply); } } }
public static void GetScreen(GameClient Client, ConquerCallback Callback) { Client.Screen.Cleanup(); try { EntityManager.AcquireLock(); int Distance = -1; GameClient[] Clients = EntityManager.Clients; foreach (GameClient Other in Clients) { if (Other == null) { continue; } if (Other.UID == Client.UID) { continue; } if (Other.Entity.Location.MapID != Client.Entity.Location.MapID) { continue; } Distance = ConquerMath.CalculateDistance(Other.Entity.Location, Client.Entity.Location); if (Distance <= ScreenView) { if (Client.Screen.Add(Other.Entity)) { if (Callback != null) { Callback(Client.Entity, Other.Entity); } } } } NonPlayerCharacter[] NPCs = EntityManager.GetNonPlayingCharacters(Client.Entity.Location.MapID); if (NPCs != null) { foreach (NonPlayerCharacter npc in NPCs) { if (npc.Location.MapID != Client.Entity.Location.MapID) { continue; } Distance = ConquerMath.CalculateDistance(npc.Location, Client.Entity.Location); if (Distance <= ScreenView) { if (Client.Screen.Add(npc)) { NpcSpawn Spawn = npc.GetSpawnPacket(); Client.Send(&Spawn, Spawn.Size); } } } } } finally { EntityManager.ReleaseLock(); } }