From a07f36e379e7f0f083b61b1c792bf138673a4d2b Mon Sep 17 00:00:00 2001 From: gsemaj Date: Tue, 19 Jul 2022 01:09:25 -0700 Subject: [PATCH] Buff framework tweaks + polish --- src/Abilities.hpp | 3 ++- src/Buffs.cpp | 19 ++++++++++--------- src/Buffs.hpp | 15 +++++++++------ src/Combat.cpp | 15 +++++++-------- src/Entities.hpp | 4 ++-- src/Items.cpp | 7 +++---- src/Player.hpp | 2 +- src/TableData.cpp | 3 ++- 8 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/Abilities.hpp b/src/Abilities.hpp index 8f964ff..f376a7e 100644 --- a/src/Abilities.hpp +++ b/src/Abilities.hpp @@ -26,12 +26,13 @@ enum class SkillDrainType { }; struct SkillData { - int skillType; + int skillType; // eST SkillEffectTarget effectTarget; int effectType; // always 1? SkillTargetType targetType; SkillDrainType drainType; int effectArea; + int charStatusTimeBuffId; // eCS(T)B int batteryUse[4]; int durationTime[4]; diff --git a/src/Buffs.cpp b/src/Buffs.cpp index 30beb48..d790566 100644 --- a/src/Buffs.cpp +++ b/src/Buffs.cpp @@ -27,13 +27,14 @@ void Buff::clear() { } void Buff::addStack(BuffStack* stack) { + stack->buff = this; if(stack->onApply) stack->onApply(self, stack); stacks.push_back(*stack); } bool Buff::hasClass(BuffClass buffClass) { for(BuffStack& stack : stacks) { - if(stack.buffClass == buffClass) + if(stack.buffStackClass == buffClass) return true; } return false; @@ -42,8 +43,8 @@ bool Buff::hasClass(BuffClass buffClass) { BuffClass Buff::maxClass() { BuffClass buffClass = BuffClass::NONE; for(BuffStack& stack : stacks) { - if(stack.buffClass > buffClass) - buffClass = stack.buffClass; + if(stack.buffStackClass > buffClass) + buffClass = stack.buffStackClass; } return buffClass; } @@ -53,7 +54,7 @@ bool Buff::isStale() { } #pragma region Handlers -void Buffs::timeBuffUpdate(EntityRef self, BuffStack* buff, int status) { +void Buffs::timeBuffUpdate(EntityRef self, BuffStack* stack, int status) { if(self.kind != EntityKind::PLAYER) return; // not implemented @@ -62,21 +63,21 @@ void Buffs::timeBuffUpdate(EntityRef self, BuffStack* buff, int status) { if(plr == nullptr) return; - if(status == ETBU_DEL && plr->hasBuff(buff->id)) + if(status == ETBU_DEL && plr->hasBuff(stack->buff->id)) return; // no premature status removal! int cbf = plr->getCompositeCondition(); - if(status == ETBU_ADD) cbf |= CSB_FROM_ECSB(buff->id); + if(status == ETBU_ADD && stack->buff->id > 0) cbf |= CSB_FROM_ECSB(stack->buff->id); INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, pkt); - pkt.eCSTB = buff->id; // eCharStatusTimeBuffID + pkt.eCSTB = stack->buff->id; // eCharStatusTimeBuffID pkt.eTBU = status; // eTimeBuffUpdate - pkt.eTBT = (int)buff->buffClass; + pkt.eTBT = (int)stack->buffStackClass; pkt.iConditionBitFlag = cbf; self.sock->sendPacket((void*)&pkt, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE)); } -void Buffs::timeBuffTimeoutViewable(EntityRef self, BuffStack* buff, int ct) { +void Buffs::timeBuffTimeoutViewable(EntityRef self, BuffStack* stack, int ct) { if(self.kind != EntityKind::PLAYER) return; // not implemented diff --git a/src/Buffs.hpp b/src/Buffs.hpp index 55f33dd..dc73f6a 100644 --- a/src/Buffs.hpp +++ b/src/Buffs.hpp @@ -25,10 +25,9 @@ enum class BuffClass { typedef std::function BuffCallback; struct BuffStack { - int id; // ECSB int durationTicks; EntityRef source; - BuffClass buffClass; + BuffClass buffStackClass; /* called just before the stack is added */ BuffCallback onApply; @@ -38,6 +37,8 @@ struct BuffStack { /* called just after the stack is removed */ BuffCallback onExpire; + + Buff* buff; }; class Buff { @@ -46,6 +47,8 @@ private: std::vector stacks; public: + int id; + void tick(); void clear(); void addStack(BuffStack* stack); @@ -67,13 +70,13 @@ public: */ bool isStale(); - Buff(EntityRef pSelf, BuffStack* firstStack) - : self(pSelf) { + Buff(int iid, EntityRef pSelf, BuffStack* firstStack) + : id(iid), self(pSelf) { addStack(firstStack); } }; namespace Buffs { - void timeBuffUpdate(EntityRef self, BuffStack* buff, int status); - void timeBuffTimeoutViewable(EntityRef self, BuffStack* buff, int ct); + void timeBuffUpdate(EntityRef self, BuffStack* stack, int status); + void timeBuffTimeoutViewable(EntityRef self, BuffStack* stack, int ct); } diff --git a/src/Combat.cpp b/src/Combat.cpp index 7dda8e3..d04a2b7 100644 --- a/src/Combat.cpp +++ b/src/Combat.cpp @@ -19,10 +19,10 @@ using namespace Combat; /// Player Id -> Bullet Id -> Bullet std::map> Combat::Bullets; -void Player::addBuff(BuffStack* buff) { +void Player::addBuff(int buffId, BuffStack* stack) { EntityRef self = PlayerManager::getSockFromID(iID); - if(!hasBuff(buff->id)) buffs[buff->id] = new Buff(self, buff); - else buffs[buff->id]->addStack(buff); + if(!hasBuff(buffId)) buffs[buffId] = new Buff(buffId, self, stack); + else buffs[buffId]->addStack(stack); } Buff* Player::getBuff(int buffId) { @@ -48,7 +48,7 @@ bool Player::hasBuff(int buffId) { int Player::getCompositeCondition() { int conditionBitFlag = 0; for(auto buff : buffs) { - if(!buff.second->isStale()) + if(!buff.second->isStale() && buff.second->id > 0) conditionBitFlag |= CSB_FROM_ECSB(buff.first); } return conditionBitFlag; @@ -79,7 +79,7 @@ void Player::step(time_t currTime) { // no-op } -void CombatNPC::addBuff(BuffStack* buff) { /* stubbed */ } +void CombatNPC::addBuff(int buffId, BuffStack* stack) { /* stubbed */ } Buff* CombatNPC::getBuff(int buffId) { /* stubbed */ return nullptr; @@ -361,7 +361,6 @@ static void dotDamageOnOff(CNSocket *sock, CNPacketData *data) { // so we add and remove a permanent debuff if (pkt->iFlag && !plr->hasBuff(ECSB_INFECTION)) { BuffStack infection = { - ECSB_INFECTION, -1, // infinite sock, // self-inflicted BuffClass::ENVIRONMENT, @@ -372,9 +371,9 @@ static void dotDamageOnOff(CNSocket *sock, CNPacketData *data) { nullptr, // client toggles for us! todo anticheat lol [](EntityRef host, BuffStack* stack) { Buffs::timeBuffUpdate(host, stack, ETBU_DEL); - }, + } }; - plr->addBuff(&infection); + plr->addBuff(ECSB_INFECTION, &infection); } else if(!pkt->iFlag && plr->hasBuff(ECSB_INFECTION)) { plr->removeBuff(ECSB_INFECTION); } diff --git a/src/Entities.hpp b/src/Entities.hpp index 47249d3..891db22 100644 --- a/src/Entities.hpp +++ b/src/Entities.hpp @@ -92,7 +92,7 @@ public: ICombatant() {} virtual ~ICombatant() {} - virtual void addBuff(BuffStack* buff) = 0; + virtual void addBuff(int buffId, BuffStack* stack) = 0; virtual Buff* getBuff(int buffId) = 0; virtual void removeBuff(int buffId) = 0; virtual bool hasBuff(int buffId) = 0; @@ -158,7 +158,7 @@ struct CombatNPC : public BaseNPC, public ICombatant { virtual bool isExtant() override { return hp > 0; } - virtual void addBuff(BuffStack* buff) override; + virtual void addBuff(int buffId, BuffStack* stack) override; virtual Buff* getBuff(int buffId) override; virtual void removeBuff(int buffId) override; virtual bool hasBuff(int buffId) override; diff --git a/src/Items.cpp b/src/Items.cpp index 4408651..b756547 100644 --- a/src/Items.cpp +++ b/src/Items.cpp @@ -493,7 +493,6 @@ static void itemUseHandler(CNSocket* sock, CNPacketData* data) { int durationMilliseconds = Abilities::SkillTable[144].durationTime[0] * 100; BuffStack gumballBuff = { - eCSB, durationMilliseconds / MS_PER_PLAYER_TICK, sock, BuffClass::CASH_ITEM, // or BuffClass::ITEM? @@ -501,12 +500,12 @@ static void itemUseHandler(CNSocket* sock, CNPacketData* data) { [](EntityRef host, BuffStack* stack) { Buffs::timeBuffUpdate(host, stack, ETBU_ADD); }, - nullptr, // client toggles for us! todo anticheat lol + nullptr, [](EntityRef host, BuffStack* stack) { Buffs::timeBuffUpdate(host, stack, ETBU_DEL); - }, + } }; - player->addBuff(&gumballBuff); + player->addBuff(eCSB, &gumballBuff); sock->sendPacket((void*)&respbuf, P_FE2CL_REP_PC_ITEM_USE_SUCC, resplen); // update inventory serverside diff --git a/src/Player.hpp b/src/Player.hpp index b6c05bd..ca55ccc 100644 --- a/src/Player.hpp +++ b/src/Player.hpp @@ -89,7 +89,7 @@ struct Player : public Entity, public ICombatant { virtual void enterIntoViewOf(CNSocket *sock) override; virtual void disappearFromViewOf(CNSocket *sock) override; - virtual void addBuff(BuffStack* buff) override; + virtual void addBuff(int buffId, BuffStack* stack) override; virtual Buff* getBuff(int buffId) override; virtual void removeBuff(int buffId) override; virtual bool hasBuff(int buffId) override; diff --git a/src/TableData.cpp b/src/TableData.cpp index 68b7cce..3c8c0ff 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -235,7 +235,8 @@ static void loadXDT(json& xdtData) { skill["m_iEffectType"], skill["m_iTargetType"], skill["m_iBatteryDrainType"], - skill["m_iEffectArea"] + skill["m_iEffectArea"], + (int)skill["m_iIcon"] - 1 }; skillData.valueTypes[0] = skill["m_iValueA_Type"];