Passive nano powers boilerplate

This commit is contained in:
gsemaj 2022-07-20 09:15:01 -07:00
parent 0e054e21b6
commit 7a7cdb1330
8 changed files with 137 additions and 22 deletions

View File

@ -2,6 +2,11 @@
#include "NPCManager.hpp"
#include "PlayerManager.hpp"
#include "Buffs.hpp"
#include <assert.h>
using namespace Abilities;
std::map<int32_t, SkillData> Abilities::SkillTable;
@ -35,15 +40,108 @@ std::vector<EntityRef> Abilities::matchTargets(SkillData* skill, int count, int3
return targets;
}
void Abilities::useAbility(SkillData* skill, EntityRef src, std::vector<EntityRef> 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<EntityRef> 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<ICombatant*>(entity);
combatant->addBuff(getCSTBFromST(skill->skillType), &passiveBuff);
}
}
#pragma endregion
void Abilities::init() {
//REGISTER_SHARD_PACKET(P_CL2FE_REQ_PC_EMAIL_UPDATE_CHECK, emailUpdateCheck);

View File

@ -1,6 +1,7 @@
#pragma once
#include "Entities.hpp"
#include "Player.hpp"
#include <map>
#include <vector>
@ -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<int32_t, SkillData> SkillTable;
std::vector<EntityRef> matchTargets(SkillData*, int, int32_t*);
void useAbility(SkillData*, EntityRef, std::vector<EntityRef>);
int getCSTBFromST(int eSkillType);
void usePassiveNanoSkill(SkillData*, Player*);
void init();
}

View File

@ -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) {

View File

@ -71,6 +71,15 @@ int Player::getCurrentHP() {
return HP;
}
std::vector<EntityRef> Player::getGroupMembers() {
std::vector<EntityRef> 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<EntityRef> CombatNPC::getGroupMembers() {
std::vector<EntityRef> members;
if(group != nullptr)
members = group->members;
else
members.push_back(id);
return members;
}
int32_t CombatNPC::getID() {
return id;
}
@ -335,7 +353,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);
},
@ -724,18 +741,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<EntityRef> 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);
}
}

View File

@ -101,6 +101,7 @@ public:
virtual void heal(EntityRef, int) = 0;
virtual bool isAlive() = 0;
virtual int getCurrentHP() = 0;
virtual std::vector<EntityRef> 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<EntityRef> getGroupMembers() override;
virtual int32_t getID() override;
virtual void step(time_t currTime) override;

View File

@ -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);
},

View File

@ -96,6 +96,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<EntityRef> getGroupMembers() override;
virtual int32_t getID() override;
virtual void step(time_t currTime) override;

View File

@ -219,8 +219,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"];