aozhiwei a5db73ab7c 1
2024-01-23 14:31:11 +08:00

402 lines
14 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)
static void LoadWorldObjects(const std::string& world_object_file,
std::vector<std::shared_ptr<mt::WorldObject>>& world_objects,
std::map<int, std::vector<std::shared_ptr<mt::WorldObject>>>& group_world_objects)
{
auto parse_func =
[] (std::shared_ptr<a8::XObject> node, std::shared_ptr<mt::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<mt::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(mt::MetaMgr::Instance()->GetResDir() + world_object_file)) {
{
auto thing = root.At("thing");
for (int i = 0; i < thing->Size(); ++i) {
auto obj = std::make_shared<mt::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<mt::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<mt::WorldObject>();
obj->object_type = WorldObjectType_e::kCarType;
parse_func(thing->At(i), obj);
world_objects.push_back(obj);
}
}
{
auto thing = root.At("monster");
for (int i = 0; i < thing->Size(); ++i) {
auto obj = std::make_shared<mt::WorldObject>();
obj->object_type = WorldObjectType_e::kMonsterType;
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<mt::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<mt::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<mt::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;
}
}
}
}
}
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 (is_open() && !IsPveMap() && !is_moba() && player() < 10) {
A8_ABORT();
}
collider_info = MapCollider::GetByName(map_collider());
LoadWorldObjects(world_object_file(),
_world_objects,
_group_world_objects);
PostProcess();
}
void Map::Init2()
{
{
if (is_open() && !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;
}
bool Map::IsOpen() const
{
return is_open();
}
glm::vec3 Map::GroundSamplingPos() const
{
return sampling_pos_;
}
void Map::PostProcess()
{
if (!is_moba()) {
return;
}
std::vector<std::shared_ptr<WorldObject>> path_objects;
std::map<int, std::vector<std::shared_ptr<WorldObject>>> group_path_objects;
std::string file_name = world_object_file();
a8::ReplaceString(file_name, ".json", ".path.json");
LoadWorldObjects(file_name,
path_objects,
group_path_objects);
std::vector<int> del_ids;
std::vector<std::shared_ptr<WorldObject>> born_points;
std::vector<std::vector<std::shared_ptr<WorldObject>>> roads_points;
roads_points.push_back(std::vector<std::shared_ptr<WorldObject>>());
roads_points.push_back(std::vector<std::shared_ptr<WorldObject>>());
roads_points.push_back(std::vector<std::shared_ptr<WorldObject>>());
{
int idx = 0;
for (auto& obj : path_objects) {
if (obj->object_type == WorldObjectType_e::kBoxType) {
switch (obj->object_id) {
case 80012:
{
born_points.push_back(obj);
del_ids.push_back(idx);
}
break;
case 66001:
{
roads_points.at(0).push_back(obj);
del_ids.push_back(idx);
}
break;
case 66002:
{
roads_points.at(1).push_back(obj);
del_ids.push_back(idx);
}
break;
case 51216:
{
roads_points.at(2).push_back(obj);
del_ids.push_back(idx);
}
break;
default:
{
break;
}
}
}
++idx;
}
}
{
if (born_points.size() != 2) {
abort();
}
std::sort(born_points.begin(), born_points.end(),
[] (std::shared_ptr<WorldObject> a, std::shared_ptr<WorldObject> b) {
return a->pos.x < b->pos.x;
});
for (auto obj : born_points) {
moba_born_points.push_back(std::make_tuple(obj, 0));
}
for (size_t i = 0; i < 3; ++i) {
moba_path_points.push_back(std::vector<std::tuple<std::shared_ptr<WorldObject>, int>>());
auto& points = moba_path_points.at(i);
for (auto obj : roads_points.at(i)) {
points.push_back(std::make_tuple(obj, 100));
}
std::sort(points.begin(), points.end(),
[] (const std::tuple<std::shared_ptr<WorldObject>, int>& a,
const std::tuple<std::shared_ptr<WorldObject>, int>& b) {
return std::get<0>(a)->pos.x < std::get<0>(b)->pos.x;
});
if (points.size() < 3) {
abort();
}
}
}
{
std::sort(del_ids.begin(), del_ids.end(),
[] (int a, int b) {
return a > b;
});
for (auto idx : del_ids) {
path_objects.erase(path_objects.begin() + idx);
}
}
}
}