From 36f329c302ff0867e6f0c2a5983fd967be528d7a Mon Sep 17 00:00:00 2001 From: gsemaj Date: Wed, 20 Jul 2022 09:15:01 -0700 Subject: [PATCH] Passive nano powers boilerplate --- src/Abilities.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++- src/Abilities.hpp | 6 ++- src/Buffs.cpp | 13 +++--- src/Combat.cpp | 31 +++++++++----- src/Entities.hpp | 2 + src/Items.cpp | 1 - src/Player.hpp | 1 + src/TableData.cpp | 3 +- 8 files changed, 137 insertions(+), 22 deletions(-) diff --git a/src/Abilities.cpp b/src/Abilities.cpp index 6b309f9..f24b3a2 100644 --- a/src/Abilities.cpp +++ b/src/Abilities.cpp @@ -2,6 +2,11 @@ #include "NPCManager.hpp" #include "PlayerManager.hpp" +#include "Buffs.hpp" + +#include + +using namespace Abilities; std::map Abilities::SkillTable; @@ -35,15 +40,108 @@ std::vector Abilities::matchTargets(SkillData* skill, int count, int3 return targets; } -void Abilities::useAbility(SkillData* skill, EntityRef src, std::vector targets) { +/* ripped from client */ +int Abilities::getCSTBFromST(int eSkillType) { + int result = 0; + switch (eSkillType) + { + case 11: + result = 1; + break; + case 10: + result = 3; + break; + case 12: + result = 4; + break; + case 16: + result = 5; + break; + case 17: + result = 6; + break; + case 18: + result = 7; + break; + case 5: + result = 8; + break; + case 4: + result = 11; + break; + case 14: + result = 13; + break; + case 15: + result = 14; + break; + case 19: + result = 15; + break; + case 20: + result = 16; + break; + case 23: + result = 17; + break; + case 25: + result = 18; + break; + case 31: + result = 19; + break; + case 32: + result = 20; + break; + case 35: + result = 24; + break; + case 33: + result = 21; + break; + } + return result; +} + +#pragma region Skill Handlers +void Abilities::usePassiveNanoSkill(SkillData* skill, Player* plr) { + assert(skill->drainType == SkillDrainType::PASSIVE); + + EntityRef self = PlayerManager::getSockFromID(plr->iID); + std::vector targets; + if (skill->targetType == SkillTargetType::GROUP) { + targets = plr->getGroupMembers(); // group + } + else if(skill->targetType == SkillTargetType::SELF) { + targets.push_back(self); // self + } else { + std::cout << "[WARN] Passive skill with type " << skill->skillType << " has target type MOB" << std::endl; + } + + BuffStack passiveBuff = { + 1, // passive nano buffs refreshed every tick + self, + BuffClass::NONE, // overwritten per target + [](EntityRef host, BuffStack* stack) { + Buffs::timeBuffUpdate(host, stack, ETBU_ADD); + }, + nullptr, + [](EntityRef host, BuffStack* stack) { + Buffs::timeBuffUpdate(host, stack, ETBU_DEL); + } + }; + for (EntityRef target : targets) { Entity* entity = target.getEntity(); if (entity->kind != PLAYER && entity->kind != COMBAT_NPC && entity->kind != MOB) continue; // not a combatant - // TODO abilities + passiveBuff.buffStackClass = target == self ? BuffClass::NANO : BuffClass::GROUP_NANO; + ICombatant* combatant = dynamic_cast(entity); + combatant->addBuff(getCSTBFromST(skill->skillType), &passiveBuff); } } +#pragma endregion void Abilities::init() { //REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_EMAIL_UPDATE_CHECK, emailUpdateCheck); diff --git a/src/Abilities.hpp b/src/Abilities.hpp index f376a7e..03b8fa7 100644 --- a/src/Abilities.hpp +++ b/src/Abilities.hpp @@ -1,6 +1,7 @@ #pragma once #include "Entities.hpp" +#include "Player.hpp" #include #include @@ -32,7 +33,6 @@ struct SkillData { SkillTargetType targetType; SkillDrainType drainType; int effectArea; - int charStatusTimeBuffId; // eCS(T)B int batteryUse[4]; int durationTime[4]; @@ -45,7 +45,9 @@ namespace Abilities { extern std::map SkillTable; std::vector matchTargets(SkillData*, int, int32_t*); - void useAbility(SkillData*, EntityRef, std::vector); + int getCSTBFromST(int eSkillType); + + void usePassiveNanoSkill(SkillData*, Player*); void init(); } diff --git a/src/Buffs.cpp b/src/Buffs.cpp index 2c12434..a925b97 100644 --- a/src/Buffs.cpp +++ b/src/Buffs.cpp @@ -10,7 +10,6 @@ void Buff::tick() { BuffStack& stack = *it; if(stack.onTick) stack.onTick(self, &stack); - if(stack.durationTicks > 0) stack.durationTicks--; if(stack.durationTicks == 0) { // erase() destroys the callbacks // with the stack struct, so we need @@ -18,7 +17,10 @@ void Buff::tick() { BuffStack deadStack = stack; it = stacks.erase(it); if(deadStack.onExpire) deadStack.onExpire(self, &deadStack); - } else it++; + } else { + if(stack.durationTicks > 0) stack.durationTicks--; + it++; + } } } @@ -31,9 +33,10 @@ void Buff::clear() { } void Buff::addStack(BuffStack* stack) { - stack->buff = this; - if(stack->onApply) stack->onApply(self, stack); - stacks.push_back(*stack); + BuffStack newStack = *stack; + newStack.buff = this; + if(newStack.onApply) newStack.onApply(self, &newStack); + stacks.push_back(newStack); } bool Buff::hasClass(BuffClass buffClass) { diff --git a/src/Combat.cpp b/src/Combat.cpp index d04a2b7..452b065 100644 --- a/src/Combat.cpp +++ b/src/Combat.cpp @@ -71,6 +71,15 @@ int Player::getCurrentHP() { return HP; } +std::vector Player::getGroupMembers() { + std::vector members; + if(group != nullptr) + members = group->members; + else + members.push_back(PlayerManager::getSockFromID(iID)); + return members; +} + int32_t Player::getID() { return iID; } @@ -116,6 +125,15 @@ int CombatNPC::getCurrentHP() { return hp; } +std::vector CombatNPC::getGroupMembers() { + std::vector members; + if(group != nullptr) + members = group->members; + else + members.push_back(id); + return members; +} + int32_t CombatNPC::getID() { return id; } @@ -364,7 +382,6 @@ static void dotDamageOnOff(CNSocket *sock, CNPacketData *data) { -1, // infinite sock, // self-inflicted BuffClass::ENVIRONMENT, - [](EntityRef host, BuffStack* stack) { Buffs::timeBuffUpdate(host, stack, ETBU_ADD); }, @@ -753,18 +770,12 @@ static void playerTick(CNServer *serv, time_t currTime) { // nano has skill data SkillData* skill = &Abilities::SkillTable[nano.iSkillID]; int boost = Nanos::getNanoBoost(plr); - drainRate = skill->batteryUse[boost * 3]; + std::cout << "[SKILL] id " << nano.iSkillID << ", type " << skill->skillType << ", target " << (int)skill->targetType << std::endl; if (skill->drainType == SkillDrainType::PASSIVE) { // apply passive buff - std::vector targets; - if (skill->targetType == SkillTargetType::GROUP && plr->group != nullptr) - targets = plr->group->members; // group - else if(skill->targetType == SkillTargetType::SELF) - targets.push_back(sock); // self - - std::cout << "[SKILL] id " << nano.iSkillID << ", type " << skill->skillType << ", target " << (int)skill->targetType << std::endl; - // TODO abilities + drainRate = skill->batteryUse[boost * 3]; + Abilities::usePassiveNanoSkill(skill, plr); } } diff --git a/src/Entities.hpp b/src/Entities.hpp index 891db22..5e98064 100644 --- a/src/Entities.hpp +++ b/src/Entities.hpp @@ -101,6 +101,7 @@ public: virtual void heal(EntityRef, int) = 0; virtual bool isAlive() = 0; virtual int getCurrentHP() = 0; + virtual std::vector getGroupMembers() = 0; virtual int32_t getID() = 0; virtual void step(time_t currTime) = 0; }; @@ -167,6 +168,7 @@ struct CombatNPC : public BaseNPC, public ICombatant { virtual void heal(EntityRef src, int amt) override; virtual bool isAlive() override; virtual int getCurrentHP() override; + virtual std::vector getGroupMembers() override; virtual int32_t getID() override; virtual void step(time_t currTime) override; diff --git a/src/Items.cpp b/src/Items.cpp index b756547..832b2f5 100644 --- a/src/Items.cpp +++ b/src/Items.cpp @@ -496,7 +496,6 @@ static void itemUseHandler(CNSocket* sock, CNPacketData* data) { durationMilliseconds / MS_PER_PLAYER_TICK, sock, BuffClass::CASH_ITEM, // or BuffClass::ITEM? - [](EntityRef host, BuffStack* stack) { Buffs::timeBuffUpdate(host, stack, ETBU_ADD); }, diff --git a/src/Player.hpp b/src/Player.hpp index ca55ccc..02b6b14 100644 --- a/src/Player.hpp +++ b/src/Player.hpp @@ -98,6 +98,7 @@ struct Player : public Entity, public ICombatant { virtual void heal(EntityRef src, int amt) override; virtual bool isAlive() override; virtual int getCurrentHP() override; + virtual std::vector getGroupMembers() override; virtual int32_t getID() override; virtual void step(time_t currTime) override; diff --git a/src/TableData.cpp b/src/TableData.cpp index 3c8c0ff..68b7cce 100644 --- a/src/TableData.cpp +++ b/src/TableData.cpp @@ -235,8 +235,7 @@ static void loadXDT(json& xdtData) { skill["m_iEffectType"], skill["m_iTargetType"], skill["m_iBatteryDrainType"], - skill["m_iEffectArea"], - (int)skill["m_iIcon"] - 1 + skill["m_iEffectArea"] }; skillData.valueTypes[0] = skill["m_iValueA_Type"];