mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 21:40:05 +00:00
Bugfixes + Damage Formula Adjustment
* Entering/exiting groups should apply/remove group buffs. * Fixed issues with nanos losing all stamina from various revives/warp away. * Heavily tweaked damage formula, nano types now boost/decrease damage. * Weapons can consume battery returning extra damage, battery consumed depends on enemy level.
This commit is contained in:
parent
bae834fefa
commit
d99dad261c
@ -3,6 +3,7 @@
|
|||||||
#include "ChatManager.hpp"
|
#include "ChatManager.hpp"
|
||||||
#include "PlayerManager.hpp"
|
#include "PlayerManager.hpp"
|
||||||
#include "GroupManager.hpp"
|
#include "GroupManager.hpp"
|
||||||
|
#include "NanoManager.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -93,7 +94,7 @@ void GroupManager::joinGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
if (otherPlr == nullptr)
|
if (otherPlr == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// fail if the group is full the other player is already in a group
|
// fail if the group is full or the other player is already in a group
|
||||||
if (plr->groupCnt > 1 || plr->iIDGroup != plr->iID || otherPlr->groupCnt >= 4) {
|
if (plr->groupCnt > 1 || plr->iIDGroup != plr->iID || otherPlr->groupCnt >= 4) {
|
||||||
INITSTRUCT(sP_FE2CL_PC_GROUP_INVITE_FAIL, resp);
|
INITSTRUCT(sP_FE2CL_PC_GROUP_INVITE_FAIL, resp);
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_PC_GROUP_JOIN_FAIL, sizeof(sP_FE2CL_PC_GROUP_JOIN_FAIL));
|
sock->sendPacket((void*)&resp, P_FE2CL_PC_GROUP_JOIN_FAIL, sizeof(sP_FE2CL_PC_GROUP_JOIN_FAIL));
|
||||||
@ -105,6 +106,8 @@ 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;
|
||||||
@ -120,10 +123,13 @@ void GroupManager::joinGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
resp->iID_NewMember = plr->iID;
|
resp->iID_NewMember = plr->iID;
|
||||||
resp->iMemberPCCnt = otherPlr->groupCnt;
|
resp->iMemberPCCnt = otherPlr->groupCnt;
|
||||||
|
|
||||||
|
int bitFlag = getGroupFlags(otherPlr);
|
||||||
|
|
||||||
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]);
|
||||||
|
|
||||||
if (varPlr == nullptr)
|
if (varPlr == nullptr || sockTo == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
respdata[i].iPC_ID = varPlr->iID;
|
respdata[i].iPC_ID = varPlr->iID;
|
||||||
@ -141,6 +147,8 @@ void GroupManager::joinGroup(CNSocket* sock, CNPacketData* data) {
|
|||||||
respdata[i].iY = varPlr->y;
|
respdata[i].iY = varPlr->y;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendToGroup(otherPlr, (void*)&respbuf, P_FE2CL_PC_GROUP_JOIN, resplen);
|
sendToGroup(otherPlr, (void*)&respbuf, P_FE2CL_PC_GROUP_JOIN, resplen);
|
||||||
@ -258,6 +266,7 @@ void GroupManager::groupTickInfo(Player* plr) {
|
|||||||
void GroupManager::groupKickPlayer(Player* plr) {
|
void GroupManager::groupKickPlayer(Player* plr) {
|
||||||
// if you are the group leader, destroy your own group and kick everybody
|
// if you are the group leader, destroy your own group and kick everybody
|
||||||
if (plr->iID == plr->iIDGroup) {
|
if (plr->iID == plr->iIDGroup) {
|
||||||
|
groupUnbuff(plr);
|
||||||
INITSTRUCT(sP_FE2CL_PC_GROUP_LEAVE_SUCC, resp1);
|
INITSTRUCT(sP_FE2CL_PC_GROUP_LEAVE_SUCC, resp1);
|
||||||
sendToGroup(plr, (void*)&resp1, P_FE2CL_PC_GROUP_LEAVE_SUCC, sizeof(sP_FE2CL_PC_GROUP_LEAVE_SUCC));
|
sendToGroup(plr, (void*)&resp1, P_FE2CL_PC_GROUP_LEAVE_SUCC, sizeof(sP_FE2CL_PC_GROUP_LEAVE_SUCC));
|
||||||
plr->groupCnt = 1;
|
plr->groupCnt = 1;
|
||||||
@ -285,12 +294,15 @@ 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 = bitFlagBefore & ~plr->iGroupConditionBitFlag;
|
||||||
int moveDown = 0;
|
int moveDown = 0;
|
||||||
|
|
||||||
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]);
|
||||||
|
|
||||||
if (varPlr == nullptr)
|
if (varPlr == nullptr || sockTo == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (moveDown == 1)
|
if (moveDown == 1)
|
||||||
@ -315,7 +327,9 @@ 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
|
||||||
|
NanoManager::nanoChangeBuff(sockTo, varPlr, bitFlagBefore | varPlr->iConditionBitFlag, bitFlag | varPlr->iConditionBitFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
plr->iIDGroup = plr->iID;
|
plr->iIDGroup = plr->iID;
|
||||||
@ -331,3 +345,32 @@ void GroupManager::groupKickPlayer(Player* plr) {
|
|||||||
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) {
|
||||||
|
int bitFlag = getGroupFlags(plr);
|
||||||
|
|
||||||
|
for (int i = 0; i < plr->groupCnt; i++) {
|
||||||
|
CNSocket* sock = PlayerManager::getSockFromID(plr->groupIDs[i]);
|
||||||
|
|
||||||
|
if (sock == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Player* otherPlr = PlayerManager::getPlayer(sock);
|
||||||
|
NanoManager::nanoChangeBuff(sock, otherPlr, bitFlag | otherPlr->iConditionBitFlag, otherPlr->iConditionBitFlag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GroupManager::getGroupFlags(Player* plr) {
|
||||||
|
int bitFlag = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < plr->groupCnt; i++) {
|
||||||
|
Player* otherPlr = PlayerManager::getPlayerFromID(plr->groupIDs[i]);
|
||||||
|
|
||||||
|
if (otherPlr == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bitFlag |= otherPlr->iGroupConditionBitFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitFlag;
|
||||||
|
}
|
@ -20,4 +20,6 @@ namespace GroupManager {
|
|||||||
void sendToGroup(Player* plr, void* buf, uint32_t type, size_t size);
|
void sendToGroup(Player* plr, void* buf, uint32_t type, size_t size);
|
||||||
void groupTickInfo(Player* plr);
|
void groupTickInfo(Player* plr);
|
||||||
void groupKickPlayer(Player* plr);
|
void groupKickPlayer(Player* plr);
|
||||||
|
void groupUnbuff(Player* plr);
|
||||||
|
int getGroupFlags(Player* plr);
|
||||||
}
|
}
|
||||||
|
@ -75,9 +75,16 @@ void MobManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
|
|||||||
std::pair<int,int> damage;
|
std::pair<int,int> damage;
|
||||||
|
|
||||||
if (pkt->iNPCCnt > 1)
|
if (pkt->iNPCCnt > 1)
|
||||||
damage = getDamage(plr->groupDamage, (int)mob->data["m_iProtection"], true, (int)mob->data["m_iNpcLevel"]);
|
damage.first = plr->groupDamage;
|
||||||
else
|
else
|
||||||
damage = getDamage(plr->pointDamage, (int)mob->data["m_iProtection"], true, (int)mob->data["m_iNpcLevel"]);
|
damage.first = plr->pointDamage;
|
||||||
|
|
||||||
|
int difficulty = (int)mob->data["m_iNpcLevel"];
|
||||||
|
|
||||||
|
damage = getDamage(damage.first, (int)mob->data["m_iProtection"], true, (plr->batteryW >= 11 + difficulty), NanoManager::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);
|
||||||
|
|
||||||
|
if (plr->batteryW >= 11 + difficulty)
|
||||||
|
plr->batteryW -= 11 + difficulty;
|
||||||
|
|
||||||
damage.first = hitMob(sock, mob, damage.first);
|
damage.first = hitMob(sock, mob, damage.first);
|
||||||
|
|
||||||
@ -114,7 +121,7 @@ void MobManager::npcAttackPc(Mob *mob, time_t currTime) {
|
|||||||
sP_FE2CL_NPC_ATTACK_PCs *pkt = (sP_FE2CL_NPC_ATTACK_PCs*)respbuf;
|
sP_FE2CL_NPC_ATTACK_PCs *pkt = (sP_FE2CL_NPC_ATTACK_PCs*)respbuf;
|
||||||
sAttackResult *atk = (sAttackResult*)(respbuf + sizeof(sP_FE2CL_NPC_ATTACK_PCs));
|
sAttackResult *atk = (sAttackResult*)(respbuf + sizeof(sP_FE2CL_NPC_ATTACK_PCs));
|
||||||
|
|
||||||
auto damage = getDamage(470 + (int)mob->data["m_iPower"], plr->defense, false, 1);
|
auto damage = getDamage(475 + (int)mob->data["m_iPower"], plr->defense, false, false, -1, -1, 1);
|
||||||
plr->HP -= damage.first;
|
plr->HP -= damage.first;
|
||||||
|
|
||||||
pkt->iNPC_ID = mob->appearanceData.iNPC_ID;
|
pkt->iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
@ -224,8 +231,26 @@ void MobManager::killMob(CNSocket *sock, Mob *mob) {
|
|||||||
|
|
||||||
// check for the edge case where hitting the mob did not aggro it
|
// check for the edge case where hitting the mob did not aggro it
|
||||||
if (sock != nullptr) {
|
if (sock != nullptr) {
|
||||||
giveReward(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
MissionManager::mobKilled(sock, mob->appearanceData.iNPCType);
|
|
||||||
|
if (plr == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (plr->groupCnt == 1 && plr->iIDGroup == plr->iID) {
|
||||||
|
giveReward(sock);
|
||||||
|
MissionManager::mobKilled(sock, mob->appearanceData.iNPCType);
|
||||||
|
} else {
|
||||||
|
plr = PlayerManager::getPlayerFromID(plr->iIDGroup);
|
||||||
|
|
||||||
|
if (plr == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < plr->groupCnt; i++) {
|
||||||
|
CNSocket* sockTo = PlayerManager::getSockFromID(plr->groupIDs[i]);
|
||||||
|
giveReward(sockTo);
|
||||||
|
MissionManager::mobKilled(sockTo, mob->appearanceData.iNPCType);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mob->despawned = false;
|
mob->despawned = false;
|
||||||
@ -676,12 +701,26 @@ void MobManager::playerTick(CNServer *serv, time_t currTime) {
|
|||||||
lastHealTime = currTime;
|
lastHealTime = currTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<int,int> MobManager::getDamage(int attackPower, int defensePower, bool shouldCrit, int crutchLevel) {
|
std::pair<int,int> MobManager::getDamage(int attackPower, int defensePower, bool shouldCrit, bool batteryBoost, int attackerStyle, int defenderStyle, int difficulty) {
|
||||||
|
std::pair<int,int> ret = {0, 1};
|
||||||
|
if (attackPower + defensePower * 2 == 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
std::pair<int,int> ret = {};
|
int damage = attackPower * attackPower / (attackPower + defensePower);
|
||||||
|
damage = std::max(std::max(29, attackPower / 7), damage - defensePower * (12 + difficulty) / 65);
|
||||||
|
damage = damage * (rand() % 40 + 80) / 100;
|
||||||
|
|
||||||
int damage = (std::max(40, attackPower - defensePower) * (34 + crutchLevel) + std::min(attackPower, attackPower * attackPower / defensePower) * (36 - crutchLevel)) / 70;
|
if (attackerStyle != -1 && defenderStyle != -1 && attackerStyle != defenderStyle) {
|
||||||
ret.first = damage * (rand() % 40 + 80) / 100; // 20% variance
|
if (attackerStyle < defenderStyle || attackerStyle - defenderStyle == 2)
|
||||||
|
damage = damage * 5 / 4;
|
||||||
|
else
|
||||||
|
damage = damage * 4 / 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (batteryBoost)
|
||||||
|
damage = damage * 5 / 4;
|
||||||
|
|
||||||
|
ret.first = damage;
|
||||||
ret.second = 1;
|
ret.second = 1;
|
||||||
|
|
||||||
if (shouldCrit && rand() % 20 == 0) {
|
if (shouldCrit && rand() % 20 == 0) {
|
||||||
@ -743,9 +782,14 @@ void MobManager::pcAttackChars(CNSocket *sock, CNPacketData *data) {
|
|||||||
std::pair<int,int> damage;
|
std::pair<int,int> damage;
|
||||||
|
|
||||||
if (pkt->iTargetCnt > 1)
|
if (pkt->iTargetCnt > 1)
|
||||||
damage = getDamage(plr->groupDamage, target->defense, true, 1);
|
damage.first = plr->groupDamage;
|
||||||
else
|
else
|
||||||
damage = getDamage(plr->pointDamage, target->defense, true, 1);
|
damage.first = plr->pointDamage;
|
||||||
|
|
||||||
|
damage = getDamage(damage.first, target->defense, true, (plr->batteryW >= 12), -1, -1, 1);
|
||||||
|
|
||||||
|
if (plr->batteryW >= 12)
|
||||||
|
plr->batteryW -= 12;
|
||||||
|
|
||||||
target->HP -= damage.first;
|
target->HP -= damage.first;
|
||||||
|
|
||||||
@ -765,9 +809,16 @@ void MobManager::pcAttackChars(CNSocket *sock, CNPacketData *data) {
|
|||||||
std::pair<int,int> damage;
|
std::pair<int,int> damage;
|
||||||
|
|
||||||
if (pkt->iTargetCnt > 1)
|
if (pkt->iTargetCnt > 1)
|
||||||
damage = getDamage(plr->groupDamage, (int)mob->data["m_iProtection"], true, (int)mob->data["m_iNpcLevel"]);
|
damage.first = plr->groupDamage;
|
||||||
else
|
else
|
||||||
damage = getDamage(plr->pointDamage, (int)mob->data["m_iProtection"], true, (int)mob->data["m_iNpcLevel"]);
|
damage.first = plr->pointDamage;
|
||||||
|
|
||||||
|
int difficulty = (int)mob->data["m_iNpcLevel"];
|
||||||
|
|
||||||
|
damage = getDamage(damage.first, (int)mob->data["m_iProtection"], true, (plr->batteryW >= 11 + difficulty), NanoManager::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);
|
||||||
|
|
||||||
|
if (plr->batteryW >= 11 + difficulty)
|
||||||
|
plr->batteryW -= 11 + difficulty;
|
||||||
|
|
||||||
damage.first = hitMob(sock, mob, damage.first);
|
damage.first = hitMob(sock, mob, damage.first);
|
||||||
|
|
||||||
@ -782,7 +833,7 @@ void MobManager::pcAttackChars(CNSocket *sock, CNPacketData *data) {
|
|||||||
sock->sendPacket((void*)respbuf, P_FE2CL_PC_ATTACK_CHARs_SUCC, resplen);
|
sock->sendPacket((void*)respbuf, P_FE2CL_PC_ATTACK_CHARs_SUCC, resplen);
|
||||||
|
|
||||||
// a bit of a hack: these are the same size, so we can reuse the response packet
|
// a bit of a hack: these are the same size, so we can reuse the response packet
|
||||||
assert(sizeof(sP_FE2CL_PC_ATTACK_NPCs_SUCC) == sizeof(sP_FE2CL_PC_ATTACK_CHARs));
|
assert(sizeof(sP_FE2CL_PC_ATTACK_CHARs_SUCC) == sizeof(sP_FE2CL_PC_ATTACK_CHARs));
|
||||||
sP_FE2CL_PC_ATTACK_CHARs *resp1 = (sP_FE2CL_PC_ATTACK_CHARs*)respbuf;
|
sP_FE2CL_PC_ATTACK_CHARs *resp1 = (sP_FE2CL_PC_ATTACK_CHARs*)respbuf;
|
||||||
|
|
||||||
resp1->iPC_ID = plr->iID;
|
resp1->iPC_ID = plr->iID;
|
||||||
|
@ -107,7 +107,7 @@ namespace MobManager {
|
|||||||
void killMob(CNSocket *sock, Mob *mob);
|
void killMob(CNSocket *sock, Mob *mob);
|
||||||
void giveReward(CNSocket *sock);
|
void giveReward(CNSocket *sock);
|
||||||
std::pair<int,int> lerp(int, int, int, int, int);
|
std::pair<int,int> lerp(int, int, int, int, int);
|
||||||
std::pair<int,int> getDamage(int, int, bool, int);
|
std::pair<int,int> getDamage(int, int, bool, bool, int, int, int);
|
||||||
|
|
||||||
void pcAttackChars(CNSocket *sock, CNPacketData *data);
|
void pcAttackChars(CNSocket *sock, CNPacketData *data);
|
||||||
void resendMobHP(Mob *mob);
|
void resendMobHP(Mob *mob);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "NPCManager.hpp"
|
#include "NPCManager.hpp"
|
||||||
#include "MobManager.hpp"
|
#include "MobManager.hpp"
|
||||||
#include "MissionManager.hpp"
|
#include "MissionManager.hpp"
|
||||||
|
#include "GroupManager.hpp"
|
||||||
|
|
||||||
namespace NanoManager {
|
namespace NanoManager {
|
||||||
|
|
||||||
@ -685,26 +686,29 @@ std::vector<ActivePower> ActivePowers = {
|
|||||||
#pragma region Passive Powers
|
#pragma region Passive Powers
|
||||||
void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t eSkillType, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue, bool groupPower) {
|
void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t eSkillType, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue, bool groupPower) {
|
||||||
Player *plr = PlayerManager::getPlayer(sock);
|
Player *plr = PlayerManager::getPlayer(sock);
|
||||||
Player *leader;
|
|
||||||
|
|
||||||
if (plr == nullptr)
|
if (plr == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (plr->iID == plr->iIDGroup)
|
int pktCnt = 1;
|
||||||
leader = plr;
|
Player *leader = plr;
|
||||||
else
|
plr->iConditionBitFlag |= iCBFlag;
|
||||||
leader = PlayerManager::getPlayerFromID(plr->iIDGroup);
|
|
||||||
|
if (groupPower) {
|
||||||
|
plr->iGroupConditionBitFlag |= iCBFlag;
|
||||||
|
|
||||||
|
if (plr->iID != plr->iIDGroup)
|
||||||
|
leader = PlayerManager::getPlayerFromID(plr->iIDGroup);
|
||||||
|
|
||||||
|
if (leader == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pktCnt = leader->groupCnt;
|
||||||
|
}
|
||||||
|
|
||||||
if (leader == nullptr)
|
if (leader == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int pktCnt = 1;
|
|
||||||
|
|
||||||
if (groupPower)
|
|
||||||
pktCnt = leader->groupCnt;
|
|
||||||
else
|
|
||||||
leader = plr;
|
|
||||||
|
|
||||||
if (!validOutVarPacket(sizeof(sP_FE2CL_NANO_SKILL_USE), pktCnt, sizeof(sSkillResult_Buff))) {
|
if (!validOutVarPacket(sizeof(sP_FE2CL_NANO_SKILL_USE), pktCnt, sizeof(sSkillResult_Buff))) {
|
||||||
std::cout << "[WARN] bad sP_FE2CL_NANO_SKILL_USE packet size\n";
|
std::cout << "[WARN] bad sP_FE2CL_NANO_SKILL_USE packet size\n";
|
||||||
return;
|
return;
|
||||||
@ -725,6 +729,8 @@ void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t
|
|||||||
resp->eST = eSkillType;
|
resp->eST = eSkillType;
|
||||||
resp->iTargetCnt = pktCnt;
|
resp->iTargetCnt = pktCnt;
|
||||||
|
|
||||||
|
int bitFlag = GroupManager::getGroupFlags(leader);
|
||||||
|
|
||||||
for (int i = 0; i < pktCnt; i++) {
|
for (int i = 0; i < pktCnt; i++) {
|
||||||
Player* varPlr;
|
Player* varPlr;
|
||||||
CNSocket* sockTo;
|
CNSocket* sockTo;
|
||||||
@ -738,21 +744,17 @@ void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (varPlr == nullptr || sockTo == nullptr)
|
if (varPlr == nullptr || sockTo == nullptr)
|
||||||
return;
|
continue;
|
||||||
|
|
||||||
if (!(varPlr->iConditionBitFlag & iCBFlag))
|
|
||||||
varPlr->iConditionBitFlag ^= iCBFlag;
|
|
||||||
|
|
||||||
respdata[i].eCT = 1;
|
respdata[i].eCT = 1;
|
||||||
respdata[i].iID = varPlr->iID;
|
respdata[i].iID = varPlr->iID;
|
||||||
respdata[i].iConditionBitFlag = iCBFlag;
|
respdata[i].iConditionBitFlag = iCBFlag;
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, pkt1);
|
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, pkt1);
|
||||||
|
|
||||||
pkt1.eCSTB = eCharStatusTimeBuffID; //eCharStatusTimeBuffID
|
pkt1.eCSTB = eCharStatusTimeBuffID; //eCharStatusTimeBuffID
|
||||||
pkt1.eTBU = 1; //eTimeBuffUpdate
|
pkt1.eTBU = 1; //eTimeBuffUpdate
|
||||||
pkt1.eTBT = 1; //eTimeBuffType 1 means nano
|
pkt1.eTBT = 1; //eTimeBuffType 1 means nano
|
||||||
pkt1.iConditionBitFlag = varPlr->iConditionBitFlag;
|
pkt1.iConditionBitFlag = bitFlag | varPlr->iConditionBitFlag;
|
||||||
|
|
||||||
if (iValue > 0)
|
if (iValue > 0)
|
||||||
pkt1.TimeBuff.iValue = iValue;
|
pkt1.TimeBuff.iValue = iValue;
|
||||||
@ -765,28 +767,28 @@ void NanoManager::nanoBuff(CNSocket* sock, int16_t nanoId, int skillId, int16_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue, bool groupPower) {
|
void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatusTimeBuffID, int16_t iValue, bool groupPower) {
|
||||||
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, resp1);
|
|
||||||
|
|
||||||
Player *plr = PlayerManager::getPlayer(sock);
|
Player *plr = PlayerManager::getPlayer(sock);
|
||||||
Player *leader;
|
|
||||||
|
|
||||||
if (plr == nullptr)
|
if (plr == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (plr->iID == plr->iIDGroup)
|
|
||||||
leader = plr;
|
|
||||||
else
|
|
||||||
leader = PlayerManager::getPlayerFromID(plr->iIDGroup);
|
|
||||||
|
|
||||||
if (leader == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int pktCnt = 1;
|
int pktCnt = 1;
|
||||||
|
Player *leader = plr;
|
||||||
|
plr->iConditionBitFlag &= ~iCBFlag;
|
||||||
|
|
||||||
|
if (groupPower) {
|
||||||
|
plr->iGroupConditionBitFlag &= ~iCBFlag;
|
||||||
|
|
||||||
|
if (plr->iID != plr->iIDGroup)
|
||||||
|
leader = PlayerManager::getPlayerFromID(plr->iIDGroup);
|
||||||
|
|
||||||
|
if (leader == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
if (groupPower)
|
|
||||||
pktCnt = leader->groupCnt;
|
pktCnt = leader->groupCnt;
|
||||||
else
|
}
|
||||||
leader = plr;
|
|
||||||
|
int bitFlag = GroupManager::getGroupFlags(leader);
|
||||||
|
|
||||||
for (int i = 0; i < pktCnt; i++) {
|
for (int i = 0; i < pktCnt; i++) {
|
||||||
Player* varPlr;
|
Player* varPlr;
|
||||||
@ -800,13 +802,11 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatu
|
|||||||
sockTo = PlayerManager::getSockFromID(leader->groupIDs[i]);
|
sockTo = PlayerManager::getSockFromID(leader->groupIDs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varPlr->iConditionBitFlag & iCBFlag)
|
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, resp1);
|
||||||
varPlr->iConditionBitFlag ^= iCBFlag;
|
|
||||||
|
|
||||||
resp1.eCSTB = eCharStatusTimeBuffID; //eCharStatusTimeBuffID
|
resp1.eCSTB = eCharStatusTimeBuffID; //eCharStatusTimeBuffID
|
||||||
resp1.eTBU = 2; //eTimeBuffUpdate
|
resp1.eTBU = 2; //eTimeBuffUpdate
|
||||||
resp1.eTBT = 1; //eTimeBuffType 1 means nano
|
resp1.eTBT = 1; //eTimeBuffType 1 means nano
|
||||||
resp1.iConditionBitFlag = varPlr->iConditionBitFlag;
|
resp1.iConditionBitFlag = bitFlag | varPlr->iConditionBitFlag;
|
||||||
|
|
||||||
if (iValue > 0)
|
if (iValue > 0)
|
||||||
resp1.TimeBuff.iValue = iValue;
|
resp1.TimeBuff.iValue = iValue;
|
||||||
@ -817,7 +817,7 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int32_t iCBFlag, int16_t eCharStatu
|
|||||||
|
|
||||||
// 0=A 1=B 2=C -1=Not found
|
// 0=A 1=B 2=C -1=Not found
|
||||||
int NanoManager::nanoStyle(int nanoId) {
|
int NanoManager::nanoStyle(int nanoId) {
|
||||||
if (nanoId < 0 || nanoId >= (int)NanoTable.size())
|
if (nanoId < 1 || nanoId >= (int)NanoTable.size())
|
||||||
return -1;
|
return -1;
|
||||||
return NanoTable[nanoId].style;
|
return NanoTable[nanoId].style;
|
||||||
}
|
}
|
||||||
@ -854,11 +854,12 @@ void NanoManager::revivePlayer(Player* plr) {
|
|||||||
|
|
||||||
// Nanos
|
// Nanos
|
||||||
int activeSlot = -1;
|
int activeSlot = -1;
|
||||||
for (int n = 0; n < 3; n++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
int nanoID = plr->equippedNanos[n];
|
int nanoID = plr->equippedNanos[i];
|
||||||
if (plr->activeNano == nanoID) {
|
if (plr->activeNano == nanoID) {
|
||||||
activeSlot = n;
|
activeSlot = i;
|
||||||
}
|
}
|
||||||
|
response.PCRegenData.Nanos[i] = plr->Nanos[nanoID];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Response parameters
|
// Response parameters
|
||||||
@ -884,4 +885,43 @@ void NanoManager::revivePlayer(Player* plr) {
|
|||||||
|
|
||||||
PlayerManager::sendToViewable(sock, (void*)&resp2, P_FE2CL_PC_REGEN, sizeof(sP_FE2CL_PC_REGEN));
|
PlayerManager::sendToViewable(sock, (void*)&resp2, P_FE2CL_PC_REGEN, sizeof(sP_FE2CL_PC_REGEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NanoManager::nanoChangeBuff(CNSocket* sock, Player* plr, int32_t cbFrom, int32_t cbTo) {
|
||||||
|
bool sentPacket = false;
|
||||||
|
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, resp);
|
||||||
|
resp.eTBU = 3;
|
||||||
|
resp.eTBT = 1;
|
||||||
|
resp.iConditionBitFlag = cbTo;
|
||||||
|
|
||||||
|
if (!(cbFrom & CSB_BIT_UP_MOVE_SPEED) && (cbTo & CSB_BIT_UP_MOVE_SPEED)) {
|
||||||
|
resp.eCSTB = ECSB_UP_MOVE_SPEED;
|
||||||
|
resp.eTBU = 1;
|
||||||
|
resp.TimeBuff.iValue = 200;
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
|
sentPacket = true;
|
||||||
|
} else if ((cbFrom & CSB_BIT_UP_MOVE_SPEED) && !(cbTo & CSB_BIT_UP_MOVE_SPEED)) {
|
||||||
|
resp.eCSTB = ECSB_UP_MOVE_SPEED;
|
||||||
|
resp.eTBU = 2;
|
||||||
|
resp.TimeBuff.iValue = 200;
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
|
sentPacket = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cbFrom & CSB_BIT_UP_JUMP_HEIGHT) && (cbTo & CSB_BIT_UP_JUMP_HEIGHT)) {
|
||||||
|
resp.eCSTB = ECSB_UP_JUMP_HEIGHT;
|
||||||
|
resp.eTBU = 1;
|
||||||
|
resp.TimeBuff.iValue = 400;
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
|
sentPacket = true;
|
||||||
|
} else if ((cbFrom & CSB_BIT_UP_JUMP_HEIGHT) && !(cbTo & CSB_BIT_UP_JUMP_HEIGHT)) {
|
||||||
|
resp.eCSTB = ECSB_UP_JUMP_HEIGHT;
|
||||||
|
resp.eTBU = 2;
|
||||||
|
resp.TimeBuff.iValue = 400;
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
|
sentPacket = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sentPacket)
|
||||||
|
sock->sendPacket((void*)&resp, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
@ -66,4 +66,5 @@ namespace NanoManager {
|
|||||||
|
|
||||||
int nanoStyle(int nanoId);
|
int nanoStyle(int nanoId);
|
||||||
void revivePlayer(Player* plr);
|
void revivePlayer(Player* plr);
|
||||||
|
void nanoChangeBuff(CNSocket* sock, Player* plr, int32_t cbFrom, int32_t cbTo);
|
||||||
}
|
}
|
||||||
|
@ -64,4 +64,5 @@ struct Player {
|
|||||||
int32_t iIDGroup;
|
int32_t iIDGroup;
|
||||||
int groupCnt;
|
int groupCnt;
|
||||||
int32_t groupIDs[4];
|
int32_t groupIDs[4];
|
||||||
|
int32_t iGroupConditionBitFlag;
|
||||||
};
|
};
|
||||||
|
@ -765,11 +765,9 @@ void PlayerManager::revivePlayer(CNSocket* sock, CNPacketData* data) {
|
|||||||
int nanoID = plr->equippedNanos[i];
|
int nanoID = plr->equippedNanos[i];
|
||||||
|
|
||||||
// halve nano health if respawning
|
// halve nano health if respawning
|
||||||
if (reviveData->iRegenType != 5) {
|
if (reviveData->iRegenType != 5)
|
||||||
plr->Nanos[nanoID].iStamina = 75; // max is 150, so 75 is half
|
plr->Nanos[nanoID].iStamina = 75; // max is 150, so 75 is half
|
||||||
response.PCRegenData.Nanos[i] = plr->Nanos[nanoID];
|
response.PCRegenData.Nanos[i] = plr->Nanos[nanoID];
|
||||||
}
|
|
||||||
|
|
||||||
if (plr->activeNano == nanoID)
|
if (plr->activeNano == nanoID)
|
||||||
activeSlot = i;
|
activeSlot = i;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user