From 244d15e1c6577dff7cc5792fedbfe78b88cf0989 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Fri, 26 Mar 2021 16:30:21 +0800 Subject: [PATCH] 1 --- server/gameserver/mapinstance.cc | 98 ++++++++++++++++++++++++++++++-- server/gameserver/mapinstance.h | 3 +- server/gameserver/mapservice.cc | 3 + server/gameserver/obstacle.cc | 5 ++ server/gameserver/obstacle.h | 1 + 5 files changed, 105 insertions(+), 5 deletions(-) diff --git a/server/gameserver/mapinstance.cc b/server/gameserver/mapinstance.cc index 01f784d..cb2c293 100644 --- a/server/gameserver/mapinstance.cc +++ b/server/gameserver/mapinstance.cc @@ -34,6 +34,7 @@ void MapInstance::Init() map_meta_->i->map_height() / MAP_GRID_WIDTH, MAP_GRID_WIDTH); CreateThings(); + CreateTerrain(); a8::UdpLog::Instance()->Info ("map_id:%d current_uniid:%d loots:%d mini_room_spawn_points:%d normal_room_spawn_points:%d " "building_num:%d obstalce_num:%d obstacle0_num:%d " @@ -149,6 +150,94 @@ void MapInstance::CreateThings() } } +void MapInstance::CreateTerrain() +{ + metatable::TerrainJson* terrain = MetaMgr::Instance()->GetTerrainJson(map_id); + std::list* layers = MetaMgr::Instance()->GetMapLayer(map_tpl_name_); + if (!terrain || !layers) { + abort(); + } + if (layers->empty()) { + return; + } + metatable::MapLayerJson* first_layer = nullptr; + for (auto layer : *layers) { + if (!first_layer) { + first_layer = &layer; + } + if (layer.width() != first_layer->width()) { + abort(); + } + if (layer.height() != first_layer->height()) { + abort(); + } + if (layer.grids().size() != first_layer->grids().size()) { + abort(); + } + } + if (first_layer->grids().size() != first_layer->width() * first_layer->height()) { + abort(); + } + if (first_layer->grids().size() <= 0) { + abort(); + } + + std::vector grids; + grids.reserve(first_layer->grids().size()); + for (int i = 0; i < first_layer->grids().size(); ++i) { + grids.push_back(0); + } + std::set dusts; + for (auto idx : terrain->dust()) { + dusts.insert(idx); + } + std::set waters; + for (auto idx : terrain->water()) { + waters.insert(idx); + } + std::set grasses; + for (auto idx : terrain->grass()) { + grasses.insert(idx); + } + + int mask = A8_DEFINE_RANGE_BIT(int, 0, 22); + for (auto layer : *layers) { + for (int i = 0; i < first_layer->grids().size(); ++i) { + int grid_val = layer.grids(i) & mask; + if (grid_val != 0) { + grids[i] = grid_val; + } + } + } + + MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(0); + if (thing_meta) { + for (int w = 0; w < first_layer->width(); ++w) { + for (int h = 0; h < first_layer->height(); ++h) { + int grid_val = grids[w * first_layer->width() + h]; + if (grid_val != 0) { + float x = w * thing_meta->i->width() + thing_meta->i->width() / 2.0f; + float y = h * thing_meta->i->height() + thing_meta->i->height() / 2.0f; + int collider_tag = 0; + if (dusts.find(grid_val) != dusts.end()) { + a8::SetBitFlag(collider_tag, kColliderTag_Ice); + } else if (waters.find(grid_val) != waters.end()) { + a8::SetBitFlag(collider_tag, kColliderTag_Water); + } else if (grasses.find(grid_val) != grasses.end()) { + a8::SetBitFlag(collider_tag, kColliderTag_Grass); + } + if (collider_tag != 0) { + InternalCreateObstacle(thing_meta->i->thing_id(), x, y, collider_tag, + [] (Obstacle* entity) + { + }); + } + } + } + } + } +} + void MapInstance::CreateMapObject(MetaData::MapTplThing& thing_tpl) { int thing_id = thing_tpl.RandThing(); @@ -157,7 +246,7 @@ void MapInstance::CreateMapObject(MetaData::MapTplThing& thing_tpl) if (thing_meta->i->is_house()) { CreateBuilding(thing_id, thing_tpl.i->x(), thing_tpl.i->y()); } else { - InternalCreateObstacle(thing_id, thing_tpl.i->x(), thing_tpl.i->y(), + InternalCreateObstacle(thing_id, thing_tpl.i->x(), thing_tpl.i->y(), 0, [] (Obstacle* entity) { }); @@ -192,7 +281,7 @@ void MapInstance::CreateBuilding(int thing_id, float building_x, float building_ MetaData::Building::Door* door_meta = &building->meta->doors[door_idx]; float x = building->GetX() + door_meta->state0->x() - building->meta->i->tilewidth() / 2.0; float y = building->GetY() + door_meta->state0->y() - building->meta->i->tileheight() / 2.0; - InternalCreateObstacle(DOOR_THING_ID, x, y, + InternalCreateObstacle(DOOR_THING_ID, x, y, 0, [building, door_idx] (Obstacle* entity) { entity->SetDoorInfo(building, door_idx); @@ -206,7 +295,7 @@ void MapInstance::CreateBuilding(int thing_id, float building_x, float building_ int rnd = rand () % obj._rand_space(); for (auto& pair : obj._things()) { if (rnd <= pair.value()) { - InternalCreateObstacle(pair.key(), x, y, + InternalCreateObstacle(pair.key(), x, y, 0, [building] (Obstacle* entity) { entity->SetBuilding(building); @@ -219,12 +308,13 @@ void MapInstance::CreateBuilding(int thing_id, float building_x, float building_ buildings_.push_back(building); } -Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, +Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int collider_tag, std::function on_precreate) { MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(id); if (thing) { Obstacle* entity = EntityFactory::Instance()->MakeObstacle(AllocUniid()); + entity->collider_tag = collider_tag; entity->meta = thing; entity->is_permanent = true; entity->permanent_map_service = map_service_; diff --git a/server/gameserver/mapinstance.h b/server/gameserver/mapinstance.h index 278dd63..76de008 100644 --- a/server/gameserver/mapinstance.h +++ b/server/gameserver/mapinstance.h @@ -26,9 +26,10 @@ class MapInstance private: void CreateThings(); + void CreateTerrain(); void CreateMapObject(MetaData::MapTplThing& thing_tpl); void CreateBuilding(int thing_id, float building_x, float building_y); - Obstacle* InternalCreateObstacle(int id, float x, float y, + Obstacle* InternalCreateObstacle(int id, float x, float y, int collider_tag, std::function on_precreate); Entity* GetEntityByUniId(int uniid); int AllocUniid(); diff --git a/server/gameserver/mapservice.cc b/server/gameserver/mapservice.cc index 7da2f31..4c47aac 100644 --- a/server/gameserver/mapservice.cc +++ b/server/gameserver/mapservice.cc @@ -184,6 +184,9 @@ void MapService::GetColliders(Room* room, } struct CellNode *node, *tmp; list_for_each_entry_safe(node, tmp, head, entry) { + if (node->collider->tag != 0) { + continue; + } switch (node->collider->owner->GetEntityType()) { case ET_Obstacle: { diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index 4300de4..d331e17 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -97,6 +97,9 @@ void Obstacle::RecalcSelfCollider() self_collider_->pos = a8::Vec2(); self_collider_->rad = 0.0f; } + for (auto collider : colliders_) { + collider->tag = collider_tag; + } } void Obstacle::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data) @@ -171,12 +174,14 @@ void Obstacle::GetAabbBox(AabbCollider& aabb_box) if (self_collider_) { aabb_box.active = true; aabb_box.owner = this; + aabb_box.tag = collider_tag; aabb_box._min.x = -self_collider_->rad; aabb_box._min.y = -self_collider_->rad; aabb_box._max.x = self_collider_->rad; aabb_box._max.y = self_collider_->rad; return; } + aabb_box.tag = collider_tag; aabb_box.active = true; aabb_box.owner = this; } diff --git a/server/gameserver/obstacle.h b/server/gameserver/obstacle.h index 8427265..a335df7 100644 --- a/server/gameserver/obstacle.h +++ b/server/gameserver/obstacle.h @@ -25,6 +25,7 @@ class Obstacle : public Entity MetaData::MapThing* meta = nullptr; MapService* permanent_map_service = nullptr; bool is_permanent = false; + int collider_tag = 0; virtual ~Obstacle() override; virtual void Initialize() override;