2023-03-01 21:27:15 +00:00
|
|
|
#include "model_preview_service.hpp"
|
|
|
|
|
2022-07-31 01:47:48 +08:00
|
|
|
#include "fiber_pool.hpp"
|
|
|
|
#include "gui.hpp"
|
|
|
|
#include "thread_pool.hpp"
|
|
|
|
#include "util/ped.hpp"
|
|
|
|
#include "util/vehicle.hpp"
|
|
|
|
|
2023-08-31 09:43:55 -04:00
|
|
|
#include "services/vehicle/persist_car_service.hpp"
|
|
|
|
|
2022-07-31 01:47:48 +08:00
|
|
|
namespace big
|
|
|
|
{
|
|
|
|
model_preview_service::model_preview_service()
|
|
|
|
{
|
|
|
|
g_model_preview_service = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
model_preview_service::~model_preview_service()
|
|
|
|
{
|
|
|
|
g_model_preview_service = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void model_preview_service::show_ped(Hash hash)
|
|
|
|
{
|
2023-03-01 21:27:15 +00:00
|
|
|
m_ped_clone = 0;
|
2022-07-31 01:47:48 +08:00
|
|
|
m_veh_model_hash = 0;
|
|
|
|
m_veh_owned_mods.clear();
|
|
|
|
|
|
|
|
if (m_ped_model_hash != hash)
|
|
|
|
{
|
|
|
|
m_ped_model_hash = hash;
|
|
|
|
|
|
|
|
if (m_ped_model_hash != 0)
|
|
|
|
{
|
|
|
|
m_new_model = true;
|
|
|
|
|
|
|
|
preview_loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-10 08:42:34 +08:00
|
|
|
void model_preview_service::show_ped(Hash hash, Ped clone)
|
|
|
|
{
|
|
|
|
m_veh_model_hash = 0;
|
|
|
|
m_veh_owned_mods.clear();
|
|
|
|
|
|
|
|
if (m_ped_model_hash != hash || m_ped_clone != clone)
|
|
|
|
{
|
|
|
|
m_ped_model_hash = hash;
|
2023-03-01 21:27:15 +00:00
|
|
|
m_ped_clone = clone;
|
2022-08-10 08:42:34 +08:00
|
|
|
|
|
|
|
if (m_ped_model_hash != 0)
|
|
|
|
{
|
|
|
|
m_new_model = true;
|
|
|
|
|
|
|
|
preview_loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-31 01:47:48 +08:00
|
|
|
void model_preview_service::show_vehicle(Hash hash, bool spawn_max)
|
|
|
|
{
|
|
|
|
m_ped_model_hash = 0;
|
2023-03-01 21:27:15 +00:00
|
|
|
m_ped_clone = 0;
|
2022-07-31 01:47:48 +08:00
|
|
|
m_veh_owned_mods.clear();
|
|
|
|
|
|
|
|
if (m_veh_model_hash != hash || m_veh_spawn_max != spawn_max)
|
|
|
|
{
|
|
|
|
m_veh_model_hash = hash;
|
2023-08-31 09:43:55 -04:00
|
|
|
m_current_persisted_vehicle_name.clear();
|
2022-07-31 01:47:48 +08:00
|
|
|
|
|
|
|
if (m_veh_model_hash != 0)
|
|
|
|
{
|
|
|
|
m_veh_spawn_max = spawn_max;
|
2023-03-01 21:27:15 +00:00
|
|
|
m_new_model = true;
|
2022-07-31 01:47:48 +08:00
|
|
|
|
|
|
|
preview_loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void model_preview_service::show_vehicle(const std::map<int, int32_t>& owned_mods, bool spawn_max)
|
|
|
|
{
|
|
|
|
m_ped_model_hash = 0;
|
2023-03-01 21:27:15 +00:00
|
|
|
m_ped_clone = 0;
|
2023-08-31 09:43:55 -04:00
|
|
|
m_current_persisted_vehicle_name.clear();
|
2022-07-31 01:47:48 +08:00
|
|
|
|
2023-03-01 21:27:15 +00:00
|
|
|
if (m_veh_spawn_max != spawn_max || m_veh_owned_mods.size() != owned_mods.size()
|
|
|
|
|| !std::equal(m_veh_owned_mods.begin(), m_veh_owned_mods.end(), owned_mods.begin()))
|
|
|
|
{
|
2022-07-31 01:47:48 +08:00
|
|
|
m_veh_owned_mods.clear();
|
|
|
|
|
|
|
|
auto hash_item = owned_mods.find(MOD_MODEL_HASH);
|
|
|
|
|
|
|
|
m_veh_model_hash = hash_item->second;
|
|
|
|
|
|
|
|
if (m_veh_model_hash != 0)
|
|
|
|
{
|
|
|
|
m_veh_owned_mods.insert(owned_mods.begin(), owned_mods.end());
|
|
|
|
m_veh_spawn_max = spawn_max;
|
2023-03-01 21:27:15 +00:00
|
|
|
m_new_model = true;
|
2022-07-31 01:47:48 +08:00
|
|
|
|
|
|
|
preview_loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-31 09:43:55 -04:00
|
|
|
void model_preview_service::show_vehicle_persisted(std::string vehicle_name)
|
|
|
|
{
|
|
|
|
m_ped_model_hash = 0;
|
|
|
|
m_ped_clone = 0;
|
|
|
|
m_veh_model_hash = 0;
|
|
|
|
|
|
|
|
if (m_current_persisted_vehicle_name != vehicle_name)
|
|
|
|
{
|
|
|
|
m_current_persisted_vehicle_name = vehicle_name;
|
|
|
|
m_new_model = true;
|
|
|
|
|
|
|
|
preview_loop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-31 01:47:48 +08:00
|
|
|
void model_preview_service::preview_loop()
|
|
|
|
{
|
|
|
|
if (m_running || m_loop_running)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_running = true;
|
|
|
|
|
|
|
|
g_fiber_pool->queue_job([this] {
|
|
|
|
m_loop_running = true;
|
|
|
|
|
2023-08-31 09:43:55 -04:00
|
|
|
while (g_running && m_running && g_gui->is_open() && (m_ped_model_hash || m_veh_model_hash || !m_current_persisted_vehicle_name.empty()))
|
2023-03-01 21:27:15 +00:00
|
|
|
{
|
2022-07-31 01:47:48 +08:00
|
|
|
Vector3 location;
|
|
|
|
|
|
|
|
if (m_ped_model_hash)
|
|
|
|
{
|
|
|
|
location = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, 5.f, -.5f);
|
|
|
|
}
|
2023-08-31 09:43:55 -04:00
|
|
|
else if (m_veh_model_hash || !m_current_persisted_vehicle_name.empty())
|
2022-07-31 01:47:48 +08:00
|
|
|
{
|
|
|
|
location = ENTITY::GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(self::ped, 0.f, 10.f, .5f);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_current_ent == 0)
|
|
|
|
{
|
|
|
|
m_new_model = false;
|
2023-03-01 21:27:15 +00:00
|
|
|
location.z = -10.f;
|
2022-07-31 01:47:48 +08:00
|
|
|
|
|
|
|
if (m_ped_model_hash)
|
|
|
|
{
|
2022-08-10 08:42:34 +08:00
|
|
|
m_current_ent = ped::spawn(ePedType::PED_TYPE_ARMY, m_ped_model_hash, m_ped_clone, location, 0.f, false);
|
|
|
|
|
2023-12-15 23:01:57 +08:00
|
|
|
ENTITY::SET_ENTITY_HEALTH(m_current_ent, 0, 0, 0);
|
2022-07-31 01:47:48 +08:00
|
|
|
script::get_current()->yield(20ms);
|
|
|
|
PED::RESURRECT_PED(m_current_ent);
|
|
|
|
TASK::CLEAR_PED_TASKS(m_current_ent);
|
|
|
|
}
|
|
|
|
else if (m_veh_model_hash)
|
|
|
|
{
|
|
|
|
if (m_veh_owned_mods.empty())
|
|
|
|
{
|
|
|
|
m_current_ent = vehicle::spawn(m_veh_model_hash, location, 0.f, false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_current_ent = vehicle::clone_from_owned_mods(m_veh_owned_mods, location, 0.f, false);
|
|
|
|
}
|
|
|
|
}
|
2023-08-31 09:43:55 -04:00
|
|
|
else if (!m_current_persisted_vehicle_name.empty())
|
|
|
|
{
|
|
|
|
m_current_ent = persist_car_service::load_vehicle(m_current_persisted_vehicle_name, g.persist_car.persist_vehicle_sub_folder, Vector3());
|
|
|
|
}
|
2022-07-31 01:47:48 +08:00
|
|
|
|
|
|
|
if (m_current_ent)
|
|
|
|
{
|
|
|
|
if (m_veh_model_hash && m_veh_spawn_max)
|
|
|
|
{
|
|
|
|
vehicle::max_vehicle(m_current_ent);
|
|
|
|
}
|
|
|
|
|
|
|
|
ENTITY::FREEZE_ENTITY_POSITION(m_current_ent, true);
|
|
|
|
ENTITY::SET_ENTITY_ALPHA(m_current_ent, 0, false);
|
|
|
|
ENTITY::SET_ENTITY_COLLISION(m_current_ent, false, false);
|
|
|
|
ENTITY::SET_CAN_CLIMB_ON_ENTITY(m_current_ent, false);
|
|
|
|
OBJECT::SET_OBJECT_ALLOW_LOW_LOD_BUOYANCY(m_current_ent, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (m_new_model)
|
|
|
|
{
|
2023-08-31 09:43:55 -04:00
|
|
|
entity::delete_entity(m_current_ent, true);
|
2022-07-31 01:47:48 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (const int alpha = ENTITY::GET_ENTITY_ALPHA(m_current_ent); alpha < 255)
|
|
|
|
{
|
|
|
|
ENTITY::SET_ENTITY_ALPHA(m_current_ent, std::min<int>(255, alpha + 20), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
ENTITY::SET_ENTITY_HEADING(m_current_ent, m_heading);
|
|
|
|
ENTITY::SET_ENTITY_COORDS(m_current_ent, location.x, location.y, location.z, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
2024-03-27 06:33:33 -04:00
|
|
|
if (m_heading += 0.11111f; m_heading > 359)
|
2022-07-31 01:47:48 +08:00
|
|
|
{
|
|
|
|
m_heading = 0;
|
|
|
|
}
|
|
|
|
|
2024-03-27 06:33:33 -04:00
|
|
|
script::get_current()->yield();
|
2022-07-31 01:47:48 +08:00
|
|
|
}
|
|
|
|
|
2023-08-31 09:43:55 -04:00
|
|
|
entity::delete_entity(m_current_ent, true);
|
2022-07-31 01:47:48 +08:00
|
|
|
|
2023-03-01 21:27:15 +00:00
|
|
|
m_current_ent = 0;
|
2022-07-31 01:47:48 +08:00
|
|
|
m_ped_model_hash = 0;
|
|
|
|
m_veh_model_hash = 0;
|
|
|
|
m_veh_owned_mods.clear();
|
2023-08-31 09:43:55 -04:00
|
|
|
m_current_persisted_vehicle_name.clear();
|
2023-03-01 21:27:15 +00:00
|
|
|
m_running = false;
|
2022-07-31 01:47:48 +08:00
|
|
|
m_loop_running = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void model_preview_service::stop_preview()
|
|
|
|
{
|
|
|
|
m_veh_owned_mods.clear();
|
|
|
|
m_running = false;
|
|
|
|
}
|
|
|
|
}
|