diff --git a/server/gameserver/android.ai.cc b/server/gameserver/android.ai.cc index ad1d543..fcf52ed 100644 --- a/server/gameserver/android.ai.cc +++ b/server/gameserver/android.ai.cc @@ -115,7 +115,7 @@ void AndroidAI::DoMove() } break; } - hum->room->grid_service.MoveHuman(hum); + hum->room->grid_service->MoveHuman(hum); } } } diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 0ece412..de8e365 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -129,7 +129,7 @@ void Bullet::ProcBomb() self_collider_->rad = gun_meta->i->explosion_range(); std::set objects; for (auto& grid : grid_list) { - for (Human* hum: grid->human_list) { + for (Human* hum: grid->human_list[room->room_idx]) { if (!is_tank_skin || player->team_id != hum->team_id) { //友军火箭筒伤害取消 if ((meta->i->_inventory_slot() == 4 || @@ -141,24 +141,40 @@ void Bullet::ProcBomb() objects.insert(hum); } } - } - for (Entity* entity : grid->entity_list) { - switch (entity->entity_type) { - case ET_Obstacle: - case ET_Building: - { - if (TestCollision(room, entity)) { - objects.insert(entity); - } + } + for (Entity* entity : grid->entity_list[0]) { + switch (entity->entity_type) { + case ET_Obstacle: + case ET_Building: + { + if (TestCollision(room, entity)) { + objects.insert(entity); } - break; - default: - { - } - break; } + break; + default: + { + } + break; } - }//end for + } + for (Entity* entity : grid->entity_list[room->room_idx]) { + switch (entity->entity_type) { + case ET_Obstacle: + case ET_Building: + { + if (TestCollision(room, entity)) { + objects.insert(entity); + } + } + break; + default: + { + } + break; + } + } + }//end for switch (meta->i->_inventory_slot()) { case 4: @@ -207,10 +223,10 @@ void Bullet::MapServiceUpdate() room->RemoveObjectLater(this); } } else { - room->grid_service.MoveBullet(this); + room->grid_service->MoveBullet(this); std::set objects; for (auto& grid : grid_list) { - for (Human* hum: grid->human_list) { + for (Human* hum: grid->human_list[room->room_idx]) { #if 1 if (hum != player && !hum->dead && TestCollision(room, hum)) { objects.insert(hum); diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index 1063901..1b32161 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -299,6 +299,6 @@ const int DEFAULT_BORN_POINT_Y = 3000; const int ADPLAY_BUFFID = 1006; -const int FIXED_OBJECT_MAXID = 2048; +const int FIXED_OBJECT_MAXID = 2018; -const int MAX_ROOM_IDX = 2048; +const int MAX_ROOM_IDX = 2018; diff --git a/server/gameserver/entity.cc b/server/gameserver/entity.cc index f193a14..ce6f124 100644 --- a/server/gameserver/entity.cc +++ b/server/gameserver/entity.cc @@ -85,6 +85,7 @@ void Entity::ClearColliders() { for (auto& itr : colliders) { ColliderComponent* collider = itr; + OnRemoveCollider(collider); DestoryCollider(collider); } colliders.clear(); @@ -93,9 +94,9 @@ void Entity::ClearColliders() void Entity::BroadcastFullState(Room* room) { std::set grid_list; - room->grid_service.GetAllCells(grid_id, grid_list); + room->grid_service->GetAllCells(room, grid_id, grid_list); for (auto& grid : grid_list) { - for (Human* hum : grid->human_list) { + for (Human* hum : grid->human_list[room->room_idx]) { hum->AddToNewObjects(this); } } @@ -104,9 +105,9 @@ void Entity::BroadcastFullState(Room* room) void Entity::BroadcastDeleteState(Room* room) { std::set grid_list; - room->grid_service.GetAllCells(grid_id, grid_list); + room->grid_service->GetAllCells(room, grid_id, grid_list); for (auto& grid : grid_list) { - for (Human* hum : grid->human_list) { + for (Human* hum : grid->human_list[room->room_idx]) { hum->RemoveObjects(this); } } diff --git a/server/gameserver/entity.h b/server/gameserver/entity.h index 0721838..a246fa8 100644 --- a/server/gameserver/entity.h +++ b/server/gameserver/entity.h @@ -39,6 +39,7 @@ class Entity virtual bool IsDead(Room* room) { return false;}; virtual long long GetDeadFrameNo(Room* room) { return 0;}; virtual void OnPreCollision(Room* room) {}; + virtual void OnRemoveCollider(ColliderComponent* collider) {}; bool TestCollision(Room* room, Entity* b); bool TestCollision(Room* room, ColliderComponent* b); bool TestCollisionEx(Room* room, const a8::Vec2& aabb_pos, AabbCollider& aabb_box); diff --git a/server/gameserver/frameevent.cc b/server/gameserver/frameevent.cc index 0189d6f..77c9bbe 100644 --- a/server/gameserver/frameevent.cc +++ b/server/gameserver/frameevent.cc @@ -7,6 +7,7 @@ #include "typeconvert.h" #include "buff.h" #include "human.h" +#include "room.h" void FrameEvent::AddAirDrop(int appear_time, int box_id, a8::Vec2 box_pos) { @@ -16,81 +17,81 @@ void FrameEvent::AddAirDrop(int appear_time, int box_id, a8::Vec2 box_pos) TypeConvert::ToPb(box_pos, airdrop->mutable_pos()); } -void FrameEvent::AddEmote(Human* hum, int emote_id) +void FrameEvent::AddEmote(Human* sender, int emote_id) { { auto& tuple = a8::FastAppend(emotes_); - std::get<0>(tuple) = hum; + std::get<0>(tuple) = sender; auto& p = std::get<1>(tuple); p.set_emote_id(emote_id); - p.set_player_id(hum->entity_uniid); + p.set_player_id(sender->entity_uniid); } { int emote_idx = emotes_.size() - 1; - for (auto& cell : hum->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& cell : sender->grid_list) { + for (auto& hum : cell->human_list[sender->room->room_idx]) { hum->emotes_.push_back(emote_idx); } } } } -void FrameEvent::AddShot(Human* hum) +void FrameEvent::AddShot(Human* sender) { { auto& tuple = a8::FastAppend(shots_); - std::get<0>(tuple) = hum; + std::get<0>(tuple) = sender; auto& p = std::get<1>(tuple); - p.set_player_id(hum->entity_uniid); - if (hum->tank_weapon.meta) { - hum->tank_weapon.ToPB(p.mutable_weapon()); + p.set_player_id(sender->entity_uniid); + if (sender->tank_weapon.meta) { + sender->tank_weapon.ToPB(p.mutable_weapon()); } else { - hum->curr_weapon->ToPB(p.mutable_weapon()); + sender->curr_weapon->ToPB(p.mutable_weapon()); } p.set_offhand(true); p.set_bullskin(10001); } { int shot_idx = shots_.size() - 1; - for (auto& cell : hum->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& cell : sender->grid_list) { + for (auto& hum : cell->human_list[sender->room->room_idx]) { hum->shots_.push_back(shot_idx); } } } } -void FrameEvent::AddBullet(Human* hum, a8::Vec2 born_pos, a8::Vec2 dir, float fly_distance) +void FrameEvent::AddBullet(Human* sender, a8::Vec2 born_pos, a8::Vec2 dir, float fly_distance) { { auto& tuple = a8::FastAppend(bullets_); - std::get<0>(tuple) = hum; + std::get<0>(tuple) = sender; auto& p = std::get<1>(tuple); - p.set_player_id(hum->entity_uniid); - if (hum->tank_weapon.meta) { - p.set_bullet_id(hum->tank_weapon.meta->i->use_bullet()); + p.set_player_id(sender->entity_uniid); + if (sender->tank_weapon.meta) { + p.set_bullet_id(sender->tank_weapon.meta->i->use_bullet()); } else { - p.set_bullet_id(hum->curr_weapon->meta->i->use_bullet()); + p.set_bullet_id(sender->curr_weapon->meta->i->use_bullet()); } TypeConvert::ToPb(born_pos, p.mutable_pos()); TypeConvert::ToPb(dir, p.mutable_dir()); p.set_bulletskin(10001); - if (hum->tank_weapon.meta) { - p.set_gun_id(hum->tank_weapon.meta->i->id()); - p.set_gun_lv(hum->tank_weapon.weapon_lv); + if (sender->tank_weapon.meta) { + p.set_gun_id(sender->tank_weapon.meta->i->id()); + p.set_gun_lv(sender->tank_weapon.weapon_lv); } else { - p.set_gun_id(hum->curr_weapon->meta->i->id()); - p.set_gun_lv(hum->curr_weapon->weapon_lv); + p.set_gun_id(sender->curr_weapon->meta->i->id()); + p.set_gun_lv(sender->curr_weapon->weapon_lv); } p.set_fly_distance(fly_distance); } { int bullet_idx = bullets_.size() - 1; - for (auto& cell : hum->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& cell : sender->grid_list) { + for (auto& hum : cell->human_list[sender->room->room_idx]) { hum->bullets_.push_back(bullet_idx); } } @@ -111,7 +112,7 @@ void FrameEvent::AddExplosion(Bullet* bullet, int item_id, a8::Vec2 bomb_pos) { int explosion_idx = explosions_.size() - 1; for (auto& cell : bullet->player->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& hum : cell->human_list[bullet->room->room_idx]){ hum->explosions_.push_back(explosion_idx); } } @@ -133,7 +134,7 @@ void FrameEvent::AddExplosionEx(Human* sender, int item_id, a8::Vec2 bomb_pos, i { int explosion_idx = explosions_.size() - 1; for (auto& cell : sender->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& hum : cell->human_list[sender->room->room_idx]) { hum->explosions_.push_back(explosion_idx); } } @@ -182,56 +183,56 @@ void FrameEvent::AddSmoke(Bullet* bullet, int item_id, a8::Vec2 pos) { int idx = smokes_.size() - 1; for (auto& cell : bullet->player->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& hum : cell->human_list[bullet->room->room_idx]) { hum->smokes_.push_back(idx); } } } } -void FrameEvent::AddHpChg(Human* hum) +void FrameEvent::AddHpChg(Human* sender) { - chged_hps_.push_back(hum); + chged_hps_.push_back(sender); int idx = chged_hps_.size() - 1; - for (auto& cell : hum->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& cell : sender->grid_list) { + for (auto& hum : cell->human_list[sender->room->room_idx]) { hum->chged_hps_.push_back(idx); } } } -void FrameEvent::AddBuff(Human* hum, Buff* buff) +void FrameEvent::AddBuff(Human* sender, Buff* buff) { { cs::MFBuffChg chged_buff_pb; - chged_buff_pb.set_obj_id(hum->entity_uniid); + chged_buff_pb.set_obj_id(sender->entity_uniid); chged_buff_pb.set_chg(0); buff->FillMFBuff(chged_buff_pb.mutable_buff()); - chged_buffs_.push_back(std::make_tuple(hum, chged_buff_pb)); + chged_buffs_.push_back(std::make_tuple(sender, chged_buff_pb)); } { int idx = chged_buffs_.size() - 1; - for (auto& cell : hum->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& cell : sender->grid_list) { + for (auto& hum : cell->human_list[sender->room->room_idx]) { hum->chged_buffs_.push_back(idx); } } } } -void FrameEvent::RemoveBuff(Human* hum, int buff_id) +void FrameEvent::RemoveBuff(Human* sender, int buff_id) { { cs::MFBuffChg chged_buff_pb; - chged_buff_pb.set_obj_id(hum->entity_uniid); + chged_buff_pb.set_obj_id(sender->entity_uniid); chged_buff_pb.set_chg(1); chged_buff_pb.mutable_buff()->set_buff_id(buff_id); - chged_buffs_.push_back(std::make_tuple(hum, chged_buff_pb)); + chged_buffs_.push_back(std::make_tuple(sender, chged_buff_pb)); } { int idx = chged_buffs_.size() - 1; - for (auto& cell : hum->grid_list) { - for (auto& hum : cell->human_list) { + for (auto& cell : sender->grid_list) { + for (auto& hum : cell->human_list[sender->room->room_idx]) { hum->chged_buffs_.push_back(idx); } } diff --git a/server/gameserver/gridservice.cc b/server/gameserver/gridservice.cc index 5359559..57f86b8 100644 --- a/server/gameserver/gridservice.cc +++ b/server/gameserver/gridservice.cc @@ -3,6 +3,19 @@ #include "gridservice.h" #include "human.h" #include "bullet.h" +#include "room.h" + +GridCell::GridCell() +{ + human_list.reserve(MAX_ROOM_IDX); + entity_list.reserve(MAX_ROOM_IDX); + bullet_list.reserve(MAX_ROOM_IDX); + for (int i = 0; i < MAX_ROOM_IDX; ++i) { + human_list.push_back(std::set()); + entity_list.push_back(std::set()); + bullet_list.push_back(std::set()); + } +} /* 1 2 3 @@ -62,14 +75,14 @@ bool GridService::BroderOverFlow(int x, int y) return x <= min_x_ || x >= max_x_ || y <= min_y_ || y >= max_y_; } -void GridService::GetAllCells(int grid_id, std::set& grid_list) +void GridService::GetAllCells(Room* room, int grid_id, std::set& grid_list) { for (size_t i = 1; i <= 9; ++i) { GetGridList(grid_id, i, grid_list); } } -void GridService::GetAllCellsByXy(int x, int y, std::set& grid_list) +void GridService::GetAllCellsByXy(Room* room, int x, int y, std::set& grid_list) { int new_x = x + cell_width_; int new_y = y + cell_width_; @@ -77,7 +90,7 @@ void GridService::GetAllCellsByXy(int x, int y, std::set& grid_list) if (BroderOverFlow(new_x, new_y)) { abort(); } - GetAllCells(new_grid_id, grid_list); + GetAllCells(room, new_grid_id, grid_list); } bool GridService::CanAdd(float x, float y) @@ -87,6 +100,19 @@ bool GridService::CanAdd(float x, float y) return !BroderOverFlow(new_x, new_y); } +void GridService::ClearRoomData(Room* room) +{ + if (room->room_idx <= 0) { + abort(); + } + for (int i = 0; i < (max_grid_id_ + 1); ++i) { + GridCell& cell = cells_[i]; + cell.human_list[room->room_idx].clear(); + cell.entity_list[room->room_idx].clear(); + cell.bullet_list[room->room_idx].clear(); + } +} + void GridService::AddHuman(Human* hum) { int x = (int)hum->GetX() + cell_width_; @@ -98,8 +124,8 @@ void GridService::AddHuman(Human* hum) if (hum->grid_id == 0 || hum->grid_id > max_grid_id_) { abort(); } - cells_[hum->grid_id].human_list.insert(hum); - GetAllCells(hum->grid_id, hum->grid_list); + cells_[hum->grid_id].human_list[hum->room->room_idx].insert(hum); + GetAllCells(hum->room, hum->grid_id, hum->grid_list); } void GridService::MoveHuman(Human* hum) @@ -117,12 +143,14 @@ void GridService::MoveHuman(Human* hum) std::set inc_grid_list; std::set dec_grid_list; std::set old_grid_list = hum->grid_list; - ComputeDiff(hum->grid_id, new_grid_id, + ComputeDiff(hum->room, + hum->grid_id, + new_grid_id, hum->grid_list, inc_grid_list, dec_grid_list); - cells_[hum->grid_id].human_list.erase(hum); - cells_[new_grid_id].human_list.insert(hum); + cells_[hum->grid_id].human_list[hum->room->room_idx].erase(hum); + cells_[new_grid_id].human_list[hum->room->room_idx].insert(hum); hum->grid_id = new_grid_id; hum->OnGridListChange(old_grid_list, inc_grid_list, dec_grid_list); } @@ -139,8 +167,8 @@ void GridService::AddBullet(Bullet* bullet) if (bullet->grid_id == 0 || bullet->grid_id > max_grid_id_) { abort(); } - cells_[bullet->grid_id].bullet_list.insert(bullet); - GetAllCells(bullet->grid_id, bullet->grid_list); + cells_[bullet->grid_id].bullet_list[bullet->room->room_idx].insert(bullet); + GetAllCells(bullet->room, bullet->grid_id, bullet->grid_list); } void GridService::MoveBullet(Bullet* bullet) @@ -158,12 +186,14 @@ void GridService::MoveBullet(Bullet* bullet) std::set inc_grid_list; std::set dec_grid_list; std::set old_grid_list = bullet->grid_list; - ComputeDiff(bullet->grid_id, new_grid_id, + ComputeDiff(bullet->room, + bullet->grid_id, + new_grid_id, bullet->grid_list, inc_grid_list, dec_grid_list); - cells_[bullet->grid_id].bullet_list.erase(bullet); - cells_[new_grid_id].bullet_list.insert(bullet); + cells_[bullet->grid_id].bullet_list[bullet->room->room_idx].erase(bullet); + cells_[new_grid_id].bullet_list[bullet->room->room_idx].insert(bullet); bullet->grid_id = new_grid_id; } } @@ -171,10 +201,10 @@ void GridService::MoveBullet(Bullet* bullet) void GridService::DelBullet(Bullet* bullet) { GridCell& cell = cells_[bullet->grid_id]; - cell.bullet_list.erase(bullet); + cell.bullet_list[bullet->room->room_idx].erase(bullet); } -void GridService::AddEntity(Entity* entity) +void GridService::AddRoomEntity(Room* room, Entity* entity) { assert(entity->entity_type != ET_Player); int x = (int)entity->GetX() + cell_width_; @@ -186,29 +216,49 @@ void GridService::AddEntity(Entity* entity) if (entity->grid_id == 0 || entity->grid_id > max_grid_id_) { abort(); } - cells_[entity->grid_id].entity_list.insert(entity); + cells_[entity->grid_id].entity_list[room->room_idx].insert(entity); } -void GridService::DelEntity(Entity* entity) +void GridService::DelRoomEntity(Room* room, Entity* entity) { GridCell& cell = cells_[entity->grid_id]; - cell.entity_list.erase(entity); + cell.entity_list[room->room_idx].erase(entity); +} + +void GridService::AddPermanentEntity(Entity* entity) +{ + assert(entity->entity_type != ET_Player); + int x = (int)entity->GetX() + cell_width_; + int y = (int)entity->GetY() + cell_width_; + if (BroderOverFlow(x, y)) { + abort(); + } + entity->grid_id = x/cell_width_ + (y/cell_width_) * cell_count_per_row_; + if (entity->grid_id == 0 || entity->grid_id > max_grid_id_) { + abort(); + } + cells_[entity->grid_id].entity_list[0].insert(entity); } bool GridService::HumanInGridList(Human* hum, std::set& grid_list) { for (auto& cell : grid_list) { - if (cell->human_list.find(hum) != cell->human_list.end()) { + if (cell->human_list[hum->room->room_idx].find(hum) != + cell->human_list[hum->room->room_idx].end()) { return true; } } return false; } -bool GridService::EntityInGridList(Entity* entity, std::set& grid_list) +bool GridService::EntityInGridList(Room* room, Entity* entity, std::set& grid_list) { for (auto& cell : grid_list) { - if (cell->entity_list.find(entity) != cell->entity_list.end()) { + if (cell->entity_list[0].find(entity) != cell->entity_list[0].end()) { + return true; + } + if (cell->entity_list[room->room_idx].find(entity) != + cell->entity_list[room->room_idx].end()) { return true; } } @@ -228,29 +278,6 @@ bool GridService::InView(int a_grid, int b_grid) a_grid + grid_offset_arr_[8] == b_grid; } -void GridService::RemoveFromGridList(std::set& grid_list, Entity* entity) -{ - for (auto& grid : grid_list) { - switch (entity->entity_type) { - case ET_Player: - { - grid->human_list.erase((Human*)entity); - } - break; - case ET_Bullet: - { - grid->bullet_list.erase((Bullet*)entity); - } - break; - default: - { - grid->entity_list.erase(entity); - } - break; - } - } -} - void GridService::GetGridList(int grid_id, int offset, std::set& grid_list) { @@ -266,7 +293,9 @@ void GridService::GetGridList(int grid_id, int offset, } } -void GridService::ComputeDiff(int old_grid_id, int new_grid_id, +void GridService::ComputeDiff(Room* room, + int old_grid_id, + int new_grid_id, std::set& grid_list, std::set& inc_grid_list, std::set& dec_grid_list) @@ -274,7 +303,7 @@ void GridService::ComputeDiff(int old_grid_id, int new_grid_id, #if 1 { std::set new_grid_list; - GetAllCells(new_grid_id, new_grid_list); + GetAllCells(room, new_grid_id, new_grid_list); for (auto& cell : new_grid_list) { if (grid_list.find(cell) == grid_list.end()) { inc_grid_list.insert(cell); @@ -289,5 +318,5 @@ void GridService::ComputeDiff(int old_grid_id, int new_grid_id, #endif grid_list.clear(); - GetAllCells(new_grid_id, grid_list); + GetAllCells(room, new_grid_id, grid_list); } diff --git a/server/gameserver/gridservice.h b/server/gameserver/gridservice.h index e752292..028a427 100644 --- a/server/gameserver/gridservice.h +++ b/server/gameserver/gridservice.h @@ -6,9 +6,11 @@ class Bullet; struct GridCell { - std::set human_list; - std::set entity_list; - std::set bullet_list; + std::vector> human_list; + std::vector> entity_list; + std::vector> bullet_list; + + GridCell(); }; class Human; @@ -23,9 +25,10 @@ class GridService void Init(int width, int height, int cell_width); void UnInit(); bool BroderOverFlow(int x, int y); - void GetAllCells(int grid_id, std::set& grid_list); - void GetAllCellsByXy(int x, int y, std::set& grid_list); + void GetAllCells(Room* room, int grid_id, std::set& grid_list); + void GetAllCellsByXy(Room* room, int x, int y, std::set& grid_list); bool CanAdd(float x, float y); + void ClearRoomData(Room* room); void AddHuman(Human* hum); void MoveHuman(Human* hum); @@ -34,24 +37,26 @@ class GridService void MoveBullet(Bullet* bullet); void DelBullet(Bullet* bullet); - void AddEntity(Entity* entity); - void DelEntity(Entity* entity); + void AddRoomEntity(Room* room, Entity* entity); + void DelRoomEntity(Room* room, Entity* entity); + + void AddPermanentEntity(Entity* entity); bool HumanInGridList(Human* hum, std::set& grid_list); - bool EntityInGridList(Entity* entity, std::set& grid_list); + bool EntityInGridList(Room* room, Entity* entity, std::set& grid_list); bool InView(int a_grid, int b_grid); - void RemoveFromGridList(std::set& grid_list, Entity* entity); private: inline void GetGridList(int grid_id, int offset, std::set& grid_list); - void ComputeDiff(int old_grid_id, int new_grid_id, + void ComputeDiff(Room* room, + int old_grid_id, + int new_grid_id, std::set& grid_list, std::set& inc_grid_list, std::set& dec_grid_list); private: - Room* room_ = nullptr; GridCell* cells_ = nullptr; int max_grid_id_ = 0; int map_width_ = 0; diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 13af9f0..902658e 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -649,7 +649,7 @@ void Human::UpdatePoisoning() void Human::SyncAroundPlayers(const char* file, int line, const char* func) { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { hum->AddToNewObjects(this); assert(hum->part_objects.find(this) != hum->part_objects.end()); if (hum->part_objects.find(this) == hum->part_objects.end()) { @@ -1104,7 +1104,33 @@ void Human::FindLocation() { Entity* target = nullptr; for (auto& grid : grid_list) { - for (Entity* entity : grid->entity_list) { + for (Entity* entity : grid->entity_list[0]) { + switch (entity->entity_type) { + case ET_Obstacle: + { + if (!target) { + if (TestCollision(room, entity)) { + target = entity; + } + } + } + break; + case ET_Building: + { + if (!target || target->entity_type != ET_Building) { + AabbCollider aabb_box; + entity->GetAabbBox(aabb_box); + if (TestCollision(room, &aabb_box)) { + target = entity; + } + } + } + break; + default: + break; + } + } + for (Entity* entity : grid->entity_list[room->room_idx]) { switch (entity->entity_type) { case ET_Obstacle: { @@ -1139,13 +1165,28 @@ void Human::FindLocation() void Human::RefreshView() { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { hum->AddToNewObjects(this); hum->AddToPartObjects(this); AddToNewObjects(hum); AddToPartObjects(hum); } - for (Entity* entity : cell->entity_list) { + for (Entity* entity : cell->entity_list[0]) { + switch (entity->entity_type) { + case ET_Building: + case ET_Obstacle: + case ET_Loot: + { + AddToNewObjects(entity); + } + break; + default: + { + } + break; + } + } + for (Entity* entity : cell->entity_list[room->room_idx]) { switch (entity->entity_type) { case ET_Building: case ET_Obstacle: @@ -1169,8 +1210,8 @@ void Human::OnGridListChange(std::set& old_grid_list, ) { for (GridCell* cell : inc_grid_list) { - for (Human* hum : cell->human_list) { - if (!room->grid_service.HumanInGridList(hum, old_grid_list)) { + for (Human* hum : cell->human_list[room->room_idx]) { + if (!room->grid_service->HumanInGridList(hum, old_grid_list)) { hum->AddToNewObjects(this); hum->AddToPartObjects(this); hum->RemoveOutObjects(this); @@ -1179,8 +1220,26 @@ void Human::OnGridListChange(std::set& old_grid_list, RemoveOutObjects(hum); } } - for (Entity* entity : cell->entity_list) { - if (!room->grid_service.EntityInGridList(entity, old_grid_list)) { + for (Entity* entity : cell->entity_list[0]) { + if (!room->grid_service->EntityInGridList(room, entity, old_grid_list)) { + switch (entity->entity_type) { + case ET_Building: + case ET_Obstacle: + case ET_Loot: + { + AddToNewObjects(entity); + RemoveOutObjects(entity); + } + break; + default: + { + } + break; + } + } + } + for (Entity* entity : cell->entity_list[room->room_idx]) { + if (!room->grid_service->EntityInGridList(room, entity, old_grid_list)) { switch (entity->entity_type) { case ET_Building: case ET_Obstacle: @@ -1199,14 +1258,31 @@ void Human::OnGridListChange(std::set& old_grid_list, } } for (GridCell* cell : dec_grid_list) { - for (Human* hum : cell->human_list) { - if (!room->grid_service.HumanInGridList(hum, grid_list)) { + for (Human* hum : cell->human_list[room->room_idx]) { + if (!room->grid_service->HumanInGridList(hum, grid_list)) { AddOutObjects(hum); hum->AddOutObjects(this); } } - for (Entity* entity : cell->entity_list) { - if (!room->grid_service.EntityInGridList(entity, grid_list)) { + for (Entity* entity : cell->entity_list[0]) { + if (!room->grid_service->EntityInGridList(room, entity, grid_list)) { + switch (entity->entity_type) { + case ET_Building: + case ET_Obstacle: + case ET_Loot: + { + AddOutObjects(entity); + } + break; + default: + { + } + break; + } + } + } + for (Entity* entity : cell->entity_list[room->room_idx]) { + if (!room->grid_service->EntityInGridList(room, entity, grid_list)) { switch (entity->entity_type) { case ET_Building: case ET_Obstacle: @@ -1319,7 +1395,7 @@ void Human::FillMFGasData(cs::MFGasData* gas_data) bool Human::CanSee(const Human* hum) const { - return room->grid_service.InView(grid_id, hum->grid_id); + return room->grid_service->InView(grid_id, hum->grid_id); } void Human::RecalcVolume() @@ -1461,10 +1537,25 @@ void Human::SendUpdateMsg() FillMFActivePlayerData(msg->mutable_active_player_data()); if (!refreshed_view) { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { view_objects.insert(hum); } - for (Entity* entity : cell->entity_list) { + for (Entity* entity : cell->entity_list[0]) { + switch (entity->entity_type) { + case ET_Building: + case ET_Obstacle: + case ET_Loot: + { + view_objects.insert(entity); + } + break; + default: + { + } + break; + } + } + for (Entity* entity : cell->entity_list[room->room_idx]) { switch (entity->entity_type) { case ET_Building: case ET_Obstacle: @@ -1781,7 +1872,7 @@ void Human::CheckSkinTank() self_collider_->rad = skin_tank_meta->i->rad2(); std::set objects; for (auto& grid : grid_list) { - for (Human* hum: grid->human_list) { + for (Human* hum: grid->human_list[room->room_idx]) { if (hum != this && !hum->dead && !hum->tank_weapon.meta && @@ -1840,7 +1931,7 @@ void Human::_UpdateMove(int speed) } #endif } - room->grid_service.MoveHuman(this); + room->grid_service->MoveHuman(this); } #endif } @@ -1854,7 +1945,7 @@ void Human::_InternalUpdateMove(float speed) #if 1 SetPos(old_pos + a8::Vec2(nx, ny)); if (!IsCollisionInMapService()) { - room->grid_service.MoveHuman(this); + room->grid_service->MoveHuman(this); return; } else { if (Global::last_collider && Global::last_collider->type == CT_Circle) { @@ -1869,7 +1960,7 @@ void Human::_InternalUpdateMove(float speed) SetPos(GetPos() + new_dir); } if (!IsCollisionInMapService()) { - room->grid_service.MoveHuman(this); + room->grid_service->MoveHuman(this); return; } } @@ -1887,7 +1978,7 @@ void Human::_InternalUpdateMove(float speed) } SetPos(old_pos + a8::Vec2(nx, ny)); - room->grid_service.MoveHuman(this); + room->grid_service->MoveHuman(this); } void Human::ClearFrameData() @@ -2350,13 +2441,29 @@ void Human::FindLocationWithTarget(Entity* target) float distance = (new_pos - old_pos).Norm(); for (int i = distance; i < 10000000; i += 5) { SetPos(old_pos + new_pos_dir * i); - room->grid_service.MoveHuman(this); + room->grid_service->MoveHuman(this); Entity* building = nullptr; std::set new_grid_list; - room->grid_service.GetAllCellsByXy(GetX(), GetY(), new_grid_list); + room->grid_service->GetAllCellsByXy(room, GetX(), GetY(), new_grid_list); for (auto& grid : new_grid_list) { - for (Entity* entity : grid->entity_list) { + for (Entity* entity : grid->entity_list[0]) { + switch (entity->entity_type) { + case ET_Building: + { + if (TestCollision(room, entity)) { + building = entity; + } + } + break; + default: + break; + } + if (building) { + break; + } + } + for (Entity* entity : grid->entity_list[room->room_idx]) { switch (entity->entity_type) { case ET_Building: { @@ -2860,7 +2967,7 @@ void Human::SelectSkillTargets(const a8::Vec2& target_pos, std::set& ta case kST_All: { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { if (hum->GetPos().Distance(target_pos) < skill_meta_->i->skill_distance()) { target_list.insert(hum); } @@ -2877,7 +2984,7 @@ void Human::SelectSkillTargets(const a8::Vec2& target_pos, std::set& ta { target_list.insert(this); for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { if ((hum == this || hum->team_id == team_id) && hum->GetPos().Distance(target_pos) < skill_meta_->i->skill_distance()) { target_list.insert(hum); @@ -2889,7 +2996,7 @@ void Human::SelectSkillTargets(const a8::Vec2& target_pos, std::set& ta case kST_FriendlyExcludeSelf: { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { if ((hum != this && hum->team_id == team_id) && hum->GetPos().Distance(target_pos) < skill_meta_->i->skill_distance()) { target_list.insert(hum); @@ -2912,7 +3019,7 @@ void Human::SelectSkillTargets(const a8::Vec2& target_pos, std::set& ta case kST_EnemyGroup: { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { if ((hum->team_id != team_id) && hum->GetPos().Distance(target_pos) < skill_meta_->i->skill_distance()) { target_list.insert(hum); @@ -2924,7 +3031,7 @@ void Human::SelectSkillTargets(const a8::Vec2& target_pos, std::set& ta case kST_EnemyAndObject: { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { if ((hum->team_id != team_id) && hum->GetPos().Distance(target_pos) < skill_meta_->i->skill_distance()) { target_list.insert(hum); @@ -2936,7 +3043,7 @@ void Human::SelectSkillTargets(const a8::Vec2& target_pos, std::set& ta case kST_EnemyAndSelf: { for (auto& cell : grid_list) { - for (Human* hum : cell->human_list) { + for (Human* hum : cell->human_list[room->room_idx]) { if ((hum == this || hum->team_id != team_id) && hum->GetPos().Distance(target_pos) < skill_meta_->i->skill_distance()) { target_list.insert(hum); diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index a55ade0..7aa58f2 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -224,14 +224,30 @@ void Obstacle::Explosion(Bullet* bullet) meta->i->damage() > 0.01f) { std::set objects; std::set grid_list; - room->grid_service.GetAllCellsByXy(GetX(), GetY(), grid_list); + room->grid_service->GetAllCellsByXy(room, GetX(), GetY(), grid_list); for (auto& grid : grid_list) { - for (Human* hum: grid->human_list) { + for (Human* hum: grid->human_list[room->room_idx]) { if (TestCollision(room, hum)) { objects.insert(hum); } } - for (Entity* entity : grid->entity_list) { + for (Entity* entity : grid->entity_list[0]) { + switch (entity->entity_type) { + case ET_Obstacle: + case ET_Building: + { + if (entity != this && TestCollision(room, entity)) { + objects.insert(entity); + } + } + break; + default: + { + } + break; + } + }//end for + for (Entity* entity : grid->entity_list[room->room_idx]) { switch (entity->entity_type) { case ET_Obstacle: case ET_Building: diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index f728e2c..0b6a67c 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -79,7 +79,7 @@ void Room::UnInit() delete pair.second; } removed_robot_hash_.clear(); - grid_service.UnInit(); + grid_service->ClearRoomData(this); } void Room::Update(int delta_time) @@ -172,7 +172,7 @@ void Room::AddPlayer(Player* hum) last_add_player_tick = a8::XGetTickCount(); ++alive_count_; ++App::Instance()->perf.alive_count; - grid_service.AddHuman(hum); + grid_service->AddHuman(hum); hum->FindLocation(); hum->RefreshView(); MatchTeam(hum); @@ -285,7 +285,7 @@ DEFAULT_BORN_POINT_Y + rand() % 1500) human_hash_[hum->entity_uniid] = hum; ++alive_count_; ++App::Instance()->perf.alive_count; - grid_service.AddHuman(hum); + grid_service->AddHuman(hum); hum->FindLocation(); hum->RefreshView(); { @@ -306,7 +306,7 @@ Human* Room::FindEnemy(Human* hum) sub_type = EST_Android; } for (auto& cell : hum->grid_list) { - for (Human* target : cell->human_list) { + for (Human* target : cell->human_list[room_idx]) { if (target->entity_subtype == sub_type && !target->dead) { if (hum->GetPos().Distance(target->GetPos()) < 300.0f) { @@ -414,7 +414,7 @@ int Room::CreateLoot(int equip_id, a8::Vec2 pos, int count, int equip_lv) entity->item_level = equip_lv; entity->Initialize(); uniid_hash_[entity->entity_uniid] = entity; - grid_service.AddEntity(entity); + grid_service->AddRoomEntity(this, entity); entity->BroadcastFullState(this); return entity->entity_uniid; } else { @@ -425,7 +425,7 @@ int Room::CreateLoot(int equip_id, a8::Vec2 pos, int count, int equip_lv) void Room::CreateBullet(Human* hum, Weapon* weapon, a8::Vec2 pos, a8::Vec2 dir, float fly_distance, bool is_tank_skin) { - if (grid_service.CanAdd(pos.x, pos.y)) { + if (grid_service->CanAdd(pos.x, pos.y)) { Bullet* bullet = new Bullet(); bullet->player = hum; bullet->room = this; @@ -441,7 +441,7 @@ void Room::CreateBullet(Human* hum, Weapon* weapon, bullet->entity_uniid = AllocUniid(); bullet->Initialize(); AddObjectLater(bullet); - grid_service.AddBullet(bullet); + grid_service->AddBullet(bullet); } } @@ -454,13 +454,13 @@ void Room::RemoveObjectLater(RoomEntity* entity) case ET_Bullet: { entity->room->moveable_hash_.erase(entity->entity_uniid); - entity->room->grid_service.DelBullet((Bullet*)entity); + entity->room->grid_service->DelBullet((Bullet*)entity); } break; case ET_Loot: { entity->BroadcastDeleteState(entity->room); - entity->room->grid_service.DelEntity(entity); + entity->room->grid_service->DelRoomEntity(entity->room, entity); } break; case ET_Player: @@ -612,9 +612,35 @@ Entity* Room::FindFirstCollisonEntity(const a8::Vec2& aabb_pos, AabbCollider& aa { Entity* target = nullptr; std::set grid_list; - grid_service.GetAllCellsByXy(aabb_pos.x, aabb_pos.y, grid_list); + grid_service->GetAllCellsByXy(this, aabb_pos.x, aabb_pos.y, grid_list); for (auto& grid : grid_list) { - for (Entity* entity : grid->entity_list) { + for (Entity* entity : grid->entity_list[0]) { + switch (entity->entity_type) { + case ET_Obstacle: + { + if (!target) { + if (entity->TestCollisionEx(this, aabb_pos, aabb_box)) { + target = entity; + } + } + } + break; + case ET_Building: + { + if (!target || target->entity_type != ET_Building) { + AabbCollider building_aabb_box; + entity->GetAabbBox(building_aabb_box); + if (building_aabb_box.IntersectEx(aabb_pos, &aabb_box)) { + target = entity; + } + } + } + break; + default: + break; + } + } + for (Entity* entity : grid->entity_list[room_idx]) { switch (entity->entity_type) { case ET_Obstacle: { @@ -829,6 +855,7 @@ void Room::UpdateGasInactive() NotifyGameStart(); NotifyWxVoip(); InitAirDrop(); + RoomMgr::Instance()->ActiveRoom(room_uuid); } } @@ -1174,7 +1201,7 @@ RoomObstacle* Room::InternalCreateObstacle(int id, float x, float y, on_precreate(entity); } uniid_hash_[entity->entity_uniid] = entity; - grid_service.AddEntity(entity); + grid_service->AddRoomEntity(this, entity); return entity; } return nullptr; @@ -1227,10 +1254,10 @@ void Room::RandRemoveAndroid() --hum->born_point->android_num; } for (auto& cell : hum->grid_list) { - for (Human* target : cell->human_list) { + for (Human* target : cell->human_list[room_idx]) { target->AddOutObjects(hum); } - cell->human_list.erase(hum); + cell->human_list[room_idx].erase(hum); } moveable_hash_.erase(hum->entity_uniid); uniid_hash_.erase(hum->entity_uniid); @@ -1511,7 +1538,7 @@ void Room::SecondRandPoint() } hum->FindLocation(); hum->RefreshView(); - grid_service.MoveHuman(hum); + grid_service->MoveHuman(hum); } } } diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 68f1696..61bcadd 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -51,7 +51,7 @@ public: long long game_over_tick = 0; timer_list* game_over_timer = nullptr; a8::XTimer xtimer; - GridService grid_service; + GridService* grid_service = nullptr; MapService* map_service = nullptr; long long battle_start_frameno_ = 0; long long pending_request = 0; diff --git a/server/gameserver/roommgr.cc b/server/gameserver/roommgr.cc index 1ff594d..37cc459 100644 --- a/server/gameserver/roommgr.cc +++ b/server/gameserver/roommgr.cc @@ -134,8 +134,10 @@ void RoomMgr::_CMJoin(f8::MsgHdr& hdr, const cs::CMJoin& msg) if (!room) { room = new Room(); room->room_type = self_room_type; - room->map_service = map_service_; room->room_uuid = App::Instance()->NewUuid(); + room->room_idx = AllocRoomIdx(); + room->grid_service = grid_service_; + room->map_service = map_service_; room->spawn_points = &spawn_points_; room->loots = &loots_; room->buildings = &buildings_; @@ -228,6 +230,12 @@ Room* RoomMgr::GetRoomByUuid(long long room_uuid) return itr != room_hash_.end() ? itr->second : nullptr; } +Room* RoomMgr::GetRoomByIdx(int room_idx) +{ + auto itr = room_idx_hash_.find(room_idx); + return itr != room_idx_hash_.end() ? itr->second : nullptr; +} + void RoomMgr::AddOverRoom(long long room_uuid) { auto callback = [] (const a8::XParams& param) @@ -327,6 +335,7 @@ void RoomMgr::FreeOverRoom(long long room_uuid) auto itr = over_room_hash_.find(room_uuid); if (itr != over_room_hash_.end()) { itr->second->UnInit(); + room_idx_hash_.erase(itr->second->room_idx); delete itr->second; over_room_hash_.erase(itr); } @@ -436,7 +445,7 @@ void RoomMgr::CreateBuilding(int thing_id, float building_x, float building_y) building->SetPos(a8::Vec2(building_x, building_y)); building->Initialize(); uniid_hash_[building->entity_uniid] = building; - grid_service_->AddEntity(building); + grid_service_->AddPermanentEntity(building); for (size_t door_idx = 0; door_idx < building_meta->doors.size(); ++door_idx) { if (door_idx >= 0 && door_idx < building->meta->doors.size()) { MetaData::Building::Door* door_meta = &building->meta->doors[door_idx]; @@ -485,7 +494,7 @@ Obstacle* RoomMgr::InternalCreateObstacle(int id, float x, float y, on_precreate(entity); } uniid_hash_[entity->entity_uniid] = entity; - grid_service_->AddEntity(entity); + grid_service_->AddPermanentEntity(entity); return entity; } return nullptr; @@ -503,3 +512,16 @@ int RoomMgr::AllocUniid() } return current_uniid_; } + +int RoomMgr::AllocRoomIdx() +{ + do { + if (current_room_idx_ <= 0) { + current_room_idx_ = 1; + } + if (current_room_idx_ >= (MAX_ROOM_IDX - 1)) { + current_room_idx_ = 1; + } + } while (GetRoomByIdx(++current_room_idx_)); + return current_room_idx_; +} diff --git a/server/gameserver/roommgr.h b/server/gameserver/roommgr.h index af4d230..bce83a5 100644 --- a/server/gameserver/roommgr.h +++ b/server/gameserver/roommgr.h @@ -43,6 +43,7 @@ class RoomMgr : public a8::Singleton int RoomNum(); int OverRoomNum(); Room* GetRoomByUuid(long long uuid); + Room* GetRoomByIdx(int room_idx); void AddOverRoom(long long room_uuid); void InstallReportStateTimer(); @@ -59,13 +60,16 @@ class RoomMgr : public a8::Singleton std::function on_precreate); Entity* GetEntityByUniId(int uniid); int AllocUniid(); + int AllocRoomIdx(); private: std::map inactive_room_hash_; std::map room_hash_; + std::map room_idx_hash_; std::map over_room_hash_; a8::TimerAttacher reportstate_timer_attacher_; + int current_room_idx_ = 0; int current_uniid_ = 0; std::map uniid_hash_; MapService* map_service_ = nullptr; diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index d504010..28754ee 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -58,3 +58,8 @@ void RoomObstacle::RecalcSelfCollider() } } } + +void RoomObstacle::OnRemoveCollider(ColliderComponent* collider) +{ + room->map_service->RemoveCollider(collider); +} diff --git a/server/gameserver/roomobstacle.h b/server/gameserver/roomobstacle.h index 25bf704..c0e1d31 100644 --- a/server/gameserver/roomobstacle.h +++ b/server/gameserver/roomobstacle.h @@ -12,5 +12,6 @@ class RoomObstacle : public Obstacle virtual ~RoomObstacle() override; virtual void Initialize() override; virtual void RecalcSelfCollider() override; + virtual void OnRemoveCollider(ColliderComponent* collider) override; };