mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 06:50:04 +00:00
Various bugfixes
- Eruption is now blocked by stun and sleep. - Corruption should block all nano abilities. - Buffs time out for other players - Timed mission bugfixes (AGAIN) - Corruption and Eruptions fire quicker. - Heal egg ids fix - No power nanos no longer break the system. - Mobs should no longer restun. - Mob ability chance calculation adjustments. - Duration of the power's debuff is sent as iDamage instead of 0, this removes the ugly "Block" that shows up on successful hits. - Group mob respawning bugfixes - a bit of a cleanup
This commit is contained in:
parent
1474ff10ac
commit
b947ff65cf
@ -106,17 +106,39 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) {
|
|||||||
// failed timed missions give an iNPC_ID of 0
|
// failed timed missions give an iNPC_ID of 0
|
||||||
if (missionData->iNPC_ID == 0) {
|
if (missionData->iNPC_ID == 0) {
|
||||||
TaskData* task = MissionManager::Tasks[missionData->iTaskNum];
|
TaskData* task = MissionManager::Tasks[missionData->iTaskNum];
|
||||||
// double-checking
|
if (task->task["m_iSTGrantTimer"] > 0) { // its a timed mission
|
||||||
if (task->task["m_iSTGrantTimer"] > 0) {
|
|
||||||
Player* plr = PlayerManager::getPlayer(sock);
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
int failTaskID = task->task["m_iFOutgoingTask"];
|
/*
|
||||||
if (failTaskID != 0) {
|
* Enemy killing missions
|
||||||
MissionManager::quitTask(sock, missionData->iTaskNum, false);
|
* this is gross and should be cleaned up later
|
||||||
|
* once we comb over mission logic more throughly
|
||||||
|
*/
|
||||||
|
bool mobsAreKilled = false;
|
||||||
|
if (task->task["m_iHTaskType"] == 5) {
|
||||||
|
mobsAreKilled = true;
|
||||||
|
for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) {
|
||||||
|
if (plr->tasks[i] == missionData->iTaskNum) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
if (plr->RemainingNPCCount[i][j] > 0) {
|
||||||
|
mobsAreKilled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
if (!mobsAreKilled) {
|
||||||
if (plr->tasks[i] == missionData->iTaskNum)
|
|
||||||
plr->tasks[i] = failTaskID;
|
int failTaskID = task->task["m_iFOutgoingTask"];
|
||||||
return;
|
if (failTaskID != 0) {
|
||||||
|
MissionManager::quitTask(sock, missionData->iTaskNum, false);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
if (plr->tasks[i] == missionData->iTaskNum)
|
||||||
|
plr->tasks[i] = failTaskID;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -443,6 +443,11 @@ void MobManager::deadStep(Mob *mob, time_t currTime) {
|
|||||||
RemovalQueue.push(mob->appearanceData.iNPC_ID);
|
RemovalQueue.push(mob->appearanceData.iNPC_ID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pre-set spawn coordinates if not marked for removal
|
||||||
|
mob->appearanceData.iX = mob->spawnX;
|
||||||
|
mob->appearanceData.iY = mob->spawnY;
|
||||||
|
mob->appearanceData.iZ = mob->spawnZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// to guide their groupmates, group leaders still need to move despite being dead
|
// to guide their groupmates, group leaders still need to move despite being dead
|
||||||
@ -457,9 +462,8 @@ void MobManager::deadStep(Mob *mob, time_t currTime) {
|
|||||||
mob->appearanceData.iHP = mob->maxHealth;
|
mob->appearanceData.iHP = mob->maxHealth;
|
||||||
mob->state = MobState::ROAMING;
|
mob->state = MobState::ROAMING;
|
||||||
|
|
||||||
// reset position
|
// if mob is a group leader/follower, spawn where the group is.
|
||||||
if (mob->groupLeader != 0) {
|
if (mob->groupLeader != 0) {
|
||||||
// mob is a group leader/follower, spawn where the group is.
|
|
||||||
if (Mobs.find(mob->groupLeader) != Mobs.end()) {
|
if (Mobs.find(mob->groupLeader) != Mobs.end()) {
|
||||||
Mob* leaderMob = Mobs[mob->groupLeader];
|
Mob* leaderMob = Mobs[mob->groupLeader];
|
||||||
mob->appearanceData.iX = leaderMob->appearanceData.iX + mob->offsetX;
|
mob->appearanceData.iX = leaderMob->appearanceData.iX + mob->offsetX;
|
||||||
@ -467,14 +471,7 @@ void MobManager::deadStep(Mob *mob, time_t currTime) {
|
|||||||
mob->appearanceData.iZ = leaderMob->appearanceData.iZ;
|
mob->appearanceData.iZ = leaderMob->appearanceData.iZ;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "[WARN] deadStep: mob cannot find it's leader!" << std::endl;
|
std::cout << "[WARN] deadStep: mob cannot find it's leader!" << std::endl;
|
||||||
mob->appearanceData.iX = mob->spawnX;
|
|
||||||
mob->appearanceData.iY = mob->spawnY;
|
|
||||||
mob->appearanceData.iZ = mob->spawnZ;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
mob->appearanceData.iX = mob->spawnX;
|
|
||||||
mob->appearanceData.iY = mob->spawnY;
|
|
||||||
mob->appearanceData.iZ = mob->spawnZ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_NPC_NEW, pkt);
|
INITSTRUCT(sP_FE2CL_NPC_NEW, pkt);
|
||||||
@ -540,8 +537,10 @@ void MobManager::combatStep(Mob *mob, time_t currTime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// skip attack if stunned or asleep
|
// skip attack if stunned or asleep
|
||||||
if (mob->appearanceData.iConditionBitFlag & (CSB_BIT_STUN|CSB_BIT_MEZ))
|
if (mob->appearanceData.iConditionBitFlag & (CSB_BIT_STUN|CSB_BIT_MEZ)) {
|
||||||
|
mob->skillStyle = -1; // in this case we also reset the any outlying abilities the mob might be winding up.
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int distance = hypot(plr->x - mob->appearanceData.iX, plr->y - mob->appearanceData.iY);
|
int distance = hypot(plr->x - mob->appearanceData.iX, plr->y - mob->appearanceData.iY);
|
||||||
int mobRange = (int)mob->data["m_iAtkRange"] + (int)mob->data["m_iRadius"];
|
int mobRange = (int)mob->data["m_iAtkRange"] + (int)mob->data["m_iRadius"];
|
||||||
@ -751,16 +750,11 @@ void MobManager::retreatStep(Mob *mob, time_t currTime) {
|
|||||||
|
|
||||||
void MobManager::step(CNServer *serv, time_t currTime) {
|
void MobManager::step(CNServer *serv, time_t currTime) {
|
||||||
for (auto& pair : Mobs) {
|
for (auto& pair : Mobs) {
|
||||||
|
|
||||||
// skip chunks without players
|
|
||||||
if (pair.second->playersInView == 0) //(!ChunkManager::inPopulatedChunks(pair.second->viewableChunks))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (pair.second->playersInView < 0)
|
if (pair.second->playersInView < 0)
|
||||||
std::cout << "[WARN] Weird playerview value " << pair.second->playersInView << std::endl;
|
std::cout << "[WARN] Weird playerview value " << pair.second->playersInView << std::endl;
|
||||||
|
|
||||||
// skip mob movement and combat if disabled
|
// skip mob movement and combat if disabled or not in view
|
||||||
if (!simulateMobs && pair.second->state != MobState::DEAD
|
if ((!simulateMobs || pair.second->playersInView == 0) && pair.second->state != MobState::DEAD
|
||||||
&& pair.second->state != MobState::RETREAT)
|
&& pair.second->state != MobState::RETREAT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -1409,7 +1403,7 @@ void MobManager::followToCombat(Mob *mob) {
|
|||||||
}
|
}
|
||||||
Mob* followerMob = Mobs[leadMob->groupMember[i]];
|
Mob* followerMob = Mobs[leadMob->groupMember[i]];
|
||||||
|
|
||||||
if (followerMob->state == MobState::COMBAT)
|
if (followerMob->state != MobState::ROAMING) // only roaming mobs should transition to combat
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
followerMob->target = mob->target;
|
followerMob->target = mob->target;
|
||||||
@ -1421,6 +1415,10 @@ void MobManager::followToCombat(Mob *mob) {
|
|||||||
followerMob->roamY = followerMob->appearanceData.iY;
|
followerMob->roamY = followerMob->appearanceData.iY;
|
||||||
followerMob->roamZ = followerMob->appearanceData.iZ;
|
followerMob->roamZ = followerMob->appearanceData.iZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (leadMob->state != MobState::ROAMING)
|
||||||
|
return;
|
||||||
|
|
||||||
leadMob->target = mob->target;
|
leadMob->target = mob->target;
|
||||||
leadMob->state = MobState::COMBAT;
|
leadMob->state = MobState::COMBAT;
|
||||||
leadMob->nextMovement = getTime();
|
leadMob->nextMovement = getTime();
|
||||||
@ -1433,6 +1431,12 @@ void MobManager::followToCombat(Mob *mob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MobManager::useAbilities(Mob *mob, time_t currTime) {
|
void MobManager::useAbilities(Mob *mob, time_t currTime) {
|
||||||
|
/*
|
||||||
|
* targetData approach
|
||||||
|
* first integer is the count
|
||||||
|
* second to fifth integers are IDs, these can be either player iID or mob's iID
|
||||||
|
* whether the skill targets players or mobs is determined by the skill packet being fired
|
||||||
|
*/
|
||||||
Player *plr = PlayerManager::getPlayer(mob->target);
|
Player *plr = PlayerManager::getPlayer(mob->target);
|
||||||
|
|
||||||
if (mob->skillStyle >= 0) { // corruption hit
|
if (mob->skillStyle >= 0) { // corruption hit
|
||||||
@ -1481,7 +1485,7 @@ void MobManager::useAbilities(Mob *mob, time_t currTime) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int random = rand() % 100 * 15000;
|
int random = rand() % 2000 * 1000;
|
||||||
int prob1 = (int)mob->data["m_iActiveSkill1Prob"]; // active skill probability
|
int prob1 = (int)mob->data["m_iActiveSkill1Prob"]; // active skill probability
|
||||||
int prob2 = (int)mob->data["m_iCorruptionTypeProb"]; // corruption probability
|
int prob2 = (int)mob->data["m_iCorruptionTypeProb"]; // corruption probability
|
||||||
int prob3 = (int)mob->data["m_iMegaTypeProb"]; // eruption probability
|
int prob3 = (int)mob->data["m_iMegaTypeProb"]; // eruption probability
|
||||||
@ -1490,8 +1494,11 @@ void MobManager::useAbilities(Mob *mob, time_t currTime) {
|
|||||||
int skillID = (int)mob->data["m_iActiveSkill1"];
|
int skillID = (int)mob->data["m_iActiveSkill1"];
|
||||||
std::vector<int> targetData = {1, plr->iID, 0, 0, 0};
|
std::vector<int> targetData = {1, plr->iID, 0, 0, 0};
|
||||||
for (auto& pwr : MobPowers)
|
for (auto& pwr : MobPowers)
|
||||||
if (pwr.skillType == NanoManager::SkillTable[skillID].skillType)
|
if (pwr.skillType == NanoManager::SkillTable[skillID].skillType) {
|
||||||
|
if (pwr.bitFlag != 0 && (plr->iConditionBitFlag & pwr.bitFlag))
|
||||||
|
return; // prevent debuffing a player twice
|
||||||
pwr.handle(mob, targetData, skillID, NanoManager::SkillTable[skillID].durationTime[0], NanoManager::SkillTable[skillID].powerIntensity[0]);
|
pwr.handle(mob, targetData, skillID, NanoManager::SkillTable[skillID].durationTime[0], NanoManager::SkillTable[skillID].powerIntensity[0]);
|
||||||
|
}
|
||||||
mob->nextAttack = currTime + (int)mob->data["m_iDelayTime"] * 100;
|
mob->nextAttack = currTime + (int)mob->data["m_iDelayTime"] * 100;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1511,7 +1518,7 @@ void MobManager::useAbilities(Mob *mob, time_t currTime) {
|
|||||||
mob->skillStyle = rand() % 3;
|
mob->skillStyle = rand() % 3;
|
||||||
pkt.iStyle = mob->skillStyle;
|
pkt.iStyle = mob->skillStyle;
|
||||||
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_SKILL_CORRUPTION_READY, sizeof(sP_FE2CL_NPC_SKILL_CORRUPTION_READY));
|
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_SKILL_CORRUPTION_READY, sizeof(sP_FE2CL_NPC_SKILL_CORRUPTION_READY));
|
||||||
mob->nextAttack = currTime + 2000;
|
mob->nextAttack = currTime + 1800;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1524,7 +1531,7 @@ void MobManager::useAbilities(Mob *mob, time_t currTime) {
|
|||||||
pkt.iValue2 = mob->hitY = plr->y;
|
pkt.iValue2 = mob->hitY = plr->y;
|
||||||
pkt.iValue3 = mob->hitZ = plr->z;
|
pkt.iValue3 = mob->hitZ = plr->z;
|
||||||
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_SKILL_READY, sizeof(sP_FE2CL_NPC_SKILL_READY));
|
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_SKILL_READY, sizeof(sP_FE2CL_NPC_SKILL_READY));
|
||||||
mob->nextAttack = currTime + 2500;
|
mob->nextAttack = currTime + 1800;
|
||||||
mob->skillStyle = -2;
|
mob->skillStyle = -2;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1651,15 +1658,10 @@ bool doDamageNDebuff(Mob *mob, sSkillResult_Damage_N_Debuff *respdata, int i, in
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int damage = duration;
|
|
||||||
|
|
||||||
if (plr->iSpecialState & CN_SPECIAL_STATE_FLAG__INVULNERABLE)
|
|
||||||
damage = 0;
|
|
||||||
|
|
||||||
respdata[i].eCT = 1;
|
respdata[i].eCT = 1;
|
||||||
respdata[i].iDamage = damage;
|
respdata[i].iDamage = duration / 10;
|
||||||
respdata[i].iID = plr->iID;
|
respdata[i].iID = plr->iID;
|
||||||
respdata[i].iHP = plr->HP -= damage;
|
respdata[i].iHP = plr->HP;
|
||||||
respdata[i].iStamina = plr->Nanos[plr->activeNano].iStamina;
|
respdata[i].iStamina = plr->Nanos[plr->activeNano].iStamina;
|
||||||
if (plr->iConditionBitFlag & CSB_BIT_FREEDOM)
|
if (plr->iConditionBitFlag & CSB_BIT_FREEDOM)
|
||||||
respdata[i].bProtected = 1;
|
respdata[i].bProtected = 1;
|
||||||
|
@ -567,7 +567,7 @@ int NPCManager::eggBuffPlayer(CNSocket* sock, int skillId, int eggId) {
|
|||||||
|
|
||||||
if (skillId == 183) {
|
if (skillId == 183) {
|
||||||
resplen = sizeof(sP_FE2CL_NPC_SKILL_HIT) + sizeof(sSkillResult_Damage);
|
resplen = sizeof(sP_FE2CL_NPC_SKILL_HIT) + sizeof(sSkillResult_Damage);
|
||||||
} else if (skillId == 147) {
|
} else if (skillId == 150) {
|
||||||
resplen = sizeof(sP_FE2CL_NPC_SKILL_HIT) + sizeof(sSkillResult_Heal_HP);
|
resplen = sizeof(sP_FE2CL_NPC_SKILL_HIT) + sizeof(sSkillResult_Heal_HP);
|
||||||
} else {
|
} else {
|
||||||
resplen = sizeof(sP_FE2CL_NPC_SKILL_HIT) + sizeof(sSkillResult_Buff);
|
resplen = sizeof(sP_FE2CL_NPC_SKILL_HIT) + sizeof(sSkillResult_Buff);
|
||||||
@ -588,7 +588,7 @@ int NPCManager::eggBuffPlayer(CNSocket* sock, int skillId, int eggId) {
|
|||||||
if (plr->HP < 0)
|
if (plr->HP < 0)
|
||||||
plr->HP = 0;
|
plr->HP = 0;
|
||||||
skill->iHP = plr->HP;
|
skill->iHP = plr->HP;
|
||||||
} else if (skillId == 147) { // heal egg
|
} else if (skillId == 150) { // heal egg
|
||||||
sSkillResult_Heal_HP* skill = (sSkillResult_Heal_HP*)(respbuf + sizeof(sP_FE2CL_NPC_SKILL_HIT));
|
sSkillResult_Heal_HP* skill = (sSkillResult_Heal_HP*)(respbuf + sizeof(sP_FE2CL_NPC_SKILL_HIT));
|
||||||
memset(respbuf, 0, resplen);
|
memset(respbuf, 0, resplen);
|
||||||
skill->eCT = 1;
|
skill->eCT = 1;
|
||||||
@ -651,6 +651,12 @@ void NPCManager::eggStep(CNServer* serv, time_t currTime) {
|
|||||||
plr->iConditionBitFlag &= ~CBFlag;
|
plr->iConditionBitFlag &= ~CBFlag;
|
||||||
resp.iConditionBitFlag = plr->iConditionBitFlag |= groupFlags | plr->iSelfConditionBitFlag;
|
resp.iConditionBitFlag = plr->iConditionBitFlag |= groupFlags | plr->iSelfConditionBitFlag;
|
||||||
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));
|
||||||
|
|
||||||
|
INITSTRUCT(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT, resp2); // send a buff timeout to other players
|
||||||
|
resp2.eCT = 1;
|
||||||
|
resp2.iID = plr->iID;
|
||||||
|
resp2.iConditionBitFlag = plr->iConditionBitFlag;
|
||||||
|
PlayerManager::sendToViewable(sock, (void*)&resp2, P_FE2CL_CHAR_TIME_BUFF_TIME_OUT, sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_OUT));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// remove buff from the map
|
// remove buff from the map
|
||||||
|
@ -287,6 +287,11 @@ void NanoManager::summonNano(CNSocket *sock, int slot, bool silent) {
|
|||||||
if (slot > 2 || slot < -1)
|
if (slot > 2 || slot < -1)
|
||||||
return; // sanity check
|
return; // sanity check
|
||||||
|
|
||||||
|
int16_t nanoID = slot == -1 ? 0 : plr->equippedNanos[slot];
|
||||||
|
|
||||||
|
if (slot != -1 && plr->Nanos[nanoID].iSkillID == 0)
|
||||||
|
return; // prevent powerless nanos from summoning
|
||||||
|
|
||||||
plr->nanoDrainRate = 0;
|
plr->nanoDrainRate = 0;
|
||||||
int16_t skillID = plr->Nanos[plr->activeNano].iSkillID;
|
int16_t skillID = plr->Nanos[plr->activeNano].iSkillID;
|
||||||
|
|
||||||
@ -299,14 +304,11 @@ void NanoManager::summonNano(CNSocket *sock, int slot, bool silent) {
|
|||||||
nanoUnbuff(sock, targetData, pwr.bitFlag, pwr.timeBuffID, 0,(SkillTable[skillID].targetType == 3));
|
nanoUnbuff(sock, targetData, pwr.bitFlag, pwr.timeBuffID, 0,(SkillTable[skillID].targetType == 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t nanoID = slot == -1 ? 0 : plr->equippedNanos[slot];
|
|
||||||
|
|
||||||
if (nanoID > 36 || nanoID < 0)
|
if (nanoID > 36 || nanoID < 0)
|
||||||
return; // sanity check
|
return; // sanity check
|
||||||
|
|
||||||
plr->activeNano = nanoID;
|
plr->activeNano = nanoID;
|
||||||
sNano nano = plr->Nanos[nanoID];
|
skillID = plr->Nanos[nanoID].iSkillID;
|
||||||
skillID = nano.iSkillID;
|
|
||||||
|
|
||||||
// passive nano buffing
|
// passive nano buffing
|
||||||
if (SkillTable[skillID].drainType == 2) {
|
if (SkillTable[skillID].drainType == 2) {
|
||||||
@ -494,6 +496,11 @@ int NanoManager::nanoStyle(int nanoID) {
|
|||||||
return NanoTable[nanoID].style;
|
return NanoTable[nanoID].style;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* targetData approach
|
||||||
|
* first integer is the count
|
||||||
|
* second to fifth integers are IDs, these can be either player iID or mob's iID
|
||||||
|
*/
|
||||||
std::vector<int> NanoManager::findTargets(Player* plr, int skillID, CNPacketData* data) {
|
std::vector<int> NanoManager::findTargets(Player* plr, int skillID, CNPacketData* data) {
|
||||||
std::vector<int> tD(5);
|
std::vector<int> tD(5);
|
||||||
|
|
||||||
@ -564,10 +571,13 @@ bool doDebuff(CNSocket *sock, sSkillResult_Buff *respdata, int i, int32_t target
|
|||||||
|
|
||||||
respdata[i].eCT = 4;
|
respdata[i].eCT = 4;
|
||||||
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
||||||
respdata[i].iConditionBitFlag = mob->appearanceData.iConditionBitFlag |= bitFlag;
|
respdata[i].bProtected = 1;
|
||||||
mob->unbuffTimes[bitFlag] = getTime() + duration * 100;
|
if (mob->skillStyle < 0 && mob->state != MobState::RETREAT) { // only debuff if the enemy is not retreating and not casting corruption
|
||||||
|
mob->appearanceData.iConditionBitFlag |= bitFlag;
|
||||||
std::cout << (int)mob->appearanceData.iNPC_ID << " was debuffed" << std::endl;
|
mob->unbuffTimes[bitFlag] = getTime() + duration * 100;
|
||||||
|
respdata[i].bProtected = 0;
|
||||||
|
}
|
||||||
|
respdata[i].iConditionBitFlag = mob->appearanceData.iConditionBitFlag;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -620,15 +630,19 @@ bool doDamageNDebuff(CNSocket *sock, sSkillResult_Damage_N_Debuff *respdata, int
|
|||||||
|
|
||||||
Mob* mob = MobManager::Mobs[targetID];
|
Mob* mob = MobManager::Mobs[targetID];
|
||||||
|
|
||||||
int damage = MobManager::hitMob(sock, mob, 0); // using amount for something else
|
MobManager::hitMob(sock, mob, 0); // just to gain aggro
|
||||||
|
|
||||||
respdata[i].eCT = 4;
|
respdata[i].eCT = 4;
|
||||||
respdata[i].iDamage = damage;
|
respdata[i].iDamage = duration / 10;
|
||||||
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
||||||
respdata[i].iHP = mob->appearanceData.iHP;
|
respdata[i].iHP = mob->appearanceData.iHP;
|
||||||
respdata[i].iConditionBitFlag = mob->appearanceData.iConditionBitFlag |= bitFlag;
|
respdata[i].bProtected = 1;
|
||||||
mob->unbuffTimes[bitFlag] = getTime() + duration * 100;
|
if (mob->skillStyle < 0 && mob->state != MobState::RETREAT) { // only debuff if the enemy is not retreating and not casting corruption
|
||||||
std::cout << (int)mob->appearanceData.iNPC_ID << " was debuffed" << std::endl;
|
mob->appearanceData.iConditionBitFlag |= bitFlag;
|
||||||
|
mob->unbuffTimes[bitFlag] = getTime() + duration * 100;
|
||||||
|
respdata[i].bProtected = 0;
|
||||||
|
}
|
||||||
|
respdata[i].iConditionBitFlag = mob->appearanceData.iConditionBitFlag;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -665,8 +679,6 @@ bool doHeal(CNSocket *sock, sSkillResult_Heal_HP *respdata, int i, int32_t targe
|
|||||||
respdata[i].iHP = plr->HP;
|
respdata[i].iHP = plr->HP;
|
||||||
respdata[i].iHealHP = healedAmount;
|
respdata[i].iHealHP = healedAmount;
|
||||||
|
|
||||||
std::cout << (int)plr->iID << " was healed" << std::endl;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,8 +699,6 @@ bool doDamage(CNSocket *sock, sSkillResult_Damage *respdata, int i, int32_t targ
|
|||||||
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
respdata[i].iID = mob->appearanceData.iNPC_ID;
|
||||||
respdata[i].iHP = mob->appearanceData.iHP;
|
respdata[i].iHP = mob->appearanceData.iHP;
|
||||||
|
|
||||||
std::cout << (int)mob->appearanceData.iNPC_ID << " was damaged" << std::endl;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,8 +747,6 @@ bool doLeech(CNSocket *sock, sSkillResult_Heal_HP *healdata, int i, int32_t targ
|
|||||||
damagedata->iID = mob->appearanceData.iNPC_ID;
|
damagedata->iID = mob->appearanceData.iNPC_ID;
|
||||||
damagedata->iHP = mob->appearanceData.iHP;
|
damagedata->iHP = mob->appearanceData.iHP;
|
||||||
|
|
||||||
std::cout << (int)mob->appearanceData.iNPC_ID << " was leeched" << std::endl;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user