mirror of
https://github.com/Mr-X-GTA/YimMenu.git
synced 2024-12-23 04:27:25 +08:00
Xml Map Loader (Menyoo) (#2233)
Co-authored-by: Yimura <24669514+Yimura@users.noreply.github.com>
This commit is contained in:
parent
9a610851cb
commit
fba0098ca3
@ -13,6 +13,7 @@
|
||||
#include "services/tunables/tunables_service.hpp"
|
||||
#include "services/vehicle/vehicle_control_service.hpp"
|
||||
#include "services/vehicle/xml_vehicles_service.hpp"
|
||||
#include "services/xml_maps/xml_map_service.hpp"
|
||||
#include "thread_pool.hpp"
|
||||
|
||||
|
||||
@ -27,6 +28,7 @@ namespace big
|
||||
|
||||
g_squad_spawner_service.fetch_squads();
|
||||
g_xml_vehicles_service->fetch_xml_files();
|
||||
g_xml_map_service->fetch_xml_files();
|
||||
g_custom_teleport_service.fetch_saved_locations();
|
||||
g_ped_animation_service.fetch_saved_animations();
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "services/vehicle/handling_service.hpp"
|
||||
#include "services/vehicle/vehicle_control_service.hpp"
|
||||
#include "services/vehicle/xml_vehicles_service.hpp"
|
||||
#include "services/xml_maps/xml_map_service.hpp"
|
||||
#include "thread_pool.hpp"
|
||||
#include "util/migrate.hpp"
|
||||
#include "version.hpp"
|
||||
@ -113,6 +114,7 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID)
|
||||
auto tunables_service_instance = std::make_unique<tunables_service>();
|
||||
auto script_connection_service_instance = std::make_unique<script_connection_service>();
|
||||
auto xml_vehicles_service_instance = std::make_unique<xml_vehicles_service>();
|
||||
auto xml_maps_service_instance = std::make_unique<xml_map_service>();
|
||||
LOG(INFO) << "Registered service instances...";
|
||||
|
||||
g_script_mgr.add_script(std::make_unique<script>(&gui::script_func, "GUI", false));
|
||||
|
@ -35,6 +35,7 @@ namespace big
|
||||
BLACKHOLE,
|
||||
MODEL_SWAPPER,
|
||||
VFX,
|
||||
XML_MAPS,
|
||||
|
||||
NETWORK,
|
||||
MISSIONS,
|
||||
@ -130,6 +131,7 @@ namespace big
|
||||
{TAB_DECL(BLACKHOLE), view::blackhole}},
|
||||
{TAB_DECL(MODEL_SWAPPER), view::model_swapper}},
|
||||
{TAB_DECL(VFX), view::vfx}},
|
||||
{TAB_DECL(XML_MAPS), view::xml_maps}},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
541
src/services/xml_maps/xml_map_service.cpp
Normal file
541
src/services/xml_maps/xml_map_service.cpp
Normal file
@ -0,0 +1,541 @@
|
||||
#include "xml_map_service.hpp"
|
||||
|
||||
#include "natives.hpp"
|
||||
#include "util/ped.hpp"
|
||||
#include "util/vehicle.hpp"
|
||||
#include "util/world_model.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
xml_map_service::xml_map_service()
|
||||
{
|
||||
g_xml_map_service = this;
|
||||
}
|
||||
|
||||
xml_map_service::~xml_map_service()
|
||||
{
|
||||
g_xml_map_service = nullptr;
|
||||
}
|
||||
|
||||
void xml_map_service::fetch_xml_files()
|
||||
{
|
||||
auto folder_path = g_file_manager.get_project_folder("xml_maps").get_path();
|
||||
|
||||
try
|
||||
{
|
||||
for (const auto& entry : std::filesystem::directory_iterator(folder_path))
|
||||
{
|
||||
if (entry.path().extension() == ".xml")
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_file(entry.path().c_str());
|
||||
|
||||
if (result)
|
||||
m_all_xml_maps.emplace(std::pair<std::string, pugi::xml_document>(entry.path().filename().generic_string(), std::move(doc)));
|
||||
else
|
||||
LOG(WARNING) << "Failed to load XML file: " << entry.path().filename().string() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
LOG(WARNING) << "Failed fetching XML maps: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void manage_ipls(pugi::xml_node unload, pugi::xml_node load)
|
||||
{
|
||||
for (auto node = unload.first_child(); node; node = node.next_sibling())
|
||||
{
|
||||
auto name = node.text().as_string();
|
||||
if (STREAMING::IS_IPL_ACTIVE(name))
|
||||
STREAMING::REMOVE_IPL(name);
|
||||
}
|
||||
|
||||
for (auto node = load.first_child(); node; node = node.next_sibling())
|
||||
{
|
||||
auto name = node.text().as_string();
|
||||
if (!STREAMING::IS_IPL_ACTIVE(name))
|
||||
STREAMING::REQUEST_IPL(name);
|
||||
}
|
||||
}
|
||||
|
||||
void manage_interiors(pugi::xml_node interiors, pugi::xml_node cap)
|
||||
{
|
||||
for (auto node = interiors.first_child(); node; node = node.next_sibling())
|
||||
{
|
||||
auto enabled = node.attribute("enable").as_bool();
|
||||
auto interior = node.attribute("id").as_int(-1);
|
||||
|
||||
if (interior == -1)
|
||||
{
|
||||
if (node.attribute("X"))
|
||||
{
|
||||
interior = INTERIOR::GET_INTERIOR_AT_COORDS(node.attribute("X").as_float(),
|
||||
node.attribute("Y").as_float(),
|
||||
node.attribute("Z").as_float());
|
||||
}
|
||||
else if (node.child("X"))
|
||||
{
|
||||
interior = INTERIOR::GET_INTERIOR_AT_COORDS(node.child("X").text().as_float(),
|
||||
node.child("Y").text().as_float(),
|
||||
node.child("Z").text().as_float());
|
||||
}
|
||||
}
|
||||
|
||||
if (INTERIOR::IS_VALID_INTERIOR(interior))
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
INTERIOR::PIN_INTERIOR_IN_MEMORY(interior);
|
||||
if (INTERIOR::IS_INTERIOR_DISABLED(interior))
|
||||
INTERIOR::DISABLE_INTERIOR(interior, false);
|
||||
|
||||
for (auto prop = node.child("InteriorProp"); prop; prop = prop.next_sibling("InteriorProp"))
|
||||
{
|
||||
auto name = prop.attribute("name").as_string();
|
||||
if (!std::string(name).empty())
|
||||
{
|
||||
if (prop.attribute("enable").as_bool(true))
|
||||
INTERIOR::ACTIVATE_INTERIOR_ENTITY_SET(interior, name);
|
||||
else
|
||||
INTERIOR::DEACTIVATE_INTERIOR_ENTITY_SET(interior, name);
|
||||
}
|
||||
}
|
||||
|
||||
INTERIOR::REFRESH_INTERIOR(interior);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!INTERIOR::IS_INTERIOR_DISABLED(interior))
|
||||
INTERIOR::DISABLE_INTERIOR(interior, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto node = cap.first_child(); node; node = node.next_sibling())
|
||||
{
|
||||
auto capped = node.attribute("cap").as_bool();
|
||||
auto interior = node.attribute("id").as_int(-1);
|
||||
|
||||
if (interior == -1)
|
||||
{
|
||||
if (node.attribute("X"))
|
||||
{
|
||||
interior = INTERIOR::GET_INTERIOR_AT_COORDS(node.attribute("X").as_float(),
|
||||
node.attribute("Y").as_float(),
|
||||
node.attribute("Z").as_float());
|
||||
}
|
||||
else if (node.child("X"))
|
||||
{
|
||||
interior = INTERIOR::GET_INTERIOR_AT_COORDS(node.child("X").text().as_float(),
|
||||
node.child("Y").text().as_float(),
|
||||
node.child("Z").text().as_float());
|
||||
}
|
||||
}
|
||||
|
||||
if (INTERIOR::IS_VALID_INTERIOR(interior))
|
||||
{
|
||||
INTERIOR::CAP_INTERIOR(interior, capped);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void object_details(pugi::xml_node object_node, Entity ent)
|
||||
{
|
||||
OBJECT::SET_OBJECT_TINT_INDEX(ent, object_node.child("TextureVariation").text().as_int());
|
||||
}
|
||||
|
||||
void vehicle_details(pugi::xml_node vehicle_node, Entity ent)
|
||||
{
|
||||
auto properties = vehicle_node.child("VehicleProperties");
|
||||
auto colors = properties.child("Colours");
|
||||
|
||||
auto primary_color = colors.child("Primary").text().as_int();
|
||||
auto secondary_color = colors.child("Secondary").text().as_int();
|
||||
auto pearl_color = colors.child("Pearl").text().as_int();
|
||||
auto rim_color = colors.child("Rim").text().as_int();
|
||||
auto tyre_smoke_r = colors.child("tyreSmoke_R").text().as_int();
|
||||
auto tyre_smoke_g = colors.child("tyreSmoke_G").text().as_int();
|
||||
auto tyre_smoke_b = colors.child("tyreSmoke_B").text().as_int();
|
||||
auto lr_interior = colors.child("LrInterior").text().as_int();
|
||||
auto lr_dashboard = colors.child("LrDashboard").text().as_int();
|
||||
|
||||
VEHICLE::SET_VEHICLE_COLOURS(ent, primary_color, secondary_color);
|
||||
VEHICLE::SET_VEHICLE_EXTRA_COLOURS(ent, pearl_color, -1);
|
||||
VEHICLE::SET_VEHICLE_WHEEL_TYPE(ent, rim_color);
|
||||
VEHICLE::SET_VEHICLE_TYRE_SMOKE_COLOR(ent, tyre_smoke_r, tyre_smoke_g, tyre_smoke_b);
|
||||
|
||||
if (auto neon_node = properties.child("Neons"); !neon_node.empty())
|
||||
{
|
||||
bool left = neon_node.child("Left").text().as_bool();
|
||||
bool right = neon_node.child("Right").text().as_bool();
|
||||
bool front = neon_node.child("Front").text().as_bool();
|
||||
bool back = neon_node.child("Back").text().as_bool();
|
||||
int r = neon_node.child("R").text().as_int();
|
||||
int g = neon_node.child("G").text().as_int();
|
||||
int b = neon_node.child("B").text().as_int();
|
||||
|
||||
VEHICLE::SET_VEHICLE_NEON_ENABLED(ent, 0, left);
|
||||
VEHICLE::SET_VEHICLE_NEON_ENABLED(ent, 1, right);
|
||||
VEHICLE::SET_VEHICLE_NEON_ENABLED(ent, 2, front);
|
||||
VEHICLE::SET_VEHICLE_NEON_ENABLED(ent, 3, back);
|
||||
VEHICLE::SET_VEHICLE_NEON_COLOUR(ent, r, g, b);
|
||||
}
|
||||
|
||||
auto number_plate_text = properties.child("NumberPlateText").text().as_string();
|
||||
auto number_plate_index = properties.child("NumberPlateIndex").text().as_int();
|
||||
auto wheel_type = properties.child("WheelType").text().as_int();
|
||||
auto wheels_invisible = properties.child("WheelsInvisible").text().as_bool();
|
||||
auto engine_sound_name = properties.child("EngineSoundName").text().as_string();
|
||||
auto window_tint = properties.child("WindowTint").text().as_int();
|
||||
auto bulletproof_tyres = properties.child("BulletProofTyres").text().as_bool();
|
||||
auto dirt_level = properties.child("DirtLevel").text().as_float();
|
||||
auto paint_fade = properties.child("PaintFade").text().as_float();
|
||||
auto roof_state = properties.child("RoofState").text().as_int();
|
||||
auto siren_active = properties.child("SirenActive").text().as_bool();
|
||||
auto engine_on = properties.child("EngineOn").text().as_bool();
|
||||
auto engine_health = properties.child("EngineHealth").text().as_float();
|
||||
auto lights_on = properties.child("LightsOn").text().as_bool();
|
||||
auto is_radio_loud = properties.child("IsRadioLoud").text().as_int();
|
||||
auto lock_status = properties.child("LockStatus").text().as_int();
|
||||
auto livery = properties.child("Livery").text().as_int();
|
||||
|
||||
VEHICLE::SET_VEHICLE_LIVERY(ent, livery);
|
||||
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT(ent, (PCHAR)number_plate_text);
|
||||
VEHICLE::SET_VEHICLE_NUMBER_PLATE_TEXT_INDEX(ent, number_plate_index);
|
||||
VEHICLE::SET_VEHICLE_WHEEL_TYPE(ent, wheel_type);
|
||||
VEHICLE::SET_VEHICLE_WHEELS_CAN_BREAK(ent, !bulletproof_tyres);
|
||||
VEHICLE::SET_VEHICLE_DIRT_LEVEL(ent, dirt_level);
|
||||
VEHICLE::SET_CONVERTIBLE_ROOF_LATCH_STATE(ent, roof_state);
|
||||
VEHICLE::SET_VEHICLE_SIREN(ent, siren_active);
|
||||
VEHICLE::SET_VEHICLE_ENGINE_ON(ent, engine_on, false, false);
|
||||
VEHICLE::SET_VEHICLE_ENGINE_HEALTH(ent, engine_health);
|
||||
VEHICLE::SET_VEHICLE_LIGHTS(ent, lights_on ? 3 : 4);
|
||||
VEHICLE::SET_VEHICLE_DOORS_LOCKED(ent, lock_status);
|
||||
|
||||
if (auto doors_node = properties.child("DoorsOpen"); !doors_node.empty())
|
||||
{
|
||||
bool back_left = doors_node.child("BackLeftDoor").text().as_bool();
|
||||
bool back_right = doors_node.child("BackRightDoor").text().as_bool();
|
||||
bool front_left = doors_node.child("FrontLeftDoor").text().as_bool();
|
||||
bool front_right = doors_node.child("FrontRightDoor").text().as_bool();
|
||||
bool hood = doors_node.child("Hood").text().as_bool();
|
||||
bool trunk = doors_node.child("Trunk").text().as_bool();
|
||||
bool trunk2 = doors_node.child("Trunk2").text().as_bool();
|
||||
|
||||
if (back_left)
|
||||
VEHICLE::SET_VEHICLE_DOOR_OPEN(ent, 2, 0, false);
|
||||
if (back_right)
|
||||
VEHICLE::SET_VEHICLE_DOOR_OPEN(ent, 3, 0, false);
|
||||
if (front_left)
|
||||
VEHICLE::SET_VEHICLE_DOOR_OPEN(ent, 0, 0, false);
|
||||
if (front_right)
|
||||
VEHICLE::SET_VEHICLE_DOOR_OPEN(ent, 1, 0, false);
|
||||
if (hood)
|
||||
VEHICLE::SET_VEHICLE_DOOR_OPEN(ent, 4, 0, false);
|
||||
if (trunk)
|
||||
VEHICLE::SET_VEHICLE_DOOR_OPEN(ent, 5, 0, false);
|
||||
if (trunk2)
|
||||
VEHICLE::SET_VEHICLE_DOOR_OPEN(ent, 6, 0, false);
|
||||
}
|
||||
|
||||
if (auto doors_broken_node = properties.child("DoorsBroken"); !doors_broken_node.empty())
|
||||
{
|
||||
bool back_left_broken = doors_broken_node.child("BackLeftDoor").text().as_bool();
|
||||
bool back_right_broken = doors_broken_node.child("BackRightDoor").text().as_bool();
|
||||
bool front_left_broken = doors_broken_node.child("FrontLeftDoor").text().as_bool();
|
||||
bool front_right_broken = doors_broken_node.child("FrontRightDoor").text().as_bool();
|
||||
bool hood_broken = doors_broken_node.child("Hood").text().as_bool();
|
||||
bool trunk_broken = doors_broken_node.child("Trunk").text().as_bool();
|
||||
bool trunk2_broken = doors_broken_node.child("Trunk2").text().as_bool();
|
||||
|
||||
if (back_left_broken)
|
||||
VEHICLE::SET_VEHICLE_DOOR_BROKEN(ent, 2, back_left_broken);
|
||||
if (back_right_broken)
|
||||
VEHICLE::SET_VEHICLE_DOOR_BROKEN(ent, 3, back_right_broken);
|
||||
if (front_left_broken)
|
||||
VEHICLE::SET_VEHICLE_DOOR_BROKEN(ent, 0, front_left_broken);
|
||||
if (front_right_broken)
|
||||
VEHICLE::SET_VEHICLE_DOOR_BROKEN(ent, 1, front_right_broken);
|
||||
if (hood_broken)
|
||||
VEHICLE::SET_VEHICLE_DOOR_BROKEN(ent, 4, hood_broken);
|
||||
if (trunk_broken)
|
||||
VEHICLE::SET_VEHICLE_DOOR_BROKEN(ent, 5, trunk_broken);
|
||||
if (trunk2_broken)
|
||||
VEHICLE::SET_VEHICLE_DOOR_BROKEN(ent, 6, trunk2_broken);
|
||||
}
|
||||
|
||||
VEHICLE::SET_VEHICLE_MOD_KIT(ent, 0);
|
||||
if (auto mods = properties.child("Mods"); !mods.empty())
|
||||
{
|
||||
int mod_type = 0;
|
||||
for (auto mod = mods.first_child(); mod; mod = mod.next_sibling())
|
||||
{
|
||||
if (mod_type >= 17 && mod_type <= 22)
|
||||
{
|
||||
VEHICLE::TOGGLE_VEHICLE_MOD(ent, mod_type, mod.text().as_bool());
|
||||
mod_type++;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string text = mod.text().as_string();
|
||||
size_t comma_pos = text.find(",");
|
||||
int first_val = std::stoi(text.substr(0, comma_pos));
|
||||
|
||||
auto mod_value = mod.child("value").text().as_int();
|
||||
VEHICLE::SET_VEHICLE_MOD(ent, mod_type, first_val, 0);
|
||||
mod_type++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ped_details(pugi::xml_node ped_node, Entity ent)
|
||||
{
|
||||
auto properties = ped_node.child("PedProperties");
|
||||
|
||||
auto is_still = properties.child("IsStill").text().as_bool();
|
||||
auto can_ragdoll = properties.child("CanRagdoll").text().as_bool();
|
||||
auto armour = properties.child("Armour").text().as_float();
|
||||
auto current_weapon = properties.child("CurrentWeapon").text().as_uint();
|
||||
|
||||
if (is_still)
|
||||
{
|
||||
TASK::CLEAR_PED_TASKS_IMMEDIATELY(ent);
|
||||
TASK::TASK_STAND_STILL(ent, -1);
|
||||
TASK::TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(ent, true);
|
||||
}
|
||||
|
||||
PED::SET_PED_CAN_RAGDOLL(ent, can_ragdoll);
|
||||
PED::SET_PED_ARMOUR(ent, armour);
|
||||
WEAPON::GIVE_DELAYED_WEAPON_TO_PED(ent, current_weapon, 0, true);
|
||||
|
||||
auto ped_props = ped_node.child("PedProps");
|
||||
|
||||
int prop_index = 0;
|
||||
for (auto prop_node : ped_props.children())
|
||||
{
|
||||
std::string prop_text = prop_node.text().as_string();
|
||||
size_t comma_pos = prop_text.find(",");
|
||||
int first_val = std::stoi(prop_text.substr(0, comma_pos));
|
||||
int second_val = std::stoi(prop_text.substr(comma_pos + 1));
|
||||
|
||||
PED::SET_PED_PROP_INDEX(ent, prop_index, first_val, second_val, true, 0);
|
||||
prop_index++;
|
||||
}
|
||||
|
||||
auto ped_comps = ped_node.child("PedComps");
|
||||
|
||||
int comp_index = 0;
|
||||
for (auto prop_node : ped_props.children())
|
||||
{
|
||||
std::string prop_text = prop_node.text().as_string();
|
||||
size_t comma_pos = prop_text.find(",");
|
||||
int first_val = std::stoi(prop_text.substr(0, comma_pos));
|
||||
int second_val = std::stoi(prop_text.substr(comma_pos + 1));
|
||||
|
||||
PED::SET_PED_COMPONENT_VARIATION(ent, comp_index, first_val, second_val, 0);
|
||||
comp_index++;
|
||||
}
|
||||
|
||||
if (properties.child("ScenarioActive").text().as_bool())
|
||||
{
|
||||
TASK::CLEAR_PED_TASKS_IMMEDIATELY(ent);
|
||||
TASK::TASK_START_SCENARIO_IN_PLACE(ent, properties.child("ScenarioName").text().as_string(), 0, true);
|
||||
}
|
||||
|
||||
if (properties.child("AnimActive").text().as_bool())
|
||||
{
|
||||
TASK::CLEAR_PED_TASKS_IMMEDIATELY(ent);
|
||||
ped::ped_play_animation(ent,
|
||||
properties.child("AnimDict").text().as_string(),
|
||||
properties.child("AnimName").text().as_string(),
|
||||
8.0f,
|
||||
-8.0f,
|
||||
-1,
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
Entity spawn_entity(pugi::xml_node entity_node)
|
||||
{
|
||||
Entity ent = 0;
|
||||
auto model = entity_node.child("ModelHash").text().as_uint();
|
||||
|
||||
if (!STREAMING::IS_MODEL_VALID(model))
|
||||
{
|
||||
LOG(WARNING) << "XML map spawner failed spawning entity: " << model << " is not a valid model" << std::endl;
|
||||
}
|
||||
|
||||
auto dynamic = entity_node.child("Dynamic").text().as_bool();
|
||||
auto frozenpos = entity_node.child("FrozenPos").text().as_bool();
|
||||
auto visible = entity_node.child("IsVisible").text().as_bool();
|
||||
auto max_health = entity_node.child("MaxHealth").text().as_int();
|
||||
auto health = entity_node.child("Health").text().as_float();
|
||||
auto gravity = entity_node.child("HasGravity").text().as_bool();
|
||||
auto on_fire = entity_node.child("IsOnFire").text().as_bool();
|
||||
auto invincible = entity_node.child("IsInvincible").text().as_bool();
|
||||
auto bullet_proof = entity_node.child("IsBulletProof").text().as_bool();
|
||||
auto collision_proof = entity_node.child("IsCollisionProof").text().as_bool();
|
||||
auto explosion_proof = entity_node.child("IsExplosionProof").text().as_bool();
|
||||
auto fire_proof = entity_node.child("IsFireProof").text().as_bool();
|
||||
auto melee_proof = entity_node.child("IsMeleeProof").text().as_bool();
|
||||
auto only_damaged_by_player = entity_node.child("IsOnlyDamagedByPlayer").text().as_bool();
|
||||
auto position_rotation = entity_node.child("PositionRotation");
|
||||
|
||||
Vector3 pos = {position_rotation.child("X").text().as_float(),
|
||||
position_rotation.child("Y").text().as_float(),
|
||||
position_rotation.child("Z").text().as_float()};
|
||||
Vector3 rot = {position_rotation.child("Pitch").text().as_float(),
|
||||
position_rotation.child("Roll").text().as_float(),
|
||||
position_rotation.child("Yaw").text().as_float()};
|
||||
|
||||
switch (entity_node.child("Type").text().as_int())
|
||||
{
|
||||
case 3: ent = world_model::spawn(model, pos); break;
|
||||
case 2: ent = vehicle::spawn(model, pos, 0); break;
|
||||
case 1: ent = ped::spawn(PED_TYPE_CIVMALE, model, 0, pos, 0); break;
|
||||
}
|
||||
|
||||
if (ent)
|
||||
{
|
||||
ENTITY::SET_ENTITY_DYNAMIC(ent, dynamic);
|
||||
ENTITY::FREEZE_ENTITY_POSITION(ent, frozenpos);
|
||||
ENTITY::SET_ENTITY_VISIBLE(ent, visible, 0);
|
||||
ENTITY::SET_ENTITY_MAX_HEALTH(ent, max_health);
|
||||
ENTITY::SET_ENTITY_HEALTH(ent, health, 0);
|
||||
ENTITY::SET_ENTITY_HAS_GRAVITY(ent, gravity);
|
||||
ENTITY::SET_ENTITY_INVINCIBLE(ent, invincible);
|
||||
ENTITY::SET_ENTITY_PROOFS(ent, bullet_proof, collision_proof, explosion_proof, fire_proof, melee_proof, false, 0, 0);
|
||||
ENTITY::SET_ENTITY_COORDS_NO_OFFSET(ent, pos.x, pos.y, pos.z, false, false, false);
|
||||
ENTITY::SET_ENTITY_ROTATION(ent, rot.x, rot.y, rot.z, 2, false);
|
||||
ENTITY::SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(ent, only_damaged_by_player);
|
||||
|
||||
if (on_fire)
|
||||
FIRE::START_ENTITY_FIRE(ent);
|
||||
|
||||
if (ENTITY::IS_ENTITY_AN_OBJECT(ent))
|
||||
object_details(entity_node, ent);
|
||||
else if (ENTITY::IS_ENTITY_A_VEHICLE(ent))
|
||||
vehicle_details(entity_node, ent);
|
||||
else if (ENTITY::IS_ENTITY_A_PED(ent))
|
||||
ped_details(entity_node, ent);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(WARNING) << "XML map spawner failed spawning entity: " << model << std::endl;
|
||||
}
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
||||
void xml_map_service::spawn_from_xml(pugi::xml_document& doc)
|
||||
{
|
||||
auto root = doc.child("SpoonerPlacements");
|
||||
auto ipls_to_unload = root.child("IPLsToRemove");
|
||||
auto ipls_to_load = root.child("IPLsToLoad");
|
||||
auto sp_maps = ipls_to_load.child("load_sp_maps").text().as_bool();
|
||||
auto mp_maps = ipls_to_load.child("load_mp_maps").text().as_bool();
|
||||
auto interiors = root.child("InteriorsToEnable");
|
||||
auto capped_interiors = root.child("InteriorsToCap");
|
||||
auto weather = root.child("WeatherToSet");
|
||||
auto ref_coords = root.child("ReferenceCoords");
|
||||
Vector3 reference_coords;
|
||||
|
||||
manage_ipls(ipls_to_unload, ipls_to_load);
|
||||
|
||||
if (sp_maps)
|
||||
{
|
||||
MISC::SET_INSTANCE_PRIORITY_MODE(true);
|
||||
DLC::ON_ENTER_SP();
|
||||
}
|
||||
|
||||
if (mp_maps)
|
||||
{
|
||||
MISC::SET_INSTANCE_PRIORITY_MODE(true);
|
||||
DLC::ON_ENTER_MP();
|
||||
}
|
||||
|
||||
if (sp_maps || mp_maps)
|
||||
MISC::SET_INSTANCE_PRIORITY_MODE(false);
|
||||
|
||||
manage_interiors(interiors, capped_interiors);
|
||||
|
||||
if (weather)
|
||||
{
|
||||
auto name = weather.text().as_string();
|
||||
|
||||
if (!std::string(name).empty())
|
||||
{
|
||||
MISC::CLEAR_OVERRIDE_WEATHER();
|
||||
MISC::SET_WEATHER_TYPE_OVERTIME_PERSIST(name, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (ref_coords)
|
||||
{
|
||||
reference_coords.x = ref_coords.child("X").text().as_float();
|
||||
reference_coords.y = ref_coords.child("Y").text().as_float();
|
||||
reference_coords.z = ref_coords.child("Z").text().as_float();
|
||||
|
||||
PED::SET_PED_COORDS_KEEP_VEHICLE(self::ped, reference_coords.x, reference_coords.y, reference_coords.z);
|
||||
}
|
||||
|
||||
std::map<std::uint32_t, std::uint32_t> initial_to_current_handle_map; //Need this garbage to handle attachments.
|
||||
|
||||
//Actual models to spawn
|
||||
try
|
||||
{
|
||||
for (auto node = root.child("Placement"); node; node = node.next_sibling("Placement"))
|
||||
{
|
||||
initial_to_current_handle_map.insert(
|
||||
std::pair<std::uint32_t, std::uint32_t>(node.child("InitialHandle").text().as_uint(), spawn_entity(node)));
|
||||
}
|
||||
|
||||
//Attachments
|
||||
for (auto node = root.child("Placement"); node; node = node.next_sibling("Placement"))
|
||||
{
|
||||
if (auto attachment = node.child("Attachment"))
|
||||
{
|
||||
auto attatched_to = attachment.child("AttachedTo").text().as_uint();
|
||||
|
||||
if (attatched_to)
|
||||
{
|
||||
auto bone_index = attachment.child("BoneIndex").text().as_int();
|
||||
auto pos = attachment.child("Position");
|
||||
auto rot = attachment.child("Rotation");
|
||||
|
||||
Vector3 position = {pos.child("X").text().as_float(),
|
||||
pos.child("Y").text().as_float(),
|
||||
pos.child("Z").text().as_float()};
|
||||
Vector3 rotation = {rot.child("Pitch").text().as_float(),
|
||||
rot.child("Roll").text().as_float(),
|
||||
rot.child("Yaw").text().as_float()};
|
||||
|
||||
ENTITY::ATTACH_ENTITY_TO_ENTITY(
|
||||
initial_to_current_handle_map.at(node.child("InitialHandle").text().as_uint()),
|
||||
initial_to_current_handle_map.at(attatched_to),
|
||||
bone_index,
|
||||
position.x,
|
||||
position.y,
|
||||
position.z,
|
||||
rotation.x,
|
||||
rotation.y,
|
||||
rotation.z,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
0,
|
||||
true,
|
||||
0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception e)
|
||||
{
|
||||
LOG(WARNING) << "Failed spawning entities: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
20
src/services/xml_maps/xml_map_service.hpp
Normal file
20
src/services/xml_maps/xml_map_service.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include "pugixml.hpp"
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace big
|
||||
{
|
||||
class xml_map_service
|
||||
{
|
||||
public:
|
||||
xml_map_service();
|
||||
~xml_map_service();
|
||||
std::map<std::string, pugi::xml_document> m_all_xml_maps;
|
||||
|
||||
void fetch_xml_files();
|
||||
void spawn_from_xml(pugi::xml_document&);
|
||||
};
|
||||
|
||||
inline xml_map_service* g_xml_map_service;
|
||||
}
|
@ -69,6 +69,7 @@ namespace big
|
||||
static void blackhole();
|
||||
static void model_swapper();
|
||||
static void world();
|
||||
static void xml_maps();
|
||||
static void gta_cache();
|
||||
static void lua_scripts();
|
||||
static void vfx();
|
||||
|
27
src/views/world/view_xml_maps.cpp
Normal file
27
src/views/world/view_xml_maps.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "views/view.hpp"
|
||||
#include "services/xml_maps/xml_map_service.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
void view::xml_maps()
|
||||
{
|
||||
components::button("REFRESH"_T, [] {
|
||||
g_fiber_pool->queue_job([] {
|
||||
g_xml_map_service->fetch_xml_files();
|
||||
});
|
||||
});
|
||||
if(ImGui::BeginListBox("##xmlmaps", get_listbox_dimensions()))
|
||||
{
|
||||
for (auto& [name, xml_map] : g_xml_map_service->m_all_xml_maps)
|
||||
{
|
||||
if (ImGui::Selectable(name.c_str()))
|
||||
{
|
||||
g_fiber_pool->queue_job([=, &xml_map] {
|
||||
g_xml_map_service->spawn_from_xml(xml_map);
|
||||
});
|
||||
}
|
||||
}
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user