From 039d537b5417d6e7cf54d74f18f21f997f5e9c5c Mon Sep 17 00:00:00 2001 From: Andreas Lierschaft Date: Tue, 18 Aug 2026 00:59:07 +0200 Subject: [PATCH] Fix white lion mount seal (71124): timer now runs only while riding The seal previously toggled the mount via a manual AddAffect+socket flag entirely inside UseItemEx, bypassing Equip()/Unequip() and the item's LIMIT_TIMER_BASED_ON_WEAR machinery entirely - so with item_proto set to LIMIT_NONE, the mount never expired at all. Now: activating starts the item's own wear-based countdown (via StartTimerBasedOnWearExpireEvent, reusing socket0 as remaining-seconds exactly like the existing wear-timer convention), deactivating pauses it (StopTimerBasedOnWearExpireEvent), and it only ticks down while the seal is active - matching the intended "usage time" behavior. Moved the seal's own active-flag from socket0 to socket2 to stop colliding with that convention. item_proto now grants 2 days (172800s) per activation. When the usage time fully runs out while riding, both the mount and the seal item are removed (timer_based_on_wear_expire_event now calls ClearMountAttributeAndAffect() for ride items before destroying them, mirroring the existing Unequip() cleanup path). --- server/game/src/char_item.cpp | 25 ++++++++++++++++++++++--- server/game/src/item.cpp | 3 +++ serverfiles/share/conf/item_proto.txt | 2 +- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/server/game/src/char_item.cpp b/server/game/src/char_item.cpp index f174d29..d5bfa1c 100755 --- a/server/game/src/char_item.cpp +++ b/server/game/src/char_item.cpp @@ -1714,7 +1714,16 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) AddAffect(AFFECT_MOUNT, POINT_MOUNT, dwMountMobVnum, item->GetID(), INFINITE_AFFECT_DURATION, 0, true, false); item->Lock(true); - item->SetSocket(0, 1); + item->SetSocket(2, 1); + + if (0 == item->GetSocket(0)) + { + const long duration = item->GetDuration(); + if (duration > 0) + item->SetSocket(0, duration); + } + + item->StartTimerBasedOnWearExpireEvent(); } else { @@ -1728,7 +1737,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (NULL != pkActiveItem) { pkActiveItem->Lock(false); - pkActiveItem->SetSocket(0, 0); + pkActiveItem->SetSocket(2, 0); + pkActiveItem->StopTimerBasedOnWearExpireEvent(); } if (pkActiveItem != item) @@ -1736,7 +1746,16 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) AddAffect(AFFECT_MOUNT, POINT_MOUNT, dwMountMobVnum, item->GetID(), INFINITE_AFFECT_DURATION, 0, true, false); item->Lock(true); - item->SetSocket(0, 1); + item->SetSocket(2, 1); + + if (0 == item->GetSocket(0)) + { + const long duration = item->GetDuration(); + if (duration > 0) + item->SetSocket(0, duration); + } + + item->StartTimerBasedOnWearExpireEvent(); } } } diff --git a/server/game/src/item.cpp b/server/game/src/item.cpp index 2007797..edc7647 100755 --- a/server/game/src/item.cpp +++ b/server/game/src/item.cpp @@ -1314,6 +1314,9 @@ EVENTFUNC(timer_based_on_wear_expire_event) pkItem->SetTimerBasedOnWearExpireEvent(NULL); pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, 0); + if (pkItem->IsRideItem()) + pkItem->ClearMountAttributeAndAffect(); + ITEM_MANAGER::instance().RemoveItem(pkItem, "TIMER_BASED_ON_WEAR_EXPIRE"); return 0; } diff --git a/serverfiles/share/conf/item_proto.txt b/serverfiles/share/conf/item_proto.txt index c0fa25a..c572b16 100755 --- a/serverfiles/share/conf/item_proto.txt +++ b/serverfiles/share/conf/item_proto.txt @@ -5199,7 +5199,7 @@ ITEM 71121 »çÀÚ¿ÕÀÌ¿ë±Ç ITEM_QUEST 0 1 NONE ITEM_STACKABLE NONE NONE 0 0 0 0 0 LIMIT_NONE 0 LIMIT_NONE 0 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 0 0 0 0 0 0 0 0 0 71122 ¼ö·æ¹æÀÔÀå±Ç ITEM_MATERIAL MATERIAL_LEATHER 1 NONE ITEM_STACKABLE NONE NONE 0 0 0 0 0 LIMIT_NONE 0 LIMIT_NONE 0 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 0 0 0 0 0 0 0 0 0 71123 ¼ö·æºñ´Ã ITEM_MATERIAL MATERIAL_LEATHER 1 NONE ITEM_STACKABLE NONE NONE 0 0 0 0 0 LIMIT_NONE 0 LIMIT_NONE 0 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 0 0 0 0 0 0 0 0 0 -71124 ¹é»çÀÚÀÌ¿ë±Ç ITEM_UNIQUE UNIQUE_SPECIAL_RIDE 1 ANTI_DROP | ANTI_SELL | ANTI_GIVE | ANTI_MYSHOP QUEST_USE_MULTIPLE | LOG WEAR_SHIELD NONE 0 0 0 0 0 LEVEL 0 LIMIT_NONE 0 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 2400 0 0 0 0 0 0 0 0 +71124 ¹é»çÀÚÀÌ¿ë±Ç ITEM_UNIQUE UNIQUE_SPECIAL_RIDE 1 ANTI_DROP | ANTI_SELL | ANTI_GIVE | ANTI_MYSHOP QUEST_USE_MULTIPLE | LOG WEAR_SHIELD NONE 0 0 0 0 0 LEVEL 0 LIMIT_TIMER_BASED_ON_WEAR 172800 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 2400 0 0 0 0 0 0 0 0 71125 ÈæÀú½ÅÀÌ¿ë±Ç ITEM_UNIQUE UNIQUE_SPECIAL_RIDE 1 ANTI_SELL | ANTI_STACK QUEST_USE_MULTIPLE | LOG WEAR_SHIELD NONE 0 0 0 0 0 LEVEL 20 LIMIT_NONE 0 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 28800 0 0 0 0 0 0 0 0 71126 Èæ»ê°ß½ÅÀÌ¿ë±Ç ITEM_UNIQUE UNIQUE_SPECIAL_RIDE 1 ANTI_SELL | ANTI_STACK QUEST_USE_MULTIPLE | LOG WEAR_SHIELD NONE 0 0 0 0 0 LEVEL 20 LIMIT_NONE 0 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 28800 0 0 0 0 0 0 0 0 71127 ÈæÅõÁö¹üÀÌ¿ë±Ç ITEM_UNIQUE UNIQUE_SPECIAL_RIDE 1 ANTI_DROP | ANTI_SELL | ANTI_GIVE | ANTI_MYSHOP QUEST_USE_MULTIPLE | LOG WEAR_SHIELD NONE 0 0 0 0 0 LEVEL 20 LIMIT_NONE 0 APPLY_NONE 0 APPLY_NONE 0 APPLY_NONE 0 28800 0 0 0 0 0 0 0 0