diff --git a/server/gameserver/building.cc b/server/gameserver/building.cc index 751af79..7841e9d 100644 --- a/server/gameserver/building.cc +++ b/server/gameserver/building.cc @@ -34,6 +34,7 @@ void Building::RecalcSelfCollider() collider->_max = Vector2D(obj.x() + obj.width()/2.0 - meta->i->tilewidth()/2.0, obj.y() + obj.height()/2.0 - meta->i->tileheight()/2.0); AddCollider(collider); + room->map_service.AddCollider(collider); } } diff --git a/server/gameserver/mapservice.cc b/server/gameserver/mapservice.cc index fb41cfc..93e9613 100644 --- a/server/gameserver/mapservice.cc +++ b/server/gameserver/mapservice.cc @@ -42,9 +42,20 @@ void MapService::Init(int width, int height, int cell_width) cell_width_ = cell_width; max_grid_id_ = map_width_ * map_height_; + grid_offset_arr_[0] = - (map_width_ + 1); + grid_offset_arr_[1] = - (map_width_ + 0); + grid_offset_arr_[2] = - (map_width_ + -1); + + grid_offset_arr_[3] = - 1; + grid_offset_arr_[4] = 0; + grid_offset_arr_[5] = 1; + + grid_offset_arr_[6] = map_width_ - 1; + grid_offset_arr_[7] = map_width_; + grid_offset_arr_[8] = map_width_ + 1; + map_cells_ = (list_head*)malloc(sizeof(list_head) * width * height); memset(map_cells_, sizeof(list_head) * width * height, 0); - } void MapService::UnInit() @@ -54,6 +65,9 @@ void MapService::UnInit() void MapService::AddCollider(ColliderComponent* collider) { +#if MAP_SERVICE + return; +#endif CellNode* top_node = nullptr; CellNode* bot_node = nullptr; switch (collider->type) { @@ -146,17 +160,30 @@ bool MapService::Walkable(float world_x, float world_y) list_empty(&node); } -void MapService::TouchAroundCell(float world_x, float world_y, - std::function callback) +void MapService::GetColliders(float world_x, float world_y, std::set& colliders) { - + int center_grid_id = GetGridId(world_x, world_y); + if (center_grid_id < 0 || center_grid_id >= max_grid_id_) { + return; + } + for (size_t i = 0; i < a8::ArraySize(grid_offset_arr_); ++i) { + int grid_id = center_grid_id + grid_offset_arr_[i]; + if (grid_id >= 0 && grid_id < max_grid_id_) { + list_head* head = &map_cells_[grid_id]; + if (head->next == nullptr && head->prev == nullptr) { + continue; + } + struct CellNode *node, *tmp; + struct list_head tv_list; + list_for_each_entry_safe(node, tmp, &tv_list, entry) { + colliders.insert(node->collider); + } + } + } } int MapService::GetGridId(float world_x, float world_y) { - int x = world_x + cell_width_; - int y = world_y + cell_width_; - assert(x >= 0 && y >= 0); - int grid_id = x/cell_width_ + (y/cell_width_) * map_width_; + int grid_id = world_x/cell_width_ + (world_y/cell_width_) * map_width_; return grid_id; } diff --git a/server/gameserver/mapservice.h b/server/gameserver/mapservice.h index 8cae1c8..dcf71f0 100644 --- a/server/gameserver/mapservice.h +++ b/server/gameserver/mapservice.h @@ -21,8 +21,7 @@ class MapService void AddCollider(ColliderComponent* collider); void RemoveCollider(ColliderComponent* collider); bool Walkable(float world_x, float world_y); - void TouchAroundCell(float world_x, float world_y, - std::function callback); + void GetColliders(float world_x, float world_y, std::set& colliders); private: int GetGridId(float world_x, float world_y); diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index cb0e896..a4ecbc5 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -34,6 +34,24 @@ void Obstacle::RecalcSelfCollider() self_collider2_ = new AabbCollider(); self_collider2_->owner = this; AddCollider(self_collider2_); + Vector2D old_pos = pos; + { + pos = Vector2D(building->pos.x + door_state1->x() - building->meta->i->tilewidth() / 2.0, + building->pos.y + door_state1->y() - building->meta->i->tileheight() / 2.0); + self_collider2_->_min = Vector2D(0.0f - door_state0->width() / 2.0f, + 0.0f - door_state0->height() / 2.0f); + self_collider2_->_max = Vector2D(door_state0->width() / 2.0f, door_state0->height() / 2.0f); + room->map_service.AddCollider(self_collider2_); + } + { + pos = Vector2D(building->pos.x + door_state0->x() - building->meta->i->tilewidth() / 2.0, + building->pos.y + door_state0->y() - building->meta->i->tileheight() / 2.0); + self_collider2_->_min = Vector2D(0.0f - door_state1->width() / 2.0f, + 0.0f - door_state1->height() / 2.0f); + self_collider2_->_max = Vector2D(door_state1->width() / 2.0f, door_state1->height() / 2.0f); + room->map_service.AddCollider(self_collider2_); + } + pos = old_pos; } if (door_state == DoorStateClose) { self_collider2_->_min = Vector2D(0.0f - door_state0->width() / 2.0f, @@ -55,6 +73,7 @@ void Obstacle::RecalcSelfCollider() } self_collider_->pos = Vector2D(); self_collider_->rad = meta->i->height() / 2.0; + room->map_service.AddCollider(self_collider_); } break; case 2: @@ -66,6 +85,7 @@ void Obstacle::RecalcSelfCollider() } self_collider2_->_min = Vector2D(meta->i->width() / -2.0f, meta->i->height() / -2.0f); self_collider2_->_max = Vector2D(meta->i->width() / 2.0f, meta->i->height() / 2.0f); + room->map_service.AddCollider(self_collider2_); } break; }