From 4670bbe4ee8e9aea30db3a9d0990e8ab4f962193 Mon Sep 17 00:00:00 2001 From: Sarah Wesker Date: Sat, 27 Apr 2024 23:13:46 -0400 Subject: [PATCH] fix condition constant and small things --- src/condition.cpp | 65 ++++++++++++++++++++++++++++++++++++++------ src/condition.h | 13 ++++++--- src/iologindata.cpp | 6 ++-- src/luacondition.cpp | 2 +- src/player.cpp | 17 ++++++------ src/player.h | 3 +- 6 files changed, 79 insertions(+), 27 deletions(-) diff --git a/src/condition.cpp b/src/condition.cpp index bd0f619..bbe873d 100644 --- a/src/condition.cpp +++ b/src/condition.cpp @@ -129,6 +129,10 @@ bool Condition::unserializeProp(ConditionAttr_t attr, PropStream& propStream) return true; } + case CONDITIONATTR_ENDTIME: { + return propStream.read(endTime); + } + case CONDITIONATTR_END: return true; @@ -158,13 +162,26 @@ void Condition::serialize(PropWriteStream& propWriteStream) propWriteStream.write(aggressive); propWriteStream.write(CONDITIONATTR_CONSTANT); - propWriteStream.write(constant ? 1 : 0); + propWriteStream.write(constant); + + if (constant) { + propWriteStream.write(CONDITIONATTR_ENDTIME); + propWriteStream.write(endTime); + } +} + +void Condition::setEndTime(int64_t newEndTime) +{ + if (endTime == 0) { + endTime = newEndTime; + } } void Condition::setTicks(int32_t newTicks) { ticks = newTicks; - endTime = ticks + OTSYS_TIME(); + + setEndTime(ticks + OTSYS_TIME()); } bool Condition::executeCondition(Creature*, int32_t interval) @@ -235,7 +252,7 @@ Condition* Condition::createCondition(ConditionId_t id, ConditionType_t type, in } } -Condition* Condition::createCondition(PropStream& propStream) +Condition_ptr Condition::createCondition(PropStream& propStream) { uint8_t attr; if (!propStream.read(attr) || attr != CONDITIONATTR_TYPE) { @@ -292,14 +309,44 @@ Condition* Condition::createCondition(PropStream& propStream) return nullptr; } - return createCondition(static_cast(id), static_cast(type), ticks, 0, buff != 0, - subId, aggressive); + if (!propStream.read(attr) || attr != CONDITIONATTR_CONSTANT) { + return nullptr; + } + + uint8_t constant; + if (!propStream.read(constant)) { + return nullptr; + } + + auto condition = Condition_ptr(createCondition(static_cast(id), static_cast(type), + ticks, 0, buff != 0, subId, aggressive)); + + if (!condition) { + return nullptr; + } + + condition->setConstant(constant != 0); + + if (condition->isConstant()) { + if (!propStream.read(attr) || attr != CONDITIONATTR_ENDTIME) { + return nullptr; + } + + int64_t endTime; + if (!propStream.read(endTime)) { + return nullptr; + } + + condition->setEndTime(endTime); + } + + return condition; } bool Condition::startCondition(Creature*) { if (ticks > 0) { - endTime = ticks + OTSYS_TIME(); + setEndTime(ticks + OTSYS_TIME()); } return true; } @@ -489,7 +536,7 @@ void ConditionAttributes::updatePercentStats(Player* player) } } -void ConditionAttributes::updateStats(Player* player) +void ConditionAttributes::updateStats(Player* player) const { bool needUpdateStats = false; @@ -518,7 +565,7 @@ void ConditionAttributes::updatePercentSkills(Player* player) } } -void ConditionAttributes::updateSkills(Player* player) +void ConditionAttributes::updateSkills(Player* player) const { bool needUpdateSkills = false; @@ -541,7 +588,7 @@ void ConditionAttributes::updateSkills(Player* player) } } -void ConditionAttributes::updateExperienceRate(Player* player) +void ConditionAttributes::updateExperienceRate(Player* player) const { for (uint8_t i = static_cast(ExperienceRateType::BASE); i <= static_cast(ExperienceRateType::STAMINA); ++i) { diff --git a/src/condition.h b/src/condition.h index e6a38d7..504352d 100644 --- a/src/condition.h +++ b/src/condition.h @@ -47,6 +47,7 @@ enum ConditionAttr_t CONDITIONATTR_HEALTHGAINPERCENT, CONDITIONATTR_MANAGAINPERCENT, CONDITIONATTR_CONSTANT, + CONDITIONATTR_ENDTIME, // only use if the condition is constant // reserved for serialization CONDITIONATTR_END = 254, @@ -59,6 +60,9 @@ struct IntervalInfo int32_t interval; }; +class Condition; +using Condition_ptr = std::unique_ptr; + class Condition { public: @@ -87,13 +91,14 @@ class Condition ConditionType_t getType() const { return conditionType; } int64_t getEndTime() const { return endTime; } + void setEndTime(int64_t newEndTime); int32_t getTicks() const { return ticks; } void setTicks(int32_t newTicks); bool isAggressive() const { return aggressive; } static Condition* createCondition(ConditionId_t id, ConditionType_t type, int32_t ticks, int32_t param = 0, bool buff = false, uint32_t subId = 0, bool aggressive = false); - static Condition* createCondition(PropStream& propStream); + static Condition_ptr createCondition(PropStream& propStream); virtual bool setParam(ConditionParam_t param, int32_t value); virtual int32_t getParam(ConditionParam_t param) const; @@ -177,10 +182,10 @@ class ConditionAttributes final : public ConditionGeneric bool disableDefense = false; void updatePercentStats(Player* player); - void updateStats(Player* player); + void updateStats(Player* player) const; void updatePercentSkills(Player* player); - void updateSkills(Player* player); - void updateExperienceRate(Player* player); + void updateSkills(Player* player) const; + void updateExperienceRate(Player* player) const; }; class ConditionRegeneration final : public ConditionGeneric diff --git a/src/iologindata.cpp b/src/iologindata.cpp index 6e9f515..9e0aced 100644 --- a/src/iologindata.cpp +++ b/src/iologindata.cpp @@ -321,12 +321,10 @@ bool IOLoginData::loadPlayer(Player* player, DBResult_ptr result) PropStream propStream; propStream.init(conditions.data(), conditions.size()); - Condition* condition = Condition::createCondition(propStream); + Condition_ptr condition = Condition::createCondition(propStream); while (condition) { if (condition->unserialize(propStream)) { - player->storedConditionList.push_front(condition); - } else { - delete condition; + player->storedConditionList.push_front(condition.release()); } condition = Condition::createCondition(propStream); } diff --git a/src/luacondition.cpp b/src/luacondition.cpp index c58400a..088dbd4 100644 --- a/src/luacondition.cpp +++ b/src/luacondition.cpp @@ -16,7 +16,7 @@ int luaConditionCreate(lua_State* L) ConditionType_t conditionType = getInteger(L, 2); ConditionId_t conditionId = getInteger(L, 3, CONDITIONID_COMBAT); - Condition* condition = Condition::createCondition(conditionId, conditionType, 0, 0); + auto condition = Condition::createCondition(conditionId, conditionType, 0, 0); if (condition) { pushUserdata(L, condition); setMetatable(L, -1, "Condition"); diff --git a/src/player.cpp b/src/player.cpp index 241457b..9a1532e 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -28,6 +28,7 @@ extern Events* g_events; MuteCountMap Player::muteCountMap; uint32_t Player::playerAutoID = 0x10000000; +std::forward_list Player::storedConditionList; Player::Player(ProtocolGame_ptr p) : Creature(), lastPing(OTSYS_TIME()), lastPong(lastPing), client(std::move(p)) { @@ -979,7 +980,7 @@ void Player::onCreatureAppear(Creature* creature, bool isLogin) } } - for (Condition* condition : storedConditionList) { + for (auto condition : storedConditionList) { addCondition(condition); } storedConditionList.clear(); @@ -1200,7 +1201,7 @@ void Player::onCreatureMove(Creature* creature, const Tile* newTile, const Posit if (teleport || oldPos.z != newPos.z) { const int64_t ticks = g_config[ConfigKeysInteger::STAIRHOP_DELAY]; if (ticks > 0) { - if (Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_PACIFIED, ticks, 0)) { + if (auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_PACIFIED, ticks, 0)) { addCondition(condition); } } @@ -1421,7 +1422,7 @@ void Player::removeMessageBuffer() uint32_t muteTime = 5 * muteCount * muteCount; muteCountMap[guid] = muteCount + 1; - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_MUTED, muteTime * 1000, 0); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_MUTED, muteTime * 1000, 0); addCondition(condition); sendTextMessage(MESSAGE_STATUS_SMALL, fmt::format("You are muted for {:d} seconds.", muteTime)); @@ -2052,13 +2053,13 @@ Item* Player::getCorpse(Creature* lastHitCreature, Creature* mostDamageCreature) void Player::addCombatExhaust(uint32_t ticks) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_EXHAUST_COMBAT, ticks, 0); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_EXHAUST_COMBAT, ticks, 0); addCondition(condition); } void Player::addHealExhaust(uint32_t ticks) { - Condition* condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_EXHAUST_HEAL, ticks, 0); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_EXHAUST_HEAL, ticks, 0); addCondition(condition); } @@ -2072,7 +2073,7 @@ void Player::addInFightTicks(bool pzlock /*= false*/) pzLocked = true; } - Condition* condition = + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_config[ConfigKeysInteger::PZ_LOCKED], 0); addCondition(condition); } @@ -3482,8 +3483,8 @@ bool Player::onKilledCreature(Creature* target, bool lastHit /* = true*/) if (lastHit && hasCondition(CONDITION_INFIGHT)) { pzLocked = true; - Condition* condition = Condition::createCondition( - CONDITIONID_DEFAULT, CONDITION_INFIGHT, g_config[ConfigKeysInteger::WHITE_SKULL_TIME] * 1000, 0); + auto condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_INFIGHT, + g_config[ConfigKeysInteger::WHITE_SKULL_TIME] * 1000, 0); addCondition(condition); } } diff --git a/src/player.h b/src/player.h index 9c967f4..6e08b73 100644 --- a/src/player.h +++ b/src/player.h @@ -1036,7 +1036,8 @@ class Player final : public Creature, public Cylinder std::forward_list invitePartyList; std::forward_list modalWindows; std::forward_list learnedInstantSpellList; - std::forward_list + + static std::forward_list storedConditionList; // TODO: This variable is only temporarily used when logging in, get rid of it somehow std::string name;