mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 21:40:05 +00:00
Nano Drain, Debuffs are timed
* Nano drain power works, currently does 30% damage over a period of 3 seconds. * Stun, Sleep and Snare powers will now run out of time on mobs. * A few other adjustments to mob mobility.
This commit is contained in:
parent
2782706355
commit
177c5f0f17
@ -330,9 +330,16 @@ int MobManager::hitMob(CNSocket *sock, Mob *mob, int damage) {
|
||||
mob->appearanceData.iHP -= damage;
|
||||
|
||||
// wake up sleeping monster
|
||||
// TODO: remove client-side bit somehow
|
||||
if (mob->appearanceData.iConditionBitFlag & CSB_BIT_MEZ) {
|
||||
mob->appearanceData.iConditionBitFlag &= ~CSB_BIT_MEZ;
|
||||
|
||||
INITSTRUCT(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT, pkt1);
|
||||
pkt1.eCT = 2;
|
||||
pkt1.iID = mob->appearanceData.iNPC_ID;
|
||||
pkt1.iConditionBitFlag = mob->appearanceData.iConditionBitFlag;
|
||||
NPCManager::sendToViewable(mob, &pkt1, P_FE2CL_CHAR_TIME_BUFF_TIME_OUT, sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT));
|
||||
}
|
||||
|
||||
if (mob->appearanceData.iHP <= 0)
|
||||
killMob(mob->target, mob);
|
||||
|
||||
@ -503,10 +510,8 @@ void MobManager::combatStep(Mob *mob, time_t currTime) {
|
||||
|
||||
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||
pkt.iSpeed = speed;
|
||||
pkt.iToX = (targ.first - mob->appearanceData.iX) * 5 / 2 + mob->appearanceData.iX;
|
||||
pkt.iToY = (targ.second - mob->appearanceData.iY) * 5 / 2 + mob->appearanceData.iY;
|
||||
mob->appearanceData.iX = targ.first;
|
||||
mob->appearanceData.iY = targ.second;
|
||||
pkt.iToX = mob->appearanceData.iX = targ.first;
|
||||
pkt.iToY = mob->appearanceData.iY = targ.second;
|
||||
pkt.iToZ = mob->target->plr->z;
|
||||
|
||||
// notify all nearby players
|
||||
@ -608,10 +613,8 @@ void MobManager::retreatStep(Mob *mob, time_t currTime) {
|
||||
pkt.iSpeed = (int)mob->data["m_iRunSpeed"] * 2;
|
||||
mob->appearanceData.iX = targ.first;
|
||||
mob->appearanceData.iY = targ.second;
|
||||
pkt.iToX = (targ.first - mob->appearanceData.iX) * 5 / 2 + mob->appearanceData.iX;
|
||||
pkt.iToY = (targ.second - mob->appearanceData.iY) * 5 / 2 + mob->appearanceData.iY;
|
||||
mob->appearanceData.iX = targ.first;
|
||||
mob->appearanceData.iY = targ.second;
|
||||
pkt.iToX = mob->appearanceData.iX = targ.first;
|
||||
pkt.iToY = mob->appearanceData.iY = targ.second;
|
||||
pkt.iToZ = mob->appearanceData.iZ;
|
||||
|
||||
// notify all nearby players
|
||||
@ -640,6 +643,27 @@ void MobManager::step(CNServer *serv, time_t currTime) {
|
||||
if (!ChunkManager::inPopulatedChunks(x, y, pair.second->instanceID))
|
||||
continue;
|
||||
|
||||
// drain
|
||||
if (pair.second->appearanceData.iConditionBitFlag & CSB_BIT_BOUNDINGBALL) {
|
||||
pair.second->appearanceData.iHP -= pair.second->maxHealth / 50; // lose 10% every second
|
||||
// TODO: Make this send a damage packet
|
||||
}
|
||||
|
||||
// unbuffing
|
||||
for (auto& pair2 : pair.second->unbuffTimes) {
|
||||
if (currTime >= pair2.second) {
|
||||
pair.second->appearanceData.iConditionBitFlag &= ~pair2.first;
|
||||
|
||||
INITSTRUCT(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT, pkt1);
|
||||
pkt1.eCT = 2;
|
||||
pkt1.iID = pair.second->appearanceData.iNPC_ID;
|
||||
pkt1.iConditionBitFlag = pair.second->appearanceData.iConditionBitFlag;
|
||||
NPCManager::sendToViewable(pair.second, &pkt1, P_FE2CL_CHAR_TIME_BUFF_TIME_OUT, sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT));
|
||||
|
||||
pair.second->unbuffTimes.erase(pair2.first);
|
||||
}
|
||||
}
|
||||
|
||||
// skip mob movement and combat if disabled
|
||||
if (!simulateMobs && pair.second->state != MobState::DEAD
|
||||
&& pair.second->state != MobState::RETREAT)
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "contrib/JSON.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <queue>
|
||||
|
||||
enum class MobState {
|
||||
@ -27,6 +28,8 @@ struct Mob : public BaseNPC {
|
||||
int spawnZ;
|
||||
int level;
|
||||
|
||||
std::unordered_map<int32_t,time_t> unbuffTimes;
|
||||
|
||||
// dead
|
||||
time_t killedTime = 0;
|
||||
time_t regenTime;
|
||||
@ -38,11 +41,12 @@ struct Mob : public BaseNPC {
|
||||
const int sightRange;
|
||||
time_t nextMovement = 0;
|
||||
bool staticPath = false;
|
||||
int roamX, roamY, roamZ;
|
||||
|
||||
// combat
|
||||
CNSocket *target = nullptr;
|
||||
time_t nextAttack = 0;
|
||||
int roamX, roamY, roamZ;
|
||||
|
||||
|
||||
// drop
|
||||
int dropType;
|
||||
|
@ -407,14 +407,14 @@ bool doDebuff(CNSocket *sock, int32_t *pktdata, sSkillResult_Damage_N_Debuff *re
|
||||
|
||||
Mob* mob = MobManager::Mobs[pktdata[i]];
|
||||
|
||||
int damage = MobManager::hitMob(sock, mob, amount);
|
||||
int damage = MobManager::hitMob(sock, mob, 0); // using amount for something else
|
||||
|
||||
respdata[i].eCT = 4;
|
||||
respdata[i].iDamage = damage;
|
||||
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
||||
respdata[i].iHP = mob->appearanceData.iHP;
|
||||
respdata[i].iConditionBitFlag = mob->appearanceData.iConditionBitFlag |= iCBFlag;
|
||||
|
||||
mob->unbuffTimes[iCBFlag] = getTime() + amount;
|
||||
std::cout << (int)mob->appearanceData.iNPC_ID << " was debuffed" << std::endl;
|
||||
|
||||
return true;
|
||||
@ -428,10 +428,12 @@ bool doBuff(CNSocket *sock, int32_t *pktdata, sSkillResult_Buff *respdata, int i
|
||||
}
|
||||
|
||||
Mob* mob = MobManager::Mobs[pktdata[i]];
|
||||
MobManager::hitMob(sock, mob, 0);
|
||||
|
||||
respdata[i].eCT = 4;
|
||||
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
||||
respdata[i].iConditionBitFlag = mob->appearanceData.iConditionBitFlag |= iCBFlag;
|
||||
mob->unbuffTimes[iCBFlag] = getTime() + amount;
|
||||
|
||||
std::cout << (int)mob->appearanceData.iNPC_ID << " was debuffed" << std::endl;
|
||||
|
||||
@ -669,15 +671,15 @@ void activePower(CNSocket *sock, CNPacketData *data,
|
||||
|
||||
// active nano power dispatch table
|
||||
std::vector<ActivePower> ActivePowers = {
|
||||
ActivePower(StunPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_STUN, CSB_BIT_STUN, 0),
|
||||
ActivePower(StunPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_STUN, CSB_BIT_STUN, 2250),
|
||||
ActivePower(HealPowers, activePower<sSkillResult_Heal_HP, doHeal>, EST_HEAL_HP, CSB_BIT_NONE, 25),
|
||||
ActivePower(GroupHealPowers, activePower<sSkillResult_Heal_HP, doGroupHeal, GHEAL>,EST_HEAL_HP, CSB_BIT_NONE, 25),
|
||||
ActivePower(GroupHealPowers, activePower<sSkillResult_Heal_HP, doGroupHeal, GHEAL>,EST_HEAL_HP, CSB_BIT_NONE, 15),
|
||||
// TODO: Recall
|
||||
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(DrainPowers, activePower<sSkillResult_Buff, doBuff>, EST_BOUNDINGBALL, CSB_BIT_BOUNDINGBALL, 3000),
|
||||
ActivePower(SnarePowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_SNARE, CSB_BIT_DN_MOVE_SPEED, 4500),
|
||||
ActivePower(DamagePowers, activePower<sSkillResult_Damage, doDamage>, EST_DAMAGE, CSB_BIT_NONE, 12),
|
||||
ActivePower(LeechPowers, activePower<sSkillResult_Heal_HP, doLeech, LEECH>, EST_BLOODSUCKING, CSB_BIT_NONE, 18),
|
||||
ActivePower(SleepPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_SLEEP, CSB_BIT_MEZ, 0),
|
||||
ActivePower(SleepPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_SLEEP, CSB_BIT_MEZ, 4500),
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
Loading…
Reference in New Issue
Block a user