diff --git a/TShockAPI/Bouncer.cs b/TShockAPI/Bouncer.cs
index 5258e7dd..511c5820 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;
@@ -183,6 +183,7 @@ namespace TShockAPI
/// The packet arguments that the event has.
internal void OnTileEdit(object sender, GetDataHandlers.TileEditEventArgs args)
{
+ // TODO: Add checks on the new edit actions. ReplaceTile, ReplaceWall, TryKillTile, Acutate, PokeLogicGate, SlopePoundTile
EditAction action = args.Action;
int tileX = args.X;
int tileY = args.Y;
@@ -795,6 +796,17 @@ namespace TShockAPI
return;
}
+
+ if (stabProjectile.ContainsKey(type))
+ {
+ if (stabProjectile[type] == args.Player.TPlayer.HeldItem.type)
+ {
+ args.Handled = false;
+ return;
+ }
+ }
+
+
// Main.projHostile contains projectiles that can harm players
// without PvP enabled and belong to enemy mobs, so they shouldn't be
// possible for players to create. (Source: Ijwu, QuiCM)
@@ -1284,7 +1296,7 @@ namespace TShockAPI
internal void OnPlayerBuff(object sender, GetDataHandlers.PlayerBuffEventArgs args)
{
byte id = args.ID;
- byte type = args.Type;
+ int type = args.Type;
int time = args.Time;
if (TShock.Players[id] == null)
@@ -1341,7 +1353,7 @@ namespace TShockAPI
internal void OnNPCAddBuff(object sender, GetDataHandlers.NPCAddBuffEventArgs args)
{
short id = args.ID;
- byte type = args.Type;
+ int type = args.Type;
short time = args.Time;
if (id >= Main.npc.Length)
@@ -1856,7 +1868,7 @@ namespace TShockAPI
}
- private static Dictionary NPCAddBuffTimeMax = new Dictionary()
+ private static Dictionary NPCAddBuffTimeMax = new Dictionary()
{
{ BuffID.Poisoned, 3600 },
{ BuffID.OnFire, 1200 },
@@ -1921,5 +1933,18 @@ namespace TShockAPI
TileID.Campfire
};
+ private static Dictionary stabProjectile = new Dictionary()
+ {
+ { ProjectileID.GladiusStab, ItemID.Gladius },
+ { ProjectileID.RulerStab, ItemID.Ruler },
+ { ProjectileID.CopperShortswordStab, ItemID.CopperShortsword },
+ { ProjectileID.TinShortswordStab, ItemID.TinShortsword },
+ { ProjectileID.IronShortswordStab, ItemID.IronShortsword },
+ { ProjectileID.LeadShortswordStab, ItemID.LeadShortsword },
+ { ProjectileID.SilverShortswordStab, ItemID.SilverShortsword },
+ { ProjectileID.TungstenShortswordStab, ItemID.TungstenShortsword },
+ { ProjectileID.GoldShortswordStab, ItemID.GoldShortsword },
+ { ProjectileID.PlatinumShortswordStab, ItemID.PlatinumShortsword }
+ };
}
}
diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index 31a316b1..a1fc937d 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;
@@ -910,7 +944,7 @@ namespace TShockAPI
///
public BitsByte Zone3 { get; set; }
///
- /// 0 = Old One's Army
+ /// 0 = Old One's Army, 1 = Granite, 2 = Marble, 3 = Hive, 4 = Gem Cave, 5 = Lihzhard Temple, 6 = Graveyard
///
public BitsByte Zone4 { get; set; }
}
@@ -1181,7 +1215,7 @@ namespace TShockAPI
///
/// Buff Type
///
- public byte Type { get; set; }
+ public int Type { get; set; }
///
/// Time the buff lasts
///
@@ -1191,7 +1225,7 @@ namespace TShockAPI
/// NPCAddBuff - Called when a npc is buffed
///
public static HandlerList NPCAddBuff = new HandlerList();
- private static bool OnNPCAddBuff(TSPlayer player, MemoryStream data, short id, byte type, short time)
+ private static bool OnNPCAddBuff(TSPlayer player, MemoryStream data, short id, int type, short time)
{
if (NPCAddBuff == null)
return false;
@@ -1220,7 +1254,7 @@ namespace TShockAPI
///
/// Buff Type
///
- public byte Type { get; set; }
+ public int Type { get; set; }
///
/// Time the buff lasts
///
@@ -1230,7 +1264,7 @@ namespace TShockAPI
/// PlayerBuff - Called when a player is buffed
///
public static HandlerList PlayerBuff = new HandlerList();
- private static bool OnPlayerBuff(TSPlayer player, MemoryStream data, byte id, byte type, int time)
+ private static bool OnPlayerBuff(TSPlayer player, MemoryStream data, byte id, int type, int time)
{
if (PlayerBuff == null)
return false;
@@ -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;
@@ -2199,17 +2249,17 @@ namespace TShockAPI
private static bool HandleTile(GetDataHandlerArgs args)
{
EditAction action = (EditAction)args.Data.ReadInt8();
- var tileX = args.Data.ReadInt16();
- var tileY = args.Data.ReadInt16();
- var editData = args.Data.ReadInt16();
+ short tileX = args.Data.ReadInt16();
+ short tileY = args.Data.ReadInt16();
+ short editData = args.Data.ReadInt16();
EditType type = (action == EditAction.KillTile || action == EditAction.KillWall ||
- action == EditAction.KillTileNoItem)
+ action == EditAction.KillTileNoItem || action == EditAction.TryKillTile)
? EditType.Fail
- : (action == EditAction.PlaceTile || action == EditAction.PlaceWall)
+ : (action == EditAction.PlaceTile || action == EditAction.PlaceWall || action == EditAction.ReplaceTile || action == EditAction.ReplaceWall)
? EditType.Type
: EditType.Slope;
- var style = args.Data.ReadInt8();
+ byte style = args.Data.ReadInt8();
if (OnTileEdit(args.Player, args.Data, tileX, tileY, action, type, editData, style))
return true;
@@ -2296,23 +2346,21 @@ namespace TShockAPI
private static bool HandleProjectileNew(GetDataHandlerArgs args)
{
short ident = args.Data.ReadInt16();
- var pos = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle());
- var vel = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle());
- float knockback = args.Data.ReadSingle();
- short dmg = args.Data.ReadInt16();
+ Vector2 pos = args.Data.ReadVector2();
+ Vector2 vel = args.Data.ReadVector2();
byte owner = args.Data.ReadInt8();
short type = args.Data.ReadInt16();
- BitsByte bits = args.Data.ReadInt8();
- //owner = (byte)args.Player.Index;
+ BitsByte bits = (BitsByte)args.Data.ReadByte();
float[] ai = new float[Projectile.maxAI];
+ for (int i = 0; i < Projectile.maxAI; ++i)
+ ai[i] = !bits[i] ? 0.0f : args.Data.ReadSingle();
+ short dmg = bits[4] ? args.Data.ReadInt16() : (short)0;
+ float knockback = bits[5] ? args.Data.ReadSingle() : 0.0f;
+ short origDmg = bits[6] ? args.Data.ReadInt16() : (short)0;
+ short projUUID = bits[7] ? args.Data.ReadInt16() : (short)-1;
+ if (projUUID >= 1000)
+ projUUID = -1;
- for (int i = 0; i < Projectile.maxAI; i++)
- {
- if (bits[i])
- ai[i] = args.Data.ReadSingle();
- else
- ai[i] = 0f;
- }
var index = TShock.Utils.SearchProjectile(ident, owner);
@@ -2666,7 +2714,7 @@ namespace TShockAPI
for (int i = 0; i < Terraria.Player.maxBuffs; i++)
{
- var buff = args.Data.ReadInt8();
+ var buff = args.Data.ReadUInt16();
if (buff == 10 && TShock.Config.DisableInvisPvP && args.TPlayer.hostile)
buff = 0;
@@ -2717,7 +2765,7 @@ namespace TShockAPI
private static bool HandleNPCAddBuff(GetDataHandlerArgs args)
{
var id = args.Data.ReadInt16();
- var type = args.Data.ReadInt8();
+ var type = args.Data.ReadUInt16();
var time = args.Data.ReadInt16();
if (OnNPCAddBuff(args.Player, args.Data, id, type, time))
@@ -2729,7 +2777,7 @@ namespace TShockAPI
private static bool HandlePlayerAddBuff(GetDataHandlerArgs args)
{
var id = args.Data.ReadInt8();
- var type = args.Data.ReadInt8();
+ var type = args.Data.ReadUInt16();
var time = args.Data.ReadInt32();
if (OnPlayerBuff(args.Player, args.Data, id, type, time))
@@ -3358,7 +3406,13 @@ namespace TShockAPI
SlopeTile,
FrameTrack,
PlaceWire4,
- KillWire4
+ KillWire4,
+ PokeLogicGate,
+ Acutate,
+ TryKillTile,
+ ReplaceTile,
+ ReplaceWall,
+ SlopePoundTile
}
public enum EditType
{
@@ -3366,7 +3420,6 @@ namespace TShockAPI
Type,
Slope,
}
-
///
/// The maximum place styles for each tile.
///
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;