mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-04 22:40:05 +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;
|
||||
}
|
||||
|
||||
int bitFlagBefore = getGroupFlags(otherPlr);
|
||||
|
||||
plr->iIDGroup = otherPlr->iID;
|
||||
otherPlr->groupCnt += 1;
|
||||
otherPlr->groupIDs[otherPlr->groupCnt-1] = plr->iID;
|
||||
@ -148,7 +146,10 @@ void GroupManager::joinGroup(CNSocket* sock, CNPacketData* data) {
|
||||
respdata[i].iZ = varPlr->z;
|
||||
// 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);
|
||||
@ -302,10 +303,14 @@ void GroupManager::groupKickPlayer(Player* plr) {
|
||||
resp->iID_LeaveMember = plr->iID;
|
||||
resp->iMemberPCCnt = otherPlr->groupCnt - 1;
|
||||
|
||||
int bitFlagBefore = getGroupFlags(otherPlr);
|
||||
int bitFlag = bitFlagBefore & ~plr->iGroupConditionBitFlag;
|
||||
int bitFlag = getGroupFlags(otherPlr) & ~plr->iGroupConditionBitFlag;
|
||||
int moveDown = 0;
|
||||
|
||||
CNSocket* sock = PlayerManager::getSockFromID(plr->iID);
|
||||
|
||||
if (sock == nullptr)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < otherPlr->groupCnt; i++) {
|
||||
Player* varPlr = PlayerManager::getPlayerFromID(otherPlr->groupIDs[i]);
|
||||
CNSocket* sockTo = PlayerManager::getSockFromID(otherPlr->groupIDs[i]);
|
||||
@ -335,9 +340,10 @@ void GroupManager::groupKickPlayer(Player* plr) {
|
||||
if (varPlr == plr) {
|
||||
moveDown = 1;
|
||||
otherPlr->groupIDs[i] = 0;
|
||||
NanoManager::nanoChangeBuff(sockTo, varPlr, bitFlagBefore | varPlr->iConditionBitFlag, varPlr->iConditionBitFlag);
|
||||
} else
|
||||
NanoManager::nanoChangeBuff(sockTo, varPlr, bitFlagBefore | varPlr->iConditionBitFlag, bitFlag | varPlr->iConditionBitFlag);
|
||||
} else {
|
||||
NanoManager::applyBuff(sock, varPlr->Nanos[varPlr->activeNano].iSkillID, 2, 1, 0);
|
||||
NanoManager::applyBuff(sockTo, plr->Nanos[plr->activeNano].iSkillID, 2, 1, bitFlag);
|
||||
}
|
||||
}
|
||||
|
||||
plr->iIDGroup = plr->iID;
|
||||
@ -345,26 +351,24 @@ void GroupManager::groupKickPlayer(Player* plr) {
|
||||
|
||||
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);
|
||||
sock->sendPacket((void*)&resp1, P_FE2CL_PC_GROUP_LEAVE_SUCC, sizeof(sP_FE2CL_PC_GROUP_LEAVE_SUCC));
|
||||
}
|
||||
|
||||
void GroupManager::groupUnbuff(Player* plr) {
|
||||
int bitFlag = getGroupFlags(plr);
|
||||
|
||||
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)
|
||||
continue;
|
||||
Player* otherPlr = PlayerManager::getPlayerFromID(plr->groupIDs[i]);
|
||||
CNSocket* sock = PlayerManager::getSockFromID(plr->groupIDs[n]);
|
||||
|
||||
Player* otherPlr = PlayerManager::getPlayer(sock);
|
||||
NanoManager::nanoChangeBuff(sock, otherPlr, bitFlag | otherPlr->iConditionBitFlag, otherPlr->iConditionBitFlag);
|
||||
if (otherPlr == nullptr || sock == nullptr)
|
||||
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)
|
||||
gumball = {};
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_ITEM_USE_SUCC, response);
|
||||
response.iPC_ID = player->iID;
|
||||
response.eIL = 1;
|
||||
response.iSlotNum = request->iSlotNum;
|
||||
response.RemainItem = gumball;
|
||||
// response.iTargetCnt = ?
|
||||
// response.eST = ?
|
||||
// response.iSkillID = ?
|
||||
size_t resplen = sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC) + sizeof(sSkillResult_Buff);
|
||||
|
||||
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_ITEM_USE_SUCC, sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC));
|
||||
// update inventory serverside
|
||||
player->Inven[response.iSlotNum] = response.RemainItem;
|
||||
// validate response packet
|
||||
if (!validOutVarPacket(sizeof(sP_FE2CL_REP_PC_ITEM_USE_SUCC), 1, sizeof(sSkillResult_Buff))) {
|
||||
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 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) {
|
||||
|
@ -505,7 +505,7 @@ void MobManager::combatStep(Mob *mob, time_t currTime) {
|
||||
|
||||
// drain
|
||||
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;
|
||||
}
|
||||
|
||||
@ -934,10 +934,7 @@ void MobManager::playerTick(CNServer *serv, time_t currTime) {
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (plr->activeNano != 0 && plr->equippedNanos[i] == plr->activeNano) { // spend stamina
|
||||
plr->Nanos[plr->activeNano].iStamina -= 1;
|
||||
|
||||
if (plr->passiveNanoOut)
|
||||
plr->Nanos[plr->activeNano].iStamina -= 1;
|
||||
plr->Nanos[plr->activeNano].iStamina -= 1 + plr->nanoDrainRate * 2 / 5;
|
||||
|
||||
if (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"
|
||||
|
||||
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 {
|
||||
std::set<int> powers;
|
||||
ActivePowerHandler handler;
|
||||
int16_t eSkillType;
|
||||
int32_t flag;
|
||||
int32_t amount;
|
||||
int16_t skillType;
|
||||
int32_t bitFlag;
|
||||
int16_t timeBuffID;
|
||||
PowerHandler handler;
|
||||
|
||||
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)
|
||||
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 {
|
||||
int skillType;
|
||||
int targetType;
|
||||
int drainType;
|
||||
int batteryUse[4];
|
||||
int durationTime[4];
|
||||
int powerIntensity[4];
|
||||
@ -67,19 +71,16 @@ namespace NanoManager {
|
||||
void nanoSkillUseHandler(CNSocket* sock, CNPacketData* data);
|
||||
void nanoSkillSetHandler(CNSocket* sock, CNPacketData* data);
|
||||
void nanoSkillSetGMHandler(CNSocket* sock, CNPacketData* data);
|
||||
void nanoRecallRegisterHandler(CNSocket* sock, CNPacketData* data);
|
||||
void nanoRecallHandler(CNSocket* sock, CNPacketData* data);
|
||||
void nanoPotionHandler(CNSocket* sock, CNPacketData* data);
|
||||
|
||||
// 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 setNanoSkill(CNSocket* sock, sP_CL2FE_REQ_NANO_TUNE* skill);
|
||||
void resetNanoSkill(CNSocket* sock, int16_t nanoId);
|
||||
|
||||
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 nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue = 0, bool groupPower = false);
|
||||
|
||||
int nanoStyle(int nanoId);
|
||||
void revivePlayer(Player* plr);
|
||||
void nanoChangeBuff(CNSocket* sock, Player* plr, int32_t cbFrom, int32_t cbTo);
|
||||
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 applyBuff(CNSocket* sock, int skillID, int eTBU, int eTBT, int32_t groupFlags);
|
||||
int nanoStyle(int nanoID);
|
||||
}
|
||||
|
@ -36,10 +36,12 @@ struct Player {
|
||||
int32_t iWarpLocationFlag;
|
||||
int64_t aSkywayLocationFlag[2];
|
||||
int32_t iConditionBitFlag;
|
||||
int32_t iSelfConditionBitFlag;
|
||||
int8_t iSpecialState;
|
||||
|
||||
int x, y, z, angle;
|
||||
int lastX, lastY, lastZ, lastAngle;
|
||||
int recallX, recallY, recallZ, recallInstance;
|
||||
uint64_t instanceID;
|
||||
sItemBase Equip[AEQUIP_COUNT];
|
||||
sItemBase Inven[AINVEN_COUNT];
|
||||
@ -51,7 +53,7 @@ struct Player {
|
||||
|
||||
bool inCombat;
|
||||
bool onMonkey;
|
||||
bool passiveNanoOut;
|
||||
int nanoDrainRate;
|
||||
int healCooldown;
|
||||
|
||||
int pointDamage;
|
||||
|
@ -712,10 +712,16 @@ void PlayerManager::revivePlayer(CNSocket* sock, CNPacketData* data) {
|
||||
|
||||
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
|
||||
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);
|
||||
} else {
|
||||
move = true;
|
||||
|
@ -195,7 +195,7 @@ void TableData::init() {
|
||||
|
||||
for (nlohmann::json::iterator _skills = skills.begin(); _skills != skills.end(); _skills++) {
|
||||
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++) {
|
||||
skillData.batteryUse[i] = skills["m_iBatteryDrainUse"][i];
|
||||
skillData.durationTime[i] = skills["m_iDurationTime"][i];
|
||||
|
Loading…
Reference in New Issue
Block a user