649 lines
23 KiB
C++
649 lines
23 KiB
C++
#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"
|
|
#include "dummyentity.h"
|
|
#include "mapblock.h"
|
|
#include "roommgr.h"
|
|
|
|
const int MAP_GRID_WIDTH = 64;
|
|
|
|
static const int NAVMESHSET_MAGIC = 'M'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'MSET';
|
|
static const int NAVMESHSET_VERSION = 1;
|
|
|
|
struct NavMeshSetHeader
|
|
{
|
|
int magic;
|
|
int version;
|
|
int numTiles;
|
|
dtNavMeshParams params;
|
|
};
|
|
|
|
struct NavMeshTileHeader
|
|
{
|
|
dtTileRef tileRef;
|
|
int dataSize;
|
|
};
|
|
|
|
void MapInstance::Init()
|
|
{
|
|
current_map_block_uniid_ = MAP_BLOCK_START_ID;
|
|
map_meta_ = MetaMgr::Instance()->GetMap(map_id);
|
|
if (!map_meta_) {
|
|
A8_ABORT();
|
|
}
|
|
if (map_meta_->i->map_width() < 1) {
|
|
A8_ABORT();
|
|
}
|
|
if (map_meta_->i->map_height() < 1) {
|
|
A8_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();
|
|
CreateTerrain();
|
|
CreateBlock();
|
|
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 "
|
|
"obstacle1_num:%d obstacle2_num:%d",
|
|
{
|
|
map_id,
|
|
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) {
|
|
A8_ABORT();
|
|
}
|
|
{
|
|
navmesh_ = dtAllocNavMesh();
|
|
FILE *fp = fopen((MetaMgr::Instance()->GetResDir() + "map3.bin").c_str(), "rb");
|
|
if(fp){
|
|
//fseek(fp, 0, SEEK_END);
|
|
//int file_size = ftell(fp);
|
|
int file_size = 1;
|
|
if(file_size){
|
|
NavMeshSetHeader header;
|
|
size_t readLen = fread(&header, sizeof(NavMeshSetHeader), 1, fp);
|
|
if (readLen != 1) {
|
|
fclose(fp);
|
|
abort();
|
|
}
|
|
if (header.magic != NAVMESHSET_MAGIC) {
|
|
fclose(fp);
|
|
abort();
|
|
}
|
|
if (header.version != NAVMESHSET_VERSION) {
|
|
fclose(fp);
|
|
abort();
|
|
}
|
|
dtStatus status = navmesh_->init(&header.params);
|
|
if (dtStatusFailed(status)) {
|
|
fclose(fp);
|
|
abort();
|
|
}
|
|
{
|
|
// Read tiles.
|
|
for (int i = 0; i < header.numTiles; ++i) {
|
|
NavMeshTileHeader tileHeader;
|
|
readLen = fread(&tileHeader, sizeof(tileHeader), 1, fp);
|
|
if (readLen != 1) {
|
|
fclose(fp);
|
|
abort();
|
|
}
|
|
|
|
if (!tileHeader.tileRef || !tileHeader.dataSize) {
|
|
abort();
|
|
break;
|
|
}
|
|
|
|
unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize,
|
|
DT_ALLOC_PERM);
|
|
if (!data) {
|
|
abort();
|
|
break;
|
|
}
|
|
memset(data, 0, tileHeader.dataSize);
|
|
readLen = fread(data, tileHeader.dataSize, 1, fp);
|
|
if (readLen != 1) {
|
|
dtFree(data);
|
|
fclose(fp);
|
|
abort();
|
|
}
|
|
navmesh_->addTile(data,
|
|
tileHeader.dataSize,
|
|
DT_TILE_FREE_DATA,
|
|
tileHeader.tileRef,
|
|
0);
|
|
}
|
|
}
|
|
}
|
|
fclose(fp);
|
|
}
|
|
}
|
|
#if 1
|
|
{
|
|
dtTileRef tile_ref = navmesh_->getTileRefAt(0, 0, 0);
|
|
int i = 0;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void MapInstance::UnInit()
|
|
{
|
|
dtFreeNavMesh(navmesh_);
|
|
navmesh_ = nullptr;
|
|
|
|
map_service_->UnInit();
|
|
grid_service_->UnInit();
|
|
A8_SAFE_DELETE(map_service_);
|
|
A8_SAFE_DELETE(grid_service_);
|
|
}
|
|
|
|
void MapInstance::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.map_instance = this;
|
|
init_info.mini_room_spawn_points = &mini_room_spawn_points_;
|
|
init_info.normal_room_spawn_points = &normal_room_spawn_points_;
|
|
init_info.room_monster_spawn_points = &room_monster_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 MapInstance::CreateThings()
|
|
{
|
|
map_tpl_name_ = map_meta_->RandTemplate();
|
|
#ifdef MAP3D
|
|
{
|
|
for (int i = 1; i < 100; i++) {
|
|
MetaData::MapTplThing* p = new MetaData::MapTplThing();
|
|
auto p2 = new metatable::MapTplThingJson;
|
|
p2->set_x(10);
|
|
p2->set_y(10);
|
|
|
|
p->i = p2;
|
|
p->param1_int = 3;
|
|
normal_room_spawn_points_.push_back(p);
|
|
mini_room_spawn_points_.push_back(p);
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
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 num = 0;
|
|
int thing_id = thing_tpl.RandThing(num);
|
|
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) {
|
|
A8_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()) {
|
|
A8_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;
|
|
case kMOT_MonsterSpawnPoint:
|
|
{
|
|
room_monster_spawn_points_.push_back(&thing_tpl);
|
|
for (int hero_id : thing_tpl.heros) {
|
|
MetaData::Player* hero_meta = MetaMgr::Instance()->GetPlayer(hero_id);
|
|
if (!hero_meta) {
|
|
A8_ABORT();
|
|
}
|
|
if (!MetaMgr::Instance()->GetHeroAI(hero_meta->i->ai())) {
|
|
A8_ABORT();
|
|
}
|
|
if (map_id > 1001) {
|
|
auto itr = spawn_name_hash_.find(thing_tpl.i->name());
|
|
if (itr != spawn_name_hash_.end()) {
|
|
abort();
|
|
}
|
|
a8::Vec2 point;
|
|
point.x = thing_tpl.i->x();
|
|
point.y = thing_tpl.i->y();
|
|
spawn_name_hash_[thing_tpl.i->name()] = point;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
A8_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::CreateTerrain()
|
|
{
|
|
#ifdef DMAP3D
|
|
return;
|
|
#endif
|
|
metatable::TerrainJson* terrain = MetaMgr::Instance()->GetTerrainJson(map_id);
|
|
std::list<metatable::MapLayerJson>* layers = MetaMgr::Instance()->GetMapLayer(map_meta_->i->map_pic());
|
|
if (!terrain || !layers) {
|
|
return;
|
|
//A8_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()) {
|
|
A8_ABORT();
|
|
}
|
|
if (layer.height() != first_layer->height()) {
|
|
A8_ABORT();
|
|
}
|
|
if (layer.grids().size() != first_layer->grids().size()) {
|
|
A8_ABORT();
|
|
}
|
|
}
|
|
if (first_layer->grids().size() != first_layer->width() * first_layer->height()) {
|
|
A8_ABORT();
|
|
}
|
|
if (first_layer->grids().size() <= 0) {
|
|
A8_ABORT();
|
|
}
|
|
|
|
std::vector<int> grids;
|
|
grids.reserve(first_layer->grids().size());
|
|
for (int i = 0; i < first_layer->grids().size(); ++i) {
|
|
grids.push_back(0);
|
|
}
|
|
std::set<int> dusts;
|
|
for (auto idx : terrain->dust()) {
|
|
dusts.insert(idx + 1);
|
|
}
|
|
std::set<int> waters;
|
|
for (auto idx : terrain->water()) {
|
|
waters.insert(idx + 1);
|
|
}
|
|
std::set<int> grasses;
|
|
for (auto idx : terrain->grass()) {
|
|
grasses.insert(idx + 1);
|
|
}
|
|
std::set<int> mountain_tops;
|
|
for (auto idx : terrain->mountain_top()) {
|
|
mountain_tops.insert(idx + 1);
|
|
}
|
|
|
|
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(80001);
|
|
#ifdef DEBUG
|
|
a8::XPrintf("%s %s %f %f\n", {map_tpl_name_,
|
|
map_meta_->i->map_pic(),
|
|
(float)first_layer->width(),
|
|
(float)first_layer->height()});
|
|
#endif
|
|
if (thing_meta) {
|
|
for (int w = 0; w < first_layer->width(); ++w) {
|
|
for (int h = 0; h < first_layer->height(); ++h) {
|
|
assert(w < 300 && h < 300);
|
|
int grid_val = grids[h * first_layer->width() + w];
|
|
if (grid_val != 0) {
|
|
float x = w * thing_meta->i->width() + thing_meta->i->width() / 2.0f;
|
|
float y = (first_layer->height() * thing_meta->i->height()) - (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);
|
|
assert(collider_tag > 0);
|
|
} else if (waters.find(grid_val) != waters.end()) {
|
|
a8::SetBitFlag(collider_tag, kColliderTag_Water);
|
|
assert(collider_tag > 0);
|
|
|
|
} else if (grasses.find(grid_val) != grasses.end()) {
|
|
a8::SetBitFlag(collider_tag, kColliderTag_Grass);
|
|
assert(collider_tag > 0);
|
|
} else if (mountain_tops.find(grid_val) != mountain_tops.end()) {
|
|
a8::SetBitFlag(collider_tag, kColliderTag_MountainTop);
|
|
assert(collider_tag > 0);
|
|
}
|
|
if (collider_tag != 0) {
|
|
#if 1
|
|
auto& block = a8::FastAppend(terrain_blocks_);
|
|
block.set_shape(2);
|
|
block.set_x(x);
|
|
block.set_y(y);
|
|
block.set_height(thing_meta->i->height());
|
|
block.set_width(thing_meta->i->width());
|
|
block.set_rad(std::max(thing_meta->i->height(), thing_meta->i->width()));
|
|
block.set_bullet_penetrate(0);
|
|
block.set_collider_tag(collider_tag);
|
|
#else
|
|
assert(w < 300 && h < 300);
|
|
assert(collider_tag > 0);
|
|
InternalCreateObstacle(thing_meta->i->thing_id(), x, y, collider_tag,
|
|
[] (Obstacle* entity)
|
|
{
|
|
},
|
|
true,
|
|
w,
|
|
h);
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
{
|
|
DummyEntity* dummy = EntityFactory::Instance()->MakeDummy(AllocUniid());
|
|
dummy->SetPos(a8::Vec2());
|
|
dummy->permanent_map_service = map_service_;
|
|
dummy->blocks = &terrain_blocks_;
|
|
dummy->Initialize();
|
|
uniid_hash_[dummy->GetUniId()] = dummy;
|
|
grid_service_->AddPermanentEntity(dummy);
|
|
}
|
|
}
|
|
|
|
void MapInstance::CreateBlock()
|
|
{
|
|
#ifdef MAP3D
|
|
return;
|
|
#endif
|
|
std::list<metatable::MapBlockJson>* blocks = MetaMgr::Instance()->GetMapBlock(map_meta_->i->map_pic());
|
|
DummyEntity* dummy = EntityFactory::Instance()->MakeDummy(AllocUniid());
|
|
dummy->SetPos(a8::Vec2());
|
|
dummy->permanent_map_service = map_service_;
|
|
dummy->blocks = blocks;
|
|
dummy->Initialize();
|
|
uniid_hash_[dummy->GetUniId()] = dummy;
|
|
grid_service_->AddPermanentEntity(dummy);
|
|
|
|
if (blocks) {
|
|
for (auto& obj : *blocks) {
|
|
switch (obj.shape()) {
|
|
case 1:
|
|
case 2:
|
|
{
|
|
if (!obj.bullet_penetrate()) {
|
|
MapBlock* block = EntityFactory::Instance()->MakeBlock(++current_map_block_uniid_);
|
|
block->meta = MetaMgr::Instance()->GetMapThing
|
|
(obj.bullet_penetrate() ? 40002 : 40001);
|
|
block->shape = obj.shape();
|
|
block->width = obj.width();
|
|
block->height = obj.height();
|
|
block->rad = obj.rad();
|
|
block->permanent_map_service = map_service_;
|
|
block->SetPos(a8::Vec2(obj.x(), obj.y()));
|
|
block->Initialize();
|
|
uniid_hash_[block->GetUniId()] = block;
|
|
grid_service_->AddPermanentEntity(block);
|
|
if (!block->meta) {
|
|
A8_ABORT();
|
|
}
|
|
} else {
|
|
int i = 0;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void MapInstance::CreateMapObject(MetaData::MapTplThing& thing_tpl)
|
|
{
|
|
int num = 0;
|
|
int thing_id = thing_tpl.RandThing(num);
|
|
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(), 0,
|
|
[] (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->GetUniId()] = 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, 0,
|
|
[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, 0,
|
|
[building] (Obstacle* entity)
|
|
{
|
|
entity->SetBuilding(building);
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
buildings_.push_back(building);
|
|
}
|
|
|
|
Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int collider_tag,
|
|
std::function<void (Obstacle*)> on_precreate,
|
|
bool no_grid_service,
|
|
int collider_param1,
|
|
int collider_param2)
|
|
{
|
|
MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(id);
|
|
if (thing) {
|
|
Obstacle* entity = EntityFactory::Instance()->MakeObstacle(AllocUniid());
|
|
entity->collider_tag = collider_tag;
|
|
entity->collider_param1 = collider_param1;
|
|
entity->collider_param2 = collider_param2;
|
|
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->GetUniId()] = entity;
|
|
if (!no_grid_service) {
|
|
grid_service_->AddPermanentEntity(entity);
|
|
}
|
|
{
|
|
#if 0
|
|
switch (thing->i->attack_type()) {
|
|
case 0:
|
|
{
|
|
++obstacle0_num_;
|
|
}
|
|
break;
|
|
case 1:
|
|
{
|
|
++obstacle1_num_;
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
++obstacle2_num_;
|
|
}
|
|
break;
|
|
default:
|
|
{
|
|
}
|
|
break;
|
|
}
|
|
#endif
|
|
++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_;
|
|
}
|
|
|
|
MapBlock* MapInstance::InternalCreateMapBlock(int id, float x, float y,
|
|
int shape, float width, float height)
|
|
{
|
|
MapBlock* p = EntityFactory::Instance()->MakeBlock(++current_map_block_uniid_);
|
|
//building->meta = building_meta;
|
|
p->permanent_map_service = map_service_;
|
|
return p;
|
|
}
|
|
|
|
a8::Vec2* MapInstance::GetSpawnPoint(const std::string& name)
|
|
{
|
|
auto itr = spawn_name_hash_.find(name);
|
|
return itr != spawn_name_hash_.end() ? &itr->second : nullptr;
|
|
}
|
|
|
|
int MapInstance::FindStraightPath(int layer,
|
|
const a8::Vec3& start,
|
|
const a8::Vec3& end,
|
|
std::vector<a8::Vec3>& paths)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int MapInstance::FindRandomPointAroundCircle(int layer,
|
|
const a8::Vec3& center_pos,
|
|
std::vector<a8::Vec3>& points,
|
|
unsigned int max_points,
|
|
float max_radius)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int MapInstance::Raycast(int layer,
|
|
const a8::Vec3& start,
|
|
const a8::Vec3& end,
|
|
std::vector<a8::Vec3>& hit_points)
|
|
{
|
|
return 0;
|
|
}
|