220 lines
7.7 KiB
C++
220 lines
7.7 KiB
C++
#include "precompile.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 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 spawn_points:%d\n",
|
|
{
|
|
current_uniid_,
|
|
loots_.size(),
|
|
spawn_points_.size()
|
|
});
|
|
if (current_uniid_ >= FIXED_OBJECT_MAXID) {
|
|
abort();
|
|
}
|
|
}
|
|
|
|
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)
|
|
{
|
|
init_info.map_tpl_name = map_tpl_name_;
|
|
init_info.map_meta = map_meta_;
|
|
init_info.grid_service = grid_service_;
|
|
init_info.map_service = map_service_;
|
|
init_info.spawn_points = &spawn_points_;
|
|
init_info.level0room_born_point_meta = level0room_born_point_;
|
|
init_info.level1room_born_point_meta = level1room_born_point_;
|
|
init_info.loots = &loots_;
|
|
init_info.buildings = &buildings_;
|
|
init_info.level0room_spec_things = &level0room_spec_things_;
|
|
}
|
|
|
|
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:
|
|
{
|
|
if (spawn_points_hash.find(thing_tpl.i->name()) !=
|
|
spawn_points_hash.end()) {
|
|
abort();
|
|
}
|
|
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];
|
|
}
|
|
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];
|
|
}
|
|
}
|
|
|
|
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);
|
|
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);
|
|
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_;
|
|
}
|