From 9266b633cc024c69a381e61c80024b3a3084625f Mon Sep 17 00:00:00 2001 From: FinnHornhoover Date: Sat, 9 Dec 2023 06:49:26 +0300 Subject: [PATCH 1/2] fixed unexpected randomization of barkers --- src/NPCManager.cpp | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 1d80a93..6d02ba7 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -94,20 +94,34 @@ void NPCManager::sendToViewable(Entity *npc, void *buf, uint32_t type, size_t si static void npcBarkHandler(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_BARKER* req = (sP_CL2FE_REQ_BARKER*)data->buf; - // get bark IDs from task data - TaskData* td = Missions::Tasks[req->iMissionTaskID]; - std::vector barks; - for (int i = 0; i < 4; i++) { - if (td->task["m_iHBarkerTextID"][i] != 0) // non-zeroes only - barks.push_back(td->task["m_iHBarkerTextID"][i]); + int taskID = req->iMissionTaskID; + int npcID = req->iNPC_ID; + + if (Missions::Tasks.find(taskID) == Missions::Tasks.end()) { + std::cout << "mission task not found: " << taskID << std::endl; + return; } - if (barks.empty()) + if (npcID < 0 || npcID >= NPCData.size()) { + std::cout << "npc not found: " << npcID << std::endl; + return; + } + + // get bark IDs from task data + TaskData* td = Missions::Tasks[taskID]; + auto& barks = td->task["m_iHBarkerTextID"]; + + int barkType = NPCData[npcID]["m_iBarkerType"]; + if (barkType < 1 || barkType > 4) + return; // no barks + + int barkID = barks[barkType - 1]; + if (barkID == 0) return; // no barks INITSTRUCT(sP_FE2CL_REP_BARKER, resp); - resp.iNPC_ID = req->iNPC_ID; - resp.iMissionStringID = barks[Rand::rand(barks.size())]; + resp.iNPC_ID = npcID; + resp.iMissionStringID = barkID; sock->sendPacket(resp, P_FE2CL_REP_BARKER); } From 6d94eec964429cc488cfce39325eb23ca7e366f9 Mon Sep 17 00:00:00 2001 From: FinnHornhoover Date: Tue, 12 Dec 2023 00:47:56 +0300 Subject: [PATCH 2/2] randomized npcs for mission barkers --- src/NPCManager.cpp | 43 +++++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/NPCManager.cpp b/src/NPCManager.cpp index 6d02ba7..cb15ca3 100644 --- a/src/NPCManager.cpp +++ b/src/NPCManager.cpp @@ -95,33 +95,48 @@ static void npcBarkHandler(CNSocket* sock, CNPacketData* data) { sP_CL2FE_REQ_BARKER* req = (sP_CL2FE_REQ_BARKER*)data->buf; int taskID = req->iMissionTaskID; - int npcID = req->iNPC_ID; + // ignore req->iNPC_ID as it is often fixated on a single npc in the region if (Missions::Tasks.find(taskID) == Missions::Tasks.end()) { std::cout << "mission task not found: " << taskID << std::endl; return; } - if (npcID < 0 || npcID >= NPCData.size()) { - std::cout << "npc not found: " << npcID << std::endl; - return; - } - - // get bark IDs from task data TaskData* td = Missions::Tasks[taskID]; auto& barks = td->task["m_iHBarkerTextID"]; - int barkType = NPCData[npcID]["m_iBarkerType"]; - if (barkType < 1 || barkType > 4) - return; // no barks + Player* plr = PlayerManager::getPlayer(sock); + std::vector> npcLines; - int barkID = barks[barkType - 1]; - if (barkID == 0) - return; // no barks + for (Chunk* chunk : plr->viewableChunks) { + for (auto ent = chunk->entities.begin(); ent != chunk->entities.end(); ent++) { + if (ent->kind == EntityKind::PLAYER) + continue; + + BaseNPC* npc = (BaseNPC*)ent->getEntity(); + if (npc->type < 0 || npc->type >= NPCData.size()) + continue; // npc unknown ?! + + int barkType = NPCData[npc->type]["m_iBarkerType"]; + if (barkType < 1 || barkType > 4) + continue; // no barks + + int barkID = barks[barkType - 1]; + if (barkID == 0) + continue; // no barks + + npcLines.push_back(std::make_pair(npc->id, barkID)); + } + } + + if (npcLines.size() == 0) + return; // totally no barks + + auto& [npcID, missionStringID] = npcLines[Rand::rand(npcLines.size())]; INITSTRUCT(sP_FE2CL_REP_BARKER, resp); resp.iNPC_ID = npcID; - resp.iMissionStringID = barkID; + resp.iMissionStringID = missionStringID; sock->sendPacket(resp, P_FE2CL_REP_BARKER); }