#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>& world_objects, std::map>>& group_world_objects) { auto parse_func = [] (std::shared_ptr node, std::shared_ptr 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 node, std::shared_ptr 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(); 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(); 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(); 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(); 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(); 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 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> 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(); { 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 strings; a8::Split(template_list(), strings, '|'); for (auto& str : strings) { std::vector 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 strings; a8::Split(airdrops(), strings, '|'); for (auto& str : strings) { airdrops_.push_back(a8::XValue(str).GetInt()); } } { std::vector strings; a8::Split(safearea(), strings, '|'); for (auto& str : strings) { safearea_list.push_back(a8::XValue(str).GetInt()); } } { std::vector strings; a8::Split(airraids(), strings, '|'); for (auto& str : strings) { airraids_.push_back(a8::XValue(str).GetInt()); } } { std::vector strings; a8::Split(car_num_limit(), strings, '|'); for (auto& str : strings) { std::vector strings2; a8::Split(str, strings2, ':'); car_num_limit_[a8::XValue(strings2[0]).GetInt()] = a8::XValue(strings2[1]).GetInt(); } } { std::vector strings; a8::Split(game_start_buff_list(), strings, ':'); for (auto& str : strings) { buff_list.push_back(a8::XValue(str).GetInt()); } } { std::vector 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 strings; a8::Split(refresh_robot(), strings, '|'); if (strings.size() != 2) { A8_ABORT(); } { std::vector 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 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 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> path_objects; std::map>> 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 del_ids; std::vector> born_points; std::vector>> roads_points; roads_points.push_back(std::vector>()); roads_points.push_back(std::vector>()); roads_points.push_back(std::vector>()); { 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 a, std::shared_ptr 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, 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, int>& a, const std::tuple, 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); } } } }