diff --git a/server/gameserver/collision.cc b/server/gameserver/collision.cc index 0241249..df975ca 100644 --- a/server/gameserver/collision.cc +++ b/server/gameserver/collision.cc @@ -114,3 +114,37 @@ bool CircleContainCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_ra float distance = (a_pos - b_pos).Norm(); return distance < a_rad - b_rad; } + +bool CalcCircleAabbSafePoint(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b_rad, + Vector2D& new_pos) +{ + new_pos = b_pos; + bool at_left = std::abs(b_pos.x - a_min.x) < std::abs(b_pos.x - a_max.x); + bool at_down = std::abs(b_pos.y - a_min.y) < std::abs(b_pos.y - a_max.y); + float x_len = at_left ? std::abs(b_pos.x - a_min.x) : std::abs(b_pos.x - a_max.x); + float y_len = at_down ? std::abs(b_pos.y - a_min.y) : std::abs(b_pos.y - a_max.y); + if (at_left) { + if (x_len < y_len) { + //左 + new_pos.x = a_min.x - b_rad - 1; + } else { + if (at_down) { + new_pos.y = a_min.y - b_rad - 1; + } else { + new_pos.y = a_max.y + b_rad + 1; + } + } + } else { + if (x_len < y_len) { + //右 + new_pos.x = a_max.x + b_rad + 1; + } else { + if (at_down) { + new_pos.y = a_min.y - b_rad - 1; + } else { + new_pos.y = a_max.y + b_rad + 1; + } + } + } + return true; +} diff --git a/server/gameserver/collision.h b/server/gameserver/collision.h index 832106b..e5a06e1 100644 --- a/server/gameserver/collision.h +++ b/server/gameserver/collision.h @@ -6,4 +6,6 @@ bool IntersectAabbCircle(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b bool IntersectAabbAabb(Vector2D a_min, Vector2D a_max, Vector2D b_min, Vector2D b_max); bool IntersectCircleCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad); bool CircleContainCircle(Vector2D a_pos, float a_rad, Vector2D b_pos, float b_rad); +bool CalcCircleAabbSafePoint(Vector2D a_min, Vector2D a_max, Vector2D b_pos, float b_rad, + Vector2D& new_pos); void TestGlm(); diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 632c565..8284500 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -7,6 +7,7 @@ #include "bullet.h" #include "collider.h" #include "loot.h" +#include "collision.h" Human::Human() { @@ -646,5 +647,24 @@ void Human::FindLocation() a8::SetBitFlag(detection_flags, ET_Building); } room->CollisionDetection(this, detection_flags, objects); + if (objects.size() > 1) { + abort(); + } + if (!objects.empty()) { + Building* building = (Building*)objects[0]; + Vector2D a_min; + Vector2D a_max; + Vector2D new_pos; + bool ret = CalcCircleAabbSafePoint( + a_min, + a_max, + pos, + GetRadius(), + new_pos + ); + if (!ret) { + abort(); + } + } } } diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 857371e..2e5a55d 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -25,7 +25,7 @@ class Human : public Entity public: int team_id = 0; std::string account_id; - std::string team_uniid; + std::string team_uuid; MetaData::Player* meta = nullptr; MetaData::Equip* helmet_meta = nullptr; MetaData::Equip* chest_meta = nullptr; diff --git a/server/gameserver/playermgr.cc b/server/gameserver/playermgr.cc index f415141..0b4439e 100644 --- a/server/gameserver/playermgr.cc +++ b/server/gameserver/playermgr.cc @@ -25,7 +25,7 @@ Player* PlayerMgr::CreatePlayerByCMJoin(int socket, const cs::CMJoin& msg) hum->account_id = msg.account_id(); hum->name = msg.name(); hum->health = 0; - hum->team_uniid = msg.team_uuid(); + hum->team_uuid = msg.team_uuid(); hum->team_mode = msg.team_mode(); hum->player_count = msg.player_count(); hum->auto_fill = msg.auto_fill(); diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index ff2776b..891c2ce 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -269,6 +269,15 @@ void Room::AddPlayer(Player* hum) pair.second->AddToPartObjects(hum); hum->AddToNewObjects(pair.second); hum->AddToPartObjects(pair.second); + 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); + } + pair.second->team_members->insert(hum); + hum->team_id = pair.second->team_id; + } } } for (auto& pair : uniid_hash_) { @@ -656,6 +665,13 @@ void Room::OnHumanDie(Human* hum) --alive_count_; } +int Room::NewTeam() +{ + ++current_teamid; + team_hash_[current_teamid] = std::set(); + return current_teamid; +} + void Room::ClearDeletedObjects() { for (auto& pair : frame_data.deleted_objects_hash) { @@ -976,7 +992,9 @@ void Room::AutoMatchTeam() { std::vector humans; for (auto& pair : human_hash_) { - humans.push_back(pair.second); + if (pair.second->team_uuid.empty()) { + humans.push_back(pair.second); + } } std::random_shuffle(humans.begin(), humans.end()); std::set* team_members = nullptr; diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 725e428..d9288e1 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -77,6 +77,7 @@ public: Vector2D pos, Vector2D dir, float fly_distance); void OnHumanDie(Human* hum); + int NewTeam(); private: unsigned short AllocUniid();