Buff framework tweaks + polish

This commit is contained in:
gsemaj 2022-07-19 01:09:25 -07:00 committed by gsemaj
parent f150595f70
commit 0c5a9400ce
No known key found for this signature in database
GPG Key ID: 24B96BAA40497929
8 changed files with 36 additions and 32 deletions

View File

@ -26,12 +26,13 @@ enum class SkillDrainType {
}; };
struct SkillData { struct SkillData {
int skillType; int skillType; // eST
SkillEffectTarget effectTarget; SkillEffectTarget effectTarget;
int effectType; // always 1? int effectType; // always 1?
SkillTargetType targetType; SkillTargetType targetType;
SkillDrainType drainType; SkillDrainType drainType;
int effectArea; int effectArea;
int charStatusTimeBuffId; // eCS(T)B
int batteryUse[4]; int batteryUse[4];
int durationTime[4]; int durationTime[4];

View File

@ -27,13 +27,14 @@ void Buff::clear() {
} }
void Buff::addStack(BuffStack* stack) { void Buff::addStack(BuffStack* stack) {
stack->buff = this;
if(stack->onApply) stack->onApply(self, stack); if(stack->onApply) stack->onApply(self, stack);
stacks.push_back(*stack); stacks.push_back(*stack);
} }
bool Buff::hasClass(BuffClass buffClass) { bool Buff::hasClass(BuffClass buffClass) {
for(BuffStack& stack : stacks) { for(BuffStack& stack : stacks) {
if(stack.buffClass == buffClass) if(stack.buffStackClass == buffClass)
return true; return true;
} }
return false; return false;
@ -42,8 +43,8 @@ bool Buff::hasClass(BuffClass buffClass) {
BuffClass Buff::maxClass() { BuffClass Buff::maxClass() {
BuffClass buffClass = BuffClass::NONE; BuffClass buffClass = BuffClass::NONE;
for(BuffStack& stack : stacks) { for(BuffStack& stack : stacks) {
if(stack.buffClass > buffClass) if(stack.buffStackClass > buffClass)
buffClass = stack.buffClass; buffClass = stack.buffStackClass;
} }
return buffClass; return buffClass;
} }
@ -53,7 +54,7 @@ bool Buff::isStale() {
} }
#pragma region Handlers #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) if(self.kind != EntityKind::PLAYER)
return; // not implemented return; // not implemented
@ -62,21 +63,21 @@ void Buffs::timeBuffUpdate(EntityRef self, BuffStack* buff, int status) {
if(plr == nullptr) if(plr == nullptr)
return; return;
if(status == ETBU_DEL && plr->hasBuff(buff->id)) if(status == ETBU_DEL && plr->hasBuff(stack->buff->id))
return; // no premature status removal! return; // no premature status removal!
int cbf = plr->getCompositeCondition(); 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); INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, pkt);
pkt.eCSTB = buff->id; // eCharStatusTimeBuffID pkt.eCSTB = stack->buff->id; // eCharStatusTimeBuffID
pkt.eTBU = status; // eTimeBuffUpdate pkt.eTBU = status; // eTimeBuffUpdate
pkt.eTBT = (int)buff->buffClass; pkt.eTBT = (int)stack->buffStackClass;
pkt.iConditionBitFlag = cbf; pkt.iConditionBitFlag = cbf;
self.sock->sendPacket((void*)&pkt, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE)); 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) if(self.kind != EntityKind::PLAYER)
return; // not implemented return; // not implemented

View File

@ -25,10 +25,9 @@ enum class BuffClass {
typedef std::function<void(EntityRef, BuffStack*)> BuffCallback; typedef std::function<void(EntityRef, BuffStack*)> BuffCallback;
struct BuffStack { struct BuffStack {
int id; // ECSB
int durationTicks; int durationTicks;
EntityRef source; EntityRef source;
BuffClass buffClass; BuffClass buffStackClass;
/* called just before the stack is added */ /* called just before the stack is added */
BuffCallback onApply; BuffCallback onApply;
@ -38,6 +37,8 @@ struct BuffStack {
/* called just after the stack is removed */ /* called just after the stack is removed */
BuffCallback onExpire; BuffCallback onExpire;
Buff* buff;
}; };
class Buff { class Buff {
@ -46,6 +47,8 @@ private:
std::vector<BuffStack> stacks; std::vector<BuffStack> stacks;
public: public:
int id;
void tick(); void tick();
void clear(); void clear();
void addStack(BuffStack* stack); void addStack(BuffStack* stack);
@ -67,13 +70,13 @@ public:
*/ */
bool isStale(); bool isStale();
Buff(EntityRef pSelf, BuffStack* firstStack) Buff(int iid, EntityRef pSelf, BuffStack* firstStack)
: self(pSelf) { : id(iid), self(pSelf) {
addStack(firstStack); addStack(firstStack);
} }
}; };
namespace Buffs { namespace Buffs {
void timeBuffUpdate(EntityRef self, BuffStack* buff, int status); void timeBuffUpdate(EntityRef self, BuffStack* stack, int status);
void timeBuffTimeoutViewable(EntityRef self, BuffStack* buff, int ct); void timeBuffTimeoutViewable(EntityRef self, BuffStack* stack, int ct);
} }

View File

@ -19,10 +19,10 @@ using namespace Combat;
/// Player Id -> Bullet Id -> Bullet /// Player Id -> Bullet Id -> Bullet
std::map<int32_t, std::map<int8_t, Bullet>> Combat::Bullets; std::map<int32_t, std::map<int8_t, Bullet>> Combat::Bullets;
void Player::addBuff(BuffStack* buff) { void Player::addBuff(int buffId, BuffStack* stack) {
EntityRef self = PlayerManager::getSockFromID(iID); EntityRef self = PlayerManager::getSockFromID(iID);
if(!hasBuff(buff->id)) buffs[buff->id] = new Buff(self, buff); if(!hasBuff(buffId)) buffs[buffId] = new Buff(buffId, self, stack);
else buffs[buff->id]->addStack(buff); else buffs[buffId]->addStack(stack);
} }
Buff* Player::getBuff(int buffId) { Buff* Player::getBuff(int buffId) {
@ -48,7 +48,7 @@ bool Player::hasBuff(int buffId) {
int Player::getCompositeCondition() { int Player::getCompositeCondition() {
int conditionBitFlag = 0; int conditionBitFlag = 0;
for(auto buff : buffs) { for(auto buff : buffs) {
if(!buff.second->isStale()) if(!buff.second->isStale() && buff.second->id > 0)
conditionBitFlag |= CSB_FROM_ECSB(buff.first); conditionBitFlag |= CSB_FROM_ECSB(buff.first);
} }
return conditionBitFlag; return conditionBitFlag;
@ -79,7 +79,7 @@ void Player::step(time_t currTime) {
// no-op // no-op
} }
void CombatNPC::addBuff(BuffStack* buff) { /* stubbed */ } void CombatNPC::addBuff(int buffId, BuffStack* stack) { /* stubbed */ }
Buff* CombatNPC::getBuff(int buffId) { /* stubbed */ Buff* CombatNPC::getBuff(int buffId) { /* stubbed */
return nullptr; return nullptr;
@ -361,7 +361,6 @@ static void dotDamageOnOff(CNSocket *sock, CNPacketData *data) {
// so we add and remove a permanent debuff // so we add and remove a permanent debuff
if (pkt->iFlag && !plr->hasBuff(ECSB_INFECTION)) { if (pkt->iFlag && !plr->hasBuff(ECSB_INFECTION)) {
BuffStack infection = { BuffStack infection = {
ECSB_INFECTION,
-1, // infinite -1, // infinite
sock, // self-inflicted sock, // self-inflicted
BuffClass::ENVIRONMENT, BuffClass::ENVIRONMENT,
@ -372,9 +371,9 @@ static void dotDamageOnOff(CNSocket *sock, CNPacketData *data) {
nullptr, // client toggles for us! todo anticheat lol nullptr, // client toggles for us! todo anticheat lol
[](EntityRef host, BuffStack* stack) { [](EntityRef host, BuffStack* stack) {
Buffs::timeBuffUpdate(host, stack, ETBU_DEL); Buffs::timeBuffUpdate(host, stack, ETBU_DEL);
}, }
}; };
plr->addBuff(&infection); plr->addBuff(ECSB_INFECTION, &infection);
} else if(!pkt->iFlag && plr->hasBuff(ECSB_INFECTION)) { } else if(!pkt->iFlag && plr->hasBuff(ECSB_INFECTION)) {
plr->removeBuff(ECSB_INFECTION); plr->removeBuff(ECSB_INFECTION);
} }

View File

@ -92,7 +92,7 @@ public:
ICombatant() {} ICombatant() {}
virtual ~ICombatant() {} virtual ~ICombatant() {}
virtual void addBuff(BuffStack* buff) = 0; virtual void addBuff(int buffId, BuffStack* stack) = 0;
virtual Buff* getBuff(int buffId) = 0; virtual Buff* getBuff(int buffId) = 0;
virtual void removeBuff(int buffId) = 0; virtual void removeBuff(int buffId) = 0;
virtual bool hasBuff(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 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 Buff* getBuff(int buffId) override;
virtual void removeBuff(int buffId) override; virtual void removeBuff(int buffId) override;
virtual bool hasBuff(int buffId) override; virtual bool hasBuff(int buffId) override;

View File

@ -493,7 +493,6 @@ static void itemUseHandler(CNSocket* sock, CNPacketData* data) {
int durationMilliseconds = Abilities::SkillTable[144].durationTime[0] * 100; int durationMilliseconds = Abilities::SkillTable[144].durationTime[0] * 100;
BuffStack gumballBuff = { BuffStack gumballBuff = {
eCSB,
durationMilliseconds / MS_PER_PLAYER_TICK, durationMilliseconds / MS_PER_PLAYER_TICK,
sock, sock,
BuffClass::CASH_ITEM, // or BuffClass::ITEM? BuffClass::CASH_ITEM, // or BuffClass::ITEM?
@ -501,12 +500,12 @@ static void itemUseHandler(CNSocket* sock, CNPacketData* data) {
[](EntityRef host, BuffStack* stack) { [](EntityRef host, BuffStack* stack) {
Buffs::timeBuffUpdate(host, stack, ETBU_ADD); Buffs::timeBuffUpdate(host, stack, ETBU_ADD);
}, },
nullptr, // client toggles for us! todo anticheat lol nullptr,
[](EntityRef host, BuffStack* stack) { [](EntityRef host, BuffStack* stack) {
Buffs::timeBuffUpdate(host, stack, ETBU_DEL); 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); sock->sendPacket((void*)&respbuf, P_FE2CL_REP_PC_ITEM_USE_SUCC, resplen);
// update inventory serverside // update inventory serverside

View File

@ -89,7 +89,7 @@ struct Player : public Entity, public ICombatant {
virtual void enterIntoViewOf(CNSocket *sock) override; virtual void enterIntoViewOf(CNSocket *sock) override;
virtual void disappearFromViewOf(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 Buff* getBuff(int buffId) override;
virtual void removeBuff(int buffId) override; virtual void removeBuff(int buffId) override;
virtual bool hasBuff(int buffId) override; virtual bool hasBuff(int buffId) override;

View File

@ -235,7 +235,8 @@ static void loadXDT(json& xdtData) {
skill["m_iEffectType"], skill["m_iEffectType"],
skill["m_iTargetType"], skill["m_iTargetType"],
skill["m_iBatteryDrainType"], skill["m_iBatteryDrainType"],
skill["m_iEffectArea"] skill["m_iEffectArea"],
(int)skill["m_iIcon"] - 1
}; };
skillData.valueTypes[0] = skill["m_iValueA_Type"]; skillData.valueTypes[0] = skill["m_iValueA_Type"];