完成队伍重构

This commit is contained in:
aozhiwei 2021-06-08 14:56:10 +08:00
parent 97aff06caa
commit f570bf3133
7 changed files with 290 additions and 159 deletions

View File

@ -28,6 +28,7 @@ class Skill;
class Obstacle;
class RoomObstacle;
class Hero;
class Team;
class Creature : public MoveableEntity
{
public:
@ -97,6 +98,8 @@ class Creature : public MoveableEntity
void AddPassiveSkill(int skill_id);
void ClearPassiveSkill();
void UpdatePoisoning();
Team* GetTeam() { return team_; }
void SetTeam(Team* team) { team_ = team; }
bool IsProperTarget(Creature* target, bool no_teammate = false);
bool IsEnemy(Creature* target);
@ -203,6 +206,7 @@ protected:
private:
CreatureWeakPtr weak_ptr_;
Team* team_ = nullptr;
Weapon* curr_weapon_ = nullptr;
CreatureWeakPtrChunk weak_ptr_chunk_;
std::array<float, kHAT_End> buff_attr_abs_ = {};

View File

@ -6,6 +6,9 @@
#include <a8/mutable_xobject.h>
#include <a8/collision.h>
#include "framework/cpp/utils.h"
#include "framework/cpp/httpclientpool.h"
#include "human.h"
#include "cs_proto.pb.h"
#include "metamgr.h"
@ -29,9 +32,7 @@
#include "jsondatamgr.h"
#include "skill.h"
#include "incubator.h"
#include "framework/cpp/utils.h"
#include "framework/cpp/httpclientpool.h"
#include "team.h"
const int kReviveTimeAdd = 12;
const int kSkinNum = 4;
@ -693,8 +694,7 @@ void Human::FillSMGameOver(cs::SMGameOver& msg)
}
}
if (room->GetAliveTeamNum() == 1) {
std::set<Human*>* alive_team = room->GetAliveTeam();
if (alive_team == team_members) {
if (room->GetAliveTeam() == GetTeam()) {
rank = 1;
}
}
@ -709,13 +709,16 @@ void Human::FillSMGameOver(cs::SMGameOver& msg)
msg.set_room_uuid(a8::XValue(room->GetRoomUuid()));
msg.set_total_human_num(room->GetHumanNum());
msg.set_alive_human_num(room->AliveCount());
{
for (auto& itr : *team_members) {
if (itr != this) {
itr->FillMFTeamData(msg.add_team_data(), true);
}
}
if (GetTeam()) {
GetTeam()->TraverseMembers
(
[this, &msg] (Human* member) -> bool
{
if (this != member) {
member->FillMFTeamData(msg.add_team_data(), true);
}
return true;
});
}
{
cs::MFPlayerStats* p = msg.add_player_stats();
@ -1045,14 +1048,20 @@ bool Human::HasLiveTeammate()
if (room->GetRoomMode() == kZombieMode) {
return true;
}
if (team_members) {
for (auto& hum : *team_members) {
if (hum != this && !hum->dead) {
return true;
}
}
bool has = false;
if (GetTeam()) {
GetTeam()->TraverseMembers
(
[this, &has] (Human* member)
{
if (member != this && !member->dead) {
has = true;
return false;
}
return true;
});
}
return false;
return has;
}
bool Human::HasNoDownedTeammate()
@ -1081,27 +1090,37 @@ bool Human::HasNoDownedTeammate()
return false;
}
}
if (team_members) {
for (auto& hum : *team_members) {
if (hum != this && !hum->dead && !hum->downed) {
return true;
}
}
bool has = false;
if (GetTeam()) {
GetTeam()->TraverseMembers
(
[this, &has] (Human* member)
{
if (member != this && !member->dead && !member->downed) {
has = true;
return false;
}
return true;
});
}
return false;
return has;
}
int Human::GetNearbyTeammateNum(float range)
{
int num = 0;
if (team_members) {
for (auto& hum : *team_members) {
if (hum != this && !hum->dead && !hum->downed) {
if (hum->GetPos().Distance(GetPos()) <= range) {
++num;
}
}
}
if (GetTeam()) {
GetTeam()->TraverseMembers
(
[this, &num, range] (Human* member)
{
if (member != this && !member->dead && !member->downed) {
if (member->GetPos().Distance(GetPos()) <= range) {
++num;
}
}
return true;
});
}
return num;
}
@ -2062,8 +2081,7 @@ void Human::GenBattleReportData(a8::MutableXObject* params)
}
}
if (room->GetAliveTeamNum() == 1) {
std::set<Human*>* alive_team = room->GetAliveTeam();
if (alive_team == team_members) {
if (room->GetAliveTeam() == GetTeam()) {
rank = 1;
}
}
@ -2085,7 +2103,7 @@ void Human::GenBattleReportData(a8::MutableXObject* params)
} else {
params->SetVal("alive_time", dead_frameno * 1000.0f / SERVER_FRAME_RATE);
}
params->SetVal("team_status", team_members && team_members->size() > 1 ? 1 : 0);
params->SetVal("team_status", GetTeam() && GetTeam()->GetMemberNum() > 1 ? 1 : 0);
params->SetVal("room_uuid", room->GetRoomUuid());
int snipe_kill = 0;
@ -2540,24 +2558,25 @@ void Human::OnDie()
real_dead_frameno = room->GetFrameNo();
room->OnHumanDie(this);
SyncAroundPlayers(__FILE__, __LINE__, __func__);
if (team_members) {
for (auto& hum : *team_members) {
if (hum != this && hum->action_type == AT_Relive &&
hum->action_target_id == GetUniId()) {
hum->CancelAction();
}
}
if (GetTeam()) {
GetTeam()->TraverseMembers
(
[this] (Human* member) -> bool
{
if (this != member &&
member->action_type == AT_Relive &&
member->action_target_id == GetUniId()) {
member->CancelAction();
}
return true;
});
}
{
std::set<Human*> over_humans;
if (!leave_) {
if (!HasNoDownedTeammate()) {
if (team_members) {
for (auto& member : *team_members) {
if (member->real_dead) {
over_humans.insert(member);
}
}
if (GetTeam()) {
GetTeam()->GetOveredHumans(over_humans);
} else {
over_humans.insert(this);
}
@ -2566,11 +2585,9 @@ void Human::OnDie()
}
}
if (room->GetAliveTeamNum() == 1) {
std::set<Human*>* alive_team = room->GetAliveTeam();
Team* alive_team = room->GetAliveTeam();
if (alive_team) {
for (Human* member : *alive_team) {
over_humans.insert(member);
}
alive_team->GetOveredHumans(over_humans);
}
}
for (Human* hum : over_humans) {
@ -2886,12 +2903,16 @@ void Human::NotifyObservers(cs::SMUpdate* msg, cs::MFActivePlayerData* active_pl
bool refreshed_view = false;
for (Human* observer : observers_) {
msg->clear_team_data();
if (observer->team_members) {
for (auto& itr : *observer->team_members) {
if (itr != observer) {
itr->FillMFTeamData(msg->add_team_data(), false);
}
}
if (observer->GetTeam()) {
observer->GetTeam()->TraverseMembers
(
[observer, msg] (Human* member) -> bool
{
if (member != observer) {
member->FillMFTeamData(msg->add_team_data(), false);
}
return true;
});
}
if (observer != this && !observer->follow_synced_active_player) {
msg->set_active_player_id(GetUniId());

View File

@ -116,7 +116,6 @@ class Human : public Creature
xtimer_list* downed_timer = nullptr;
std::set<Human*>* team_members = nullptr;
std::set<Human*> kill_humans;
BornPoint* born_point = nullptr;

View File

@ -7,6 +7,8 @@
#include <a8/udplog.h>
#include <a8/collision.h>
#include "framework/cpp/utils.h"
#include "playermgr.h"
#include "player.h"
#include "cs_proto.pb.h"
@ -30,8 +32,7 @@
#include "mapinstance.h"
#include "mapmgr.h"
#include "incubator.h"
#include "framework/cpp/utils.h"
#include "team.h"
const int SHUA_RANGE = 580;
@ -119,6 +120,10 @@ void Room::UnInit()
delete pair.second;
}
removed_robot_hash_.clear();
for (auto& pair : team_hash_) {
delete pair.second;
}
team_hash_.clear();
grid_service->ClearRoomData(this);
PerfMonitor::Instance()->alive_count -= alive_count_;
}
@ -898,11 +903,10 @@ void Room::AdjustPosInnerMap(a8::Vec2& pos, float radius)
Human* Room::GetWatchWarTarget(Human* hum)
{
if (hum->team_members) {
for (auto& member : *hum->team_members) {
if (member != hum && !member->dead) {
return member;
}
if (hum->GetTeam()) {
Human* member = hum->GetTeam()->GetOneAliveMember(hum);
if (member) {
return member;
}
}
std::vector<Human*> humans;
@ -927,11 +931,8 @@ int Room::GetAliveTeamNum()
{
int num = 0;
for (auto& pair : team_hash_) {
for (Human* hum : pair.second) {
if (!hum->real_dead) {
++num;
break;
}
if (pair.second->HasAliveMember()) {
++num;
}
}
return num;
@ -1114,23 +1115,23 @@ void Room::FillSMUiUpdate(cs::SMUiUpdate& msg)
}
}
std::set<Human*>* Room::GetAliveTeam()
Team* Room::GetAliveTeam()
{
for (auto& pair : team_hash_) {
for (Human* hum : pair.second) {
if (!hum->real_dead) {
return &pair.second;
}
if (pair.second->HasAliveMember()) {
return pair.second;
}
}
return nullptr;
}
int Room::NewTeam()
Team* Room::NewTeam()
{
++current_teamid_;
team_hash_[current_teamid_] = std::set<Human*>();
return current_teamid_;
Team* team = new Team();
team->room = this;
team->SetTeamId(++current_teamid_);
team_hash_[team->GetTeamId()] = team;
return team;
}
void Room::TraversePlayerList(a8::XParams param,
@ -1447,25 +1448,19 @@ void Room::MatchTeam(Human* hum)
for (auto& pair : human_hash_) {
if (pair.second != hum) {
if (!hum->team_uuid.empty() && pair.second->team_uuid == hum->team_uuid) {
if (!pair.second->team_members) {
pair.second->team_id = NewTeam();
pair.second->team_members = &team_hash_[pair.second->team_id];
pair.second->team_members->insert(pair.second);
if (!pair.second->GetTeam()) {
NewTeam()->AddMember(pair.second);
}
if (pair.second->team_members->size() < MAX_TEAM_NUM) {
pair.second->team_members->insert(hum);
hum->team_id = pair.second->team_id;
hum->team_members = pair.second->team_members;
if (!pair.second->GetTeam()->IsFull()) {
pair.second->GetTeam()->AddMember(hum);
}
break;
}
}
}
}
if (hum->team_id == 0) {
hum->team_id = NewTeam();
hum->team_members = &team_hash_[hum->team_id];
hum->team_members->insert(hum);
if (!hum->GetTeam()) {
NewTeam()->AddMember(hum);
}
}
@ -1499,16 +1494,21 @@ void Room::CombineTeam()
int first_team_id = 0;
int total_count = 0;
for (auto& pair : team_hash_) {
for (Human* hum : pair.second) {
if (hum->auto_fill && !hum->team_uuid.empty()) {
if (first_team_id == 0) {
first_team_id = pair.first;
}
need_combine_teams[pair.first] = pair.second.size();
total_count += pair.second.size();
break;
}
}
Team* team = pair.second;
team->TraverseMembers
(
[this, team, &first_team_id, &total_count, &need_combine_teams] (Human* member) -> bool
{
if (member->auto_fill && !member->team_uuid.empty()) {
if (first_team_id == 0) {
first_team_id = team->GetTeamId();
}
need_combine_teams[team->GetTeamId()] = team->GetMemberNum();
total_count += team->GetMemberNum();
return false;
}
return true;
});
}
if (total_count <= 1) {
@ -1562,27 +1562,21 @@ void Room::CombineTeam()
if (pair1.second + pair2.second <= MAX_TEAM_NUM) {
int new_team_num = pair1.second + pair2.second;
{
std::set<Human*>& team1_members = team_hash_[team_id1];
std::set<Human*>& team2_members = team_hash_[team_id2];
if (team1_members.size() + team2_members.size() > MAX_TEAM_NUM) {
Team* team1 = team_hash_[team_id1];
Team* team2 = team_hash_[team_id2];
if (team1->GetMemberNum() + team2->GetMemberNum() > MAX_TEAM_NUM) {
a8::UdpLog::Instance()->Warning("team_member > 4 :%d",
{
team1_members.size() + team2_members.size()
team1->GetMemberNum() + team2->GetMemberNum()
});
}
if (pair1.first == first_team_id || pair1.second >= pair2.second) {
for (Human* hum : team2_members) {
hum->team_id = team_id1;
hum->team_members = &team1_members;
team1_members.insert(hum);
}
team1->CombineTeam(team2);
delete team2;
team_hash_.erase(pair2.first);
} else {
for (Human* hum : team1_members) {
hum->team_id = team_id2;
hum->team_members = &team2_members;
team2_members.insert(hum);
}
team2->CombineTeam(team1);
delete team1;
team_hash_.erase(pair1.first);
}
}
@ -2286,10 +2280,16 @@ void Room::SecondRandPoint()
pair.second->on_grid_chg = std::bind(&Room::OnHumanGridChg,
this,
std::placeholders::_1);
for (Human* member : *pair.second->team_members) {
if (newbie_point) {
ForceSetBornPoint(member, newbie_point);
}
if (pair.second->GetTeam()) {
pair.second->GetTeam()->TraverseMembers
(
[this, newbie_point] (Human* member) -> bool
{
if (newbie_point) {
ForceSetBornPoint(member, newbie_point);
}
return true;
});
}
}
}
@ -3233,35 +3233,7 @@ void Room::RemoveFromLaterAddHash(RoomEntity* entity)
void Room::CombineTeamBornPoint()
{
for (auto& pair : team_hash_) {
Human* target = nullptr;
for (Human* hum : pair.second) {
if (!target) {
target = hum;
} else {
if (target->born_point) {
if (hum->born_point) {
DecBornPointHumanNum(hum->born_point, hum);
}
hum->born_point = target->born_point;
if (hum->born_point) {
IncBornPointHumanNum(hum->born_point, hum);
}
}
} //end if
if (!hum->born_point) {
hum->SetX(DEFAULT_BORN_POINT_X + rand() % 100);
hum->SetY(DEFAULT_BORN_POINT_Y + rand() % 200);
} else {
hum->SetPos(hum->born_point->RandPoint());
}
if (!a8::HasBitFlag(hum->status, HS_Disable)) {
hum->FindLocation();
hum->RefreshView();
grid_service->MoveCreature(hum);
} else if (room_type_ == RT_MidBrid && !hum->team_uuid.empty()){
EnableHuman(hum);
}
}
pair.second->CombineBornPoint();
}
}
@ -3553,11 +3525,7 @@ void Room::CheckShowHand()
for (auto& pair : accountid_hash_) {
Human* player = pair.second;
real_player_num = 0;
for (Human* hum : *player->team_members) {
if (!hum->real_dead) {
++real_player_num;
}
}
real_player_num = player->GetTeam()->GetAliveNum();
break;
}
}

View File

@ -37,6 +37,7 @@ class Android;
class Car;
class Hero;
class Incubator;
class Team;
class Room
{
public:
@ -138,7 +139,7 @@ public:
Human* GetWatchWarTarget(Human* hum);
bool BattleStarted();
int GetAliveTeamNum();
std::set<Human*>* GetAliveTeam();
Team* GetAliveTeam();
bool CanJoin(const std::string& accountid,
RoomType_e self_roomm_type,
RoomMode_e self_room_mode,
@ -199,7 +200,7 @@ private:
void AirDrop(int appear_time, int box_id, int airdrop_id);
void AdjustAirDropPos(MetaData::MapThing* thing_meta, a8::Vec2& box_pos);
void ShuaPlane();
int NewTeam();
Team* NewTeam();
RoomObstacle* InternalCreateObstacle(int id, float x, float y,
std::function<void (Obstacle*)> on_precreate);
void AddObjectLater(RoomEntity* entity);
@ -318,7 +319,7 @@ private:
int current_uniid_ = FIXED_OBJECT_MAXID;
std::set<int> refreshed_robot_set_;
std::map<int, std::set<Human*>> team_hash_;
std::map<int, Team*> team_hash_;
std::map<std::string, Player*> accountid_hash_;
std::map<int, MoveableEntity*> moveable_hash_;
std::map<int, Entity*> uniid_hash_;
@ -339,4 +340,5 @@ private:
Incubator* incubator_ = nullptr;
friend class Incubator;
friend class Team;
};

111
server/gameserver/team.cc Normal file
View File

@ -0,0 +1,111 @@
#include "precompile.h"
#include "team.h"
#include "human.h"
#include "room.h"
void Team::TraverseMembers(std::function<bool (Human*)> func)
{
for (Human* member : members_) {
if (!func(member)) {
break;
}
}
}
void Team::GetOveredHumans(std::set<Human*>& overed_humans)
{
for (Human* member : members_) {
if (member->real_dead) {
overed_humans.insert(member);
}
}
}
Human* Team::GetOneAliveMember(Human* exclude_hum)
{
for (Human* member : members_) {
if (member != exclude_hum && member->dead) {
return member;
}
}
return nullptr;
}
bool Team::HasAliveMember()
{
for (Human* member : members_) {
if (!member->real_dead) {
return true;
}
}
return false;
}
void Team::AddMember(Human* member)
{
member->team_id = team_id_;
member->SetTeam(this);
members_.insert(member);
}
bool Team::IsFull()
{
return GetMemberNum() >= MAX_TEAM_NUM;
}
void Team::CombineBornPoint()
{
Human* target = nullptr;
for (Human* member : members_) {
if (!target) {
target = member;
} else {
if (target->born_point) {
if (member->born_point) {
room->DecBornPointHumanNum(member->born_point, member);
}
member->born_point = target->born_point;
if (member->born_point) {
room->IncBornPointHumanNum(member->born_point, member);
}
}
} //end if
if (!member->born_point) {
member->SetX(DEFAULT_BORN_POINT_X + rand() % 100);
member->SetY(DEFAULT_BORN_POINT_Y + rand() % 200);
} else {
member->SetPos(member->born_point->RandPoint());
}
if (!a8::HasBitFlag(member->status, HS_Disable)) {
member->FindLocation();
member->RefreshView();
room->grid_service->MoveCreature(member);
} else if (room->GetRoomType() == RT_MidBrid && !member->team_uuid.empty()){
room->EnableHuman(member);
}
}
}
int Team::GetAliveNum()
{
int num = 0;
for (Human* member : members_) {
if (!member->real_dead) {
++num;
}
}
return num;
}
void Team::CombineTeam(Team* b_team)
{
b_team->TraverseMembers
(
[this] (Human* member) -> bool
{
AddMember(member);
return true;
});
}

26
server/gameserver/team.h Normal file
View File

@ -0,0 +1,26 @@
#pragma once
class Room;
class Human;
class Team
{
public:
Room* room = nullptr;
int GetTeamId() { return team_id_; }
void SetTeamId(int team_id) { team_id_ = team_id; }
void TraverseMembers(std::function<bool (Human*)> func);
size_t GetMemberNum() { return members_.size(); }
void GetOveredHumans(std::set<Human*>& overed_humans);
Human* GetOneAliveMember(Human* exclude_hum);
bool HasAliveMember();
int GetAliveNum();
void AddMember(Human* member);
bool IsFull();
void CombineBornPoint();
void CombineTeam(Team* b_team);
private:
int team_id_ = 0;
std::set<Human*> members_;
};