mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-26 06:50:06 +00:00
Adapted Egg Buffing to Nano powers
* Adapted eggs to nano power data. * Tweaked nano abilities.
This commit is contained in:
parent
fe7ec44554
commit
f7c0596a4c
@ -847,7 +847,7 @@ void MobManager::dotDamageOnOff(CNSocket *sock, CNPacketData *data) {
|
|||||||
pkt1.eCSTB = ECSB_INFECTION; // eCharStatusTimeBuffID
|
pkt1.eCSTB = ECSB_INFECTION; // eCharStatusTimeBuffID
|
||||||
pkt1.eTBU = 1; // eTimeBuffUpdate
|
pkt1.eTBU = 1; // eTimeBuffUpdate
|
||||||
pkt1.eTBT = 0; // eTimeBuffType 1 means nano
|
pkt1.eTBT = 0; // eTimeBuffType 1 means nano
|
||||||
pkt1.iConditionBitFlag = plr->iConditionBitFlag | plr->iGroupConditionBitFlag | plr->iEggConditionBitFlag;
|
pkt1.iConditionBitFlag = plr->iConditionBitFlag;
|
||||||
|
|
||||||
sock->sendPacket((void*)&pkt1, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
sock->sendPacket((void*)&pkt1, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
}
|
}
|
||||||
@ -895,7 +895,7 @@ void MobManager::dealGooDamage(CNSocket *sock, int amount) {
|
|||||||
dmg->iID = plr->iID;
|
dmg->iID = plr->iID;
|
||||||
dmg->iDamage = amount;
|
dmg->iDamage = amount;
|
||||||
dmg->iHP = plr->HP;
|
dmg->iHP = plr->HP;
|
||||||
dmg->iConditionBitFlag = plr->iConditionBitFlag | plr->iGroupConditionBitFlag | plr->iEggConditionBitFlag;
|
dmg->iConditionBitFlag = plr->iConditionBitFlag;
|
||||||
|
|
||||||
sock->sendPacket((void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
|
sock->sendPacket((void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
|
||||||
PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
|
PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "NanoManager.hpp"
|
#include "NanoManager.hpp"
|
||||||
#include "TableData.hpp"
|
#include "TableData.hpp"
|
||||||
#include "ChatManager.hpp"
|
#include "ChatManager.hpp"
|
||||||
|
#include "GroupManager.hpp"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -570,93 +571,48 @@ BaseNPC* NPCManager::getNearestNPC(std::set<Chunk*>* chunks, int X, int Y, int Z
|
|||||||
return npc;
|
return npc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NPCManager::eggBuffPlayer(CNSocket* sock, int skillId, int duration) {
|
int NPCManager::eggBuffPlayer(CNSocket* sock, int skillId, int eggId) {
|
||||||
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
Player* otherPlr = PlayerManager::getPlayerFromID(plr->iIDGroup);
|
||||||
|
|
||||||
int32_t CBFlag = -1, iValue = 0, CSTB, EST;
|
if (otherPlr == nullptr)
|
||||||
|
|
||||||
// damage and heal have to be set by hand
|
|
||||||
if (skillId == 183) {
|
|
||||||
// damage
|
|
||||||
CBFlag = CSB_BIT_INFECTION;
|
|
||||||
CSTB = ECSB_INFECTION;
|
|
||||||
EST = EST_INFECTIONDAMAGE;
|
|
||||||
}
|
|
||||||
else if (skillId == 150) {
|
|
||||||
// heal
|
|
||||||
CBFlag = CSB_BIT_HEAL;
|
|
||||||
CSTB = ECSB_HEAL;
|
|
||||||
EST = EST_HEAL_HP;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// find the right passive power data
|
|
||||||
for (auto& pwr : NanoManager::PassivePowers)
|
|
||||||
if (pwr.powers.count(skillId)) {
|
|
||||||
CBFlag = pwr.iCBFlag;
|
|
||||||
CSTB = pwr.eCharStatusTimeBuffID;
|
|
||||||
EST = pwr.eSkillType;
|
|
||||||
iValue = pwr.iValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CBFlag < 0)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
std::pair<CNSocket*, int32_t> key = std::make_pair(sock, CBFlag);
|
std::pair<CNSocket*, int32_t> key = std::make_pair(sock, skillId);
|
||||||
|
int bitFlag = GroupManager::getGroupFlags(otherPlr);
|
||||||
|
|
||||||
// if player doesn't have this buff yet
|
|
||||||
if (EggBuffs.find(key) == EggBuffs.end())
|
if (EggBuffs.find(key) == EggBuffs.end())
|
||||||
{
|
if (!NanoManager::applyBuff(sock, skillId, 1, 3, bitFlag, true))
|
||||||
// save new cbflag serverside
|
return -1;
|
||||||
plr->iEggConditionBitFlag |= CBFlag;
|
|
||||||
|
|
||||||
// send buff update package
|
|
||||||
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, updatePacket);
|
|
||||||
updatePacket.eCSTB = CSTB; // eCharStatusTimeBuffID
|
|
||||||
updatePacket.eTBU = 1; // eTimeBuffUpdate 1 means Add
|
|
||||||
updatePacket.eTBT = 3; // eTimeBuffType 3 means egg
|
|
||||||
updatePacket.TimeBuff.iValue = iValue;
|
|
||||||
int32_t updatedFlag = plr->iConditionBitFlag | plr->iGroupConditionBitFlag | plr->iEggConditionBitFlag;
|
|
||||||
updatePacket.iConditionBitFlag = updatedFlag;
|
|
||||||
|
|
||||||
sock->sendPacket((void*)&updatePacket, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// save the buff serverside;
|
// save the buff serverside;
|
||||||
// if you get the same buff again, new duration will override the previous one
|
// if you get the same buff again, new duration will override the previous one
|
||||||
time_t until = getTime() + (time_t)duration * 1000;
|
time_t until = getTime() + (time_t)NanoManager::SkillTable[skillId].durationTime[0] * 10;
|
||||||
EggBuffs[key] = until;
|
EggBuffs[key] = until;
|
||||||
|
|
||||||
/*
|
const size_t resplen = sizeof(sP_FE2CL_NPC_SKILL_HIT) + sizeof(sSkillResult_Buff);
|
||||||
* to give player a visual effect (eg. blue particles for run or wings for jump)
|
|
||||||
* we have to send him NANO_SKILL_USE packet with nano Id set to 0
|
|
||||||
* yes, this is utterly stupid and disgusting
|
|
||||||
*/
|
|
||||||
|
|
||||||
const size_t resplen = sizeof(sP_FE2CL_NANO_SKILL_USE) + sizeof(sSkillResult_Buff);
|
|
||||||
assert(resplen < CN_PACKET_BUFFER_SIZE - 8);
|
assert(resplen < CN_PACKET_BUFFER_SIZE - 8);
|
||||||
// we know it's only one trailing struct, so we can skip full validation
|
// we know it's only one trailing struct, so we can skip full validation
|
||||||
|
|
||||||
uint8_t respbuf[resplen]; // not a variable length array, don't worry
|
uint8_t respbuf[resplen]; // not a variable length array, don't worry
|
||||||
sP_FE2CL_NANO_SKILL_USE* skillUse = (sP_FE2CL_NANO_SKILL_USE*)respbuf;
|
sP_FE2CL_NPC_SKILL_HIT* skillUse = (sP_FE2CL_NPC_SKILL_HIT*)respbuf;
|
||||||
sSkillResult_Buff* skill = (sSkillResult_Buff*)(respbuf + sizeof(sP_FE2CL_NANO_SKILL_USE));
|
sSkillResult_Buff* skill = (sSkillResult_Buff*)(respbuf + sizeof(sP_FE2CL_NPC_SKILL_HIT));
|
||||||
|
|
||||||
memset(respbuf, 0, resplen);
|
memset(respbuf, 0, resplen);
|
||||||
|
skillUse->iNPC_ID = eggId;
|
||||||
skillUse->iPC_ID = plr->iID;
|
|
||||||
skillUse->iSkillID = skillId;
|
skillUse->iSkillID = skillId;
|
||||||
skillUse->iNanoID = plr->activeNano;
|
if (skillId == 183) // The only exception
|
||||||
skillUse->iNanoStamina = plr->activeNano < 1 ? 0 : plr->Nanos[plr->activeNano].iStamina;
|
skillUse->eST = EST_INFECTIONDAMAGE;
|
||||||
skillUse->eST = EST;
|
else
|
||||||
|
skillUse->eST = NanoManager::SkillTable[skillId].skillType;
|
||||||
skillUse->iTargetCnt = 1;
|
skillUse->iTargetCnt = 1;
|
||||||
|
|
||||||
skill->eCT = 1;
|
skill->eCT = 1;
|
||||||
skill->iID = plr->iID;
|
skill->iID = plr->iID;
|
||||||
skill->iConditionBitFlag = plr->iConditionBitFlag | plr->iGroupConditionBitFlag | plr->iEggConditionBitFlag;
|
skill->iConditionBitFlag = plr->iConditionBitFlag;
|
||||||
|
|
||||||
sock->sendPacket((void*)&respbuf, P_FE2CL_NANO_SKILL_USE_SUCC, resplen);
|
sock->sendPacket((void*)&respbuf, P_FE2CL_NPC_SKILL_HIT, resplen);
|
||||||
PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen);
|
PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_NPC_SKILL_HIT, resplen);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -673,44 +629,15 @@ void NPCManager::eggStep(CNServer* serv, time_t currTime) {
|
|||||||
// if time reached 0
|
// if time reached 0
|
||||||
else {
|
else {
|
||||||
CNSocket* sock = it->first.first;
|
CNSocket* sock = it->first.first;
|
||||||
|
int32_t skillId = it->first.second;
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
Player* otherPlr = PlayerManager::getPlayerFromID(plr->iIDGroup);
|
||||||
|
|
||||||
// if player is still on the server
|
if (otherPlr == nullptr)
|
||||||
if (plr != nullptr) {
|
return;
|
||||||
|
|
||||||
int32_t CBFlag = it->first.second;
|
int bitFlag = GroupManager::getGroupFlags(otherPlr);
|
||||||
int32_t CSTB = -1, iValue = 0;
|
NanoManager::applyBuff(sock, skillId, 2, 3, bitFlag);
|
||||||
|
|
||||||
// find CSTB Value
|
|
||||||
if (CBFlag == CSB_BIT_INFECTION)
|
|
||||||
CSTB = ECSB_INFECTION;
|
|
||||||
|
|
||||||
else if (CBFlag == CSB_BIT_HEAL)
|
|
||||||
CSTB = ECSB_HEAL;
|
|
||||||
|
|
||||||
else {
|
|
||||||
for (auto pwr : NanoManager::PassivePowers) {
|
|
||||||
if (pwr.iCBFlag == CBFlag) {
|
|
||||||
CSTB = pwr.eCharStatusTimeBuffID;
|
|
||||||
iValue = pwr.iValue;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CSTB > 0) {
|
|
||||||
// update CBFlag serverside
|
|
||||||
plr->iEggConditionBitFlag &= ~CBFlag;
|
|
||||||
// send buff update packet
|
|
||||||
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, updatePacket);
|
|
||||||
updatePacket.eCSTB = CSTB; // eCharStatusTimeBuffID
|
|
||||||
updatePacket.eTBU = 2; // eTimeBuffUpdate 2 means remove
|
|
||||||
updatePacket.eTBT = 3; // eTimeBuffType 3 means egg
|
|
||||||
updatePacket.iConditionBitFlag = plr->iConditionBitFlag | plr->iGroupConditionBitFlag | plr->iEggConditionBitFlag;
|
|
||||||
updatePacket.TimeBuff.iValue = iValue;
|
|
||||||
sock->sendPacket((void*)&updatePacket, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// remove buff from the map
|
// remove buff from the map
|
||||||
it = EggBuffs.erase(it);
|
it = EggBuffs.erase(it);
|
||||||
}
|
}
|
||||||
@ -779,7 +706,7 @@ void NPCManager::eggPickup(CNSocket* sock, CNPacketData* data) {
|
|||||||
|
|
||||||
// buff the player
|
// buff the player
|
||||||
if (type->effectId != 0)
|
if (type->effectId != 0)
|
||||||
eggBuffPlayer(sock, type->effectId, type->duration);
|
eggBuffPlayer(sock, type->effectId, eggId);
|
||||||
|
|
||||||
// damage egg
|
// damage egg
|
||||||
if (type->effectId == 183) {
|
if (type->effectId == 183) {
|
||||||
|
@ -479,25 +479,33 @@ void NanoManager::nanoUnbuff(CNSocket* sock, int targetData[], int32_t bitFlag,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NanoManager::applyBuff(CNSocket* sock, int skillID, int eTBU, int eTBT, int32_t groupFlags) {
|
bool NanoManager::applyBuff(CNSocket* sock, int skillID, int eTBU, int eTBT, int32_t groupFlags, bool eggBuff) {
|
||||||
if (SkillTable[skillID].drainType != 2)
|
if (SkillTable[skillID].drainType == 1)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
|
int32_t bitFlag = 0;
|
||||||
|
|
||||||
for (auto& pwr : NanoPowers) {
|
for (auto& pwr : NanoPowers) {
|
||||||
if (pwr.skillType == SkillTable[skillID].skillType) {
|
if (pwr.skillType == SkillTable[skillID].skillType) {
|
||||||
|
bitFlag = pwr.bitFlag;
|
||||||
Player *plr = PlayerManager::getPlayer(sock);
|
Player *plr = PlayerManager::getPlayer(sock);
|
||||||
if (eTBU == 1 || !((groupFlags | plr->iSelfConditionBitFlag) & pwr.bitFlag)) {
|
if (eTBU == 1 || !((groupFlags | plr->iSelfConditionBitFlag) & bitFlag)) {
|
||||||
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, resp);
|
INITSTRUCT(sP_FE2CL_PC_BUFF_UPDATE, resp);
|
||||||
resp.eCSTB = pwr.timeBuffID;
|
resp.eCSTB = pwr.timeBuffID;
|
||||||
resp.eTBU = eTBU;
|
resp.eTBU = eTBU;
|
||||||
resp.eTBT = eTBT;
|
resp.eTBT = eTBT;
|
||||||
resp.iConditionBitFlag = plr->iConditionBitFlag = groupFlags | plr->iSelfConditionBitFlag;
|
resp.iConditionBitFlag = plr->iConditionBitFlag = groupFlags | plr->iSelfConditionBitFlag;
|
||||||
|
if (eggBuff)
|
||||||
|
resp.iConditionBitFlag = plr->iConditionBitFlag |= bitFlag;
|
||||||
resp.TimeBuff.iValue = SkillTable[skillID].powerIntensity[0];
|
resp.TimeBuff.iValue = SkillTable[skillID].powerIntensity[0];
|
||||||
|
|
||||||
sock->sendPacket((void*)&resp, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
sock->sendPacket((void*)&resp, P_FE2CL_PC_BUFF_UPDATE, sizeof(sP_FE2CL_PC_BUFF_UPDATE));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0=A 1=B 2=C -1=Not found
|
// 0=A 1=B 2=C -1=Not found
|
||||||
@ -511,7 +519,7 @@ int* NanoManager::findTargets(Player* plr, int skillID, CNPacketData* data) {
|
|||||||
static int tD[5] = {0, 0, 0, 0, 0};
|
static int tD[5] = {0, 0, 0, 0, 0};
|
||||||
tD[0] = 0;
|
tD[0] = 0;
|
||||||
|
|
||||||
if (SkillTable[skillID].targetType == 1 && data != nullptr) { // client gives us the targets
|
if (SkillTable[skillID].targetType <= 2 && data != nullptr) { // client gives us the targets
|
||||||
sP_CL2FE_REQ_NANO_SKILL_USE* pkt = (sP_CL2FE_REQ_NANO_SKILL_USE*)data->buf;
|
sP_CL2FE_REQ_NANO_SKILL_USE* pkt = (sP_CL2FE_REQ_NANO_SKILL_USE*)data->buf;
|
||||||
|
|
||||||
// validate request check
|
// validate request check
|
||||||
@ -637,7 +645,7 @@ bool doHeal(CNSocket *sock, sSkillResult_Heal_HP *respdata, int i, int32_t targe
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int healedAmount = PC_MAXHEALTH(plr->level) * amount / 1000;
|
int healedAmount = PC_MAXHEALTH(plr->level) * amount / 1500;
|
||||||
|
|
||||||
plr->HP += healedAmount;
|
plr->HP += healedAmount;
|
||||||
|
|
||||||
@ -667,7 +675,7 @@ bool doDamage(CNSocket *sock, sSkillResult_Damage *respdata, int i, int32_t targ
|
|||||||
if (plr == nullptr)
|
if (plr == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int damage = MobManager::hitMob(sock, mob, PC_MAXHEALTH(plr->level) * amount / 1000);
|
int damage = MobManager::hitMob(sock, mob, PC_MAXHEALTH(plr->level) * amount / 2000 + mob->appearanceData.iHP * amount / 2000);
|
||||||
|
|
||||||
respdata[i].eCT = 4;
|
respdata[i].eCT = 4;
|
||||||
respdata[i].iDamage = damage;
|
respdata[i].iDamage = damage;
|
||||||
@ -856,7 +864,7 @@ void nanoPower(CNSocket *sock, int targetData[],
|
|||||||
// nano power dispatch table
|
// nano power dispatch table
|
||||||
std::vector<NanoPower> NanoPowers = {
|
std::vector<NanoPower> NanoPowers = {
|
||||||
NanoPower(EST_STUN, CSB_BIT_STUN, ECSB_STUN, nanoPower<sSkillResult_Damage_N_Debuff, doDamageNDebuff>),
|
NanoPower(EST_STUN, CSB_BIT_STUN, ECSB_STUN, nanoPower<sSkillResult_Damage_N_Debuff, doDamageNDebuff>),
|
||||||
NanoPower(EST_HEAL_HP, CSB_BIT_NONE, ECSB_NONE, nanoPower<sSkillResult_Heal_HP, doHeal>),
|
NanoPower(EST_HEAL_HP, CSB_BIT_HEAL, ECSB_HEAL, nanoPower<sSkillResult_Heal_HP, doHeal>),
|
||||||
NanoPower(EST_BOUNDINGBALL, CSB_BIT_BOUNDINGBALL, ECSB_BOUNDINGBALL, nanoPower<sSkillResult_Buff, doDebuff>),
|
NanoPower(EST_BOUNDINGBALL, CSB_BIT_BOUNDINGBALL, ECSB_BOUNDINGBALL, nanoPower<sSkillResult_Buff, doDebuff>),
|
||||||
NanoPower(EST_SNARE, CSB_BIT_DN_MOVE_SPEED, ECSB_DN_MOVE_SPEED, nanoPower<sSkillResult_Damage_N_Debuff, doDamageNDebuff>),
|
NanoPower(EST_SNARE, CSB_BIT_DN_MOVE_SPEED, ECSB_DN_MOVE_SPEED, nanoPower<sSkillResult_Damage_N_Debuff, doDamageNDebuff>),
|
||||||
NanoPower(EST_DAMAGE, CSB_BIT_NONE, ECSB_NONE, nanoPower<sSkillResult_Damage, doDamage>),
|
NanoPower(EST_DAMAGE, CSB_BIT_NONE, ECSB_NONE, nanoPower<sSkillResult_Damage, doDamage>),
|
||||||
|
@ -65,7 +65,7 @@ namespace NanoManager {
|
|||||||
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, int* targetData, int32_t bitFlag, int16_t timeBuffID, int16_t amount, bool groupPower);
|
void nanoUnbuff(CNSocket* sock, int* 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);
|
bool applyBuff(CNSocket* sock, int skillID, int eTBU, int eTBT, int32_t groupFlags, bool eggBuff=false);
|
||||||
int nanoStyle(int nanoID);
|
int nanoStyle(int nanoID);
|
||||||
int* findTargets(Player* plr, int skillID, CNPacketData* data = nullptr);
|
int* findTargets(Player* plr, int skillID, CNPacketData* data = nullptr);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user