Refactored passive nano powers.

This commit is contained in:
JadeShrineMaiden 2020-09-18 17:37:26 +01:00 committed by dongresource
parent dc9de5a54a
commit 113ecc8f60
3 changed files with 176 additions and 120 deletions

View File

@ -15,6 +15,77 @@ const float CN_EP_RANK_3 = 0.5f;
const float CN_EP_RANK_4 = 0.3f;
const float CN_EP_RANK_5 = 0.29f;
enum {
EST_NONE = 0,
EST_DAMAGE = 1,
EST_HEAL_HP = 2,
EST_KNOCKDOWN = 3,
EST_SLEEP = 4,
EST_SNARE = 5,
EST_HEAL_STAMINA = 6,
EST_STAMINA_SELF = 7,
EST_STUN = 8,
EST_WEAPONSLOW = 9,
EST_JUMP = 10,
EST_RUN = 11,
EST_STEALTH = 12,
EST_SWIM = 13,
EST_MINIMAPENEMY = 14,
EST_MINIMAPTRESURE = 15,
EST_PHOENIX = 16,
EST_PROTECTBATTERY = 17,
EST_PROTECTINFECTION = 18,
EST_REWARDBLOB = 19,
EST_REWARDCASH = 20,
EST_BATTERYDRAIN = 21,
EST_CORRUPTIONATTACK = 22,
EST_INFECTIONDAMAGE = 23,
EST_KNOCKBACK = 24,
EST_FREEDOM = 25,
EST_PHOENIX_GROUP = 26,
EST_RECALL = 27,
EST_RECALL_GROUP = 28,
EST_RETROROCKET_SELF = 29,
EST_BLOODSUCKING = 30,
EST_BOUNDINGBALL = 31,
EST_INVULNERABLE = 32,
EST_NANOSTIMPAK = 33,
EST_RETURNHOMEHEAL = 34,
EST_BUFFHEAL = 35,
EST_EXTRABANK = 36,
EST__END = 37,
EST_CORRUPTIONATTACKWIN = 38,
EST_CORRUPTIONATTACKLOSE = 39,
ECSB_NONE = 0,
ECSB_UP_MOVE_SPEED = 1,
ECSB_UP_SWIM_SPEED = 2,
ECSB_UP_JUMP_HEIGHT = 3,
ECSB_UP_STEALTH = 4,
ECSB_PHOENIX = 5,
ECSB_PROTECT_BATTERY = 6,
ECSB_PROTECT_INFECTION = 7,
ECSB_DN_MOVE_SPEED = 8,
ECSB_DN_ATTACK_SPEED = 9,
ECSB_STUN = 10,
ECSB_MEZ = 11,
ECSB_KNOCKDOWN = 12,
ECSB_MINIMAP_ENEMY = 13,
ECSB_MINIMAP_TRESURE = 14,
ECSB_REWARD_BLOB = 15,
ECSB_REWARD_CASH = 16,
ECSB_INFECTION = 17,
ECSB_FREEDOM = 18,
ECSB_BOUNDINGBALL = 19,
ECSB_INVULNERABLE = 20,
ECSB_STIMPAKSLOT1 = 21,
ECSB_STIMPAKSLOT2 = 22,
ECSB_STIMPAKSLOT3 = 23,
ECSB_HEAL = 24,
ECSB_EXTRABANK = 25,
ECSTB__END = 26,
};
enum {
SUCC = 1,
FAIL = 0,

View File

@ -3,7 +3,7 @@
#include "NanoManager.hpp"
#include "PlayerManager.hpp"
#include "NPCManager.hpp"
#include "CombatManager.hpp"
#include "MobManager.hpp"
namespace NanoManager {
@ -24,7 +24,7 @@ std::set<int> RunPowers = {4, 8, 62, 68, 73, 86};
std::set<int> BonusPowers = {6, 54, 104};
std::set<int> GuardPowers = {9, 57, 76};
std::set<int> RadarPowers = {11, 67, 95};
std::set<int> AnitdotePowers = {14, 58, 102};
std::set<int> AntidotePowers = {14, 58, 102};
std::set<int> FreedomPowers = {15, 31, 39, 55, 77, 107};
std::set<int> JumpPowers = {16, 35, 44, 60, 88, 100};
std::set<int> SelfRevivePowers = {22, 48, 83};
@ -188,7 +188,7 @@ void NanoManager::addNano(CNSocket* sock, int16_t nanoId, int16_t slot) {
// Update player
plr->Nanos[nanoId] = resp.Nano;
plr->level = level;
plr->HP = 1000 * plr->level;
plr->iConditionBitFlag = 0;
sock->sendPacket((void*)&resp, P_FE2CL_REP_PC_NANO_CREATE_SUCC, sizeof(sP_FE2CL_REP_PC_NANO_CREATE_SUCC));
@ -216,80 +216,29 @@ void NanoManager::summonNano(CNSocket *sock, int slot) {
if (slot > 2 || slot < -1)
return; // sanity check
int nanoId = slot == -1 ? -1 : plr->equippedNanos[slot];
int16_t nanoId = slot == -1 ? -1 : plr->equippedNanos[slot];
if (nanoId > 36 || nanoId < -1)
return; // sanity check
int16_t skillId = 0;
if (plr->activeNano > 0) {
skillId = plr->Nanos[plr->activeNano].iSkillID;
if (skillId == 3 || skillId == 50 || skillId == 99)
nanoUnbuff(sock, 16384, 15); // Scavenge
else if (skillId == 4 || skillId == 8 || skillId == 62 || skillId == 68 || skillId == 73 || skillId == 86)
nanoUnbuff(sock, 1, 1, 200); // Run
else if (skillId == 6 || skillId == 54 || skillId == 104)
nanoUnbuff(sock, 32768, 16); // Bonus
else if (skillId == 9 || skillId == 57 || skillId == 76)
nanoUnbuff(sock, 32, 6); // Guard
else if (skillId == 11 || skillId == 67 || skillId == 95)
nanoUnbuff(sock, 4096, 13); // Radar
else if (skillId == 14 || skillId == 58 || skillId == 102)
nanoUnbuff(sock, 64, 7); // Antidote
else if (skillId == 15 || skillId == 31 || skillId == 39 || skillId == 55 || skillId == 77 || skillId == 107)
nanoUnbuff(sock, 131072, 18); // Freedom
else if (skillId == 16 || skillId == 35 || skillId == 44 || skillId == 60 || skillId == 88 || skillId == 100)
nanoUnbuff(sock, 4, 3, 400); // Jump
else if (skillId == 22 || skillId == 48 || skillId == 83)
nanoUnbuff(sock, 16, 5); // Self Revive
else if (skillId == 23 || skillId == 29 || skillId == 65 || skillId == 72 || skillId == 80 || skillId == 82)
nanoUnbuff(sock, 8, 4); // Sneak
else if (skillId == 26 || skillId == 40 || skillId == 74)
nanoUnbuff(sock, 8192, 14); // Treasure Finder
}
if (plr->activeNano > 0)
for (auto& pwr : PassivePowers)
if (pwr.powers.count(plr->Nanos[plr->activeNano].iSkillID)) // std::set's contains method is C++20 only...
nanoUnbuff(sock, pwr.iCBFlag, pwr.eCharStatusTimeBuffID, pwr.iValue);
sNano nano = plr->Nanos[nanoId];
skillId = nano.iSkillID;
if (slot > -1) {
plr->activeNano = nanoId;
if (skillId == 3 || skillId == 50 || skillId == 99) {
nanoBuff(sock, nanoId, skillId, 19, 16384, 15); // Scavenge
resp.eCSTB___Add = 1;
} else if (skillId == 4 || skillId == 8 || skillId == 62 || skillId == 68 || skillId == 73 || skillId == 86) {
nanoBuff(sock, nanoId, skillId, 11, 1, 1, 200); // Run
resp.eCSTB___Add = 1;
} else if (skillId == 6 || skillId == 54 || skillId == 104) {
nanoBuff(sock, nanoId, skillId, 20, 32768, 16); // Bonus
resp.eCSTB___Add = 1;
} else if (skillId == 9 || skillId == 57 || skillId == 76) {
nanoBuff(sock, nanoId, skillId, 17, 32, 6); // Guard
resp.eCSTB___Add = 1;
} else if (skillId == 11 || skillId == 67 || skillId == 95) {
nanoBuff(sock, nanoId, skillId, 14, 4096, 13); // Radar
resp.eCSTB___Add = 1;
} else if (skillId == 14 || skillId == 58 || skillId == 102) {
nanoBuff(sock, nanoId, skillId, 18, 64, 7); // Antidote
resp.eCSTB___Add = 1;
} else if (skillId == 15 || skillId == 31 || skillId == 39 || skillId == 55 || skillId == 77 || skillId == 107) {
nanoBuff(sock, nanoId, skillId, 25, 131072, 18); // Freedom
resp.eCSTB___Add = 1;
} else if (skillId == 16 || skillId == 35 || skillId == 44) {
nanoBuff(sock, nanoId, skillId, 10, 4, 3, 400); // Jump
resp.eCSTB___Add = 1;
} else if (skillId == 22 || skillId == 48 || skillId == 83) {
nanoBuff(sock, nanoId, skillId, 16, 16, 5); // Self Revive
resp.eCSTB___Add = 1;
} else if (skillId == 23 || skillId == 29 || skillId == 65 || skillId == 72 || skillId == 80 || skillId == 82) {
nanoBuff(sock, nanoId, skillId, 12, 8, 4); // Sneak
resp.eCSTB___Add = 1;
} else if (skillId == 26 || skillId == 40 || skillId == 74) {
nanoBuff(sock, nanoId, skillId, 15, 8192, 14); // Treasure Finder
resp.eCSTB___Add = 1;
}
for (auto& pwr : PassivePowers)
if (pwr.powers.count(skillId)) { // std::set's contains method is C++20 only...
resp.eCSTB___Add = 1;
nanoBuff(sock, nanoId, skillId, pwr.eSkillType, pwr.iCBFlag, pwr.eCharStatusTimeBuffID, pwr.iValue);
}
} else
plr->activeNano = 0;
@ -299,6 +248,7 @@ void NanoManager::summonNano(CNSocket *sock, int slot) {
INITSTRUCT(sP_FE2CL_NANO_ACTIVE, pkt1);
pkt1.iPC_ID = plr->iID;
if (nanoId == -1)
memset(&pkt1.Nano, 0, sizeof(pkt1.Nano));
else
@ -324,6 +274,7 @@ void NanoManager::setNanoSkill(CNSocket* sock, int16_t nanoId, int16_t skillId)
INITSTRUCT(sP_FE2CL_REP_NANO_TUNE_SUCC, resp);
resp.iNanoID = nanoId;
resp.iSkillID = skillId;
resp.aItem[9] = plr->Inven[0]; // temp fix for a bug TODO: Use this for nano power changing later
sock->sendPacket((void*)&resp, P_FE2CL_REP_NANO_TUNE_SUCC, sizeof(sP_FE2CL_REP_NANO_TUNE_SUCC));
@ -348,32 +299,50 @@ void NanoManager::resetNanoSkill(CNSocket* sock, int16_t nanoId) {
#pragma region Active Powers
namespace NanoManager {
bool doDebuff(CNSocket *sock, int32_t *pktdata, sSkillResult_Damage_N_Debuff *respdata, int i, int16_t iCBFlag, int32_t amount) {
if (NPCManager::NPCs.find(pktdata[i]) == NPCManager::NPCs.end()) {
bool doDebuff(CNSocket *sock, int32_t *pktdata, sSkillResult_Damage_N_Debuff *respdata, int i, int32_t iCBFlag, int32_t amount) {
if (MobManager::Mobs.find(pktdata[i]) == MobManager::Mobs.end()) {
// not sure how to best handle this
std::cout << "[WARN] nanoDebuffEnemy: mob ID not found" << std::endl;
return false;
}
BaseNPC& mob = NPCManager::NPCs[pktdata[i]];
Mob* mob = MobManager::Mobs[pktdata[i]];
mob.appearanceData.iHP -= amount;
mob->appearanceData.iHP -= amount;
if (mob.appearanceData.iHP <= 0)
CombatManager::giveReward(sock);
if (mob->appearanceData.iHP <= 0)
MobManager::giveReward(sock);
respdata[i].eCT = 4;
respdata[i].iDamage = amount;
respdata[i].iID = mob.appearanceData.iNPC_ID;
respdata[i].iHP = mob.appearanceData.iHP;
respdata[i].iID = mob->appearanceData.iNPC_ID;
respdata[i].iHP = mob->appearanceData.iHP;
respdata[i].iConditionBitFlag = iCBFlag;
std::cout << (int)mob.appearanceData.iNPC_ID << " was debuffed" << std::endl;
std::cout << (int)mob->appearanceData.iNPC_ID << " was debuffed" << std::endl;
return true;
}
bool doHeal(CNSocket *sock, int32_t *pktdata, sSkillResult_Heal_HP *respdata, int i, int16_t iCBFlag, int32_t amount) {
bool doBuff(CNSocket *sock, int32_t *pktdata, sSkillResult_Buff *respdata, int i, int32_t iCBFlag, int32_t amount) {
if (MobManager::Mobs.find(pktdata[i]) == MobManager::Mobs.end()) {
// not sure how to best handle this
std::cout << "[WARN] nanoBuffEnemy: mob ID not found" << std::endl;
return false;
}
Mob* mob = MobManager::Mobs[pktdata[i]];
respdata[i].eCT = 4;
respdata[i].iID = mob->appearanceData.iNPC_ID;
respdata[i].iConditionBitFlag = iCBFlag;
std::cout << (int)mob->appearanceData.iNPC_ID << " was debuffed" << std::endl;
return true;
}
bool doHeal(CNSocket *sock, int32_t *pktdata, sSkillResult_Heal_HP *respdata, int i, int32_t iCBFlag, int32_t amount) {
Player *plr = nullptr;
for (auto& pair : PlayerManager::players) {
@ -401,25 +370,25 @@ bool doHeal(CNSocket *sock, int32_t *pktdata, sSkillResult_Heal_HP *respdata, in
return true;
}
bool doDamage(CNSocket *sock, int32_t *pktdata, sSkillResult_Damage *respdata, int i, int16_t iCBFlag, int32_t amount) {
if (NPCManager::NPCs.find(pktdata[i]) == NPCManager::NPCs.end()) {
bool doDamage(CNSocket *sock, int32_t *pktdata, sSkillResult_Damage *respdata, int i, int32_t iCBFlag, int32_t amount) {
if (MobManager::Mobs.find(pktdata[i]) == MobManager::Mobs.end()) {
// not sure how to best handle this
std::cout << "[WARN] nanoDebuffEnemy: mob ID not found" << std::endl;
return false;
}
BaseNPC& mob = NPCManager::NPCs[pktdata[i]];
Mob* mob = MobManager::Mobs[pktdata[i]];
mob.appearanceData.iHP -= amount;
mob->appearanceData.iHP -= amount;
if (mob.appearanceData.iHP <= 0)
CombatManager::giveReward(sock);
if (mob->appearanceData.iHP <= 0)
MobManager::giveReward(sock);
respdata[i].eCT = 4;
respdata[i].iDamage = amount;
respdata[i].iID = mob.appearanceData.iNPC_ID;
respdata[i].iHP = mob.appearanceData.iHP;
respdata[i].iID = mob->appearanceData.iNPC_ID;
respdata[i].iHP = mob->appearanceData.iHP;
std::cout << (int)mob.appearanceData.iNPC_ID << " was damaged" << std::endl;
std::cout << (int)mob->appearanceData.iNPC_ID << " was damaged" << std::endl;
return true;
}
@ -432,7 +401,7 @@ bool doDamage(CNSocket *sock, int32_t *pktdata, sSkillResult_Damage *respdata, i
* will only every leech a single mob, and the sanity check that enforces that
* assumption is critical.
*/
bool doLeech(CNSocket *sock, int32_t *pktdata, sSkillResult_Heal_HP *healdata, int i, int16_t iCBFlag, int32_t amount) {
bool doLeech(CNSocket *sock, int32_t *pktdata, sSkillResult_Heal_HP *healdata, int i, int32_t iCBFlag, int32_t amount) {
// this sanity check is VERY important
if (i != 0) {
std::cout << "[WARN] Player attempted to leech more than one mob!" << std::endl;
@ -452,33 +421,33 @@ bool doLeech(CNSocket *sock, int32_t *pktdata, sSkillResult_Heal_HP *healdata, i
healdata->iHP = plr->HP;
healdata->iHealHP = amount;
if (NPCManager::NPCs.find(pktdata[i]) == NPCManager::NPCs.end()) {
if (MobManager::Mobs.find(pktdata[i]) == MobManager::Mobs.end()) {
// not sure how to best handle this
std::cout << "[WARN] doLeech: mob ID not found" << std::endl;
return false;
}
BaseNPC& mob = NPCManager::NPCs[pktdata[i]];
Mob* mob = MobManager::Mobs[pktdata[i]];
mob.appearanceData.iHP -= amount;
mob->appearanceData.iHP -= amount;
if (mob.appearanceData.iHP <= 0)
CombatManager::giveReward(sock);
if (mob->appearanceData.iHP <= 0)
MobManager::giveReward(sock);
damagedata->eCT = 4;
damagedata->iDamage = amount;
damagedata->iID = mob.appearanceData.iNPC_ID;
damagedata->iHP = mob.appearanceData.iHP;
damagedata->iID = mob->appearanceData.iNPC_ID;
damagedata->iHP = mob->appearanceData.iHP;
std::cout << (int)mob.appearanceData.iNPC_ID << " was leeched" << std::endl;
std::cout << (int)mob->appearanceData.iNPC_ID << " was leeched" << std::endl;
return true;
}
template<class sPAYLOAD,
bool (*work)(CNSocket*,int32_t*,sPAYLOAD*,int,int16_t,int32_t),
bool (*work)(CNSocket*,int32_t*,sPAYLOAD*,int,int32_t,int32_t),
bool isLeech=false>
void activePower(CNSocket *sock, CNPacketData *data,
int16_t nanoId, int16_t skillId, SkillType eSkillType,
int16_t nanoId, int16_t skillId, int16_t eSkillType,
int32_t iCBFlag, int32_t amount) {
sP_CL2FE_REQ_NANO_SKILL_USE* pkt = (sP_CL2FE_REQ_NANO_SKILL_USE*)data->buf;
@ -518,7 +487,7 @@ void activePower(CNSocket *sock, CNPacketData *data,
resp->iSkillID = skillId;
resp->iNanoID = nanoId;
resp->iNanoStamina = 150;
resp->eST = (int32_t)eSkillType;
resp->eST = eSkillType;
resp->iTargetCnt = pkt->iTargetCnt;
for (int i = 0; i < pkt->iTargetCnt; i++) {
@ -527,21 +496,20 @@ void activePower(CNSocket *sock, CNPacketData *data,
}
sock->sendPacket((void*)&respbuf, P_FE2CL_NANO_SKILL_USE_SUCC, resplen);
for (CNSocket* s : PlayerManager::players[sock].viewable)
s->sendPacket((void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen);
PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen);
}
// active nano power dispatch table
std::vector<ActivePower> ActivePowers = {
ActivePower(StunPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, SkillType::STUN, 0x200, 0),
ActivePower(HealPowers, activePower<sSkillResult_Heal_HP, doHeal>, SkillType::HEAL, 0, 333),
ActivePower(StunPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_STUN, CSB_BIT_STUN, 0),
ActivePower(HealPowers, activePower<sSkillResult_Heal_HP, doHeal>, EST_HEAL_HP, CSB_BIT_NONE, 333),
// TODO: Recall
ActivePower(DrainPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, SkillType::DRAIN, 0x40000, 0),
ActivePower(SnarePowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, SkillType::SNARE, 0x80, 0),
ActivePower(DamagePowers, activePower<sSkillResult_Damage, doDamage>, SkillType::DAMAGE, 0, 133),
ActivePower(DrainPowers, activePower<sSkillResult_Buff, doBuff>, EST_BOUNDINGBALL, CSB_BIT_BOUNDINGBALL, 0),
ActivePower(SnarePowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_SNARE, CSB_BIT_DN_MOVE_SPEED, 0),
ActivePower(DamagePowers, activePower<sSkillResult_Damage, doDamage>, EST_DAMAGE, CSB_BIT_NONE, 133),
// TODO: GroupRevive
ActivePower(LeechPowers, activePower<sSkillResult_Heal_HP, doLeech, true>, SkillType::LEECH, 0, 133),
ActivePower(SleepPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, SkillType::SLEEP, 0x400, 0),
ActivePower(LeechPowers, activePower<sSkillResult_Heal_HP, doLeech, true>, EST_BLOODSUCKING, CSB_BIT_NONE, 133),
ActivePower(SleepPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_SLEEP, CSB_BIT_MEZ, 0),
};
}; // namespace
@ -594,8 +562,7 @@ void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t
}
sock->sendPacket((void*)&respbuf, P_FE2CL_NANO_SKILL_USE_SUCC, resplen);
for (CNSocket* s : PlayerManager::players[sock].viewable)
s->sendPacket((void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen);
PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen);
}
void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue) {
@ -618,4 +585,21 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatu
sock->sendPacket((void*)&resp1, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
}
namespace NanoManager {
std::vector<PassivePower> PassivePowers = {
PassivePower(ScavangePowers, EST_REWARDBLOB, CSB_BIT_REWARD_BLOB, ECSB_REWARD_BLOB, 0),
PassivePower(RunPowers, EST_RUN, CSB_BIT_UP_MOVE_SPEED, ECSB_UP_MOVE_SPEED, 200),
PassivePower(BonusPowers, EST_REWARDCASH, CSB_BIT_REWARD_CASH, ECSB_REWARD_CASH, 0),
PassivePower(GuardPowers, EST_PROTECTBATTERY, CSB_BIT_PROTECT_BATTERY, ECSB_PROTECT_BATTERY, 0),
PassivePower(RadarPowers, EST_MINIMAPENEMY, CSB_BIT_MINIMAP_ENEMY, ECSB_MINIMAP_ENEMY, 0),
PassivePower(AntidotePowers, EST_PROTECTINFECTION, CSB_BIT_PROTECT_INFECTION, ECSB_PROTECT_INFECTION, 0),
PassivePower(FreedomPowers, EST_FREEDOM, CSB_BIT_FREEDOM, ECSB_FREEDOM, 0),
PassivePower(JumpPowers, EST_JUMP, CSB_BIT_UP_JUMP_HEIGHT, ECSB_UP_JUMP_HEIGHT, 400),
PassivePower(SelfRevivePowers, EST_PHOENIX, CSB_BIT_PHOENIX, ECSB_PHOENIX, 0),
PassivePower(SneakPowers, EST_STEALTH, CSB_BIT_UP_STEALTH, ECSB_UP_STEALTH, 0),
PassivePower(TreasureFinderPowers, EST_MINIMAPTRESURE, CSB_BIT_MINIMAP_TRESURE, ECSB_MINIMAP_TRESURE, 0),
};
}; // namespace
#pragma endregion

View File

@ -5,26 +5,16 @@
#include "CNShardServer.hpp"
enum class SkillType {
DAMAGE = 1,
HEAL = 2,
DRAIN = 3,
SLEEP = 4,
SNARE = 5,
STUN = 8,
LEECH = 30, // ...what?
};
typedef void (*ActivePowerHandler)(CNSocket*, CNPacketData*, int16_t, int16_t, SkillType, int32_t, int32_t);
typedef void (*ActivePowerHandler)(CNSocket*, CNPacketData*, int16_t, int16_t, int16_t, int32_t, int32_t);
struct ActivePower {
std::set<int> powers;
ActivePowerHandler handler;
SkillType eSkillType;
int16_t eSkillType;
int32_t flag;
int32_t amount;
ActivePower(std::set<int> p, ActivePowerHandler h, SkillType t, int32_t f, int32_t a) : powers(p), handler(h), eSkillType(t), flag(f), amount(a) {}
ActivePower(std::set<int> p, ActivePowerHandler h, int16_t t, int32_t f, int32_t a) : powers(p), handler(h), eSkillType(t), flag(f), amount(a) {}
void handle(CNSocket *sock, CNPacketData *data, int16_t nanoId, int16_t skillId) {
if (handler == nullptr)
@ -34,8 +24,19 @@ struct ActivePower {
}
};
struct PassivePower {
std::set<int> powers;
int16_t eSkillType;
int32_t iCBFlag;
int16_t eCharStatusTimeBuffID;
int16_t iValue;
PassivePower(std::set<int> p, int16_t t, int32_t f, int16_t b, int16_t a) : powers(p), eSkillType(t), iCBFlag(f), eCharStatusTimeBuffID(b), iValue(a) {}
};
namespace NanoManager {
extern std::vector<ActivePower> ActivePowers;
extern std::vector<PassivePower> PassivePowers;
void init();
void nanoSummonHandler(CNSocket* sock, CNPacketData* data);