internal bool Teleport(int tx, int ty, bool retrying) { if (Main.players[whoAmi] != this) { ProgramLog.Error.Log ("Attempt to teleport inactive player {0}.", Name ?? IPAddress); return false; } if (!retrying && System.Threading.Interlocked.CompareExchange (ref this.teleportInProgress, 1, 0) != 0) { ProgramLog.Error.Log ("Teleportation of player {0} already in progress.", Name ?? IPAddress); return false; } if (tx < 0 || ty < 0 || tx >= Main.maxTilesX || ty >= Main.maxTilesY) { ProgramLog.Error.Log ("Attempt to teleport player {0} to invalid location: {1}, {2}.", Name ?? IPAddress, tx, ty); return false; } PlayerTeleportEvent playerEvent = new PlayerTeleportEvent(); playerEvent.ToLocation = new Vector2 (tx * 16, ty * 16); playerEvent.FromLocation = new Vector2(this.Position.X, this.Position.Y); playerEvent.Sender = this; Program.server.PluginManager.processHook(Hooks.PLAYER_TELEPORT, playerEvent); if (playerEvent.Cancelled) { return false; } bool changeSpawn = false; int ox = Main.spawnTileX; int oy = Main.spawnTileY; if (SpawnX >= 0 && SpawnY >= 0) { changeSpawn = true; ox = SpawnX; oy = SpawnY; } else if (OldSpawnX >= 0 && OldSpawnY >= 0) { changeSpawn = true; ox = OldSpawnX; oy = OldSpawnY; } var slot = Netplay.slots[whoAmi]; int sx = tx / 200; int sy = ty / 150; // send up to 9 sections around the player int fromX = Math.Max (0, sx - 1); int fromY = Math.Max (0, sy - 1); int toX = Math.Min (sx + 1, Main.maxTilesX/200-1); int toY = Math.Min (sy + 1, Main.maxTilesY/150-1); int sections = 0; for (int x = fromX; x <= toX; x++) { for (int y = fromY; y <= toY; y++) { if (! slot.tileSection[x, y]) { sections += 1; } } } var msg = NetMessage.PrepareThreadInstance (); if (sections > 0) { msg.SendTileLoading (sections * 150, "Teleporting..."); msg.Send (whoAmi); msg.Clear (); for (int x = fromX; x <= toX; x++) { for (int y = fromY; y <= toY; y++) { if (! slot.tileSection[x, y]) { NetMessage.SendSection (whoAmi, x, y); } } } msg.SendTileConfirm (fromX, fromY, toX, toY); msg.Send (whoAmi); msg.Clear (); } // kill players' hooks and vines foreach (var proj in Main.projectile) { if (proj.Active && proj.Owner == whoAmi && (proj.type == ProjectileType.HOOK || proj.type == ProjectileType.WHIP_IVY)) { proj.Active = false; proj.type = ProjectileType.UNKNOWN; msg.Projectile (proj); } } msg.Broadcast (); msg.Clear (); int left = 0; int right = -1; if (changeSpawn && oy > 1) { // invalidate player's bed temporarily // we used to kill a tile under the bed, but that could cause // side-effects, like killing objects hanging from the ceiling below left = Math.Max (0, ox - 4); right = Math.Min (ox + 4, Main.maxTilesX); while (left < Main.maxTilesX && Main.tile.At (left, oy - 1).Type != 79) left += 1; while (right > 0 && Main.tile.At (right, oy - 1).Type != 79) right -= 1; for (int x = left; x <= right; x++) { var data = Main.tile.At (x, oy - 1).Data; data.Active = false; msg.SingleTileSquare (x, oy - 1, data); data = Main.tile.At (x, oy - 2).Data; data.Active = false; msg.SingleTileSquare (x, oy - 2, data); } } // change the global spawn point msg.WorldData (tx, ty); // trigger respawn TeleSpawnX = tx; TeleSpawnY = ty; msg.ReceivingPlayerJoined (whoAmi); // fix holes at target location int fx = Math.Max (0, Math.Min (Main.maxTilesX - 8, tx - 4)); int fy = Math.Max (0, Math.Min (Main.maxTilesY - 8, ty - 4)); msg.TileSquare (7, fx, fy); // msg.Send (whoAmi); // msg.Clear (); if (changeSpawn && oy > 1) { // restore player's bed msg.TileSquare (1, ox, oy); if (right - left >= 0 && oy >= 2) msg.TileSquare (right - left + 1, left, oy - 2); } // restore the global spawn point msg.WorldData (); msg.Send (whoAmi); return true; }
public void teleportTo(float tileX, float tileY) { PlayerTeleportEvent playerEvent = new PlayerTeleportEvent(); playerEvent.ToLocation = new Vector2(tileX, tileY); playerEvent.FromLocation = new Vector2(this.Position.X, this.Position.Y); playerEvent.Sender = this; Program.server.PluginManager.processHook(Hooks.PLAYER_TELEPORT, playerEvent); if (playerEvent.Cancelled) { return; } //Preserve out Spawn point. int xPreserve = Main.spawnTileX; int yPreserve = Main.spawnTileY; //The spawn the client wants is the from player Pos /16. //This is because the Client reads frames, Not Tile Records. Main.spawnTileX = ((int)tileX / 16); Main.spawnTileY = ((int)tileY / 16); NetMessage.SendData((int)Packet.WORLD_DATA, this.whoAmi); //Trigger Client Data Update (Updates Spawn Position) NetMessage.SendData((int)Packet.WORLD_DATA); //Trigger Client Data Update (Updates Spawn Position) NetMessage.SendData((int)Packet.RECEIVING_PLAYER_JOINED, -1, -1, "", this.whoAmi); //Trigger the player to spawn this.UpdatePlayer(this.whoAmi); //Update players data (I don't think needed by default, But hay) this.Position.X = tileX; this.Position.Y = tileY; //Return our preserved Spawn Point. Main.spawnTileX = xPreserve; Main.spawnTileY = yPreserve; this.SpawnX = Main.spawnTileX; this.SpawnY = Main.spawnTileY; this.Spawn(); //Tell the Client to Spawn (Sets Defaults) this.UpdatePlayer(this.whoAmi); //Update players data (I don't think needed by default, But hay) NetMessage.SendData((int)Packet.WORLD_DATA, this.whoAmi); //Trigger Client Data Update (Updates Spawn Position) NetMessage.SyncPlayers(); //Sync the Players Position. }
/* /// <summary> /// Hook method for the player state (Byte) updating /// </summary> /// <param name="Event">PlayerStateUpdateEvent info</param>*/ //public virtual void onPlayerStateUpdate(PlayerStateUpdateEvent Event) { } //Send with KB & Movement Events instead /// <summary> /// Hook method for the player teleport /// </summary> /// <param name="Event">PlayerTeleportEvent info</param> public virtual void onPlayerTeleport(PlayerTeleportEvent Event) { }