add mapinstance

This commit is contained in:
aozhiwei 2020-07-18 21:17:44 +08:00
parent a773c855dd
commit 20ff6afd30
4 changed files with 312 additions and 274 deletions

View File

@ -0,0 +1,254 @@
#include "precompile.h"
#include "mapinstance.h"
#include "mapservice.h"
#include "gridservice.h"
#include "building.h"
#include "obstacle.h"
#include "loot.h"
#include "mapmgr.h"
#include "metamgr.h"
#include "room.h"
#include "entityfactory.h"
const int MAP_GRID_WIDTH = 64;
void MapInstance::Init()
{
map_meta_ = MetaMgr::Instance()->GetMap(map_id);
if (!map_meta_) {
abort();
}
if (map_meta_->i->map_width() < 1) {
abort();
}
if (map_meta_->i->map_height() < 1) {
abort();
}
map_service_ = new MapService();
grid_service_ = new GridService();
grid_service_->Init(map_meta_->i->map_width(),
map_meta_->i->map_height(),
MetaMgr::Instance()->map_cell_width);
map_service_->Init(map_meta_->i->map_width() / MAP_GRID_WIDTH,
map_meta_->i->map_height() / MAP_GRID_WIDTH,
MAP_GRID_WIDTH);
CreateThings();
a8::UdpLog::Instance()->Info
("current_uniid:%d loots:%d mini_room_spawn_points:%d normal_room_spawn_points:%d "
"building_num:%d obstalce_num:%d obstacle0_num:%d "
"obstacle1_num:%d obstacle2_num:%d",
{
current_uniid_,
loots_.size(),
mini_room_spawn_points_.size(),
normal_room_spawn_points_.size(),
building_num_,
obstacle_num_,
obstacle0_num_,
obstacle1_num_,
obstacle2_num_,
});
if (current_uniid_ >= FIXED_OBJECT_MAXID) {
abort();
}
}
void MapInstance::UnInit()
{
map_service_->UnInit();
grid_service_->UnInit();
A8_SAFE_DELETE(map_service_);
A8_SAFE_DELETE(grid_service_);
}
void MapInstance::CreateThings()
{
map_tpl_name_ = map_meta_->RandTemplate();
std::map<std::string, MetaData::MapTplThing*> spawn_points_hash;
std::vector<MetaData::MapTplThing>* things = MetaMgr::Instance()->GetMapTplThing(map_tpl_name_);
if (things) {
for (auto& thing_tpl : *things) {
switch (thing_tpl.i->_object_type()) {
case kMOT_Object:
{
{
int thing_id = thing_tpl.RandThing();
if (MetaMgr::Instance()->level0room_spec_things_set.find(thing_id) !=
MetaMgr::Instance()->level0room_spec_things_set.end()) {
level0room_spec_things_.push_back(&thing_tpl);
continue;
}
}
if (thing_tpl.i->weight() >= rand() % 10000) {
CreateMapObject(thing_tpl);
}
}
break;
case kMOT_SpawnPoint:
{
std::string point_name = thing_tpl.i->name();
//pointxxx
if (point_name.size() < 6) {
abort();
}
std::string name_part = point_name.substr(0, 5);
std::string id_part = point_name.substr(5, point_name.size() - 5);
int point_id = a8::XValue(id_part);
if (spawn_points_hash.find(thing_tpl.i->name()) !=
spawn_points_hash.end()) {
abort();
}
if (point_id <= 100) {
normal_room_spawn_points_.push_back(&thing_tpl);
} else {
mini_room_spawn_points_.push_back(&thing_tpl);
}
spawn_points_hash[thing_tpl.i->name()] = &thing_tpl;
}
break;
default:
abort();
break;
}
}
}
if (spawn_points_hash.find(MetaMgr::Instance()->newbie_born_point) !=
spawn_points_hash.end()) {
level0room_born_point_ = spawn_points_hash[MetaMgr::Instance()->newbie_born_point];
mini_room_spawn_points_.push_back(level0room_born_point_);
}
if (spawn_points_hash.find(MetaMgr::Instance()->level1room_born_point) !=
spawn_points_hash.end()) {
level1room_born_point_ = spawn_points_hash[MetaMgr::Instance()->level1room_born_point];
mini_room_spawn_points_.push_back(level1room_born_point_);
}
}
void MapInstance::CreateMapObject(MetaData::MapTplThing& thing_tpl)
{
int thing_id = thing_tpl.RandThing();
MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(thing_id);
if (thing_meta) {
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(),
[] (Obstacle* entity)
{
});
}
} else {
loots_.push_back(&thing_tpl);
}
}
void MapInstance::CreateBuilding(int thing_id, float building_x, float building_y)
{
MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(thing_id);
if (!thing_meta) {
return;
}
MetaData::Building* building_meta = MetaMgr::Instance()->GetBuilding(thing_meta->i->house_id());
if (!building_meta) {
return;
}
Building* building = EntityFactory::Instance()->MakeBuilding(AllocUniid());
building->meta = building_meta;
building->permanent_map_service = map_service_;
building->building_id = thing_id;
building->SetPos(a8::Vec2(building_x, building_y));
building->Initialize();
uniid_hash_[building->GetEntityUniId()] = building;
grid_service_->AddPermanentEntity(building);
++building_num_;
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];
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,
[building, door_idx] (Obstacle* entity)
{
entity->SetDoorInfo(building, door_idx);
});
}
}
for (auto& obj : building_meta->i->lootobj()) {
float x = building->GetX() + obj.x() - building->meta->i->tilewidth() / 2.0;
float y = building->GetY() + obj.y() - building->meta->i->tileheight() / 2.0;
if (obj._rand_space() > 0) {
int rnd = rand () % obj._rand_space();
for (auto& pair : obj._things()) {
if (rnd <= pair.value()) {
InternalCreateObstacle(pair.key(), x, y,
[building] (Obstacle* entity)
{
entity->SetBuilding(building);
});
break;
}
}
}
}
buildings_.push_back(building);
}
Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y,
std::function<void (Obstacle*)> on_precreate)
{
MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(id);
if (thing) {
Obstacle* entity = EntityFactory::Instance()->MakeObstacle(AllocUniid());
entity->meta = thing;
entity->is_permanent = true;
entity->permanent_map_service = map_service_;
entity->SetPos(a8::Vec2(x, y));
entity->Initialize();
if (on_precreate) {
on_precreate(entity);
}
uniid_hash_[entity->GetEntityUniId()] = entity;
grid_service_->AddPermanentEntity(entity);
{
switch (thing->i->attack_type()) {
case 0:
{
++obstacle0_num_;
}
break;
case 1:
{
++obstacle1_num_;
}
break;
case 2:
{
++obstacle2_num_;
}
break;
default:
{
}
break;
}
++obstacle_num_;
}
return entity;
}
return nullptr;
}
Entity* MapInstance::GetEntityByUniId(int uniid)
{
auto itr = uniid_hash_.find(uniid);
return itr != uniid_hash_.end() ? itr->second : nullptr;
}
int MapInstance::AllocUniid()
{
while (GetEntityByUniId(++current_uniid_) || current_uniid_ == 0) {
}
return current_uniid_;
}

View File

@ -0,0 +1,54 @@
#pragma once
namespace MetaData
{
struct Map;
struct MapTplThing;
}
class Entity;
class Obstacle;
class Building;
class MapService;
class GridService;
class Room;
class MapInstance
{
public:
int map_id = 0;
void Init();
void UnInit();
private:
void CreateThings();
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,
std::function<void (Obstacle*)> on_precreate);
Entity* GetEntityByUniId(int uniid);
int AllocUniid();
private:
int current_uniid_ = 0;
std::map<int, Entity*> uniid_hash_;
std::string map_tpl_name_;
MetaData::Map* map_meta_ = nullptr;
MapService* map_service_ = nullptr;
GridService* grid_service_ = nullptr;
std::vector<MetaData::MapTplThing*> mini_room_spawn_points_;
std::vector<MetaData::MapTplThing*> normal_room_spawn_points_;
MetaData::MapTplThing* level0room_born_point_ = nullptr;
MetaData::MapTplThing* level1room_born_point_ = nullptr;
std::vector<MetaData::MapTplThing*> loots_;
std::vector<Building*> buildings_;
std::vector<MetaData::MapTplThing*> level0room_spec_things_;
int building_num_ = 0;
int obstacle_num_ = 0;
int obstacle0_num_ = 0;
int obstacle1_num_ = 0;
int obstacle2_num_ = 0;
};

View File

@ -10,59 +10,17 @@
#include "room.h" #include "room.h"
#include "entityfactory.h" #include "entityfactory.h"
const int MAP_GRID_WIDTH = 64;
void MapMgr::Init() void MapMgr::Init()
{ {
map_meta_ = MetaMgr::Instance()->GetMap(2001);
if (!map_meta_) {
abort();
}
if (map_meta_->i->map_width() < 1) {
abort();
}
if (map_meta_->i->map_height() < 1) {
abort();
}
map_service_ = new MapService();
grid_service_ = new GridService();
grid_service_->Init(map_meta_->i->map_width(),
map_meta_->i->map_height(),
MetaMgr::Instance()->map_cell_width);
map_service_->Init(map_meta_->i->map_width() / MAP_GRID_WIDTH,
map_meta_->i->map_height() / MAP_GRID_WIDTH,
MAP_GRID_WIDTH);
CreateThings();
a8::UdpLog::Instance()->Info
("current_uniid:%d loots:%d mini_room_spawn_points:%d normal_room_spawn_points:%d "
"building_num:%d obstalce_num:%d obstacle0_num:%d "
"obstacle1_num:%d obstacle2_num:%d",
{
current_uniid_,
loots_.size(),
mini_room_spawn_points_.size(),
normal_room_spawn_points_.size(),
building_num_,
obstacle_num_,
obstacle0_num_,
obstacle1_num_,
obstacle2_num_,
});
if (current_uniid_ >= FIXED_OBJECT_MAXID) {
abort();
}
} }
void MapMgr::UnInit() void MapMgr::UnInit()
{ {
map_service_->UnInit();
grid_service_->UnInit();
A8_SAFE_DELETE(map_service_);
A8_SAFE_DELETE(grid_service_);
} }
void MapMgr::AttachRoom(Room* room, RoomInitInfo& init_info) void MapMgr::AttachRoom(Room* room, RoomInitInfo& init_info)
{ {
#if 0
init_info.map_tpl_name = map_tpl_name_; init_info.map_tpl_name = map_tpl_name_;
init_info.map_meta = map_meta_; init_info.map_meta = map_meta_;
init_info.grid_service = grid_service_; init_info.grid_service = grid_service_;
@ -74,195 +32,5 @@ void MapMgr::AttachRoom(Room* room, RoomInitInfo& init_info)
init_info.loots = &loots_; init_info.loots = &loots_;
init_info.buildings = &buildings_; init_info.buildings = &buildings_;
init_info.level0room_spec_things = &level0room_spec_things_; init_info.level0room_spec_things = &level0room_spec_things_;
} #endif
void MapMgr::CreateThings()
{
map_tpl_name_ = map_meta_->RandTemplate();
std::map<std::string, MetaData::MapTplThing*> spawn_points_hash;
std::vector<MetaData::MapTplThing>* things = MetaMgr::Instance()->GetMapTplThing(map_tpl_name_);
if (things) {
for (auto& thing_tpl : *things) {
switch (thing_tpl.i->_object_type()) {
case kMOT_Object:
{
{
int thing_id = thing_tpl.RandThing();
if (MetaMgr::Instance()->level0room_spec_things_set.find(thing_id) !=
MetaMgr::Instance()->level0room_spec_things_set.end()) {
level0room_spec_things_.push_back(&thing_tpl);
continue;
}
}
if (thing_tpl.i->weight() >= rand() % 10000) {
CreateMapObject(thing_tpl);
}
}
break;
case kMOT_SpawnPoint:
{
std::string point_name = thing_tpl.i->name();
//pointxxx
if (point_name.size() < 6) {
abort();
}
std::string name_part = point_name.substr(0, 5);
std::string id_part = point_name.substr(5, point_name.size() - 5);
int point_id = a8::XValue(id_part);
if (spawn_points_hash.find(thing_tpl.i->name()) !=
spawn_points_hash.end()) {
abort();
}
if (point_id <= 100) {
normal_room_spawn_points_.push_back(&thing_tpl);
} else {
mini_room_spawn_points_.push_back(&thing_tpl);
}
spawn_points_hash[thing_tpl.i->name()] = &thing_tpl;
}
break;
default:
abort();
break;
}
}
}
if (spawn_points_hash.find(MetaMgr::Instance()->newbie_born_point) !=
spawn_points_hash.end()) {
level0room_born_point_ = spawn_points_hash[MetaMgr::Instance()->newbie_born_point];
mini_room_spawn_points_.push_back(level0room_born_point_);
}
if (spawn_points_hash.find(MetaMgr::Instance()->level1room_born_point) !=
spawn_points_hash.end()) {
level1room_born_point_ = spawn_points_hash[MetaMgr::Instance()->level1room_born_point];
mini_room_spawn_points_.push_back(level1room_born_point_);
}
}
void MapMgr::CreateMapObject(MetaData::MapTplThing& thing_tpl)
{
int thing_id = thing_tpl.RandThing();
MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(thing_id);
if (thing_meta) {
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(),
[] (Obstacle* entity)
{
});
}
} else {
loots_.push_back(&thing_tpl);
}
}
void MapMgr::CreateBuilding(int thing_id, float building_x, float building_y)
{
MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(thing_id);
if (!thing_meta) {
return;
}
MetaData::Building* building_meta = MetaMgr::Instance()->GetBuilding(thing_meta->i->house_id());
if (!building_meta) {
return;
}
Building* building = EntityFactory::Instance()->MakeBuilding(AllocUniid());
building->meta = building_meta;
building->permanent_map_service = map_service_;
building->building_id = thing_id;
building->SetPos(a8::Vec2(building_x, building_y));
building->Initialize();
uniid_hash_[building->GetEntityUniId()] = building;
grid_service_->AddPermanentEntity(building);
++building_num_;
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];
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,
[building, door_idx] (Obstacle* entity)
{
entity->SetDoorInfo(building, door_idx);
});
}
}
for (auto& obj : building_meta->i->lootobj()) {
float x = building->GetX() + obj.x() - building->meta->i->tilewidth() / 2.0;
float y = building->GetY() + obj.y() - building->meta->i->tileheight() / 2.0;
if (obj._rand_space() > 0) {
int rnd = rand () % obj._rand_space();
for (auto& pair : obj._things()) {
if (rnd <= pair.value()) {
InternalCreateObstacle(pair.key(), x, y,
[building] (Obstacle* entity)
{
entity->SetBuilding(building);
});
break;
}
}
}
}
buildings_.push_back(building);
}
Obstacle* MapMgr::InternalCreateObstacle(int id, float x, float y,
std::function<void (Obstacle*)> on_precreate)
{
MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(id);
if (thing) {
Obstacle* entity = EntityFactory::Instance()->MakeObstacle(AllocUniid());
entity->meta = thing;
entity->is_permanent = true;
entity->permanent_map_service = map_service_;
entity->SetPos(a8::Vec2(x, y));
entity->Initialize();
if (on_precreate) {
on_precreate(entity);
}
uniid_hash_[entity->GetEntityUniId()] = entity;
grid_service_->AddPermanentEntity(entity);
{
switch (thing->i->attack_type()) {
case 0:
{
++obstacle0_num_;
}
break;
case 1:
{
++obstacle1_num_;
}
break;
case 2:
{
++obstacle2_num_;
}
break;
default:
{
}
break;
}
++obstacle_num_;
}
return entity;
}
return nullptr;
}
Entity* MapMgr::GetEntityByUniId(int uniid)
{
auto itr = uniid_hash_.find(uniid);
return itr != uniid_hash_.end() ? itr->second : nullptr;
}
int MapMgr::AllocUniid()
{
while (GetEntityByUniId(++current_uniid_) || current_uniid_ == 0) {
}
return current_uniid_;
} }

View File

@ -1,16 +1,6 @@
#pragma once #pragma once
namespace MetaData class MapInstance;
{
struct Map;
struct MapTplThing;
}
class Entity;
class Obstacle;
class Building;
class MapService;
class GridService;
class Room; class Room;
class MapMgr : public a8::Singleton<MapMgr> class MapMgr : public a8::Singleton<MapMgr>
{ {
@ -25,33 +15,5 @@ class MapMgr : public a8::Singleton<MapMgr>
void AttachRoom(Room* room, RoomInitInfo& init_info); void AttachRoom(Room* room, RoomInitInfo& init_info);
private: private:
void CreateThings(); std::map<int, MapInstance*> instance_hash_;
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,
std::function<void (Obstacle*)> on_precreate);
Entity* GetEntityByUniId(int uniid);
int AllocUniid();
private:
int current_uniid_ = 0;
std::map<int, Entity*> uniid_hash_;
std::string map_tpl_name_;
MetaData::Map* map_meta_ = nullptr;
MapService* map_service_ = nullptr;
GridService* grid_service_ = nullptr;
std::vector<MetaData::MapTplThing*> mini_room_spawn_points_;
std::vector<MetaData::MapTplThing*> normal_room_spawn_points_;
MetaData::MapTplThing* level0room_born_point_ = nullptr;
MetaData::MapTplThing* level1room_born_point_ = nullptr;
std::vector<MetaData::MapTplThing*> loots_;
std::vector<Building*> buildings_;
std::vector<MetaData::MapTplThing*> level0room_spec_things_;
int building_num_ = 0;
int obstacle_num_ = 0;
int obstacle0_num_ = 0;
int obstacle1_num_ = 0;
int obstacle2_num_ = 0;
}; };