mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
Refactored Nano Powers
* All nano power functions have been merged into one goliath of a function. * Nano powers consume the correct amount of stamina. * Bugfixed gumball issues, gumballed nanos now perform better. * Revive powers now work correctly. * Recall powers both self and group are functional. * Removed nanoBuff. * Added a new applyBuff function, this allows for quick and easy application of nano skills. * Numerous other bugfixes.
This commit is contained in:
parent
2acb90f2d2
commit
299fc1b461
@ -106,8 +106,6 @@ void GroupManager::joinGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bitFlagBefore = getGroupFlags(otherPlr);
|
|
||||||
|
|
||||||
plr->iIDGroup = otherPlr->iID;
|
plr->iIDGroup = otherPlr->iID;
|
||||||
otherPlr->groupCnt += 1;
|
otherPlr->groupCnt += 1;
|
||||||
otherPlr->groupIDs[otherPlr->groupCnt-1] = plr->iID;
|
otherPlr->groupIDs[otherPlr->groupCnt-1] = plr->iID;
|
||||||
@ -148,7 +146,10 @@ void GroupManager::joinGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
respdata[i].iZ = varPlr->z;
|
respdata[i].iZ = varPlr->z;
|
||||||
// client doesnt read nano data here
|
// client doesnt read nano data here
|
||||||
|
|
||||||
NanoManager::nanoChangeBuff(sockTo, varPlr, bitFlagBefore | varPlr->iConditionBitFlag, bitFlag | varPlr->iConditionBitFlag);
|
if (varPlr != plr) {
|
||||||
|
NanoManager::applyBuff(sock, varPlr->Nanos[varPlr->activeNano].iSkillID, 1, 1, bitFlag);
|
||||||
|
NanoManager::applyBuff(sockTo, plr->Nanos[plr->activeNano].iSkillID, 1, 1, bitFlag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendToGroup(otherPlr, (void*)&respbuf, P_FE2CL_PC_GROUP_JOIN, resplen);
|
sendToGroup(otherPlr, (void*)&respbuf, P_FE2CL_PC_GROUP_JOIN, resplen);
|
||||||
@ -302,10 +303,14 @@ void GroupManager::groupKickPlayer(Player* plr) {
|
|||||||
resp->iID_LeaveMember = plr->iID;
|
resp->iID_LeaveMember = plr->iID;
|
||||||
resp->iMemberPCCnt = otherPlr->groupCnt - 1;
|
resp->iMemberPCCnt = otherPlr->groupCnt - 1;
|
||||||
|
|
||||||
int bitFlagBefore = getGroupFlags(otherPlr);
|
int bitFlag = getGroupFlags(otherPlr) & ~plr->iGroupConditionBitFlag;
|
||||||
int bitFlag = bitFlagBefore & ~plr->iGroupConditionBitFlag;
|
|
||||||
int moveDown = 0;
|
int moveDown = 0;
|
||||||
|
|
||||||
|
CNSocket* sock = PlayerManager::getSockFromID(plr->iID);
|
||||||
|
|
||||||
|
if (sock == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < otherPlr->groupCnt; i++) {
|
for (int i = 0; i < otherPlr->groupCnt; i++) {
|
||||||
Player* varPlr = PlayerManager::getPlayerFromID(otherPlr->groupIDs[i]);
|
Player* varPlr = PlayerManager::getPlayerFromID(otherPlr->groupIDs[i]);
|
||||||
CNSocket* sockTo = PlayerManager::getSockFromID(otherPlr->groupIDs[i]);
|
CNSocket* sockTo = PlayerManager::getSockFromID(otherPlr->groupIDs[i]);
|
||||||
@ -335,9 +340,10 @@ void GroupManager::groupKickPlayer(Player* plr) {
|
|||||||
if (varPlr == plr) {
|
if (varPlr == plr) {
|
||||||
moveDown = 1;
|
moveDown = 1;
|
||||||
otherPlr->groupIDs[i] = 0;
|
otherPlr->groupIDs[i] = 0;
|
||||||
NanoManager::nanoChangeBuff(sockTo, varPlr, bitFlagBefore | varPlr->iConditionBitFlag, varPlr->iConditionBitFlag);
|
} else {
|
||||||
} else
|
NanoManager::applyBuff(sock, varPlr->Nanos[varPlr->activeNano].iSkillID, 2, 1, 0);
|
||||||
NanoManager::nanoChangeBuff(sockTo, varPlr, bitFlagBefore | varPlr->iConditionBitFlag, bitFlag | varPlr->iConditionBitFlag);
|
NanoManager::applyBuff(sockTo, plr->Nanos[plr->activeNano].iSkillID, 2, 1, bitFlag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plr->iIDGroup = plr->iID;
|
plr->iIDGroup = plr->iID;
|
||||||
@ -345,26 +351,24 @@ void GroupManager::groupKickPlayer(Player* plr) {
|
|||||||
|
|
||||||
sendToGroup(otherPlr, (void*)&respbuf, P_FE2CL_PC_GROUP_LEAVE, resplen);
|
sendToGroup(otherPlr, (void*)&respbuf, P_FE2CL_PC_GROUP_LEAVE, resplen);
|
||||||
|
|
||||||
CNSocket* sock = PlayerManager::getSockFromID(plr->iID);
|
|
||||||
|
|
||||||
if (sock == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_PC_GROUP_LEAVE_SUCC, resp1);
|
INITSTRUCT(sP_FE2CL_PC_GROUP_LEAVE_SUCC, resp1);
|
||||||
sock->sendPacket((void*)&resp1, P_FE2CL_PC_GROUP_LEAVE_SUCC, sizeof(sP_FE2CL_PC_GROUP_LEAVE_SUCC));
|
sock->sendPacket((void*)&resp1, P_FE2CL_PC_GROUP_LEAVE_SUCC, sizeof(sP_FE2CL_PC_GROUP_LEAVE_SUCC));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GroupManager::groupUnbuff(Player* plr) {
|
void GroupManager::groupUnbuff(Player* plr) {
|
||||||
int bitFlag = getGroupFlags(plr);
|
|
||||||
|
|
||||||
for (int i = 0; i < plr->groupCnt; i++) {
|
for (int i = 0; i < plr->groupCnt; i++) {
|
||||||
CNSocket* sock = PlayerManager::getSockFromID(plr->groupIDs[i]);
|
for (int n = 0; n < plr->groupCnt; n++) {
|
||||||
|
if (i == n)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (sock == nullptr)
|
Player* otherPlr = PlayerManager::getPlayerFromID(plr->groupIDs[i]);
|
||||||
continue;
|
CNSocket* sock = PlayerManager::getSockFromID(plr->groupIDs[n]);
|
||||||
|
|
||||||
Player* otherPlr = PlayerManager::getPlayer(sock);
|
if (otherPlr == nullptr || sock == nullptr)
|
||||||
NanoManager::nanoChangeBuff(sock, otherPlr, bitFlag | otherPlr->iConditionBitFlag, otherPlr->iConditionBitFlag);
|
continue;
|
||||||
|
|
||||||
|
NanoManager::applyBuff(sock, otherPlr->Nanos[otherPlr->activeNano].iSkillID, 2, 1, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,25 +263,44 @@ void ItemManager::itemUseHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
if (gumball.iOpt == 0)
|
if (gumball.iOpt == 0)
|
||||||
gumball = {};
|
gumball = {};
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_SUCC, response);
|
size_t resplen = sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC) + sizeof(sSkillResult_Buff);
|
||||||
response.iPC_ID = player->iID;
|
|
||||||
response.eIL = 1;
|
|
||||||
response.iSlotNum = request->iSlotNum;
|
|
||||||
response.RemainItem = gumball;
|
|
||||||
// response.iTargetCnt = ?
|
|
||||||
// response.eST = ?
|
|
||||||
// response.iSkillID = ?
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_SUCC, sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC));
|
// validate response packet
|
||||||
// update inventory serverside
|
if (!validOutVarPacket(sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC), 1, sizeof(sSkillResult_Buff))) {
|
||||||
player->Inven[response.iSlotNum] = response.RemainItem;
|
std::cout << "[WARN] bad sP_FE2CL_REP_PC_ITEM_USE_SUCC packet size" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
||||||
|
memset(respbuf, 0, resplen);
|
||||||
|
|
||||||
|
sP_FE2CL_REP_PC_ITEM_USE_SUCC *resp = (sP_FE2CL_REP_PC_ITEM_USE_SUCC*)respbuf;
|
||||||
|
sSkillResult_Buff *respdata = (sSkillResult_Buff*)(respbuf+sizeof(sP_FE2CL_NANO_SKILL_USE_SUCC));
|
||||||
|
resp->iPC_ID = player->iID;
|
||||||
|
resp->eIL = 1;
|
||||||
|
resp->iSlotNum = request->iSlotNum;
|
||||||
|
resp->RemainItem = gumball;
|
||||||
|
resp->iTargetCnt = 1;
|
||||||
|
resp->eST = EST_NANOSTIMPAK;
|
||||||
|
resp->iSkillID = 144;
|
||||||
|
|
||||||
// this is a temporary way of calling buff efect
|
|
||||||
// TODO: send buff data via response packet
|
|
||||||
int value1 = CSB_BIT_STIMPAKSLOT1 << request->iNanoSlot;
|
int value1 = CSB_BIT_STIMPAKSLOT1 << request->iNanoSlot;
|
||||||
int value2 = ECSB_STIMPAKSLOT1 + request->iNanoSlot;
|
int value2 = ECSB_STIMPAKSLOT1 + request->iNanoSlot;
|
||||||
|
|
||||||
NanoManager::nanoBuff(sock, nano.iID, 144, EST_NANOSTIMPAK, value1, value2, 0);
|
respdata->eCT = 1;
|
||||||
|
respdata->iID = player->iID;
|
||||||
|
respdata->iConditionBitFlag = value1;
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, pkt);
|
||||||
|
pkt.eCSTB = value2; // eCharStatusTimeBuffID
|
||||||
|
pkt.eTBU = 1; // eTimeBuffUpdate
|
||||||
|
pkt.eTBT = 1; // eTimeBuffType 1 means nano
|
||||||
|
pkt.iConditionBitFlag = player->iConditionBitFlag |= value1;
|
||||||
|
sock->sendPacket((void*)&pkt, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
|
|
||||||
|
sock->sendPacket((void*)&respbuf, P_FE2CL_REP_PC_ITEM_USE_SUCC, resplen);
|
||||||
|
// update inventory serverside
|
||||||
|
player->Inven[resp->iSlotNum] = resp->RemainItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemManager::itemBankOpenHandler(CNSocket* sock, CNPacketData* data) {
|
void ItemManager::itemBankOpenHandler(CNSocket* sock, CNPacketData* data) {
|
||||||
|
@ -505,7 +505,7 @@ void MobManager::combatStep(Mob *mob, time_t currTime) {
|
|||||||
|
|
||||||
// drain
|
// drain
|
||||||
if ((mob->lastDrainTime == 0 || currTime - mob->lastDrainTime >= 1000) && mob->appearanceData.iConditionBitFlag & CSB_BIT_BOUNDINGBALL) {
|
if ((mob->lastDrainTime == 0 || currTime - mob->lastDrainTime >= 1000) && mob->appearanceData.iConditionBitFlag & CSB_BIT_BOUNDINGBALL) {
|
||||||
drainMobHP(mob, mob->maxHealth / 15); // lose 6.67% every second
|
drainMobHP(mob, mob->maxHealth / 20); // lose 5% every second
|
||||||
mob->lastDrainTime = currTime;
|
mob->lastDrainTime = currTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -934,10 +934,7 @@ void MobManager::playerTick(CNServer *serv, time_t currTime) {
|
|||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
if (plr->activeNano != 0 && plr->equippedNanos[i] == plr->activeNano) { // spend stamina
|
if (plr->activeNano != 0 && plr->equippedNanos[i] == plr->activeNano) { // spend stamina
|
||||||
plr->Nanos[plr->activeNano].iStamina -= 1;
|
plr->Nanos[plr->activeNano].iStamina -= 1 + plr->nanoDrainRate * 2 / 5;
|
||||||
|
|
||||||
if (plr->passiveNanoOut)
|
|
||||||
plr->Nanos[plr->activeNano].iStamina -= 1;
|
|
||||||
|
|
||||||
if (plr->Nanos[plr->activeNano].iStamina <= 0) {
|
if (plr->Nanos[plr->activeNano].iStamina <= 0) {
|
||||||
plr->Nanos[plr->activeNano].iStamina = 0;
|
plr->Nanos[plr->activeNano].iStamina = 0;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,22 +5,25 @@
|
|||||||
|
|
||||||
#include "CNShardServer.hpp"
|
#include "CNShardServer.hpp"
|
||||||
|
|
||||||
typedef void (*ActivePowerHandler)(CNSocket*, CNPacketData*, int16_t, int16_t, int16_t, int32_t, int32_t);
|
struct TargetData {
|
||||||
|
int targetID[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*PowerHandler)(CNSocket*, TargetData, int16_t, int16_t, int16_t, int16_t, int16_t, int32_t, int16_t);
|
||||||
|
|
||||||
struct ActivePower {
|
struct ActivePower {
|
||||||
std::set<int> powers;
|
int16_t skillType;
|
||||||
ActivePowerHandler handler;
|
int32_t bitFlag;
|
||||||
int16_t eSkillType;
|
int16_t timeBuffID;
|
||||||
int32_t flag;
|
PowerHandler handler;
|
||||||
int32_t amount;
|
|
||||||
|
|
||||||
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) {}
|
ActivePower(int16_t s, int32_t b, int16_t t, PowerHandler h) : skillType(s), bitFlag(b), timeBuffID(t), handler(h) {}
|
||||||
|
|
||||||
void handle(CNSocket *sock, CNPacketData *data, int16_t nanoId, int16_t skillId) {
|
void handle(CNSocket *sock, TargetData targetData, int16_t nanoID, int16_t skillID, int16_t duration, int16_t amount) {
|
||||||
if (handler == nullptr)
|
if (handler == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
handler(sock, data, nanoId, skillId, eSkillType, flag, amount);
|
handler(sock, targetData, nanoID, skillID, duration, amount, skillType, bitFlag, timeBuffID);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,6 +50,7 @@ struct NanoTuning {
|
|||||||
struct SkillData {
|
struct SkillData {
|
||||||
int skillType;
|
int skillType;
|
||||||
int targetType;
|
int targetType;
|
||||||
|
int drainType;
|
||||||
int batteryUse[4];
|
int batteryUse[4];
|
||||||
int durationTime[4];
|
int durationTime[4];
|
||||||
int powerIntensity[4];
|
int powerIntensity[4];
|
||||||
@ -67,19 +71,16 @@ namespace NanoManager {
|
|||||||
void nanoSkillUseHandler(CNSocket* sock, CNPacketData* data);
|
void nanoSkillUseHandler(CNSocket* sock, CNPacketData* data);
|
||||||
void nanoSkillSetHandler(CNSocket* sock, CNPacketData* data);
|
void nanoSkillSetHandler(CNSocket* sock, CNPacketData* data);
|
||||||
void nanoSkillSetGMHandler(CNSocket* sock, CNPacketData* data);
|
void nanoSkillSetGMHandler(CNSocket* sock, CNPacketData* data);
|
||||||
|
void nanoRecallRegisterHandler(CNSocket* sock, CNPacketData* data);
|
||||||
void nanoRecallHandler(CNSocket* sock, CNPacketData* data);
|
void nanoRecallHandler(CNSocket* sock, CNPacketData* data);
|
||||||
void nanoPotionHandler(CNSocket* sock, CNPacketData* data);
|
void nanoPotionHandler(CNSocket* sock, CNPacketData* data);
|
||||||
|
|
||||||
// Helper methods
|
// Helper methods
|
||||||
void addNano(CNSocket* sock, int16_t nanoId, int16_t slot, bool spendfm=false);
|
void addNano(CNSocket* sock, int16_t nanoID, int16_t slot, bool spendfm=false);
|
||||||
void summonNano(CNSocket* sock, int slot);
|
void summonNano(CNSocket* sock, int slot);
|
||||||
void setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill);
|
void setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill);
|
||||||
void resetNanoSkill(CNSocket* sock, int16_t nanoId);
|
void resetNanoSkill(CNSocket* sock, int16_t nanoID);
|
||||||
|
void nanoUnbuff(CNSocket* sock, TargetData targetData, int32_t bitFlag, int16_t timeBuffID, int16_t amount, bool groupPower);
|
||||||
void nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t eSkillType, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0, bool groupPower = false);
|
void applyBuff(CNSocket* sock, int skillID, int eTBU, int eTBT, int32_t groupFlags);
|
||||||
void nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0, bool groupPower = false);
|
int nanoStyle(int nanoID);
|
||||||
|
|
||||||
int nanoStyle(int nanoId);
|
|
||||||
void revivePlayer(Player* plr);
|
|
||||||
void nanoChangeBuff(CNSocket* sock, Player* plr, int32_t cbFrom, int32_t cbTo);
|
|
||||||
}
|
}
|
||||||
|
@ -36,10 +36,12 @@ struct Player {
|
|||||||
int32_t iWarpLocationFlag;
|
int32_t iWarpLocationFlag;
|
||||||
int64_t aSkywayLocationFlag[2];
|
int64_t aSkywayLocationFlag[2];
|
||||||
int32_t iConditionBitFlag;
|
int32_t iConditionBitFlag;
|
||||||
|
int32_t iSelfConditionBitFlag;
|
||||||
int8_t iSpecialState;
|
int8_t iSpecialState;
|
||||||
|
|
||||||
int x, y, z, angle;
|
int x, y, z, angle;
|
||||||
int lastX, lastY, lastZ, lastAngle;
|
int lastX, lastY, lastZ, lastAngle;
|
||||||
|
int recallX, recallY, recallZ, recallInstance;
|
||||||
uint64_t instanceID;
|
uint64_t instanceID;
|
||||||
sItemBase Equip[AEQUIP_COUNT];
|
sItemBase Equip[AEQUIP_COUNT];
|
||||||
sItemBase Inven[AINVEN_COUNT];
|
sItemBase Inven[AINVEN_COUNT];
|
||||||
@ -51,7 +53,7 @@ struct Player {
|
|||||||
|
|
||||||
bool inCombat;
|
bool inCombat;
|
||||||
bool onMonkey;
|
bool onMonkey;
|
||||||
bool passiveNanoOut;
|
int nanoDrainRate;
|
||||||
int healCooldown;
|
int healCooldown;
|
||||||
|
|
||||||
int pointDamage;
|
int pointDamage;
|
||||||
|
@ -712,10 +712,16 @@ void PlayerManager::revivePlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
bool move = false;
|
bool move = false;
|
||||||
|
|
||||||
if (reviveData->iRegenType == 3 && plr->iConditionBitFlag & CSB_BIT_PHOENIX) {
|
if (reviveData->iRegenType == 3 && plr->iConditionBitFlag & CSB_BIT_PHOENIX || reviveData->iRegenType == 4) {
|
||||||
// nano revive
|
// nano revive
|
||||||
plr->Nanos[plr->activeNano].iStamina = 0;
|
plr->Nanos[plr->activeNano].iStamina = 0;
|
||||||
NanoManager::nanoUnbuff(sock, CSB_BIT_PHOENIX, ECSB_PHOENIX, 0, false);
|
|
||||||
|
INITSTRUCT(TargetData, targetData);
|
||||||
|
targetData.targetID[0] = plr->iID;
|
||||||
|
for (int i = 1; i < 4; i++)
|
||||||
|
targetData.targetID[i] = -1;
|
||||||
|
NanoManager::nanoUnbuff(sock, targetData, CSB_BIT_PHOENIX, ECSB_PHOENIX, 0, false);
|
||||||
|
|
||||||
plr->HP = PC_MAXHEALTH(plr->level);
|
plr->HP = PC_MAXHEALTH(plr->level);
|
||||||
} else {
|
} else {
|
||||||
move = true;
|
move = true;
|
||||||
|
@ -195,7 +195,7 @@ void TableData::init() {
|
|||||||
|
|
||||||
for (nlohmann::json::iterator _skills = skills.begin(); _skills != skills.end(); _skills++) {
|
for (nlohmann::json::iterator _skills = skills.begin(); _skills != skills.end(); _skills++) {
|
||||||
auto skills = _skills.value();
|
auto skills = _skills.value();
|
||||||
SkillData skillData = {skills["m_iSkillType"], skills["m_iTargetType"]};
|
SkillData skillData = {skills["m_iSkillType"], skills["m_iTargetType"], skills["m_iBatteryDrainType"]};
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
skillData.batteryUse[i] = skills["m_iBatteryDrainUse"][i];
|
skillData.batteryUse[i] = skills["m_iBatteryDrainUse"][i];
|
||||||
skillData.durationTime[i] = skills["m_iDurationTime"][i];
|
skillData.durationTime[i] = skills["m_iDurationTime"][i];
|
||||||
|
Loading…
Reference in New Issue
Block a user