First four bits of more1/2 doesn't store value above 07fff
When settings more1/2 higher 4 bits (more1h / more2h) these values doesn't store in more. I'll be using only more1 in example.
You can set more1h value from 0 to 65535 (0 - ffff), but only first half gets saved (0 - 7fff). I've tested it with loop and with save:
Loop (more1l is val-1):
val: 32763; more1h: 07ffb; more1l: 07ffa; more: 07ffb7ffa
val: 32764; more1h: 07ffc; more1l: 07ffb; more: 07ffc7ffb
val: 32765; more1h: 07ffd; more1l: 07ffc; more: 07ffd7ffc
val: 32766; more1h: 07ffe; more1l: 07ffd; more: 07ffe7ffd
val: 32767; more1h: 07fff; more1l: 07ffe; more: 07fff7ffe
val: 32768; more1h: 08000; more1l: 07fff; more: 07fff
val: 32769; more1h: 08001; more1l: 08000; more: 018000
val: 32770; more1h: 08002; more1l: 08001; more: 028001
val: 32771; more1h: 08003; more1l: 08002; more: 038002
val: 32772; more1h: 08004; more1l: 08003; more: 048003
Set value and check before and after save and restart:
more1h: 33000 (080e8)
more1l: 32999 (080e7)
more1: 0880e7 (0880e7)
Startup complete (items=6, chars=1, Accounts = 1)
more1h: 8 (08)
more1l: 32999 (080e7)
more1: 0880e7 (0880e7)
Test scenario:
- Set more1 value above 07fffffff (for example 080018000)
- check more1l, more1h and more
- restart sphere
- check more1l, more1h and more
Tested on branch main (rev 3941).
Just for reference, We had a similar bug and was fixed about spellbook https://github.com/Sphereserver/Source-X/issues/1221
I've tracked the issue down. Problem is here: https://github.com/Sphereserver/Source-X/blob/5db37f1fa83409049ecfbbb969e8a7e696542ff4/src/game/items/CItem.cpp#L2349
In this condition the check for IsResource: https://github.com/Sphereserver/Source-X/blob/5db37f1fa83409049ecfbbb969e8a7e696542ff4/src/common/CUID.cpp#L44 https://github.com/Sphereserver/Source-X/blob/5db37f1fa83409049ecfbbb969e8a7e696542ff4/src/common/CUID.cpp#L39
is true (because it contains mask for UID_F_RESOURCE https://github.com/Sphereserver/Source-X/blob/5db37f1fa83409049ecfbbb969e8a7e696542ff4/src/common/CUID.h#L19
I've tested removing this condition only to save value with sVal.FormatHex(m_itNormal.m_more1); and it worked.
Ok, after some digging, I tested it with CAN_I_SCRIPTEDMORE (which was missing from scriptpack; already created PR), but to no avail, if fails also.
During checking for resource name, the index get stripped in ResGetIndex:
https://github.com/Sphereserver/Source-X/blob/0911dd22b145d4bb006c9a3371b658ec63df26ca/src/game/items/CItem.cpp#L3038
But since we are using scriptedmore, we shouldn't strip it. Maybe during CItem::ResourceGetName, return whole index in hexa, instead of stripped value from rid.GetResIndex()
Does this happen with some specific item types or with anyone of them?
I've tested it with type 0, but it defaults to this behaviour, so it can be any type, that is not explicitly defined in void CItem::r_WriteMore1(CSString & sVal) (or More2).
If more1/2 is greater than 080000000 the check for if (CResourceIDBase::IsValidResource(m_itNormal.m_more1)) is true and it goes to lpctstr CItem::ResourceGetName(const CResourceID& rid).
During this, there is check for if (Can(CAN_I_SCRIPTEDMORE)) (now commented). And here, I would think, since we are not using any hardcoded logic because of the flag, should be returned value, that we set (without any resource checks).
This check might just go to directly to void CItem::r_WriteMore1(CSString & sVal) and if true, just store value with sVal.FormatHex(m_itNormal.m_more1);
Test case scenario:
Lets say we have item, called i_quest_book.
[ITEMDEF i_quest_book]
ID=0fbe
NAME=Quest Book
TYPE=0
// Hex, since it is not in scriptpack.
CAN=020000000
WEIGHT=0
And we store in more1/2 completed quests as flags. So if a player has a lot of quests completed, more1 (2) could look like: MORE1=0ce7532c4
Okay, thank you for your in-depth investigation about this issue, i agree with everything. I'll commit a fix with the suggestions.
Addressed to in dev branch.