diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs index 5258e7dd..56c77839 100644 --- a/TShockAPI/Bouncer.cs +++ b/TShockAPI/Bouncer.cs @@ -99,7 +99,7 @@ namespace TShockAPI byte plr = args.PlayerId; BitsByte control = args.Control; BitsByte pulley = args.Pulley; - byte item = args.Item; + byte item = args.SelectedItem ; var pos = args.Position; var vel = args.Velocity; diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs index 599133d6..360fd6e8 100644 --- a/TShockAPI/GetDataHandlers.cs +++ b/TShockAPI/GetDataHandlers.cs @@ -307,25 +307,44 @@ namespace TShockAPI /// public byte Control { get; set; } /// - /// Selected item + /// Pulley update (BitFlags) /// - public byte Item { get; set; } + public byte Pulley { get; set; } /// - /// Position of the player + /// Misc (BitFlags) Check tshock.readme.io + /// + public byte Misc { get; set; } + /// + /// (BitFlags) Wether or not the player is sleeping. + /// + public byte Sleeping { get; set; } + /// + /// The selected item in player's hand. + /// + public byte SelectedItem { get; set; } + /// + /// Position of the player. /// public Vector2 Position { get; set; } /// - /// Velocity of the player + /// Velocity of the player. /// public Vector2 Velocity { get; set; } - /// Pulley update (BitFlags) - public byte Pulley { get; set; } + /// + /// Original poisition of the player when using Potion of Return. + /// + public Vector2? OriginalPos { get; set; } + /// + /// Home Position of the player for Potion of Return. + /// + public Vector2? HomePos { get; set; } + } /// /// PlayerUpdate - When the player sends it's updated information to the server /// public static HandlerList PlayerUpdate = new HandlerList(); - private static bool OnPlayerUpdate(TSPlayer player, MemoryStream data, byte plr, byte control, byte item, Vector2 position, Vector2 velocity, byte pulley) + private static bool OnPlayerUpdate(TSPlayer player, MemoryStream data, byte plr, byte control, byte pulley, byte misc, byte sleeping, byte selectedItem, Vector2 position, Vector2 velocity, Vector2? originalPos, Vector2? homePos) { if (PlayerUpdate == null) return false; @@ -336,10 +355,14 @@ namespace TShockAPI Data = data, PlayerId = plr, Control = control, - Item = item, + Pulley = pulley, + Misc = misc, + Sleeping = sleeping, + SelectedItem = selectedItem, Position = position, Velocity = velocity, - Pulley = pulley + OriginalPos = originalPos, + HomePos = homePos }; PlayerUpdate.Invoke(null, args); return args.Handled; @@ -746,12 +769,21 @@ namespace TShockAPI /// Y location of the player's spawn /// public int SpawnY { get; set; } + /// + /// Value of the timer countdown before the player can respawn alive. + /// If > 0, then player is still dead. + /// + public int RespawnTimer { get; set; } + /// + /// Context of where the player is spawning from. + /// + public PlayerSpawnContext SpawnContext { get; set; } } /// /// PlayerSpawn - When a player spawns /// public static HandlerList PlayerSpawn = new HandlerList(); - private static bool OnPlayerSpawn(TSPlayer player, MemoryStream data, byte pid, int spawnX, int spawnY) + private static bool OnPlayerSpawn(TSPlayer player, MemoryStream data, byte pid, int spawnX, int spawnY, int respawnTimer, PlayerSpawnContext spawnContext) { if (PlayerSpawn == null) return false; @@ -763,6 +795,8 @@ namespace TShockAPI PlayerId = pid, SpawnX = spawnX, SpawnY = spawnY, + RespawnTimer = respawnTimer, + SpawnContext = spawnContext }; PlayerSpawn.Invoke(null, args); return args.Handled; @@ -2006,11 +2040,13 @@ namespace TShockAPI private static bool HandleSpawn(GetDataHandlerArgs args) { - var player = args.Data.ReadInt8(); - var spawnx = args.Data.ReadInt16(); - var spawny = args.Data.ReadInt16(); + byte player = args.Data.ReadInt8(); + short spawnx = args.Data.ReadInt16(); + short spawny = args.Data.ReadInt16(); + int respawnTimer = args.Data.ReadInt32(); + PlayerSpawnContext context = (PlayerSpawnContext)args.Data.ReadByte(); - if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny)) + if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny, respawnTimer, context)) return true; if ((Main.ServerSideCharacter) && (args.Player.sX > 0) && (args.Player.sY > 0) && (args.TPlayer.SpawnX > 0) && ((args.TPlayer.SpawnX != args.Player.sX) && (args.TPlayer.SpawnY != args.Player.sY))) @@ -2029,7 +2065,10 @@ namespace TShockAPI args.Player.Teleport(args.Player.sX * 16, (args.Player.sY * 16) - 48); } - args.Player.Dead = false; + if (respawnTimer > 0) + args.Player.Dead = true; + else + args.Player.Dead = false; return false; } @@ -2040,34 +2079,45 @@ namespace TShockAPI return true; } - byte plr = args.Data.ReadInt8(); - BitsByte control = args.Data.ReadInt8(); - BitsByte pulley = args.Data.ReadInt8(); - byte item = args.Data.ReadInt8(); - var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); - var vel = Vector2.Zero; - if (pulley[2]) - vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle()); + byte playerID = args.Data.ReadInt8(); + BitsByte control = (BitsByte)args.Data.ReadByte(); + BitsByte pulley = (BitsByte)args.Data.ReadByte(); + BitsByte misc = (BitsByte)args.Data.ReadByte(); + BitsByte sleeping = (BitsByte)args.Data.ReadByte(); + byte selectedItem = args.Data.ReadInt8(); + Vector2 position = args.Data.ReadVector2(); - if (OnPlayerUpdate(args.Player, args.Data, plr, control, item, pos, vel, pulley)) + Vector2 velocity = Vector2.Zero; + if (pulley[2]) // if UpdateVelocity + velocity = args.Data.ReadVector2(); + + Vector2? originalPosition = new Vector2?(); + Vector2? homePosition = Vector2.Zero; + if (misc[6]) // if UsedPotionofReturn + { + originalPosition = new Vector2?(args.Data.ReadVector2()); + homePosition = new Vector2?(args.Data.ReadVector2()); + } + + if (OnPlayerUpdate(args.Player, args.Data, playerID, control, pulley, misc, sleeping, selectedItem, position, velocity, originalPosition, homePosition)) return true; if (control[5]) { // Reimplementation of normal Terraria stuff? - if (args.TPlayer.inventory[item].Name == "Mana Crystal" && args.Player.TPlayer.statManaMax <= 180) + if (args.TPlayer.inventory[selectedItem].Name == "Mana Crystal" && args.Player.TPlayer.statManaMax <= 180) { args.Player.TPlayer.statMana += 20; args.Player.TPlayer.statManaMax += 20; args.Player.PlayerData.maxMana += 20; } - else if (args.TPlayer.inventory[item].Name == "Life Crystal" && args.Player.TPlayer.statLifeMax <= 380) + else if (args.TPlayer.inventory[selectedItem].Name == "Life Crystal" && args.Player.TPlayer.statLifeMax <= 380) { args.TPlayer.statLife += 20; args.TPlayer.statLifeMax += 20; args.Player.PlayerData.maxHealth += 20; } - else if (args.TPlayer.inventory[item].Name == "Life Fruit" && args.Player.TPlayer.statLifeMax >= 400 && args.Player.TPlayer.statLifeMax <= 495) + else if (args.TPlayer.inventory[selectedItem].Name == "Life Fruit" && args.Player.TPlayer.statLifeMax >= 400 && args.Player.TPlayer.statLifeMax <= 495) { args.TPlayer.statLife += 5; args.TPlayer.statLifeMax += 5; @@ -2076,11 +2126,11 @@ namespace TShockAPI } // Where we rebuild sync data for Terraria? - args.TPlayer.selectedItem = item; - args.TPlayer.position = pos; + args.TPlayer.selectedItem = selectedItem; + args.TPlayer.position = position; args.TPlayer.oldVelocity = args.TPlayer.velocity; - args.TPlayer.velocity = vel; - args.TPlayer.fallStart = (int)(pos.Y / 16f); + args.TPlayer.velocity = velocity; + args.TPlayer.fallStart = (int)(position.Y / 16f); args.TPlayer.controlUp = false; args.TPlayer.controlDown = false; args.TPlayer.controlLeft = false; diff --git a/TShockAPI/ItemBans.cs b/TShockAPI/ItemBans.cs index a85f462c..0ebd7ee6 100644 --- a/TShockAPI/ItemBans.cs +++ b/TShockAPI/ItemBans.cs @@ -156,9 +156,9 @@ namespace TShockAPI DisableFlags disableFlags = TShock.Config.DisableSecondUpdateLogs ? DisableFlags.WriteToConsole : DisableFlags.WriteToLogAndConsole; bool useItem = ((BitsByte) args.Control)[5]; TSPlayer player = args.Player; - string itemName = player.TPlayer.inventory[args.Item].Name; + string itemName = player.TPlayer.inventory[args.SelectedItem].Name; - if (DataModel.ItemIsBanned(EnglishLanguage.GetItemNameById(player.TPlayer.inventory[args.Item].netID), args.Player)) + if (DataModel.ItemIsBanned(EnglishLanguage.GetItemNameById(player.TPlayer.inventory[args.SelectedItem].netID), args.Player)) { player.TPlayer.controlUseItem = false; player.Disable($"holding banned item: {itemName}", disableFlags); diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs index 5829f877..9a772227 100644 --- a/TShockAPI/TSPlayer.cs +++ b/TShockAPI/TSPlayer.cs @@ -360,6 +360,8 @@ namespace TShockAPI Item[] piggy = TPlayer.bank.item; Item[] safe = TPlayer.bank2.item; Item[] forge = TPlayer.bank3.item; + Item[] voidVault = TPlayer.bank4.item; + Item trash = TPlayer.trashItem; for (int i = 0; i < NetItem.MaxInventory; i++) { @@ -507,7 +509,7 @@ namespace TShockAPI } else if (i < NetItem.TrashIndex.Item2) { - // 179-219 + // 178-179 Item item = new Item(); if (trash != null && trash.netID != 0) { @@ -525,9 +527,9 @@ namespace TShockAPI } } } - else + else if (i < NetItem.ForgeIndex.Item2) { - // 220 + // 179-220 var index = i - NetItem.ForgeIndex.Item1; Item item = new Item(); if (forge[index] != null && forge[index].netID != 0) @@ -545,8 +547,29 @@ namespace TShockAPI } } } - } + else if (i < NetItem.VoidIndex.Item2) + { + // 220-260 + var index = i - NetItem.VoidIndex.Item1; + Item item = new Item(); + if (voidVault[index] != null && voidVault[index].netID != 0) + { + item.netDefaults(voidVault[index].netID); + item.Prefix(voidVault[index].prefix); + item.AffixName(); + + if (voidVault[index].stack > item.maxStack || voidVault[index].stack < 0) + { + check = true; + if (shouldWarnPlayer) + { + SendErrorMessage("Stack cheat detected. Remove Void Vault item {0} ({1}) and then rejoin.", item.Name, voidVault[index].stack); + } + } + } + } + } return check;