From 848fd6a8959394ea592767126bed591cb3018517 Mon Sep 17 00:00:00 2001 From: David Kindl Date: Thu, 15 May 2025 08:31:08 +0200 Subject: [PATCH 1/2] - add check for real and sent layer in PacketItemEquipReq (#1391) - swap real layer during ItemEquip withing EquipTest / ItemEquipTest trigger --- src/game/chars/CCharAct.cpp | 14 +++++++++++++- src/network/receive.cpp | 11 +++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/game/chars/CCharAct.cpp b/src/game/chars/CCharAct.cpp index 62e40e1be..b2824fa8e 100644 --- a/src/game/chars/CCharAct.cpp +++ b/src/game/chars/CCharAct.cpp @@ -3285,9 +3285,12 @@ bool CChar::ItemEquip( CItem * pItem, CChar * pCharMsg, bool fFromDClick ) if ( !pCharMsg ) pCharMsg = this; + // Remember original layer, because we need to return to it after equiptest trigger. + LAYER_TYPE const requestedLayer = pItem->GetEquipLayer(); + if ( pItem->GetParent() == this ) { - if ( pItem->GetEquipLayer() != LAYER_DRAGGING ) // already equipped. + if ( requestedLayer != LAYER_DRAGGING ) // already equipped. return true; } @@ -3303,8 +3306,14 @@ bool CChar::ItemEquip( CItem * pItem, CChar * pCharMsg, bool fFromDClick ) if (IsTrigUsed(TRIGGER_EQUIPTEST) || IsTrigUsed(TRIGGER_ITEMEQUIPTEST)) { + // Swap the layer for real one, because if we don't use dclick for equip, real layer gets rewritten with LAYER_DRAGGING. + pItem->SetEquipLayer(layer); + if (pItem->OnTrigger(ITRIG_EQUIPTEST, this) == TRIGRET_RET_TRUE) { + // Reset layer to the original value, that item doesn't get misplaced. + pItem->SetEquipLayer(requestedLayer); + // since this trigger is called also when creating an item via ITEM=, if the created item has a RETURN 1 in @EquipTest // (or if the NPC has a RETURN 1 in @ItemEquipTest), the item will be created but not placed in the world. // so, if this is an NPC, even if there's a RETURN 1 i need to bounce the item inside his pack @@ -3315,6 +3324,9 @@ bool CChar::ItemEquip( CItem * pItem, CChar * pCharMsg, bool fFromDClick ) return false; } + // Reset layer to the original value. + pItem->SetEquipLayer(requestedLayer); + if (pItem->IsDeleted()) return false; } diff --git a/src/network/receive.cpp b/src/network/receive.cpp index 3aa57263a..d77b6bfcf 100644 --- a/src/network/receive.cpp +++ b/src/network/receive.cpp @@ -546,6 +546,17 @@ bool PacketItemEquipReq::onReceive(CNetState* net) CChar* target = targetSerial.CharFind(); bool fSuccess = false; + + // Check if player is sending wrong / forged layer. + const LAYER_TYPE itemRealLayer = target->CanEquipLayer(item, LAYER_QTY, target, true); + if (itemLayer != itemRealLayer) + { +#ifdef _DEBUG + g_Log.EventDebug("Player trying to equip item to invalid layer (sent: %d, should be %d)\n", itemLayer, itemRealLayer); +#endif + itemLayer = itemRealLayer; + } + if (target && (itemLayer < LAYER_HORSE) && source->CanDress(target) && source->CanTouch(item)) { //if (target->CanCarry(item)) //Since Weight behavior rework, we want avoid don't be able to equip an item if overweight From 1e3a9b98ca56c47f357d3b5a71bd58d9b8ee53ea Mon Sep 17 00:00:00 2001 From: David Kindl Date: Fri, 16 May 2025 08:40:54 +0200 Subject: [PATCH 2/2] Changelog entry to explain behaviour of EquipTest trigger change --- Changelog.txt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Changelog.txt b/Changelog.txt index 2e34870e8..e6836e13b 100644 --- a/Changelog.txt +++ b/Changelog.txt @@ -3967,16 +3967,16 @@ Added: 'H' shortcut for variables to get the value as hexadecimal. 6-12-2024, canerksk - Added: LOCAL.WOPTalkMode in @SpellCast trigger and ini setting WOPTalkMode. In some clients, different operations can be performed based on this. For example, if this talk mode was sent from Sphere as TALKMODE_SPELL, the operation is performed according to the client version. The possibility of changing the talk mode according to the client version used is now provided. By default, TALKMODE_SPELL. - + Default talk mode: TALKMODE_SPELL = 10 - + Sphere.ini: WOPTalkMode = 0/14 - + Trigger: @SpellCast Local.WOPTalkMode = 0/14 - + TALKMODE_SAY = 0 // A character speaking. TALKMODE_SYSTEM = 1 // Display as system prompt. TALKMODE_EMOTE = 2 // *smiles* at object (client shortcut: :+space). @@ -4019,7 +4019,7 @@ Added: 'H' shortcut for variables to get the value as hexadecimal. VerboseItemBounce = 0 // (default) 22-04-2025, canerksk -- Added: New item function, CARVECORPSE: carves a corpse with SRC = char carving the corpse. +- Added: New item function, CARVECORPSE: carves a corpse with SRC = char carving the corpse. - Added: New ini RevealFlag setting REVEALF_ONHORSE, to allow or disallow stealth walking if you are on a mount. - Added: new ini CombatFlags setting COMBAT_ATTACK_NOAGGREIVED. In the old behavior (55i/55r/56b/56c) we were not guilty when we hit a murderer. Now when we attack a criminal or murderer we are guilty towards that person. An ini setting option has been added for this behavior. Although this is a normal behavior in OSI, it can be perceived as a problem since not every server designs games like OSI. @@ -4047,3 +4047,6 @@ When setting a property like MORE to the a spell or skill defname, trying to rea 08-05-2025, Nolok - Added: NPCWanderingLookAroundChance ini setting and TAG.OVERRIDE.LOOKAROUNDCHANCE. It allows to change the chance that a wandering NPC will analyze its surroundings for the current step. This also means that the trigger @NPCLookAtChar will fire more frequently. + +16-05-2025, Mulambo +- Changed: When equipping item by dragging or using Dress macro, the item layer is now showing actual layer of the object in EquipTest and ItemEquipTest trigger (instead of 31 = LAYER_DRAGGING). This is the same behaviour, as equipping by double clicking.