L2JMobius

Dwelling of Spirits [Classic 3.5 – Tales Untold] Pet/Servitor stats panel shows absurd/incorrect

mfg1984 · 7 · 491

Offline mfg1984

  • Vassal
  • *
    • Posts: 4
Environment

Project/Pack: L2J_Mobius_Classic_3.5_TalesUntold

Revision/build: Created on June 17, 2025

Client protocol: 286

Clean install; no custom scripts or client mods (configs available on request).

Description
The Manage Servitor window displays nonsensical stats for summoned pets/servitors (e.g., negative P. Atk, extremely large P. Def/Accuracy/Crit, etc.). Example in screenshot: Lv 27 Silhouette shows P. Atk: -197,971, P. Def: 9,056,969, M. Critical: -194,615, Speed: 3,690,987, etc.

Scope
This is not limited to a single pet or character: it also appears on other pets and across different characters.

Reproduction steps

Log in on Classic 3.5 (protocol 286).

Summon any servitor (e.g., Silhouette, others also affected).

Open Manage Servitor → Details.

Observe the displayed combat stats.

Expected result
Reasonable, level-appropriate stats (no negative values or out-of-range magnitudes).

Actual result
UI shows wild/incorrect numbers (negative or extremely high).
Gameplay-wise, the pet’s damage taken/dealt seems normal, so this looks like a display/packet/calculation issue rather than real stats being applied.

Frequency / Impact

Always reproducible.

Impact: Misleading UI for players/admins; not game-breaking but confusing.

What I checked so far

Tested with the same client & system on another server running protocol 286 → issue does not appear there, suggesting it’s server-side on my setup rather than client-side.

No gameserver console errors during summon or while opening the panel.

Evidence

Screenshot: (attach / imgbb link of the shown example)
https://i.ibb.co/DHyrxxx2/Screenshot-4.png

Notes / Possible direction

Possibly related to servitor stat calculation or values sent in the status packet for the Manage Servitor window (servitor status update vs. actual combat formulas).

Thanks in advance for any guidance or fixes!


Offline justwmz

  • Vassal
  • *
    • Posts: 3
Hello,
Same also happens to me, just get a latest build and I am observing same behavior.

https://snipboard.io/4ZrDp3.jpg

Hi @Mobius, Could you please help here?



Offline justwmz

  • Vassal
  • *
    • Posts: 3
@Mobius  Just tied it with Dweling of Spirits and it seems to be working as expected but with Classic client.

https://snipboard.io/AS8uLT.jpg

Also I just ported same packets responsible for Servitor Window into Classic from Essence and now it works fine:

https://snipboard.io/QnzGbm.jpg


Online Mobius

  • Distinguished King
  • *****
    • Posts: 19715
Try this.
Code: (diff) [Select]
Index: java/org/l2jmobius/gameserver/network/serverpackets/PetSummonInfo.java
===================================================================
--- java/org/l2jmobius/gameserver/network/serverpackets/PetSummonInfo.java (revision 20232)
+++ java/org/l2jmobius/gameserver/network/serverpackets/PetSummonInfo.java (working copy)
@@ -130,7 +130,7 @@
  buffer.writeInt(_summon.getWeapon()); // right hand weapon
  buffer.writeInt(_summon.getArmor()); // body armor
  buffer.writeInt(0); // left hand weapon
- buffer.writeByte(_summon.isShowSummonAnimation() ? 2 : _value); // 0=teleported 1=default 2=summoned
+ buffer.writeByte(_summon.isDead() ? 0 : _summon.isShowSummonAnimation() ? 2 : _value);
  buffer.writeInt(-1); // High Five NPCString ID
  if (_summon.isPet())
  {
@@ -152,17 +152,9 @@
  buffer.writeInt((int) _summon.getCurrentMp()); // current mp
  buffer.writeInt(_summon.getMaxMp()); // max mp
  buffer.writeLong(_summon.getStat().getSp()); // sp
- buffer.writeByte(_summon.getLevel()); // level
- buffer.writeLong(_summon.getStat().getExp());
- if (_summon.getExpForThisLevel() > _summon.getStat().getExp())
- {
- buffer.writeLong(_summon.getStat().getExp()); // 0% absolute value
- }
- else
- {
- buffer.writeLong(_summon.getExpForThisLevel()); // 0% absolute value
- }
-
+ buffer.writeShort(_summon.getLevel()); // level
+ buffer.writeLong(_summon.getStat().getExp()); // 0% absolute value
+ buffer.writeLong(Math.min(_summon.getExpForThisLevel(), _summon.getStat().getExp())); // 0% absolute value
  buffer.writeLong(_summon.getExpForNextLevel()); // 100% absoulte value
  buffer.writeInt(_summon.isPet() ? _summon.getInventory().getTotalWeight() : 0); // weight
  buffer.writeInt(_summon.getMaxLoad()); // max weight it can carry
@@ -183,7 +175,7 @@
  buffer.writeByte(_summon.getTeam().getId()); // Confirmed
  buffer.writeByte(_summon.getSoulShotsPerHit()); // How many soulshots this servitor uses per hit - Confirmed
  buffer.writeByte(_summon.getSpiritShotsPerHit()); // How many spiritshots this servitor uses per hit - - Confirmed
- buffer.writeInt(0); // TODO: Find me
+ buffer.writeInt(-1);
  buffer.writeInt(0); // "Transformation ID - Confirmed" - Used to bug Fenrir after 64 level.
  buffer.writeByte(_summon.getOwner().getSummonPoints()); // Used Summon Points
  buffer.writeByte(_summon.getOwner().getMaxSummonPoints()); // Maximum Summon Points


Offline justwmz

  • Vassal
  • *
    • Posts: 3
Try this.
Code: (diff) [Select]
Index: java/org/l2jmobius/gameserver/network/serverpackets/PetSummonInfo.java
===================================================================
--- java/org/l2jmobius/gameserver/network/serverpackets/PetSummonInfo.java (revision 20232)
+++ java/org/l2jmobius/gameserver/network/serverpackets/PetSummonInfo.java (working copy)
@@ -130,7 +130,7 @@
  buffer.writeInt(_summon.getWeapon()); // right hand weapon
  buffer.writeInt(_summon.getArmor()); // body armor
  buffer.writeInt(0); // left hand weapon
- buffer.writeByte(_summon.isShowSummonAnimation() ? 2 : _value); // 0=teleported 1=default 2=summoned
+ buffer.writeByte(_summon.isDead() ? 0 : _summon.isShowSummonAnimation() ? 2 : _value);
  buffer.writeInt(-1); // High Five NPCString ID
  if (_summon.isPet())
  {
@@ -152,17 +152,9 @@
  buffer.writeInt((int) _summon.getCurrentMp()); // current mp
  buffer.writeInt(_summon.getMaxMp()); // max mp
  buffer.writeLong(_summon.getStat().getSp()); // sp
- buffer.writeByte(_summon.getLevel()); // level
- buffer.writeLong(_summon.getStat().getExp());
- if (_summon.getExpForThisLevel() > _summon.getStat().getExp())
- {
- buffer.writeLong(_summon.getStat().getExp()); // 0% absolute value
- }
- else
- {
- buffer.writeLong(_summon.getExpForThisLevel()); // 0% absolute value
- }
-
+ buffer.writeShort(_summon.getLevel()); // level
+ buffer.writeLong(_summon.getStat().getExp()); // 0% absolute value
+ buffer.writeLong(Math.min(_summon.getExpForThisLevel(), _summon.getStat().getExp())); // 0% absolute value
  buffer.writeLong(_summon.getExpForNextLevel()); // 100% absoulte value
  buffer.writeInt(_summon.isPet() ? _summon.getInventory().getTotalWeight() : 0); // weight
  buffer.writeInt(_summon.getMaxLoad()); // max weight it can carry
@@ -183,7 +175,7 @@
  buffer.writeByte(_summon.getTeam().getId()); // Confirmed
  buffer.writeByte(_summon.getSoulShotsPerHit()); // How many soulshots this servitor uses per hit - Confirmed
  buffer.writeByte(_summon.getSpiritShotsPerHit()); // How many spiritshots this servitor uses per hit - - Confirmed
- buffer.writeInt(0); // TODO: Find me
+ buffer.writeInt(-1);
  buffer.writeInt(0); // "Transformation ID - Confirmed" - Used to bug Fenrir after 64 level.
  buffer.writeByte(_summon.getOwner().getSummonPoints()); // Used Summon Points
  buffer.writeByte(_summon.getOwner().getMaxSummonPoints()); // Maximum Summon Points

Just ported it by myself from essence and it seems to be working:

https://snipboard.io/QnzGbm.jpg