• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ [TFS 1.3] Conditions Not Being Properly Deserialized

Aoxomoxoa

Dev
Joined
Jun 23, 2020
Messages
95
Solutions
1
Reaction score
54
Location
USA
GitHub
TheAoxomoxoa
Hello,

I've been messing around with TFS 1.3 and ran into one issue that's been bugging me. I can't seem how to fix it and don't have enough knowledge of the system to repair it.

Steps to reproduce:
1. Eat food.
2. Start regening health/mana.
3. Logout.
4. Login.

You're now hungry again and your regen time remaining is back to 0, you stop regening health/mana.

I found this issue on Github, but was wondering if we can fix this together!

Issue #3114 <-- Github issue regarding health/mana regen bug after #2545
Pull Request #2545 <-- #2545
Changes made in Pull Request #2545 <-- Changes made in #2545

Any help would be appreciated. Or if someone could point me in the right direction on how to go about solving this myself, that would be nice too.
 
Solution
A temporarily workaround can be to add this to a logout creatureevent:

Lua:
 local condition = player:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
player:setStorageValue(132721,condition:getTicks()) -- Store this as storagevalue for player

And then add it back to him on login.

I used this while playing around with an autoeat revscriptsys code:

The condition worked fine back then (10 months ago).
This might be a good way to see if regen conditions are working properly as well.
I have tried replacing:
C++:
        case CONDITION_REGENERATION:
            return new ConditionRegeneration(id, type, ticks, buff, subId, aggressive);
C++:
        ConditionRegeneration(ConditionId_t id, ConditionType_t type, int32_t ticks, bool buff = false, uint32_t subId = 0, bool aggressive = false):
            ConditionGeneric(id, type, ticks, buff, subId, aggressive) {}
with what was removed:
C++:
        case CONDITION_REGENERATION:
            return new ConditionRegeneration(id, type, ticks, buff, subId);
C++:
        ConditionRegeneration(ConditionId_t id, ConditionType_t type, int32_t ticks, bool buff = false, uint32_t subId = 0):
            ConditionGeneric(id, type, ticks, buff, subId) {}

and that didn't seem to change anything with the player's regeneration returning to 0 after they logout.
 
How is player regeneration values stored after the player has logged out? As far as I know, on logout the player should store its data to database and the player object destroyed in-game. (until player logs in again, then it should load it back).
I don't think the remaining regen time is stored anywere, thus being initialized to value 0 when the player object is re-created.

I don't think this has anything to do with #2410? Have you tried to fork latest TFS, revert #2410 and seen the problem solved?
The solution might be as easy as an extra column in the players table, a smallint that keeps track of remaining regeneration.
 
Last edited:
How is player regeneration values stored after the player has logged out? As far as I know, on logout the player should store its data to database and the player object destroyed in-game. (until player logs in again, then it should load it back).
I don't think the remaining regen time is stored anywere, thus being initialized to value 0 when the player object is re-created.

I don't think this has anything to do with #2410? Have you tried to fork latest TFS, revert #2410 and seen the problem solved?
The solution might be as easy as an extra column in the players table, a smallint that keeps track of remaining regeneration.

I have tried to revert #2410. To my surprise it was not the issue. I'm not sure why this is an issue now though, as the previous TFS 1.3 that I had compiled a few weeks ago didn't have that issue. Only the current one. Still not seeing anything in the source that would cause this problem though. It is concerning for me though, as my OT is very heavily RPG based and food is a major factor to gameplay. Really annoying to have to recreate 10 meats every time I want to relog.. lol

What controls player regeneration in the source besides this condition? I don't know much about TFS and am just playing around with the source trying to modify it to fit a project. However, I know my modifications, a quiver, player lighting, and health regen on level up, would not affect food regeneration on logout.
 
A temporarily workaround can be to add this to a logout creatureevent:

Lua:
 local condition = player:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
player:setStorageValue(132721,condition:getTicks()) -- Store this as storagevalue for player

And then add it back to him on login.

I used this while playing around with an autoeat revscriptsys code:

The condition worked fine back then (10 months ago).
This might be a good way to see if regen conditions are working properly as well.
 
Solution
A temporarily workaround can be to add this to a logout creatureevent:

Lua:
 local condition = player:getCondition(CONDITION_REGENERATION, CONDITIONID_DEFAULT)
player:setStorageValue(132721,condition:getTicks()) -- Store this as storagevalue for player

And then add it back to him on login.

I used this while playing around with an autoeat revscriptsys code:

The condition worked fine back then (10 months ago).
This might be a good way to see if regen conditions are working properly as well.

Thanks for that workaround. I'll add that in there and keep working on trying to fix it myself to learn a bit more!
 
Works even better! Thanks StreamSide! Everything seems to be back to normal. I'm curious, how did you go about finding that was the solution? I'm trying to learn all of this stuff.
Well let me explain it to you (because I also learned from this)
if you remember the previous condition commit you might need to look at this part
1594160549902.png
that part adds two new bytes as you can see, one related to the condition attribute and then the value itself
but then when its created the condition and the values are readed again, here
1594160752126.png
as you notice there is no attribute check, so this produces corrupt data and so a nullptr will be returned :)
 
Well let me explain it to you (because I also learned from this)
if you remember the previous condition commit you might need to look at this part
View attachment 47259
that part adds two new bytes as you can see, one related to the condition attribute and then the value itself
but then when its created the condition and the values are readed again, here
View attachment 47260
as you notice there is no attribute check, so this produces corrupt data and so a nullptr will be returned :)
Very interesting! Thanks for explaining this. I've been looking all around the source for a fix and would've never guessed it'd be this simple.
 
Back
Top