From 657061083eeff1ed9007c1ef4310641e14d867d3 Mon Sep 17 00:00:00 2001 From: dongresource Date: Tue, 1 Dec 2020 21:34:14 +0100 Subject: [PATCH] Lose aggro and do not take damage if invulnerable --- src/MobManager.cpp | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/MobManager.cpp b/src/MobManager.cpp index 80959cd..54d1429 100644 --- a/src/MobManager.cpp +++ b/src/MobManager.cpp @@ -128,7 +128,9 @@ void MobManager::npcAttackPc(Mob *mob, time_t currTime) { sAttackResult *atk = (sAttackResult*)(respbuf + sizeof(sP_FE2CL_NPC_ATTACK_PCs)); auto damage = getDamage(450 + (int)mob->data["m_iPower"], plr->defense, false, false, -1, -1, 0); - plr->HP -= damage.first; + + if (!(plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE)) + plr->HP -= damage.first; pkt->iNPC_ID = mob->appearanceData.iNPC_ID; pkt->iPCCnt = 1; @@ -486,19 +488,12 @@ void MobManager::deadStep(Mob *mob, time_t currTime) { void MobManager::combatStep(Mob *mob, time_t currTime) { assert(mob->target != nullptr); - // sanity check: did the target player lose connection? - if (PlayerManager::players.find(mob->target) == PlayerManager::players.end()) { - mob->target = nullptr; - mob->state = MobState::RETREAT; - if (!aggroCheck(mob, currTime)) - clearDebuff(mob); - return; - } - Player *plr = PlayerManager::getPlayer(mob->target); - // did something else kill the player in the mean time? - if (plr->HP <= 0) { + // Lose aggro if the player lost connection, became invulnerable or died + if (plr->HP <= 0 + || PlayerManager::players.find(mob->target) == PlayerManager::players.end() + || (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE)) { mob->target = nullptr; mob->state = MobState::RETREAT; if (!aggroCheck(mob, currTime)) @@ -868,6 +863,9 @@ void MobManager::dealGooDamage(CNSocket *sock, int amount) { sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK *pkt = (sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK*)respbuf; sSkillResult_DotDamage *dmg = (sSkillResult_DotDamage*)(respbuf + sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK)); + if (!(plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE)) + amount = 0; + if (plr->iConditionBitFlag & CSB_BIT_PROTECT_INFECTION) { amount = -2; // -2 is the magic number for "Protected" to appear as the damage number dmg->bProtected = 1; @@ -1610,7 +1608,10 @@ void MobManager::dealCorruption(Mob *mob, std::vector targetData, int skill } } - respdata[i].iHP = plr->HP-= respdata[i].iDamage; + if (!(plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE)) + plr->HP -= respdata[i].iDamage; + + respdata[i].iHP = plr->HP; respdata[i].iConditionBitFlag = plr->iConditionBitFlag; if (plr->HP <= 0) { @@ -1646,6 +1647,9 @@ bool doDamageNDebuff(Mob *mob, sSkillResult_Damage_N_Debuff *respdata, int i, in int damage = duration; + if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE) + damage = 0; + respdata[i].eCT = 1; respdata[i].iDamage = damage; respdata[i].iID = plr->iID; @@ -1712,6 +1716,9 @@ bool doDamage(Mob *mob, sSkillResult_Damage *respdata, int i, int32_t targetID, int damage = amount * PC_MAXHEALTH((int)mob->data["m_iNpcLevel"]) / 1500; + if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE) + damage = 0; + respdata[i].eCT = 1; respdata[i].iDamage = damage; respdata[i].iID = plr->iID; @@ -1763,6 +1770,9 @@ bool doLeech(Mob *mob, sSkillResult_Heal_HP *healdata, int i, int32_t targetID, int damage = amount * PC_MAXHEALTH(plr->level) / 1000; + if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE) + damage = 0; + damagedata->eCT = 1; damagedata->iDamage = damage; damagedata->iID = plr->iID;