mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-12-23 11:50:04 +00:00
Instance tweaks + fixes
Instanced mobs tick, fusions stay dead, missions reset on enter
This commit is contained in:
parent
3050801399
commit
6473951b9a
@ -2,6 +2,7 @@
|
||||
#include "PlayerManager.hpp"
|
||||
#include "NPCManager.hpp"
|
||||
#include "settings.hpp"
|
||||
#include "MobManager.hpp"
|
||||
|
||||
std::map<std::tuple<int, int, uint64_t>, Chunk*> ChunkManager::chunks;
|
||||
|
||||
@ -207,11 +208,18 @@ void ChunkManager::createInstance(uint64_t instanceID) {
|
||||
for (int npcID : chunks[coords]->NPCs) {
|
||||
// make a copy of each NPC in the template chunks and put them in the new instance
|
||||
int newID = NPCManager::nextId++;
|
||||
BaseNPC* newNPC = new BaseNPC();
|
||||
memcpy(newNPC, NPCManager::NPCs[npcID], sizeof(BaseNPC));
|
||||
newNPC->appearanceData.iNPC_ID = newID;
|
||||
NPCManager::NPCs[newID] = newNPC;
|
||||
NPCManager::updateNPCInstance(newID, instanceID);
|
||||
BaseNPC* baseNPC = NPCManager::NPCs[npcID];
|
||||
if (baseNPC->npcClass == NPC_MOB) {
|
||||
Mob* newMob = new Mob(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
|
||||
instanceID, baseNPC->appearanceData.iNPCType, baseNPC->appearanceData.iHP, NPCManager::NPCData[baseNPC->appearanceData.iNPCType], newID);
|
||||
NPCManager::NPCs[newID] = newMob;
|
||||
MobManager::Mobs[newID] = newMob;
|
||||
} else {
|
||||
BaseNPC* newNPC = new BaseNPC(baseNPC->appearanceData.iX, baseNPC->appearanceData.iY, baseNPC->appearanceData.iZ, baseNPC->appearanceData.iAngle,
|
||||
instanceID, baseNPC->appearanceData.iNPCType, newID);
|
||||
NPCManager::NPCs[newID] = newNPC;
|
||||
}
|
||||
NPCManager::updateNPCInstance(newID, instanceID); // make sure the npc state gets updated
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,11 +199,10 @@ void MissionManager::quitMission(CNSocket* sock, CNPacketData* data) {
|
||||
return; // malformed packet
|
||||
|
||||
sP_CL2FE_REQ_PC_TASK_STOP* missionData = (sP_CL2FE_REQ_PC_TASK_STOP*)data->buf;
|
||||
quitTask(sock, missionData->iTaskNum);
|
||||
quitTask(sock, missionData->iTaskNum, true);
|
||||
}
|
||||
|
||||
void MissionManager::quitTask(CNSocket* sock, int32_t taskNum) {
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TASK_STOP_SUCC, response);
|
||||
void MissionManager::quitTask(CNSocket* sock, int32_t taskNum, bool manual) {
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
|
||||
if (plr == nullptr)
|
||||
@ -242,6 +241,14 @@ void MissionManager::quitTask(CNSocket* sock, int32_t taskNum) {
|
||||
memset(&plr->QInven[j], 0, sizeof(sItemBase));
|
||||
}
|
||||
|
||||
if (!manual) {
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TASK_END_FAIL, failResp);
|
||||
failResp.iErrorCode = 1;
|
||||
failResp.iTaskNum = taskNum;
|
||||
sock->sendPacket((void*)&failResp, P_FE2CL_REP_PC_TASK_END_FAIL, sizeof(sP_FE2CL_REP_PC_TASK_END_FAIL));
|
||||
}
|
||||
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_TASK_STOP_SUCC, response);
|
||||
response.iTaskNum = taskNum;
|
||||
sock->sendPacket((void*)&response, P_FE2CL_REP_PC_TASK_STOP_SUCC, sizeof(sP_FE2CL_REP_PC_TASK_STOP_SUCC));
|
||||
}
|
||||
@ -510,16 +517,17 @@ bool MissionManager::isQuestItemFull(CNSocket* sock, int itemId, int itemCount)
|
||||
void MissionManager::failInstancedMissions(CNSocket* sock) {
|
||||
// loop through all tasks; if the required instance is being left, "fail" the task
|
||||
Player* plr = PlayerManager::getPlayer(sock);
|
||||
for (int taskNum : plr->tasks) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int taskNum = plr->tasks[i];
|
||||
if (MissionManager::Tasks.find(taskNum) == MissionManager::Tasks.end())
|
||||
continue; // sanity check
|
||||
|
||||
TaskData* task = MissionManager::Tasks[taskNum];
|
||||
if ((plr->instanceID & 0xffffffff) == (int)(task->task["m_iRequireInstanceID"])) { // map num matches
|
||||
if (task->task["m_iRequireInstanceID"] != 0) { // mission is instanced
|
||||
int failTaskID = task->task["m_iFOutgoingTask"];
|
||||
if (failTaskID != 0) {
|
||||
MissionManager::quitTask(sock, taskNum);
|
||||
MissionManager::startTask(sock, failTaskID, task->task["m_iSTNanoID"] != 0);
|
||||
MissionManager::quitTask(sock, taskNum, false);
|
||||
plr->tasks[i] = failTaskID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ namespace MissionManager {
|
||||
|
||||
bool endTask(CNSocket *sock, int32_t taskNum);
|
||||
void saveMission(Player* player, int missionId);
|
||||
void quitTask(CNSocket* sock, int32_t taskNum);
|
||||
void quitTask(CNSocket* sock, int32_t taskNum, bool manual);
|
||||
|
||||
void failInstancedMissions(CNSocket* sock);
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ struct Mob : public BaseNPC {
|
||||
idleRange = (int)data["m_iIdleRange"] * 2; // TODO: tuning?
|
||||
|
||||
// XXX: temporarily force respawns for Fusions until we implement instancing
|
||||
if (regenTime >= 300000000)
|
||||
regenTime = 1500;
|
||||
//if (regenTime >= 300000000)
|
||||
// regenTime = 1500;
|
||||
|
||||
roamX = spawnX = appearanceData.iX;
|
||||
roamY = spawnY = appearanceData.iY;
|
||||
|
@ -65,7 +65,7 @@ void PlayerManager::addPlayer(CNSocket* key, Player plr) {
|
||||
void PlayerManager::removePlayer(CNSocket* key) {
|
||||
PlayerView& view = players[key];
|
||||
|
||||
MissionManager::failInstancedMissions(key);
|
||||
//MissionManager::failInstancedMissions(key); moved to enter
|
||||
GroupManager::groupKickPlayer(view.plr);
|
||||
|
||||
// save player to DB
|
||||
@ -233,11 +233,13 @@ void PlayerManager::sendPlayerTo(CNSocket* sock, int X, int Y, int Z, uint64_t I
|
||||
plr->instanceID = I;
|
||||
if (I != INSTANCE_OVERWORLD) {
|
||||
INITSTRUCT(sP_FE2CL_INSTANCE_MAP_INFO, pkt);
|
||||
pkt.iEP_ID = (I >> 32) == 0; // iEP_ID has to be positive for the map to be enabled
|
||||
pkt.iInstanceMapNum = (int32_t)(I & 0xffffffff); // lower 32 bits are mapnum
|
||||
sock->sendPacket((void*)&pkt, P_FE2CL_INSTANCE_MAP_INFO, sizeof(sP_FE2CL_INSTANCE_MAP_INFO));
|
||||
sendPlayerTo(sock, X, Y, Z);
|
||||
} else {
|
||||
// annoying but necessary to set the flag back
|
||||
MissionManager::failInstancedMissions(sock); // fail any instanced missions
|
||||
INITSTRUCT(sP_FE2CL_REP_PC_WARP_USE_NPC_SUCC, resp);
|
||||
resp.iX = X;
|
||||
resp.iY = Y;
|
||||
@ -383,6 +385,8 @@ void PlayerManager::enterPlayer(CNSocket* sock, CNPacketData* data) {
|
||||
|
||||
//set player equip stats
|
||||
ItemManager::setItemStats(getPlayer(sock));
|
||||
|
||||
MissionManager::failInstancedMissions(sock);
|
||||
}
|
||||
|
||||
void PlayerManager::sendToViewable(CNSocket* sock, void* buf, uint32_t type, size_t size) {
|
||||
@ -692,8 +696,9 @@ void PlayerManager::gotoPlayer(CNSocket* sock, CNPacketData* data) {
|
||||
std::cout << "\tX: " << gotoData->iToX << std::endl;
|
||||
std::cout << "\tY: " << gotoData->iToY << std::endl;
|
||||
std::cout << "\tZ: " << gotoData->iToZ << std::endl;
|
||||
)
|
||||
)
|
||||
|
||||
MissionManager::failInstancedMissions(sock); // this ensures warping by command still fails instanced missions
|
||||
sendPlayerTo(sock, gotoData->iToX, gotoData->iToY, gotoData->iToZ, 0);
|
||||
}
|
||||
|
||||
@ -910,7 +915,7 @@ void PlayerManager::changePlayerGuide(CNSocket *sock, CNPacketData *data) {
|
||||
// remove all active missions
|
||||
for (int i = 0; i < ACTIVE_MISSION_COUNT; i++) {
|
||||
if (plr->tasks[i] != 0)
|
||||
MissionManager::quitTask(sock, plr->tasks[i]);
|
||||
MissionManager::quitTask(sock, plr->tasks[i], true);
|
||||
}
|
||||
|
||||
// start Blossom nano mission if applicable
|
||||
|
Loading…
Reference in New Issue
Block a user