From db73b85bc8318fb3c5672e3f216316f20d935a23 Mon Sep 17 00:00:00 2001 From: gsemaj Date: Sat, 23 Apr 2022 15:58:08 -0400 Subject: [PATCH] Refactor player groups Group structures are used now. Adds more checks in some places but simplifies things overall. We can expand this system to entities as well now pretty trivially. --- src/Combat.cpp | 10 ++-------- src/Combat.hpp | 2 +- src/Groups.cpp | 6 ++++-- src/MobAI.cpp | 8 +++++--- src/PlayerManager.cpp | 3 ++- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/Combat.cpp b/src/Combat.cpp index 5304c16..5f08f9e 100644 --- a/src/Combat.cpp +++ b/src/Combat.cpp @@ -268,16 +268,10 @@ void Combat::npcAttackPc(Mob *mob, time_t currTime) { * single RNG roll per mission task, and every group member shares that same * set of rolls. */ -void Combat::genQItemRolls(Player *leader, std::map& rolls) { - auto players = (*leader->group)[EntityKind::PLAYER]; +void Combat::genQItemRolls(std::vector players, std::map& rolls) { for (int i = 0; i < players.size(); i++) { - CNSocket *otherSock = players[i].sock; - if (otherSock == nullptr) - continue; - - Player *member = PlayerManager::getPlayer(otherSock); - + Player* member = players[i]; for (int j = 0; j < ACTIVE_MISSION_COUNT; j++) if (member->tasks[j] != 0) rolls[member->tasks[j]] = Rand::rand(); diff --git a/src/Combat.hpp b/src/Combat.hpp index 14d0076..5b53c86 100644 --- a/src/Combat.hpp +++ b/src/Combat.hpp @@ -25,5 +25,5 @@ namespace Combat { void init(); void npcAttackPc(Mob *mob, time_t currTime); - void genQItemRolls(Player* leader, std::map& rolls); + void genQItemRolls(std::vector players, std::map& rolls); } diff --git a/src/Groups.cpp b/src/Groups.cpp index 605beef..ba85d4c 100644 --- a/src/Groups.cpp +++ b/src/Groups.cpp @@ -120,14 +120,16 @@ static void joinGroup(CNSocket* sock, CNPacketData* data) { if (otherPlr == nullptr) return; + int size = otherPlr->group == nullptr ? 1 : (*otherPlr->group)[EntityKind::PLAYER].size(); + // fail if the group is full or the other player is already in a group - if (plr->group != nullptr || (otherPlr->group != nullptr && (*otherPlr->group)[EntityKind::PLAYER].size() >= 4)) { + if (plr->group != nullptr || size + 1 > 4) { INITSTRUCT(sP_FE2CL_PC_GROUP_JOIN_FAIL, resp); sock->sendPacket((void*)&resp, P_FE2CL_PC_GROUP_JOIN_FAIL, sizeof(sP_FE2CL_PC_GROUP_JOIN_FAIL)); return; } - if (!validOutVarPacket(sizeof(sP_FE2CL_PC_GROUP_JOIN), (*otherPlr->group)[EntityKind::PLAYER].size() + 1, sizeof(sPCGroupMemberInfo))) { + if (!validOutVarPacket(sizeof(sP_FE2CL_PC_GROUP_JOIN), size + 1, sizeof(sPCGroupMemberInfo))) { std::cout << "[WARN] bad sP_FE2CL_PC_GROUP_JOIN packet size\n"; return; } diff --git a/src/MobAI.cpp b/src/MobAI.cpp index 6d71e81..1c9b860 100644 --- a/src/MobAI.cpp +++ b/src/MobAI.cpp @@ -842,16 +842,18 @@ void MobAI::onDeath(CombatNPC* npc, EntityRef src) { Items::DropRoll rolled; Items::DropRoll eventRolled; std::map qitemRolls; + std::vector playerRefs; if (plr->group == nullptr) { - Combat::genQItemRolls(plr, qitemRolls); + playerRefs.push_back(plr); + Combat::genQItemRolls(playerRefs, qitemRolls); Items::giveMobDrop(src.sock, self, rolled, eventRolled); Missions::mobKilled(src.sock, self->type, qitemRolls); } else { auto players = (*plr->group)[EntityKind::PLAYER]; - Player* leader = PlayerManager::getPlayer(players[0].sock); - Combat::genQItemRolls(leader, qitemRolls); + for (EntityRef pRef : players) playerRefs.push_back(PlayerManager::getPlayer(pRef.sock)); + Combat::genQItemRolls(playerRefs, qitemRolls); for (int i = 0; i < players.size(); i++) { CNSocket* sockTo = players[i].sock; Player* otherPlr = PlayerManager::getPlayer(sockTo); diff --git a/src/PlayerManager.cpp b/src/PlayerManager.cpp index 2cdd0fc..1dcc579 100644 --- a/src/PlayerManager.cpp +++ b/src/PlayerManager.cpp @@ -41,7 +41,8 @@ void PlayerManager::removePlayer(CNSocket* key) { Player* plr = getPlayer(key); uint64_t fromInstance = plr->instanceID; - Groups::groupKick(plr); + if(plr->group != nullptr) + Groups::groupKick(plr); // remove player's bullets Combat::Bullets.erase(plr->iID);