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.
This commit is contained in:
gsemaj 2022-04-23 15:58:08 -04:00
parent 71e78afa0b
commit 3dc7124f58
5 changed files with 14 additions and 15 deletions

View File

@ -259,16 +259,10 @@ void Combat::npcAttackPc(Mob *mob, time_t currTime) {
* single RNG roll per mission task, and every group member shares that same * single RNG roll per mission task, and every group member shares that same
* set of rolls. * set of rolls.
*/ */
void Combat::genQItemRolls(Player *leader, std::map<int, int>& rolls) { void Combat::genQItemRolls(std::vector<Player*> players, std::map<int, int>& rolls) {
auto players = (*leader->group)[EntityKind::PLAYER];
for (int i = 0; i < players.size(); i++) { for (int i = 0; i < players.size(); i++) {
CNSocket *otherSock = players[i].sock; Player* member = players[i];
if (otherSock == nullptr)
continue;
Player *member = PlayerManager::getPlayer(otherSock);
for (int j = 0; j < ACTIVE_MISSION_COUNT; j++) for (int j = 0; j < ACTIVE_MISSION_COUNT; j++)
if (member->tasks[j] != 0) if (member->tasks[j] != 0)
rolls[member->tasks[j]] = Rand::rand(); rolls[member->tasks[j]] = Rand::rand();

View File

@ -25,5 +25,5 @@ namespace Combat {
void init(); void init();
void npcAttackPc(Mob *mob, time_t currTime); void npcAttackPc(Mob *mob, time_t currTime);
void genQItemRolls(Player* leader, std::map<int, int>& rolls); void genQItemRolls(std::vector<Player*> players, std::map<int, int>& rolls);
} }

View File

@ -120,14 +120,16 @@ static void joinGroup(CNSocket* sock, CNPacketData* data) {
if (otherPlr == nullptr) if (otherPlr == nullptr)
return; 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 // 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); 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)); sock->sendPacket((void*)&resp, P_FE2CL_PC_GROUP_JOIN_FAIL, sizeof(sP_FE2CL_PC_GROUP_JOIN_FAIL));
return; 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"; std::cout << "[WARN] bad sP_FE2CL_PC_GROUP_JOIN packet size\n";
return; return;
} }

View File

@ -842,16 +842,18 @@ void MobAI::onDeath(CombatNPC* npc, EntityRef src) {
Items::DropRoll rolled; Items::DropRoll rolled;
Items::DropRoll eventRolled; Items::DropRoll eventRolled;
std::map<int, int> qitemRolls; std::map<int, int> qitemRolls;
std::vector<Player*> playerRefs;
if (plr->group == nullptr) { if (plr->group == nullptr) {
Combat::genQItemRolls(plr, qitemRolls); playerRefs.push_back(plr);
Combat::genQItemRolls(playerRefs, qitemRolls);
Items::giveMobDrop(src.sock, self, rolled, eventRolled); Items::giveMobDrop(src.sock, self, rolled, eventRolled);
Missions::mobKilled(src.sock, self->type, qitemRolls); Missions::mobKilled(src.sock, self->type, qitemRolls);
} }
else { else {
auto players = (*plr->group)[EntityKind::PLAYER]; auto players = (*plr->group)[EntityKind::PLAYER];
Player* leader = PlayerManager::getPlayer(players[0].sock); for (EntityRef pRef : players) playerRefs.push_back(PlayerManager::getPlayer(pRef.sock));
Combat::genQItemRolls(leader, qitemRolls); Combat::genQItemRolls(playerRefs, qitemRolls);
for (int i = 0; i < players.size(); i++) { for (int i = 0; i < players.size(); i++) {
CNSocket* sockTo = players[i].sock; CNSocket* sockTo = players[i].sock;
Player* otherPlr = PlayerManager::getPlayer(sockTo); Player* otherPlr = PlayerManager::getPlayer(sockTo);

View File

@ -46,7 +46,8 @@ void PlayerManager::removePlayer(CNSocket* key) {
Player* plr = getPlayer(key); Player* plr = getPlayer(key);
uint64_t fromInstance = plr->instanceID; uint64_t fromInstance = plr->instanceID;
Groups::groupKick(plr); if(plr->group != nullptr)
Groups::groupKick(plr);
// remove player's bullets // remove player's bullets
Combat::Bullets.erase(plr->iID); Combat::Bullets.erase(plr->iID);