diff --git a/src/ChatManager.cpp b/src/ChatManager.cpp index 86a79a6..a278266 100644 --- a/src/ChatManager.cpp +++ b/src/ChatManager.cpp @@ -448,6 +448,9 @@ void minfoCommand(std::string full, std::vector& args, CNSocket* so ChatManager::sendServerMessage(sock, "[MINFO] Current waypoint NPC ID: " + std::to_string((int)(task["m_iSTGrantWayPoint"]))); ChatManager::sendServerMessage(sock, "[MINFO] Current terminator NPC ID: " + std::to_string((int)(task["m_iHTerminatorNPCID"]))); + if ((int)(task["m_iSTGrantTimer"]) != 0) + ChatManager::sendServerMessage(sock, "[MINFO] Current task timer: " + std::to_string((int)(task["m_iSTGrantTimer"]))); + for (int j = 0; j < 3; j++) if ((int)(task["m_iCSUEnemyID"][j]) != 0) ChatManager::sendServerMessage(sock, "[MINFO] Current task mob #" + std::to_string(j+1) +": " + std::to_string((int)(task["m_iCSUEnemyID"][j]))); diff --git a/src/MissionManager.cpp b/src/MissionManager.cpp index c06ee1d..5786381 100644 --- a/src/MissionManager.cpp +++ b/src/MissionManager.cpp @@ -110,7 +110,7 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) { if (missionData->iNPC_ID == 0) { TaskData* task = MissionManager::Tasks[missionData->iTaskNum]; // double-checking - if (task->task["m_iHTaskType"] == 3) { + if (task->task["m_iSTGrantTimer"] > 0) { Player* plr = PlayerManager::getPlayer(sock); int failTaskID = task->task["m_iFOutgoingTask"]; if (failTaskID != 0) { diff --git a/src/MobManager.cpp b/src/MobManager.cpp index 1188e99..626f9fe 100644 --- a/src/MobManager.cpp +++ b/src/MobManager.cpp @@ -522,7 +522,8 @@ void MobManager::combatStep(Mob *mob, time_t currTime) { } // drain - if ((mob->lastDrainTime == 0 || currTime - mob->lastDrainTime >= 1000) && mob->appearanceData.iConditionBitFlag & CSB_BIT_BOUNDINGBALL) { + if (mob->skillStyle < 0 && (mob->lastDrainTime == 0 || currTime - mob->lastDrainTime >= 1000) + && mob->appearanceData.iConditionBitFlag & CSB_BIT_BOUNDINGBALL) { drainMobHP(mob, mob->maxHealth / 20); // lose 5% every second mob->lastDrainTime = currTime; } @@ -558,7 +559,7 @@ void MobManager::combatStep(Mob *mob, time_t currTime) { int mobRange = (int)mob->data["m_iAtkRange"] + (int)mob->data["m_iRadius"]; if (currTime >= mob->nextAttack) { - if (mob->skillStyle != -1 || distance <= mobRange || rand() % 10 == 0) // while not in attack range, 1 / 10 chance. + if (mob->skillStyle != -1 || distance <= mobRange || rand() % 20 == 0) // while not in attack range, 1 / 10 chance. useAbilities(mob, currTime); if (mob->target == nullptr) return; @@ -963,23 +964,10 @@ void MobManager::playerTick(CNServer *serv, time_t currTime) { for (int i = 0; i < 3; i++) { if (plr->activeNano != 0 && plr->equippedNanos[i] == plr->activeNano) { // spend stamina - plr->Nanos[plr->activeNano].iStamina -= 1 + plr->nanoDrainRate * 2 / 5; + plr->Nanos[plr->activeNano].iStamina -= 1 + plr->nanoDrainRate / 5; - if (plr->Nanos[plr->activeNano].iStamina <= 0) { - // passive nano unbuffing - int skillID = plr->Nanos[plr->activeNano].iSkillID; - if (NanoManager::SkillTable[skillID].drainType == 2) { - std::vector targetData = NanoManager::findTargets(plr, skillID); - - for (auto& pwr : NanoManager::NanoPowers) - if (pwr.skillType == NanoManager::SkillTable[skillID].skillType) - NanoManager::nanoUnbuff(sock, targetData, pwr.bitFlag, pwr.timeBuffID, 0, (NanoManager::SkillTable[skillID].targetType == 3)); - } - - plr->Nanos[plr->activeNano].iStamina = 0; - plr->activeNano = 0; - plr->nanoDrainRate = 0; - } + if (plr->Nanos[plr->activeNano].iStamina <= 0) + NanoManager::summonNano(sock, -1); // unsummon nano transmit = true; } else if (plr->Nanos[plr->equippedNanos[i]].iStamina < 150) { // regain stamina @@ -1521,7 +1509,7 @@ void MobManager::useAbilities(Mob *mob, time_t currTime) { return; } - int random = rand() % 100 * 10000; + int random = rand() % 100 * 15000; int prob1 = (int)mob->data["m_iActiveSkill1Prob"]; // active skill probability int prob2 = (int)mob->data["m_iCorruptionTypeProb"]; // corruption probability int prob3 = (int)mob->data["m_iMegaTypeProb"]; // eruption probability @@ -1646,10 +1634,8 @@ void MobManager::dealCorruption(Mob *mob, std::vector targetData, int skill respdata[i].iHitFlag = 16; // lose respdata[i].iDamage = NanoManager::SkillTable[skillID].powerIntensity[0] * PC_MAXHEALTH((int)mob->data["m_iNpcLevel"]) / 1500; respdata[i].iNanoStamina = plr->Nanos[plr->activeNano].iStamina -= 90; - if (plr->Nanos[plr->activeNano].iStamina < 0) { + if (plr->Nanos[plr->activeNano].iStamina < 0) respdata[i].iNanoStamina = plr->Nanos[plr->activeNano].iStamina = 0; - NanoManager::summonNano(sock, -1); // unsummon when stamina is 0 - } } respdata[i].iHP = plr->HP-= respdata[i].iDamage; diff --git a/src/NanoManager.cpp b/src/NanoManager.cpp index e47d691..84a06bf 100644 --- a/src/NanoManager.cpp +++ b/src/NanoManager.cpp @@ -142,15 +142,15 @@ void NanoManager::nanoSkillUseHandler(CNSocket* sock, CNPacketData* data) { boost = 1; plr->Nanos[plr->activeNano].iStamina -= SkillTable[skillID].batteryUse[boost*3]; - if (plr->Nanos[plr->activeNano].iStamina < 0) { + if (plr->Nanos[plr->activeNano].iStamina < 0) plr->Nanos[plr->activeNano].iStamina = 0; - plr->activeNano = 0; - plr->nanoDrainRate = 0; - } for (auto& pwr : NanoPowers) if (pwr.skillType == SkillTable[skillID].skillType) pwr.handle(sock, targetData, nanoID, skillID, SkillTable[skillID].durationTime[boost], SkillTable[skillID].powerIntensity[boost]); + + if (plr->Nanos[plr->activeNano].iStamina < 0) + summonNano(sock, -1); } void NanoManager::nanoSkillSetHandler(CNSocket* sock, CNPacketData* data) { @@ -798,12 +798,14 @@ bool doMove(CNSocket *sock, sSkillResult_Move *respdata, int i, int32_t targetID return false; } + Player *plr2 = PlayerManager::getPlayer(sock); + respdata[i].eCT = 1; respdata[i].iID = plr->iID; - respdata[i].iMapNum = plr->recallInstance; - respdata[i].iMoveX = plr->recallX; - respdata[i].iMoveY = plr->recallY; - respdata[i].iMoveZ = plr->recallZ; + respdata[i].iMapNum = plr2->recallInstance; + respdata[i].iMoveX = plr2->recallX; + respdata[i].iMoveY = plr2->recallY; + respdata[i].iMoveZ = plr2->recallZ; return true; } @@ -854,18 +856,19 @@ void nanoPower(CNSocket *sock, std::vector targetData, plr->iGroupConditionBitFlag |= bitFlag; } - CNSocket *workSock = sock; - - for (int i = 0; i < targetData[0]; i++) { - if (SkillTable[skillID].targetType == 3 && PlayerManager::getSockFromID(targetData[i + 1]) != nullptr) - workSock = PlayerManager::getSockFromID(targetData[i+1]); - if (!work(workSock, respdata, i, targetData[i+1], bitFlag, timeBuffID, duration, amount)) - return; // TODO: Jade fix pls (name in popup is wrong) - } + for (int i = 0; i < targetData[0]; i++) + if (!work(sock, respdata, i, targetData[i+1], bitFlag, timeBuffID, duration, amount)) + return; sock->sendPacket((void*)&respbuf, P_FE2CL_NANO_SKILL_USE_SUCC, resplen); assert(sizeof(sP_FE2CL_NANO_SKILL_USE_SUCC) == sizeof(sP_FE2CL_NANO_SKILL_USE)); - PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen); + if (skillType == EST_RECALL_GROUP) { // in the case of group recall, nobody but group members need the packet + for (int i = 0; i < targetData[0]; i++) { + CNSocket *sock2 = PlayerManager::getSockFromID(targetData[i+1]); + sock2->sendPacket((void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen); + } + } else + PlayerManager::sendToViewable(sock, (void*)&respbuf, P_FE2CL_NANO_SKILL_USE, resplen); // Warping on recall if (skillType == EST_RECALL || skillType == EST_RECALL_GROUP) { diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 64547eb..66eb569 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -728,7 +728,8 @@ void PlayerManager::revivePlayer(CNSocket* sock, CNPacketData* data) { for (int i = 0; i < 3; i++) { int nanoID = plr->equippedNanos[i]; // halve nano health if respawning - if (reviveData->iRegenType == 6) + // all revives not 3-5 are normal respawns. + if (reviveData->iRegenType < 3 && reviveData->iRegenType > 5) plr->Nanos[nanoID].iStamina = 75; // max is 150, so 75 is half response.PCRegenData.Nanos[i] = plr->Nanos[nanoID]; if (plr->activeNano == nanoID)