mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-22 21:40:05 +00:00
Implement two more mission types + tweaks & fixes
* Weapons will consume your batteries fully. * Nerfed enemy damage at lower levels. * Further reworked drain, uses a static variable as a timer (lastDrainTime) * resendMobHP has been repurposed to drainMobHP. * Players heal faster after a sizable cooldown. * Nano type advantage is more noticeable during combat. Implemented two more mission types + Tweaks * Item delivery quests now work. * Timed missions now work. * All escort missions (type 6) are skipped. * /minfo now also prints the terminator npc. * Weapon battery consumption tweaked * Fixed indentations. * Heal nanos have better output (25% -> 35%) * Damage formula had a slight tweak. * Bugfixed weapon equipping. * Other tweaks
This commit is contained in:
parent
177c5f0f17
commit
c8497a4856
@ -411,6 +411,7 @@ void minfoCommand(std::string full, std::vector<std::string>& args, CNSocket* so
|
|||||||
ChatManager::sendServerMessage(sock, "[MINFO] Current task ID: " + std::to_string(plr->tasks[i]));
|
ChatManager::sendServerMessage(sock, "[MINFO] Current task ID: " + std::to_string(plr->tasks[i]));
|
||||||
ChatManager::sendServerMessage(sock, "[MINFO] Current task type: " + std::to_string((int)(task["m_iHTaskType"])));
|
ChatManager::sendServerMessage(sock, "[MINFO] Current task type: " + std::to_string((int)(task["m_iHTaskType"])));
|
||||||
ChatManager::sendServerMessage(sock, "[MINFO] Current waypoint NPC ID: " + std::to_string((int)(task["m_iSTGrantWayPoint"])));
|
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"])));
|
||||||
|
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
if ((int)(task["m_iCSUEnemyID"][j]) != 0)
|
if ((int)(task["m_iCSUEnemyID"][j]) != 0)
|
||||||
|
@ -140,12 +140,12 @@ void ItemManager::itemMoveHandler(CNSocket* sock, CNPacketData* data) {
|
|||||||
INITSTRUCT(sP_FE2CL_PC_EQUIP_CHANGE, equipChange);
|
INITSTRUCT(sP_FE2CL_PC_EQUIP_CHANGE, equipChange);
|
||||||
|
|
||||||
equipChange.iPC_ID = plr.plr->iID;
|
equipChange.iPC_ID = plr.plr->iID;
|
||||||
if (itemmove->eFrom == (int)SlotType::EQUIP) {
|
if (itemmove->eTo == (int)SlotType::EQUIP) {
|
||||||
equipChange.iEquipSlotNum = itemmove->iFromSlotNum;
|
|
||||||
equipChange.EquipSlotItem = resp.ToSlotItem;
|
|
||||||
} else {
|
|
||||||
equipChange.iEquipSlotNum = itemmove->iToSlotNum;
|
equipChange.iEquipSlotNum = itemmove->iToSlotNum;
|
||||||
equipChange.EquipSlotItem = resp.FromSlotItem;
|
equipChange.EquipSlotItem = resp.FromSlotItem;
|
||||||
|
} else {
|
||||||
|
equipChange.iEquipSlotNum = itemmove->iFromSlotNum;
|
||||||
|
equipChange.EquipSlotItem = resp.ToSlotItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// unequip vehicle if equip slot 8 is 0
|
// unequip vehicle if equip slot 8 is 0
|
||||||
|
@ -77,20 +77,27 @@ void MissionManager::taskStart(CNSocket* sock, CNPacketData* data) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TaskData& task = *Tasks[missionData->iTaskNum];
|
||||||
|
|
||||||
response.iTaskNum = missionData->iTaskNum;
|
response.iTaskNum = missionData->iTaskNum;
|
||||||
|
response.iRemainTime = task["m_iSTGrantTimer"];
|
||||||
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_START_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_START_SUCC));
|
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_START_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_START_SUCC));
|
||||||
|
|
||||||
// HACK: auto-succeed Eduardo escort task
|
// HACK: auto-succeed escort task
|
||||||
// TODO: maybe check for iTaskType == 6 and skip all escort missions?
|
if (task["m_iHTaskType"] == 6) {
|
||||||
if (missionData->iTaskNum == 576) {
|
|
||||||
std::cout << "Sending Eduardo success packet" << std::endl;
|
std::cout << "Sending Eduardo success packet" << std::endl;
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_SUCC, response);
|
INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_SUCC, response);
|
||||||
|
|
||||||
endTask(sock, 576);
|
endTask(sock, missionData->iTaskNum);
|
||||||
response.iTaskNum = 576;
|
response.iTaskNum = missionData->iTaskNum;
|
||||||
|
|
||||||
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC));
|
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_END_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_END_SUCC));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Give player their delivery items at the start.
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
if (task["m_iSTItemID"][i] != 0 && task["m_iSTItemNumNeeded"][i] > 0)
|
||||||
|
dropQuestItem(sock, missionData->iTaskNum, task["m_iSTItemNumNeeded"][i], task["m_iSTItemID"][i], 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) {
|
void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) {
|
||||||
@ -98,6 +105,25 @@ void MissionManager::taskEnd(CNSocket* sock, CNPacketData* data) {
|
|||||||
return; // malformed packet
|
return; // malformed packet
|
||||||
|
|
||||||
sP_CL2FE_REQ_PC_TASK_END* missionData = (sP_CL2FE_REQ_PC_TASK_END*)data->buf;
|
sP_CL2FE_REQ_PC_TASK_END* missionData = (sP_CL2FE_REQ_PC_TASK_END*)data->buf;
|
||||||
|
|
||||||
|
// failed timed missions give an iNPC_ID of 0
|
||||||
|
if (missionData->iNPC_ID == 0) {
|
||||||
|
TaskData* task = MissionManager::Tasks[missionData->iTaskNum];
|
||||||
|
// double-checking
|
||||||
|
if (task->task["m_iHTaskType"] == 3) {
|
||||||
|
Player* plr = PlayerManager::getPlayer(sock);
|
||||||
|
int failTaskID = task->task["m_iFOutgoingTask"];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_SUCC, response);
|
INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_SUCC, response);
|
||||||
|
|
||||||
response.iTaskNum = missionData->iTaskNum;
|
response.iTaskNum = missionData->iTaskNum;
|
||||||
|
@ -85,11 +85,12 @@ void MobManager::pcAttackNpcs(CNSocket *sock, CNPacketData *data) {
|
|||||||
damage.first = plr->pointDamage;
|
damage.first = plr->pointDamage;
|
||||||
|
|
||||||
int difficulty = (int)mob->data["m_iNpcLevel"];
|
int difficulty = (int)mob->data["m_iNpcLevel"];
|
||||||
|
damage = getDamage(damage.first, (int)mob->data["m_iProtection"], true, (plr->batteryW > 6 + difficulty), NanoManager::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);
|
||||||
|
|
||||||
damage = getDamage(damage.first, (int)mob->data["m_iProtection"], true, (plr->batteryW >= 11 + difficulty), NanoManager::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);
|
if (plr->batteryW >= 6 + difficulty)
|
||||||
|
plr->batteryW -= 6 + difficulty;
|
||||||
if (plr->batteryW >= 11 + difficulty)
|
else
|
||||||
plr->batteryW -= 11 + difficulty;
|
plr->batteryW = 0;
|
||||||
|
|
||||||
damage.first = hitMob(sock, mob, damage.first);
|
damage.first = hitMob(sock, mob, damage.first);
|
||||||
|
|
||||||
@ -126,7 +127,7 @@ void MobManager::npcAttackPc(Mob *mob, time_t currTime) {
|
|||||||
sP_FE2CL_NPC_ATTACK_PCs *pkt = (sP_FE2CL_NPC_ATTACK_PCs*)respbuf;
|
sP_FE2CL_NPC_ATTACK_PCs *pkt = (sP_FE2CL_NPC_ATTACK_PCs*)respbuf;
|
||||||
sAttackResult *atk = (sAttackResult*)(respbuf + sizeof(sP_FE2CL_NPC_ATTACK_PCs));
|
sAttackResult *atk = (sAttackResult*)(respbuf + sizeof(sP_FE2CL_NPC_ATTACK_PCs));
|
||||||
|
|
||||||
auto damage = getDamage(475 + (int)mob->data["m_iPower"], plr->defense, false, false, -1, -1, 1);
|
auto damage = getDamage(450 + (int)mob->data["m_iPower"], plr->defense, false, false, -1, -1, rand() % plr->level + 1);
|
||||||
plr->HP -= damage.first;
|
plr->HP -= damage.first;
|
||||||
|
|
||||||
pkt->iNPC_ID = mob->appearanceData.iNPC_ID;
|
pkt->iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
@ -492,7 +493,7 @@ void MobManager::combatStep(Mob *mob, time_t currTime) {
|
|||||||
// movement logic
|
// movement logic
|
||||||
if (mob->nextMovement != 0 && currTime < mob->nextMovement)
|
if (mob->nextMovement != 0 && currTime < mob->nextMovement)
|
||||||
return;
|
return;
|
||||||
mob->nextMovement = currTime + 399;
|
mob->nextMovement = currTime + 400;
|
||||||
if (currTime >= mob->nextAttack)
|
if (currTime >= mob->nextAttack)
|
||||||
mob->nextAttack = 0;
|
mob->nextAttack = 0;
|
||||||
|
|
||||||
@ -598,7 +599,7 @@ void MobManager::retreatStep(Mob *mob, time_t currTime) {
|
|||||||
if (mob->nextMovement != 0 && currTime < mob->nextMovement)
|
if (mob->nextMovement != 0 && currTime < mob->nextMovement)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mob->nextMovement = currTime + 399;
|
mob->nextMovement = currTime + 400;
|
||||||
|
|
||||||
// distance between spawn point and current location
|
// distance between spawn point and current location
|
||||||
int distance = hypot(mob->appearanceData.iX - mob->roamX, mob->appearanceData.iY - mob->roamY);
|
int distance = hypot(mob->appearanceData.iX - mob->roamX, mob->appearanceData.iY - mob->roamY);
|
||||||
@ -611,11 +612,9 @@ void MobManager::retreatStep(Mob *mob, time_t currTime) {
|
|||||||
|
|
||||||
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
pkt.iNPC_ID = mob->appearanceData.iNPC_ID;
|
||||||
pkt.iSpeed = (int)mob->data["m_iRunSpeed"] * 2;
|
pkt.iSpeed = (int)mob->data["m_iRunSpeed"] * 2;
|
||||||
mob->appearanceData.iX = targ.first;
|
|
||||||
mob->appearanceData.iY = targ.second;
|
|
||||||
pkt.iToX = mob->appearanceData.iX = targ.first;
|
pkt.iToX = mob->appearanceData.iX = targ.first;
|
||||||
pkt.iToY = mob->appearanceData.iY = targ.second;
|
pkt.iToY = mob->appearanceData.iY = targ.second;
|
||||||
pkt.iToZ = mob->appearanceData.iZ;
|
pkt.iToZ = mob->appearanceData.iZ = mob->spawnZ;
|
||||||
|
|
||||||
// notify all nearby players
|
// notify all nearby players
|
||||||
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_MOVE, sizeof(sP_FE2CL_NPC_MOVE));
|
NPCManager::sendToViewable(mob, &pkt, P_FE2CL_NPC_MOVE, sizeof(sP_FE2CL_NPC_MOVE));
|
||||||
@ -630,11 +629,14 @@ void MobManager::retreatStep(Mob *mob, time_t currTime) {
|
|||||||
mob->nextAttack = 0;
|
mob->nextAttack = 0;
|
||||||
mob->appearanceData.iConditionBitFlag = 0;
|
mob->appearanceData.iConditionBitFlag = 0;
|
||||||
|
|
||||||
resendMobHP(mob);
|
// HACK: we haven't found a better way to refresh a mob's client-side status
|
||||||
|
drainMobHP(mob, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobManager::step(CNServer *serv, time_t currTime) {
|
void MobManager::step(CNServer *serv, time_t currTime) {
|
||||||
|
static time_t lastDrainTime = 0;
|
||||||
|
|
||||||
for (auto& pair : Mobs) {
|
for (auto& pair : Mobs) {
|
||||||
int x = pair.second->appearanceData.iX;
|
int x = pair.second->appearanceData.iX;
|
||||||
int y = pair.second->appearanceData.iY;
|
int y = pair.second->appearanceData.iY;
|
||||||
@ -644,9 +646,8 @@ void MobManager::step(CNServer *serv, time_t currTime) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// drain
|
// drain
|
||||||
if (pair.second->appearanceData.iConditionBitFlag & CSB_BIT_BOUNDINGBALL) {
|
if (currTime - lastDrainTime >= 600 && pair.second->appearanceData.iConditionBitFlag & CSB_BIT_BOUNDINGBALL) {
|
||||||
pair.second->appearanceData.iHP -= pair.second->maxHealth / 50; // lose 10% every second
|
drainMobHP(pair.second, pair.second->maxHealth * 3 / 50); // lose 10% every second
|
||||||
// TODO: Make this send a damage packet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// unbuffing
|
// unbuffing
|
||||||
@ -693,6 +694,9 @@ void MobManager::step(CNServer *serv, time_t currTime) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currTime - lastDrainTime >= 600)
|
||||||
|
lastDrainTime = currTime;
|
||||||
|
|
||||||
// deallocate all NPCs queued for removal
|
// deallocate all NPCs queued for removal
|
||||||
while (RemovalQueue.size() > 0) {
|
while (RemovalQueue.size() > 0) {
|
||||||
NPCManager::destroyNPC(RemovalQueue.front());
|
NPCManager::destroyNPC(RemovalQueue.front());
|
||||||
@ -752,8 +756,10 @@ void MobManager::combatBegin(CNSocket *sock, CNPacketData *data) {
|
|||||||
void MobManager::combatEnd(CNSocket *sock, CNPacketData *data) {
|
void MobManager::combatEnd(CNSocket *sock, CNPacketData *data) {
|
||||||
Player *plr = PlayerManager::getPlayer(sock);
|
Player *plr = PlayerManager::getPlayer(sock);
|
||||||
|
|
||||||
if (plr != nullptr)
|
if (plr != nullptr) {
|
||||||
plr->inCombat = false;
|
plr->inCombat = false;
|
||||||
|
plr->healCooldown = 4000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MobManager::dotDamageOnOff(CNSocket *sock, CNPacketData *data) {
|
void MobManager::dotDamageOnOff(CNSocket *sock, CNPacketData *data) {
|
||||||
@ -848,11 +854,14 @@ void MobManager::playerTick(CNServer *serv, time_t currTime) {
|
|||||||
dealGooDamage(sock, PC_MAXHEALTH(plr->level) * 3 / 20);
|
dealGooDamage(sock, PC_MAXHEALTH(plr->level) * 3 / 20);
|
||||||
|
|
||||||
// heal
|
// heal
|
||||||
if (currTime - lastHealTime >= 6000 && !plr->inCombat && plr->HP < PC_MAXHEALTH(plr->level)) {
|
if (currTime - lastHealTime >= 4000 && !plr->inCombat && plr->HP < PC_MAXHEALTH(plr->level)) {
|
||||||
|
if (currTime - lastHealTime - plr->healCooldown >= 4000) {
|
||||||
plr->HP += PC_MAXHEALTH(plr->level) / 5;
|
plr->HP += PC_MAXHEALTH(plr->level) / 5;
|
||||||
if (plr->HP > PC_MAXHEALTH(plr->level))
|
if (plr->HP > PC_MAXHEALTH(plr->level))
|
||||||
plr->HP = PC_MAXHEALTH(plr->level);
|
plr->HP = PC_MAXHEALTH(plr->level);
|
||||||
transmit = true;
|
transmit = true;
|
||||||
|
} else
|
||||||
|
plr->healCooldown -= 4000;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
@ -894,7 +903,7 @@ void MobManager::playerTick(CNServer *serv, time_t currTime) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if this was a heal tick, update the counter outside of the loop
|
// if this was a heal tick, update the counter outside of the loop
|
||||||
if (currTime - lastHealTime >= 6000)
|
if (currTime - lastHealTime >= 4000)
|
||||||
lastHealTime = currTime;
|
lastHealTime = currTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -907,15 +916,15 @@ std::pair<int,int> MobManager::getDamage(int attackPower, int defensePower, bool
|
|||||||
|
|
||||||
// base calculation
|
// base calculation
|
||||||
int damage = attackPower * attackPower / (attackPower + defensePower);
|
int damage = attackPower * attackPower / (attackPower + defensePower);
|
||||||
damage = std::max(std::max(29, attackPower / 7), damage - defensePower * (12 + difficulty) / 65);
|
damage = std::max(10 + attackPower / 10, damage - defensePower * (4 + difficulty) / 40);
|
||||||
damage = damage * (rand() % 40 + 80) / 100;
|
damage = damage * (rand() % 40 + 80) / 100;
|
||||||
|
|
||||||
// Adaptium/Blastons/Cosmix
|
// Adaptium/Blastons/Cosmix
|
||||||
if (attackerStyle != -1 && defenderStyle != -1 && attackerStyle != defenderStyle) {
|
if (attackerStyle != -1 && defenderStyle != -1 && attackerStyle != defenderStyle) {
|
||||||
if (attackerStyle < defenderStyle || attackerStyle - defenderStyle == 2)
|
if (attackerStyle < defenderStyle || attackerStyle - defenderStyle == 2)
|
||||||
damage = damage * 5 / 4;
|
damage = damage * 3 / 2;
|
||||||
else
|
else
|
||||||
damage = damage * 4 / 5;
|
damage = damage * 2 / 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// weapon boosts
|
// weapon boosts
|
||||||
@ -988,10 +997,12 @@ void MobManager::pcAttackChars(CNSocket *sock, CNPacketData *data) {
|
|||||||
else
|
else
|
||||||
damage.first = plr->pointDamage;
|
damage.first = plr->pointDamage;
|
||||||
|
|
||||||
damage = getDamage(damage.first, target->defense, true, (plr->batteryW >= 12), -1, -1, 1);
|
damage = getDamage(damage.first, target->defense, true, (plr->batteryW > 6 + plr->level), -1, -1, 1);
|
||||||
|
|
||||||
if (plr->batteryW >= 12)
|
if (plr->batteryW >= 6 + plr->level)
|
||||||
plr->batteryW -= 12;
|
plr->batteryW -= 6 + plr->level;
|
||||||
|
else
|
||||||
|
plr->batteryW = 0;
|
||||||
|
|
||||||
target->HP -= damage.first;
|
target->HP -= damage.first;
|
||||||
|
|
||||||
@ -1017,11 +1028,13 @@ void MobManager::pcAttackChars(CNSocket *sock, CNPacketData *data) {
|
|||||||
|
|
||||||
int difficulty = (int)mob->data["m_iNpcLevel"];
|
int difficulty = (int)mob->data["m_iNpcLevel"];
|
||||||
|
|
||||||
damage = getDamage(damage.first, (int)mob->data["m_iProtection"], true, (plr->batteryW >= 11 + difficulty),
|
damage = getDamage(damage.first, (int)mob->data["m_iProtection"], true, (plr->batteryW > 6 + difficulty),
|
||||||
NanoManager::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);
|
NanoManager::nanoStyle(plr->activeNano), (int)mob->data["m_iNpcStyle"], difficulty);
|
||||||
|
|
||||||
if (plr->batteryW >= 11 + difficulty)
|
if (plr->batteryW >= 6 + difficulty)
|
||||||
plr->batteryW -= 11 + difficulty;
|
plr->batteryW -= 6 + difficulty;
|
||||||
|
else
|
||||||
|
plr->batteryW = 0;
|
||||||
|
|
||||||
damage.first = hitMob(sock, mob, damage.first);
|
damage.first = hitMob(sock, mob, damage.first);
|
||||||
|
|
||||||
@ -1045,25 +1058,24 @@ void MobManager::pcAttackChars(CNSocket *sock, CNPacketData *data) {
|
|||||||
PlayerManager::sendToViewable(sock, (void*)respbuf, P_FE2CL_PC_ATTACK_CHARs, resplen);
|
PlayerManager::sendToViewable(sock, (void*)respbuf, P_FE2CL_PC_ATTACK_CHARs, resplen);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: we haven't found a better way to refresh a mob's client-side status
|
void MobManager::drainMobHP(Mob *mob, int amount) {
|
||||||
void MobManager::resendMobHP(Mob *mob) {
|
size_t resplen = sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK) + sizeof(sSkillResult_Damage);
|
||||||
size_t resplen = sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK) + sizeof(sSkillResult_Heal_HP);
|
|
||||||
assert(resplen < CN_PACKET_BUFFER_SIZE - 8);
|
assert(resplen < CN_PACKET_BUFFER_SIZE - 8);
|
||||||
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
uint8_t respbuf[CN_PACKET_BUFFER_SIZE];
|
||||||
|
|
||||||
memset(respbuf, 0, resplen);
|
memset(respbuf, 0, resplen);
|
||||||
|
|
||||||
sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK *pkt = (sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK*)respbuf;
|
sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK *pkt = (sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK*)respbuf;
|
||||||
sSkillResult_Heal_HP *heal = (sSkillResult_Heal_HP*)(respbuf + sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK));
|
sSkillResult_Damage *drain = (sSkillResult_Damage*)(respbuf + sizeof(sP_FE2CL_CHAR_TIME_BUFF_TIME_TICK));
|
||||||
|
|
||||||
pkt->iID = mob->appearanceData.iNPC_ID;
|
pkt->iID = mob->appearanceData.iNPC_ID;
|
||||||
pkt->eCT = 4; // mob
|
pkt->eCT = 4; // mob
|
||||||
pkt->iTB_ID = ECSB_HEAL; // sSkillResult_Heal_HP
|
pkt->iTB_ID = ECSB_BOUNDINGBALL;
|
||||||
|
|
||||||
heal->eCT = 4;
|
drain->eCT = 4;
|
||||||
heal->iID = mob->appearanceData.iNPC_ID;
|
drain->iID = mob->appearanceData.iNPC_ID;
|
||||||
heal->iHealHP = 0;
|
drain->iDamage = amount;
|
||||||
heal->iHP = mob->appearanceData.iHP;
|
drain->iHP = mob->appearanceData.iHP -= amount;
|
||||||
|
|
||||||
NPCManager::sendToViewable(mob, (void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
|
NPCManager::sendToViewable(mob, (void*)&respbuf, P_FE2CL_CHAR_TIME_BUFF_TIME_TICK, resplen);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ namespace MobManager {
|
|||||||
std::pair<int,int> getDamage(int, int, bool, bool, int, int, int);
|
std::pair<int,int> getDamage(int, int, bool, bool, int, int, int);
|
||||||
|
|
||||||
void pcAttackChars(CNSocket *sock, CNPacketData *data);
|
void pcAttackChars(CNSocket *sock, CNPacketData *data);
|
||||||
void resendMobHP(Mob *mob);
|
void drainMobHP(Mob *mob, int amount);
|
||||||
void incNextMovement(Mob *mob, time_t currTime=0);
|
void incNextMovement(Mob *mob, time_t currTime=0);
|
||||||
bool aggroCheck(Mob *mob, time_t currTime);
|
bool aggroCheck(Mob *mob, time_t currTime);
|
||||||
}
|
}
|
||||||
|
@ -608,13 +608,6 @@ void NPCManager::handleWarp(CNSocket* sock, int32_t warpId) {
|
|||||||
if (otherPlr == nullptr || sockTo == nullptr)
|
if (otherPlr == nullptr || sockTo == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (otherPlr->instanceID == 0) {
|
|
||||||
otherPlr->lastX = otherPlr->x;
|
|
||||||
otherPlr->lastY = otherPlr->y;
|
|
||||||
otherPlr->lastZ = otherPlr->z;
|
|
||||||
otherPlr->lastAngle = otherPlr->angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerManager::sendPlayerTo(sockTo, Warps[warpId].x, Warps[warpId].y, Warps[warpId].z, instanceID);
|
PlayerManager::sendPlayerTo(sockTo, Warps[warpId].x, Warps[warpId].y, Warps[warpId].z, instanceID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -672,8 +672,8 @@ void activePower(CNSocket *sock, CNPacketData *data,
|
|||||||
// active nano power dispatch table
|
// active nano power dispatch table
|
||||||
std::vector<ActivePower> ActivePowers = {
|
std::vector<ActivePower> ActivePowers = {
|
||||||
ActivePower(StunPowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_STUN, CSB_BIT_STUN, 2250),
|
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(HealPowers, activePower<sSkillResult_Heal_HP, doHeal>, EST_HEAL_HP, CSB_BIT_NONE, 35),
|
||||||
ActivePower(GroupHealPowers, activePower<sSkillResult_Heal_HP, doGroupHeal, GHEAL>,EST_HEAL_HP, CSB_BIT_NONE, 15),
|
ActivePower(GroupHealPowers, activePower<sSkillResult_Heal_HP, doGroupHeal, GHEAL>,EST_HEAL_HP, CSB_BIT_NONE, 20),
|
||||||
// TODO: Recall
|
// TODO: Recall
|
||||||
ActivePower(DrainPowers, activePower<sSkillResult_Buff, doBuff>, EST_BOUNDINGBALL, CSB_BIT_BOUNDINGBALL, 3000),
|
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(SnarePowers, activePower<sSkillResult_Damage_N_Debuff, doDebuff>, EST_SNARE, CSB_BIT_DN_MOVE_SPEED, 4500),
|
||||||
|
@ -50,6 +50,7 @@ struct Player {
|
|||||||
|
|
||||||
bool inCombat;
|
bool inCombat;
|
||||||
bool passiveNanoOut;
|
bool passiveNanoOut;
|
||||||
|
int healCooldown;
|
||||||
|
|
||||||
int pointDamage;
|
int pointDamage;
|
||||||
int groupDamage;
|
int groupDamage;
|
||||||
|
@ -280,7 +280,6 @@ void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z) {
|
|||||||
plrv.currentChunks.clear();
|
plrv.currentChunks.clear();
|
||||||
plrv.chunkPos = std::make_tuple(0, 0, plrv.plr->instanceID);
|
plrv.chunkPos = std::make_tuple(0, 0, plrv.plr->instanceID);
|
||||||
sock->sendPacket((void*)&pkt, P_FE2CL_REP_PC_GOTO_SUCC, sizeof(sP_FE2CL_REP_PC_GOTO_SUCC));
|
sock->sendPacket((void*)&pkt, P_FE2CL_REP_PC_GOTO_SUCC, sizeof(sP_FE2CL_REP_PC_GOTO_SUCC));
|
||||||
updatePlayerPosition(sock, X, Y, Z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
||||||
|
Loading…
Reference in New Issue
Block a user