320 lines
11 KiB
C++
320 lines
11 KiB
C++
#include "precompile.h"
|
|
|
|
#include "mt/Map.h"
|
|
#include "mt/MapCollider.h"
|
|
#include "mt/SafeArea.h"
|
|
#include "mt/MetaMgr.h"
|
|
|
|
IMPL_TABLE(mt::Map)
|
|
|
|
namespace mt
|
|
{
|
|
|
|
void Map::Init1()
|
|
{
|
|
scale_ = 0.1f;
|
|
rand_space = 0;
|
|
{
|
|
std::vector<std::string> strings;
|
|
a8::Split(template_list(), strings, '|');
|
|
for (auto& str : strings) {
|
|
std::vector<std::string> strings2;
|
|
a8::Split(str, strings2, ':');
|
|
assert(strings2.size() == 2);
|
|
rand_space += a8::XValue(strings2[1]).GetInt();
|
|
template_list_.push_back(std::make_tuple(
|
|
strings2[0],
|
|
rand_space
|
|
));
|
|
}
|
|
}
|
|
{
|
|
std::vector<std::string> strings;
|
|
a8::Split(airdrops(), strings, '|');
|
|
for (auto& str : strings) {
|
|
airdrops_.push_back(a8::XValue(str).GetInt());
|
|
}
|
|
}
|
|
{
|
|
std::vector<std::string> strings;
|
|
a8::Split(safearea(), strings, '|');
|
|
for (auto& str : strings) {
|
|
safearea_list.push_back(a8::XValue(str).GetInt());
|
|
}
|
|
}
|
|
{
|
|
std::vector<std::string> strings;
|
|
a8::Split(airraids(), strings, '|');
|
|
for (auto& str : strings) {
|
|
airraids_.push_back(a8::XValue(str).GetInt());
|
|
}
|
|
}
|
|
{
|
|
std::vector<std::string> strings;
|
|
a8::Split(car_num_limit(), strings, '|');
|
|
for (auto& str : strings) {
|
|
std::vector<std::string> strings2;
|
|
a8::Split(str, strings2, ':');
|
|
car_num_limit_[a8::XValue(strings2[0]).GetInt()] = a8::XValue(strings2[1]).GetInt();
|
|
}
|
|
}
|
|
{
|
|
std::vector<std::string> strings;
|
|
a8::Split(game_start_buff_list(), strings, ':');
|
|
for (auto& str : strings) {
|
|
buff_list.push_back(a8::XValue(str).GetInt());
|
|
}
|
|
}
|
|
{
|
|
std::vector<std::string> strings;
|
|
a8::Split(ground_sampling_pos(), strings, ':');
|
|
if (strings.size() != 3) {
|
|
abort();
|
|
}
|
|
sampling_pos_ = glm::vec3((float)a8::XValue(strings[0]).GetDouble(),
|
|
(float)a8::XValue(strings[1]).GetDouble(),
|
|
(float)a8::XValue(strings[2]).GetDouble());
|
|
}
|
|
if (!IsPveMap()) {
|
|
std::vector<std::string> strings;
|
|
a8::Split(refresh_robot(), strings, '|');
|
|
if (strings.size() != 2) {
|
|
A8_ABORT();
|
|
}
|
|
{
|
|
std::vector<std::string> strings2;
|
|
a8::Split(strings[0], strings2, '-');
|
|
if (strings2.size() != 2) {
|
|
A8_ABORT();
|
|
}
|
|
refresh_robot_min_num = a8::XValue(strings2[0]);
|
|
refresh_robot_max_num = a8::XValue(strings2[1]);
|
|
}
|
|
{
|
|
std::vector<std::string> strings2;
|
|
a8::Split(strings[1], strings2, '-');
|
|
if (strings2.size() != 2) {
|
|
A8_ABORT();
|
|
}
|
|
refresh_robot_min_time = a8::XValue(strings2[0]);
|
|
refresh_robot_max_time = a8::XValue(strings2[1]);
|
|
}
|
|
if (refresh_robot_min_num >= refresh_robot_max_num) {
|
|
A8_ABORT();
|
|
}
|
|
if (refresh_robot_min_time >= refresh_robot_max_time) {
|
|
A8_ABORT();
|
|
}
|
|
if (refresh_robot_min_num <= 0 || refresh_robot_max_num <= 0 ||
|
|
refresh_robot_min_time <= 0 || refresh_robot_max_time <= 0) {
|
|
A8_ABORT();
|
|
}
|
|
}
|
|
first_safearea_center_ = glm::vec3(map_width() / 2.0f,
|
|
0.0f,
|
|
map_height() / 2.0f);
|
|
if (!first_safearea_center().empty()) {
|
|
std::vector<std::string> strings;
|
|
a8::Split(first_safearea_center(), strings, ':');
|
|
if (strings.size() != 2) {
|
|
A8_ABORT();
|
|
}
|
|
first_safearea_center_ = glm::vec3(a8::XValue(strings[0]).GetDouble(),
|
|
0.0f,
|
|
a8::XValue(strings[1]).GetDouble());
|
|
}
|
|
if (!IsPveMap() && !is_moba() && player() < 10) {
|
|
A8_ABORT();
|
|
}
|
|
collider_info = MapCollider::GetByName(map_collider());
|
|
LoadWorldObjects();
|
|
PostProcess();
|
|
}
|
|
|
|
void Map::Init2()
|
|
{
|
|
{
|
|
if (!IsPveMap() && !is_moba() && safearea_list.empty()) {
|
|
A8_ABORT();
|
|
}
|
|
for (const int area_type : safearea_list) {
|
|
if (!mt::SafeArea::GetByType(area_type)) {
|
|
A8_ABORT();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string Map::RandTemplate() const
|
|
{
|
|
if (rand_space <= 0) {
|
|
return "";
|
|
}
|
|
int rnd = rand() % rand_space;
|
|
for (auto& tpl : template_list_) {
|
|
if (rnd <= std::get<1>(tpl)) {
|
|
return std::get<0>(tpl);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
int Map::GetCarLimit(int car_id) const
|
|
{
|
|
auto itr = car_num_limit_.find(car_id);
|
|
return itr != car_num_limit_.end() ? itr->second : 666;
|
|
}
|
|
|
|
glm::vec3 Map::GetCenter() const
|
|
{
|
|
glm::vec3 center(map_width() / 2, 0.0f, map_height() / 2);
|
|
return center;
|
|
}
|
|
|
|
int Map::RandSafeArea() const
|
|
{
|
|
if (safearea_list.empty()) {
|
|
A8_ABORT();
|
|
}
|
|
return safearea_list[rand() % safearea_list.size()];
|
|
}
|
|
|
|
bool Map::IsPveMap() const
|
|
{
|
|
return map_id() >= 1002 && map_id() <= 1003;
|
|
}
|
|
|
|
void Map::LoadWorldObjects()
|
|
{
|
|
auto parse_func =
|
|
[] (std::shared_ptr<a8::XObject> node, std::shared_ptr<WorldObject> obj)
|
|
{
|
|
obj->object_id = node->At("id")->AsXValue();
|
|
auto bounds = node->At("bounds");
|
|
auto center = bounds->At("center");
|
|
auto size = bounds->At("size");
|
|
obj->pos.x = center->At("x")->AsXValue().GetDouble();
|
|
obj->pos.y = center->At("y")->AsXValue().GetDouble();
|
|
obj->pos.z = center->At("z")->AsXValue().GetDouble();
|
|
|
|
obj->size.x = size->At("x")->AsXValue().GetDouble();
|
|
obj->size.y = size->At("y")->AsXValue().GetDouble();
|
|
obj->size.z = size->At("z")->AsXValue().GetDouble();
|
|
};
|
|
|
|
auto parse_human_func =
|
|
[] (std::shared_ptr<a8::XObject> node, std::shared_ptr<WorldObject> obj)
|
|
{
|
|
auto pos = node->At("pos");
|
|
obj->pos.x = pos->At("x")->AsXValue().GetDouble();
|
|
obj->pos.y = pos->At("y")->AsXValue().GetDouble();
|
|
obj->pos.z = pos->At("z")->AsXValue().GetDouble();
|
|
};
|
|
|
|
a8::XObject root;
|
|
if (!world_object_file().empty() &&
|
|
root.ReadFromFile(MetaMgr::Instance()->GetResDir() + world_object_file())) {
|
|
{
|
|
auto thing = root.At("thing");
|
|
for (int i = 0; i < thing->Size(); ++i) {
|
|
auto obj = std::make_shared<WorldObject>();
|
|
obj->object_type = WorldObjectType_e::kBoxType;
|
|
parse_func(thing->At(i), obj);
|
|
_world_objects.push_back(obj);
|
|
}
|
|
}
|
|
{
|
|
auto thing = root.At("loot");
|
|
for (int i = 0; i < thing->Size(); ++i) {
|
|
auto obj = std::make_shared<WorldObject>();
|
|
obj->object_type = WorldObjectType_e::kLootType;
|
|
parse_func(thing->At(i), obj);
|
|
_world_objects.push_back(obj);
|
|
}
|
|
}
|
|
{
|
|
auto thing = root.At("car");
|
|
for (int i = 0; i < thing->Size(); ++i) {
|
|
auto obj = std::make_shared<WorldObject>();
|
|
obj->object_type = WorldObjectType_e::kCarType;
|
|
parse_func(thing->At(i), obj);
|
|
_world_objects.push_back(obj);
|
|
}
|
|
}
|
|
{
|
|
auto thing = root.At("human");
|
|
for (int i = 0; i < thing->Size(); ++i) {
|
|
auto obj = std::make_shared<WorldObject>();
|
|
obj->object_type = WorldObjectType_e::kBornPointType;
|
|
parse_human_func(thing->At(i), obj);
|
|
_world_objects.push_back(obj);
|
|
}
|
|
}
|
|
{
|
|
auto group = root.At("group");
|
|
for (int i = 0; i < group->Size(); ++i) {
|
|
auto group_obj = group->At(i);
|
|
std::vector<std::string> keys;
|
|
group_obj->GetKeys(keys);
|
|
for (auto key : keys) {
|
|
int ikey = a8::XValue(key);
|
|
if (_group_world_objects.find(ikey) != _group_world_objects.end()) {
|
|
abort();
|
|
}
|
|
std::vector<std::shared_ptr<WorldObject>> objects;
|
|
auto items = group_obj->At(key);
|
|
for (int iii = 0; iii < items->Size(); ++iii) {
|
|
auto item_obj = items->At(iii);
|
|
auto obj = std::make_shared<WorldObject>();
|
|
{
|
|
obj->pos.x = item_obj->At("x")->AsXValue().GetDouble();
|
|
obj->pos.y = item_obj->At("y")->AsXValue().GetDouble();
|
|
obj->pos.z = item_obj->At("z")->AsXValue().GetDouble();
|
|
}
|
|
objects.push_back(obj);
|
|
}
|
|
_group_world_objects[ikey] = objects;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Map::IsOpen() const
|
|
{
|
|
return is_open();
|
|
}
|
|
|
|
glm::vec3 Map::GroundSamplingPos() const
|
|
{
|
|
return sampling_pos_;
|
|
}
|
|
|
|
void Map::PostProcess()
|
|
{
|
|
if (!is_moba()) {
|
|
return;
|
|
}
|
|
std::vector<int> del_ids;
|
|
std::vector<std::shared_ptr<WorldObject>> born_points;
|
|
int idx = 0;
|
|
for (auto& obj : _world_objects) {
|
|
if (obj->object_type == WorldObjectType_e::kBoxType) {
|
|
if (obj->object_id == 80012) {
|
|
born_points.push_back(obj);
|
|
del_ids.push_back(idx);
|
|
}
|
|
}
|
|
++idx;
|
|
}
|
|
std::sort(del_ids.begin(), del_ids.end(),
|
|
[] (int a, int b) {
|
|
return a > b;
|
|
});
|
|
for (auto idx : del_ids) {
|
|
_world_objects.erase(_world_objects.begin() + idx);
|
|
}
|
|
}
|
|
|
|
}
|