diff --git a/TShockAPI/GetDataHandlers.cs b/TShockAPI/GetDataHandlers.cs
index 9f955c95..0aa2dce6 100644
--- a/TShockAPI/GetDataHandlers.cs
+++ b/TShockAPI/GetDataHandlers.cs
@@ -856,6 +856,14 @@ namespace TShockAPI
///
public int RespawnTimer { get; set; }
///
+ /// Number Of Deaths PVE
+ ///
+ public int NumberOfDeathsPVE { get; set; }
+ ///
+ /// Number Of Deaths PVP
+ ///
+ public int NumberOfDeathsPVP { get; set; }
+ ///
/// Context of where the player is spawning from.
///
public PlayerSpawnContext SpawnContext { get; set; }
@@ -864,7 +872,7 @@ namespace TShockAPI
/// 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, int respawnTimer, PlayerSpawnContext spawnContext)
+ private static bool OnPlayerSpawn(TSPlayer player, MemoryStream data, byte pid, int spawnX, int spawnY, int respawnTimer, int numberOfDeathsPVE, int numberOfDeathsPVP, PlayerSpawnContext spawnContext)
{
if (PlayerSpawn == null)
return false;
@@ -877,6 +885,8 @@ namespace TShockAPI
SpawnX = spawnX,
SpawnY = spawnY,
RespawnTimer = respawnTimer,
+ NumberOfDeathsPVE = numberOfDeathsPVE,
+ NumberOfDeathsPVP = numberOfDeathsPVP,
SpawnContext = spawnContext
};
PlayerSpawn.Invoke(null, args);
@@ -1033,12 +1043,16 @@ namespace TShockAPI
/// 0 = Old One's Army, 1 = Granite, 2 = Marble, 3 = Hive, 4 = Gem Cave, 5 = Lihzhard Temple, 6 = Graveyard
///
public BitsByte Zone4 { get; set; }
+ ///
+ /// 0 = The Aether
+ ///
+ public BitsByte Zone5 { get; set; }
}
///
/// PlayerZone - When the player sends it's zone/biome information to the server
///
public static HandlerList PlayerZone = new HandlerList();
- private static bool OnPlayerZone(TSPlayer player, MemoryStream data, byte plr, BitsByte zone1, BitsByte zone2, BitsByte zone3, BitsByte zone4)
+ private static bool OnPlayerZone(TSPlayer player, MemoryStream data, byte plr, BitsByte zone1, BitsByte zone2, BitsByte zone3, BitsByte zone4, BitsByte zone5)
{
if (PlayerZone == null)
return false;
@@ -1051,7 +1065,8 @@ namespace TShockAPI
Zone1 = zone1,
Zone2 = zone2,
Zone3 = zone3,
- Zone4 = zone4
+ Zone4 = zone4,
+ Zone5 = zone5
};
PlayerZone.Invoke(null, args);
return args.Handled;
@@ -1519,12 +1534,16 @@ namespace TShockAPI
/// Type
///
public byte type { get; set; }
+ ///
+ /// Paint Coat Tile
+ ///
+ public byte coatTile { get; set; }
}
///
/// NPCStrike - Called when an NPC is attacked
///
public static HandlerList PaintTile = new HandlerList();
- private static bool OnPaintTile(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t)
+ private static bool OnPaintTile(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t, byte ct)
{
if (PaintTile == null)
return false;
@@ -1535,7 +1554,8 @@ namespace TShockAPI
Data = data,
X = x,
Y = y,
- type = t
+ type = t,
+ coatTile = ct
};
PaintTile.Invoke(null, args);
return args.Handled;
@@ -1558,12 +1578,16 @@ namespace TShockAPI
/// Type
///
public byte type { get; set; }
+ ///
+ /// Paint Coat Wall
+ ///
+ public byte coatWall { get; set; }
}
///
/// Called When a wall is painted
///
public static HandlerList PaintWall = new HandlerList();
- private static bool OnPaintWall(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t)
+ private static bool OnPaintWall(TSPlayer player, MemoryStream data, Int32 x, Int32 y, byte t, byte cw)
{
if (PaintWall == null)
return false;
@@ -1574,7 +1598,8 @@ namespace TShockAPI
Data = data,
X = x,
Y = y,
- type = t
+ type = t,
+ coatWall = cw
};
PaintWall.Invoke(null, args);
return args.Handled;
@@ -1734,12 +1759,15 @@ namespace TShockAPI
/// Alternate variation of the object placed.
public byte Alternate { get; set; }
+ /// Related to Rubblemaker.
+ public sbyte Random { get; set; }
+
/// The direction the object was placed.
public bool Direction { get; set; }
}
/// Fired when an object is placed in the world.
public static HandlerList PlaceObject = new HandlerList();
- private static bool OnPlaceObject(TSPlayer player, MemoryStream data, short x, short y, short type, short style, byte alternate, bool direction)
+ private static bool OnPlaceObject(TSPlayer player, MemoryStream data, short x, short y, short type, short style, byte alternate, sbyte random, bool direction)
{
if (PlaceObject == null)
return false;
@@ -1753,6 +1781,7 @@ namespace TShockAPI
Type = type,
Style = style,
Alternate = alternate,
+ Random = random,
Direction = direction
};
@@ -1980,6 +2009,10 @@ namespace TShockAPI
/// Is the damage critical?
///
public bool Critical { get; set; }
+ ///
+ /// Cooldown Counter
+ ///
+ public sbyte CooldownCounter { get; set; }
/// The reason the player took damage and/or died.
public PlayerDeathReason PlayerDeathReason { get; set; }
}
@@ -1987,7 +2020,7 @@ namespace TShockAPI
/// PlayerDamage - Called when a player is damaged
///
public static HandlerList PlayerDamage = new HandlerList();
- private static bool OnPlayerDamage(TSPlayer player, MemoryStream data, byte id, byte dir, short dmg, bool pvp, bool crit, PlayerDeathReason playerDeathReason)
+ private static bool OnPlayerDamage(TSPlayer player, MemoryStream data, byte id, byte dir, short dmg, bool pvp, bool crit, sbyte cooldownCounter, PlayerDeathReason playerDeathReason)
{
if (PlayerDamage == null)
return false;
@@ -2001,6 +2034,7 @@ namespace TShockAPI
Damage = dmg,
PVP = pvp,
Critical = crit,
+ CooldownCounter = cooldownCounter,
PlayerDeathReason = playerDeathReason,
};
PlayerDamage.Invoke(null, args);
@@ -2687,9 +2721,11 @@ namespace TShockAPI
short spawnx = args.Data.ReadInt16();
short spawny = args.Data.ReadInt16();
int respawnTimer = args.Data.ReadInt32();
+ short numberOfDeathsPVE = args.Data.ReadInt16();
+ short numberOfDeathsPVP = args.Data.ReadInt16();
PlayerSpawnContext context = (PlayerSpawnContext)args.Data.ReadByte();
- if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny, respawnTimer, context))
+ if (OnPlayerSpawn(args.Player, args.Data, player, spawnx, spawny, respawnTimer, numberOfDeathsPVE, numberOfDeathsPVP, context))
return true;
if ((Main.ServerSideCharacter) && (spawnx == -1 && spawny == -1)) //this means they want to spawn to vanilla spawn
@@ -2912,17 +2948,19 @@ namespace TShockAPI
Vector2 vel = args.Data.ReadVector2();
byte owner = args.Data.ReadInt8();
short type = args.Data.ReadInt16();
- NewProjectileData bits = new NewProjectileData((BitsByte)args.Data.ReadByte());
+ BitsByte bitsByte = (BitsByte)args.Data.ReadByte();
+ BitsByte bitsByte2 = (BitsByte)(bitsByte[2] ? args.Data.ReadByte() : 0);
float[] ai = new float[Projectile.maxAI];
- for (int i = 0; i < Projectile.maxAI; ++i)
- ai[i] = !bits.AI[i] ? 0.0f : args.Data.ReadSingle();
- ushort bannerId = bits.HasBannerIdToRespondTo ? args.Data.ReadUInt16() : (ushort)0;
- short dmg = bits.HasDamage ? args.Data.ReadInt16() : (short)0;
- float knockback = bits.HasKnockback ? args.Data.ReadSingle() : 0.0f;
- short origDmg = bits.HasOriginalDamage ? args.Data.ReadInt16() : (short)0;
- short projUUID = bits.HasUUUID ? args.Data.ReadInt16() : (short)-1;
- if (projUUID >= 1000)
- projUUID = -1;
+ for (int i = 0; i < Projectile.maxAI; ++i) ai[i] = 0f;
+ ai[0] = bitsByte[0] ? args.Data.ReadSingle() : 0f;
+ ai[1] = bitsByte[1] ? args.Data.ReadSingle() : 0f;
+ ushort bannerId = (ushort)(bitsByte[3] ? args.Data.ReadUInt16() : 0);
+ short dmg = (short)(bitsByte[4] ? args.Data.ReadInt16() : 0);
+ float knockback = bitsByte[5] ? args.Data.ReadSingle() : 0f;
+ short origDmg = (short)(bitsByte[6] ? args.Data.ReadInt16() : 0);
+ short projUUID = (short)(bitsByte[7] ? args.Data.ReadInt16() : -1);
+ if (projUUID >= 1000) projUUID = -1;
+ ai[2] = (bitsByte2[0] ? args.Data.ReadSingle() : 0f);
var index = TShock.Utils.SearchProjectile(ident, owner);
@@ -3150,8 +3188,9 @@ namespace TShockAPI
BitsByte zone2 = args.Data.ReadInt8();
BitsByte zone3 = args.Data.ReadInt8();
BitsByte zone4 = args.Data.ReadInt8();
+ BitsByte zone5 = args.Data.ReadInt8();
- if (OnPlayerZone(args.Player, args.Data, plr, zone1, zone2, zone3, zone4))
+ if (OnPlayerZone(args.Player, args.Data, plr, zone1, zone2, zone3, zone4, zone5))
return true;
return false;
@@ -3616,13 +3655,14 @@ namespace TShockAPI
var x = args.Data.ReadInt16();
var y = args.Data.ReadInt16();
var t = args.Data.ReadInt8();
+ var ct = args.Data.ReadInt8();//PaintCoatTile
if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY || t > Main.numTileColors)
{
TShock.Log.ConsoleDebug(GetString("GetDataHandlers / HandlePaintTile rejected range check {0}", args.Player.Name));
return true;
}
- if (OnPaintTile(args.Player, args.Data, x, y, t))
+ if (OnPaintTile(args.Player, args.Data, x, y, t, ct))
{
return true;
}
@@ -3663,13 +3703,14 @@ namespace TShockAPI
var x = args.Data.ReadInt16();
var y = args.Data.ReadInt16();
var t = args.Data.ReadInt8();
+ var cw = args.Data.ReadInt8();//PaintCoatWall
if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY || t > Main.numTileColors)
{
TShock.Log.ConsoleDebug(GetString("GetDataHandlers / HandlePaintWall rejected range check {0}", args.Player.Name));
return true;
}
- if (OnPaintWall(args.Player, args.Data, x, y, t))
+ if (OnPaintWall(args.Player, args.Data, x, y, t, cw))
{
return true;
}
@@ -3928,9 +3969,10 @@ namespace TShockAPI
short type = args.Data.ReadInt16();
short style = args.Data.ReadInt16();
byte alternate = args.Data.ReadInt8();
+ sbyte random = (sbyte)args.Data.ReadInt8();
bool direction = args.Data.ReadBoolean();
- if (OnPlaceObject(args.Player, args.Data, x, y, type, style, alternate, direction))
+ if (OnPlaceObject(args.Player, args.Data, x, y, type, style, alternate, random, direction))
return true;
return false;
@@ -4068,7 +4110,7 @@ namespace TShockAPI
private static bool HandleNpcTeleportPortal(GetDataHandlerArgs args)
{
- var npcIndex = args.Data.ReadByte();
+ var npcIndex = args.Data.ReadUInt16();
var portalColorIndex = args.Data.ReadInt16();
var newPosition = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle());
var velocity = new Vector2(args.Data.ReadSingle(), args.Data.ReadSingle());
@@ -4162,8 +4204,9 @@ namespace TShockAPI
var bits = (BitsByte)(args.Data.ReadByte());
var crit = bits[0];
var pvp = bits[1];
+ var cooldownCounter = (sbyte)args.Data.ReadInt8();
- if (OnPlayerDamage(args.Player, args.Data, id, direction, dmg, pvp, crit, playerDeathReason))
+ if (OnPlayerDamage(args.Player, args.Data, id, direction, dmg, pvp, crit, cooldownCounter, playerDeathReason))
return true;
return false;
diff --git a/TShockAPI/Net/SpawnMsg.cs b/TShockAPI/Net/SpawnMsg.cs
index 8f0d2752..241a42fa 100644
--- a/TShockAPI/Net/SpawnMsg.cs
+++ b/TShockAPI/Net/SpawnMsg.cs
@@ -33,6 +33,8 @@ namespace TShockAPI.Net
public short TileX { get; set; }
public short TileY { get; set; }
public int RespawnTimer { get; set; }
+ public short NumberOfDeathsPVE { get; set; }
+ public short NumberOfDeathsPVP { get; set; }
public PlayerSpawnContext PlayerSpawnContext { get; set; }
public override void Pack(Stream stream)
@@ -41,6 +43,8 @@ namespace TShockAPI.Net
stream.WriteInt16(TileX);
stream.WriteInt16(TileY);
stream.WriteInt32(RespawnTimer);
+ stream.WriteInt16(NumberOfDeathsPVE);
+ stream.WriteInt16(NumberOfDeathsPVP);
stream.WriteByte((byte) PlayerSpawnContext);
}
}
diff --git a/TShockAPI/TSPlayer.cs b/TShockAPI/TSPlayer.cs
index 553ab9d9..ef5c3c22 100644
--- a/TShockAPI/TSPlayer.cs
+++ b/TShockAPI/TSPlayer.cs
@@ -1394,7 +1394,9 @@ namespace TShockAPI
/// The Y coordinate.
/// The PlayerSpawnContext.
/// The respawn timer, will be Player.respawnTimer if parameter is null.
- public void Spawn(int tilex, int tiley, PlayerSpawnContext context, int? respawnTimer = null)
+ /// The number of deaths PVE, will be TPlayer.numberOfDeathsPVE if parameter is null.
+ /// The number of deaths PVP, will be TPlayer.numberOfDeathsPVP if parameter is null.
+ public void Spawn(int tilex, int tiley, PlayerSpawnContext context, int? respawnTimer = null, short? numberOfDeathsPVE = null, short? numberOfDeathsPVP = null)
{
using (var ms = new MemoryStream())
{
@@ -1404,6 +1406,8 @@ namespace TShockAPI
TileX = (short)tilex,
TileY = (short)tiley,
RespawnTimer = respawnTimer ?? TShock.Players[Index].RespawnTimer * 60,
+ NumberOfDeathsPVE = numberOfDeathsPVE ?? (short)TPlayer.numberOfDeathsPVE,
+ NumberOfDeathsPVP = numberOfDeathsPVP ?? (short)TPlayer.numberOfDeathsPVP,
PlayerSpawnContext = context,
};
msg.PackFull(ms);
diff --git a/docs/changelog.md b/docs/changelog.md
index cd74676e..6bb0c295 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -78,6 +78,18 @@ Use past tense when adding new entries; sign your name off when you add or chang
* If there is no section called "Upcoming changes" below this line, please add one with `## Upcoming changes` as the first line, and then a bulleted item directly after with the first change. -->
## Upcoming changes
+* Corrected and updated deserialization of the following packets (@ATFGK):
+ * `ProjectileNew`: Read the third `AI` value.
+ * Before this change, it was previously possible for the projectile damage limit to falsely trigger, such as when using the Terra Balde and Fire Gauntlet together.
+ * `PlayerSpawn`: Read the `NumberOfDeathsPVE` and `NumberOfDeathsPVP` values.
+ * Before this change, the `PlayerSpawnContext` was always read incorrectly, due to the values above being placed in the middle of the existing structure.
+ * `NpcTeleportPortal`: Read the NPC index as a `ushort` instead of a `byte`.
+ * `PlaceObject`: Read the `Random` value.
+ * Before this change, the `Direction` was always read incorrectly, due to the value above being placed in the middle of the existing structure.
+ * `Zones`: Read the `zone5` value.
+ * `PaintTile` and `PaintWall`: Read the `coatTile` and `coatWall` values.
+ * `PlayerHurtV2`: Read the `cooldownCounter` value.
+* Updated `SpawnMsg` to include the `NumberOfDeathsPVE` and `NumberOfDeathsPVP`, and allow them to be optionally used in `TSPlayer.Spawn`. (@ATFGK)
* Added `WorldTileProvider` to the tshock config with values `default`, `constileation` or `heaptile`. This allows tile providers to be changed in environments where CLI args cannot be altered. See the documentation website for more info about these providers. (@SignatureBeef)
* Updated the Utils.FindByIdOrName to follow same logic. Now fuzzy match fallback to `StartsWith` and then `Contains`. (@sgkoishi)
* Added `ShadowCandle` and `BrainOfConfusionBuff` (BoC dodge buff) to the `PlayerAddBuffWhitelist` (@drunderscore)
@@ -89,6 +101,7 @@ Use past tense when adding new entries; sign your name off when you add or chang
* Increased whitelisted duration of the Mighty Wind (`WindPushed`) buff (from sandstorms). (@drunderscore)
* Allowed the Hellfire (`OnFire3`) buff. (@drunderscore)
+
## TShock 5.1.3
* Added support for Terraria 1.4.4.9 via OTAPI 3.1.20. (@SignatureBeef)