Add Garage drop-down to Spawn PV menu (#2171)
* Fixed edge case where a garage that contained only banned vehicles would show if the user was using Spawn Clone. Refactored a large portion of the garage code to be production ready. Formatting changes. * Added singular garage items to the m_garage setter like the Terrorbyte. * Fixed is_blacklisted_vehicle returning an inverted condition. Fixed Garage drop-down not updating properly. * Separated out m_garage's setter into a ctor function. Replaced the 4 singular garages that use an overloaded index with a define to be able to shift them easier when new properties are added. * Removed obsolete and incorrect player.character_slot config entry. Removed deprecated local_player.hpp. Added self::char_slot that is guaranteed to be correct. * Removed extraneous semi-colon. * Added more stuff to fillsnacks. Removed more extraneous usages of MPPLY_LAST_MP_CHAR. * Added the vehicle's name to player info. * Fixed get_property_garage_size returning the incorrect size for the facility. Fixed get_static_property_name returning the Nightclub's name instead of Nightclub Service Entrance to maintain consistency with the Mechanic. Fixed garage_slot_iterator not starting and ending at the correct indexes. * Shifted the singular properties down one to compensate for the new math. * Fixed backwards math on Terrorbyte and Nightclub B1. * Fixed garage not being updated when the player moved the vehicle. * Fixed backwards comments.
This commit is contained in:
parent
92b6df7653
commit
afd3a5e943
@ -1,6 +1,5 @@
|
||||
#include "backend/command.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "util/local_player.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -10,15 +9,20 @@ namespace big
|
||||
|
||||
virtual void execute(const command_arguments&, const std::shared_ptr<command_context> ctx) override
|
||||
{
|
||||
std::string mpPrefix = local_player::get_mp_prefix();
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "NO_BOUGHT_YUM_SNACKS"), 30, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "NO_BOUGHT_HEALTH_SNACKS"), 15, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "NO_BOUGHT_EPIC_SNACKS"), 5, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_1_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_2_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_3_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_4_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(mpPrefix + "MP_CHAR_ARMOUR_5_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "NO_BOUGHT_YUM_SNACKS"), 30, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "NO_BOUGHT_HEALTH_SNACKS"), 15, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "NO_BOUGHT_EPIC_SNACKS"), 5, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "NUMBER_OF_CHAMP_BOUGHT"), 5, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "NUMBER_OF_ORANGE_BOUGHT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "NUMBER_OF_BOURGE_BOUGHT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "NUMBER_OF_SPRUNK_BOUGHT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "MP_CHAR_ARMOUR_1_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "MP_CHAR_ARMOUR_2_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "MP_CHAR_ARMOUR_3_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "MP_CHAR_ARMOUR_4_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "MP_CHAR_ARMOUR_5_COUNT"), 10, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "CIGARETTES_BOUGHT"), 20, true);
|
||||
STATS::STAT_SET_INT(rage::joaat(self::char_index + "BREATHING_APPAR_BOUGHT"), 20, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -16,6 +16,8 @@ namespace big
|
||||
|
||||
self::ped = PLAYER::PLAYER_PED_ID();
|
||||
|
||||
STATS::STAT_GET_INT(RAGE_JOAAT("MPPLY_LAST_MP_CHAR"), &self::char_index, true);
|
||||
|
||||
self::pos = ENTITY::GET_ENTITY_COORDS(self::ped, false /*Unused*/);
|
||||
|
||||
self::rot = ENTITY::GET_ENTITY_ROTATION(self::ped, 2);
|
||||
|
@ -82,6 +82,7 @@ namespace self
|
||||
inline Vector3 pos;
|
||||
inline Vector3 rot;
|
||||
inline Vehicle veh;
|
||||
inline int char_index;
|
||||
}
|
||||
|
||||
template<size_t N>
|
||||
|
@ -57,6 +57,9 @@ namespace big::scr_globals
|
||||
static inline const script_global gooch(1890378);
|
||||
|
||||
static inline const script_global passive(1574582);
|
||||
|
||||
static inline const script_global property_garage(1945123);
|
||||
static inline const script_global property_names(1312228);
|
||||
}
|
||||
|
||||
namespace big::scr_locals
|
||||
|
@ -227,10 +227,9 @@ namespace big
|
||||
|
||||
struct player
|
||||
{
|
||||
int character_slot = 1;
|
||||
bool spectating = false;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(player, character_slot, spectating)
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(player, spectating)
|
||||
} player{};
|
||||
|
||||
struct player_db
|
||||
@ -488,8 +487,9 @@ namespace big
|
||||
bool spawn_maxed = false;
|
||||
bool clone_plate = false;
|
||||
std::string plate = "";
|
||||
std::string garage = "";
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(clone_pv, preview_vehicle, spawn_inside, spawn_clone, spawn_maxed, clone_plate, plate)
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(clone_pv, preview_vehicle, spawn_inside, spawn_clone, spawn_maxed, clone_plate, plate, garage)
|
||||
} clone_pv{};
|
||||
|
||||
struct persist_car
|
||||
|
@ -6497,5 +6497,6 @@ namespace big
|
||||
{0x40EB1EFD921822BC, 0xFAF127E6FF05E72E},
|
||||
{0x340A36A700E99699, 0xA759D3AD1579CBCB},
|
||||
{0x8E580AB902917360, 0x3AABE0CD8115D72E},
|
||||
{0xD69CE161FE614531, 0xD69CE161FE614531},
|
||||
}};
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace big
|
||||
{
|
||||
constexpr auto NATIVE_COUNT = 6494;
|
||||
constexpr auto NATIVE_COUNT = 6495;
|
||||
using crossmap = std::array<std::pair<rage::scrNativeHash, rage::scrNativeHash>, NATIVE_COUNT>;
|
||||
extern const crossmap g_crossmap;
|
||||
}
|
||||
|
@ -15,9 +15,7 @@ namespace lua::stats
|
||||
// Returns: integer: The current multiplayer character index (0 or 1).
|
||||
static int get_character_index()
|
||||
{
|
||||
int character_index = 0;
|
||||
STATS::STAT_GET_INT(RAGE_JOAAT("MPPLY_LAST_MP_CHAR"), &character_index, -1);
|
||||
return character_index;
|
||||
return self::char_index;
|
||||
}
|
||||
|
||||
static Hash stat_text_to_hash(std::string& text)
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "util/vehicle.hpp"
|
||||
#include "yim_fipackfile.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -28,7 +29,7 @@ namespace big
|
||||
|
||||
gta_data_service::gta_data_service() :
|
||||
m_peds_cache(g_file_manager.get_project_file("./cache/peds.bin"), 5),
|
||||
m_vehicles_cache(g_file_manager.get_project_file("./cache/vehicles.bin"), 5),
|
||||
m_vehicles_cache(g_file_manager.get_project_file("./cache/vehicles.bin"), 6),
|
||||
m_update_state(eGtaDataUpdateState::IDLE)
|
||||
{
|
||||
if (!is_cache_up_to_date())
|
||||
@ -271,7 +272,8 @@ namespace big
|
||||
{
|
||||
const auto item = item_node.node();
|
||||
|
||||
const auto name = item.child("modelName").text().as_string();
|
||||
std::string name = item.child("modelName").text().as_string();
|
||||
std::transform(name.begin(), name.end(), name.begin(), ::toupper);
|
||||
const auto hash = rage::joaat(name);
|
||||
if (protection::is_crash_vehicle(hash))
|
||||
continue;
|
||||
@ -281,7 +283,7 @@ namespace big
|
||||
mapped_vehicles.emplace_back(hash);
|
||||
|
||||
auto veh = vehicle_item{};
|
||||
std::strncpy(veh.m_name, name, sizeof(veh.m_name));
|
||||
std::strncpy(veh.m_name, name.c_str(), sizeof(veh.m_name));
|
||||
|
||||
const auto manufacturer_display = item.child("vehicleMakeName").text().as_string();
|
||||
std::strncpy(veh.m_display_manufacturer, manufacturer_display, sizeof(veh.m_display_manufacturer));
|
||||
|
@ -5,15 +5,237 @@
|
||||
#include "script.hpp"
|
||||
#include "util/mobile.hpp"
|
||||
|
||||
#define MAX_GARAGE_NUM 30
|
||||
|
||||
namespace big
|
||||
{
|
||||
int get_property_garage_offset(int property)
|
||||
{
|
||||
switch (property)
|
||||
{
|
||||
case 0: return 13 * 0;
|
||||
case 1: return 13 * 1;
|
||||
case 2: return 13 * 2;
|
||||
case 3: return 13 * 3;
|
||||
case 4: return 13 * 4;
|
||||
//Property 5 is not used.
|
||||
case 6: return 65;
|
||||
case 7: return 75;
|
||||
case 8: return 88;
|
||||
case 9: return 108;
|
||||
case 10: return 128;
|
||||
case 11: return 148;
|
||||
case 12: return 159;
|
||||
case 13: return 179;
|
||||
case 14: return 191;
|
||||
case 15: return 192;
|
||||
case 16: return 202;
|
||||
case 17: return 212;
|
||||
case 18: return 227;
|
||||
case 19: return 237;
|
||||
case 20: return 247;
|
||||
case 21: return 258;
|
||||
case 22: return 268;
|
||||
case 23: return 281;
|
||||
case 24: return 294;
|
||||
case 25: return 307;
|
||||
case 26: return 317;
|
||||
case 27: return 337;
|
||||
case 28: return 350;
|
||||
case 29: return 363;
|
||||
case MAX_GARAGE_NUM+0: return 156; //Mobile Operations Center
|
||||
case MAX_GARAGE_NUM+1: return 224; //Nightclub B1
|
||||
case MAX_GARAGE_NUM+2: return 223; //Terrorbyte
|
||||
case MAX_GARAGE_NUM+3: return 278; //Kosatka
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_property_garage_size(int property)
|
||||
{
|
||||
switch (property)
|
||||
{
|
||||
case MAX_GARAGE_NUM+0: //Mobile Operations Center
|
||||
case MAX_GARAGE_NUM+2: //Terrorbyte
|
||||
case MAX_GARAGE_NUM+3: //Kosatka
|
||||
case 14: return 1;
|
||||
case MAX_GARAGE_NUM+1: return 3; //Nightclub B1
|
||||
case 11: return 8;
|
||||
case 6:
|
||||
case 15:
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 25: return 10;
|
||||
case 13: return 11;
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 7:
|
||||
case 23:
|
||||
case 24:
|
||||
case 27:
|
||||
case 28: return 13;
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
case 12:
|
||||
case 26: return 20;
|
||||
case 29: return 50;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_property_stat_state(int property)
|
||||
{
|
||||
int stat_to_lookup = -1;
|
||||
switch (property)
|
||||
{
|
||||
case 0: stat_to_lookup = 1279; break;
|
||||
case 1: stat_to_lookup = 1878; break;
|
||||
case 2: stat_to_lookup = 2269; break;
|
||||
case 3: stat_to_lookup = 2932; break;
|
||||
case 4: stat_to_lookup = 3061; break;
|
||||
case 5: stat_to_lookup = 3230; break;
|
||||
case 6: stat_to_lookup = 3233; break;
|
||||
case 7: stat_to_lookup = 3235; break;
|
||||
case 8: stat_to_lookup = 4023; break;
|
||||
case 9: stat_to_lookup = 4026; break;
|
||||
case 10: stat_to_lookup = 4029; break;
|
||||
case 11: stat_to_lookup = 4032; break;
|
||||
case 12: stat_to_lookup = 6113; break;
|
||||
case 13: stat_to_lookup = 6171; break;
|
||||
case 14: stat_to_lookup = 6549; break;
|
||||
case 15: stat_to_lookup = 6562; break;
|
||||
case 16: stat_to_lookup = 6565; break;
|
||||
case 17: stat_to_lookup = 6568; break;
|
||||
case 18: stat_to_lookup = 7286; break;
|
||||
case 19: stat_to_lookup = 7288; break;
|
||||
case 20: stat_to_lookup = 7290; break;
|
||||
case 21: stat_to_lookup = 8013; break;
|
||||
case 22: stat_to_lookup = 8537; break;
|
||||
case 23: stat_to_lookup = 8980; break;
|
||||
case 24: stat_to_lookup = 8983; break;
|
||||
case 25: stat_to_lookup = 9624; break;
|
||||
case 26: stat_to_lookup = 9913; break;
|
||||
case 27: stat_to_lookup = 10441; break;
|
||||
case 28: stat_to_lookup = 10444; break;
|
||||
case 29: stat_to_lookup = 10874; break;
|
||||
case MAX_GARAGE_NUM+0:
|
||||
case MAX_GARAGE_NUM+1:
|
||||
case MAX_GARAGE_NUM+2:
|
||||
case MAX_GARAGE_NUM+3: return 1;
|
||||
}
|
||||
if (stat_to_lookup == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
Hash stat_hash = STATS::_GET_STAT_HASH_FOR_CHARACTER_STAT(0, stat_to_lookup, self::char_index);
|
||||
int stat_value{};
|
||||
if (STATS::STAT_GET_INT(stat_hash, &stat_value, -1))
|
||||
{
|
||||
return stat_value;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string get_static_property_name(int property)
|
||||
{
|
||||
switch (property)
|
||||
{
|
||||
case 12: //Hangar
|
||||
{
|
||||
auto hangar_id = *scr_globals::gpbd_fm_1.at(self::id, 867).at(267).at(293).as<PINT>();
|
||||
switch (hangar_id)
|
||||
{
|
||||
case 1: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_HANGAR_1"); //LSIA Hangar 1
|
||||
case 2: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_HANGAR_2"); //LSIA Hangar A17
|
||||
case 3: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_HANGAR_3"); //Fort Zancudo Hangar A2
|
||||
case 4: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_HANGAR_4"); //Fort Zancudo Hangar 3497
|
||||
case 5: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_HANGAR_5"); //Fort Zancudo Hangar 3499
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 13: //Facility
|
||||
{
|
||||
auto facility_id = *scr_globals::gpbd_fm_1.at(self::id, 867).at(267).at(300).as<PINT>();
|
||||
switch (facility_id)
|
||||
{
|
||||
case 1: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_1"); //Grand Senora Desert Facility
|
||||
case 2: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_2"); //Route 68 Facility
|
||||
case 3: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_3"); //Sandy Shores Facility
|
||||
case 4: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_4"); //Mount Gordo Facility
|
||||
case 5: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_6"); //Paleto Bay Facility
|
||||
case 6: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_7"); //Lago Zancudo Facility
|
||||
case 7: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_8"); //Zancudo River Facility
|
||||
case 8: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_9"); //Ron Alternates Wind Farm Facility
|
||||
case 9: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_DBASE_10"); //Land Act Reservoir Facility
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 14: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_BHUB_CLUBG"); //Nightclub Service Entrance
|
||||
case 15: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_BHUB_GAR1"); //Nightclub B2
|
||||
case 16: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_BHUB_GAR2"); //Nightclub B3
|
||||
case 17: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_BHUB_GAR3"); //Nightclub B4
|
||||
case 18: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("ARENA_GAR_F0"); //Arena Workshop
|
||||
case 19: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("ARENA_GAR_F1"); //Arena Workshop B1
|
||||
case 20: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("ARENA_GAR_F2"); //Arena Workshop B1
|
||||
case 21: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("CASINO_GARNAME"); //Casino Penthouse
|
||||
case 22: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("ARCADE_GARNAME"); //Arcade
|
||||
case 25: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("AUT_SHP_GAR"); //Auto Shop
|
||||
case 26: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("FIXER_GARNAME"); //Agency
|
||||
case 29: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("WIN22_GARNAME"); //Eclipse Blvd Garage
|
||||
case MAX_GARAGE_NUM+0: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("GRTRUCK"); //Mobile Operations Center
|
||||
case MAX_GARAGE_NUM+1: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_BHUB_GAR0"); //Nightclub B1
|
||||
case MAX_GARAGE_NUM+2: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_BHUB_CLUBT"); //Terrorbyte
|
||||
case MAX_GARAGE_NUM+3: return HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION("MP_BHUB_SUB"); //Kosatka
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void personal_vehicle::set_garage()
|
||||
{
|
||||
for (int property_iterator = 0; property_iterator < MAX_GARAGE_NUM+4; property_iterator++)
|
||||
{
|
||||
auto property_stat_state = get_property_stat_state(property_iterator);
|
||||
if (property_stat_state > 0) //Check if the player owns the property
|
||||
{
|
||||
auto garage_size = get_property_garage_size(property_iterator);
|
||||
auto garage_offset = get_property_garage_offset(property_iterator);
|
||||
for (int garage_slot_iterator = 1; garage_slot_iterator <= garage_size; garage_slot_iterator++)
|
||||
{
|
||||
auto item_in_slot = *scr_globals::property_garage.at(garage_offset).at(garage_slot_iterator).as<PINT>() - 1;
|
||||
if (item_in_slot == m_id)
|
||||
{
|
||||
auto static_property_string = get_static_property_name(property_iterator);
|
||||
if (static_property_string.empty())
|
||||
{
|
||||
m_garage = HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(scr_globals::property_names.at(property_stat_state, 1951).at(16).as<const char*>());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_garage = static_property_string;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
personal_vehicle::personal_vehicle(int idx, script_global vehicle_idx) :
|
||||
m_id(idx),
|
||||
m_vehicle_idx(vehicle_idx)
|
||||
{
|
||||
m_plate = m_vehicle_idx.at(1).as<char*>();
|
||||
m_hash = *m_vehicle_idx.at(66).as<Hash*>();
|
||||
m_state_bitfield = m_vehicle_idx.at(103).as<int*>();
|
||||
set_garage();
|
||||
|
||||
m_name = std::format("{} ({})", HUD::GET_FILENAME_FOR_AUDIO_CONVERSATION(VEHICLE::GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(m_hash)), m_plate);
|
||||
}
|
||||
@ -48,6 +270,42 @@ namespace big
|
||||
mobile::mechanic::summon_vehicle_by_index(m_id);
|
||||
}
|
||||
|
||||
std::string personal_vehicle::get_garage() const
|
||||
{
|
||||
return m_garage;
|
||||
}
|
||||
|
||||
bool personal_vehicle::is_in_selected_garage() const
|
||||
{
|
||||
return g.clone_pv.garage.empty() || m_garage == g.clone_pv.garage;
|
||||
}
|
||||
|
||||
bool personal_vehicle::is_blacklisted_vehicle() const
|
||||
{
|
||||
switch (m_hash)
|
||||
{
|
||||
case RAGE_JOAAT("avenger"):
|
||||
case RAGE_JOAAT("avenger3"):
|
||||
case RAGE_JOAAT("hauler2"):
|
||||
case RAGE_JOAAT("phantom3"):
|
||||
case RAGE_JOAAT("trailersmall2"):
|
||||
case RAGE_JOAAT("khanjali"):
|
||||
case RAGE_JOAAT("chernobog"):
|
||||
case RAGE_JOAAT("riot2"):
|
||||
case RAGE_JOAAT("thruster"):
|
||||
case RAGE_JOAAT("brickade2"):
|
||||
case RAGE_JOAAT("manchez3"):
|
||||
case RAGE_JOAAT("terbyte"):
|
||||
case RAGE_JOAAT("speedo4"):
|
||||
case RAGE_JOAAT("mule4"):
|
||||
case RAGE_JOAAT("pounder2"):
|
||||
case RAGE_JOAAT("rcbandito"):
|
||||
case RAGE_JOAAT("minitank"):
|
||||
return !g.clone_pv.spawn_clone;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mobile_service::mobile_service()
|
||||
{
|
||||
g_mobile_service = this;
|
||||
@ -67,6 +325,7 @@ namespace big
|
||||
|
||||
g_fiber_pool->queue_job([this] {
|
||||
register_vehicles();
|
||||
refresh_garages();
|
||||
});
|
||||
}
|
||||
|
||||
@ -100,6 +359,8 @@ namespace big
|
||||
m_personal_vehicles.emplace(veh->get_display_name(), std::move(veh));
|
||||
}
|
||||
|
||||
m_personal_vehicles[veh->get_display_name()]->set_garage();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -117,4 +378,20 @@ namespace big
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mobile_service::refresh_garages()
|
||||
{
|
||||
m_garages.clear();
|
||||
for (const auto& [name, personal_vehicle_ptr] : personal_vehicles())
|
||||
{
|
||||
if (!personal_vehicle_ptr->is_blacklisted_vehicle())
|
||||
{
|
||||
auto garage_name = personal_vehicle_ptr->get_garage();
|
||||
if (!garage_name.empty())
|
||||
{
|
||||
m_garages.emplace(personal_vehicle_ptr->get_garage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -8,8 +8,9 @@ namespace big
|
||||
Hash m_hash;
|
||||
int m_id;
|
||||
std::string m_name;
|
||||
std::string m_garage{};
|
||||
const char* m_plate;
|
||||
int* m_state_bitfield;
|
||||
|
||||
script_global m_vehicle_idx;
|
||||
|
||||
public:
|
||||
@ -20,6 +21,10 @@ namespace big
|
||||
[[nodiscard]] int get_id() const;
|
||||
[[nodiscard]] const char* get_plate() const;
|
||||
[[nodiscard]] script_global get_vehicle_idx() const;
|
||||
[[nodiscard]] std::string get_garage() const;
|
||||
[[nodiscard]] void set_garage();
|
||||
[[nodiscard]] bool is_in_selected_garage() const;
|
||||
[[nodiscard]] bool is_blacklisted_vehicle() const;
|
||||
|
||||
void summon() const;
|
||||
};
|
||||
@ -28,6 +33,7 @@ namespace big
|
||||
{
|
||||
std::map<std::string, std::unique_ptr<personal_vehicle>> m_personal_vehicles;
|
||||
std::map<int, std::string> m_pv_lookup;
|
||||
std::set<std::string> m_garages;
|
||||
|
||||
std::chrono::time_point<std::chrono::steady_clock> m_last_update;
|
||||
|
||||
@ -44,7 +50,12 @@ namespace big
|
||||
{
|
||||
return m_personal_vehicles;
|
||||
}
|
||||
std::set<std::string>& garages()
|
||||
{
|
||||
return m_garages;
|
||||
}
|
||||
void refresh_personal_vehicles();
|
||||
void refresh_garages();
|
||||
void register_vehicles();
|
||||
};
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
#include "core/data/levels.hpp"
|
||||
#include "gta/joaat.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "script_global.hpp"
|
||||
|
||||
namespace big::local_player
|
||||
{
|
||||
inline void get_active_character_slot(int* character_slot)
|
||||
{
|
||||
STATS::STAT_GET_INT(RAGE_JOAAT("MPPLY_LAST_MP_CHAR"), character_slot, true);
|
||||
}
|
||||
|
||||
inline std::string get_mp_prefix()
|
||||
{
|
||||
get_active_character_slot(&g.player.character_slot);
|
||||
return "MP" + std::to_string(g.player.character_slot) + "_";
|
||||
}
|
||||
|
||||
inline void set_player_level(int level)
|
||||
{
|
||||
STATS::STAT_SET_INT(rage::joaat(get_mp_prefix() + "CHAR_SET_RP_GIFT_ADMIN"), levels[level - 1], 0);
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "entity.hpp"
|
||||
#include "gta/enums.hpp"
|
||||
#include "local_player.hpp"
|
||||
#include "math.hpp"
|
||||
#include "natives.hpp"
|
||||
#include "outfit.hpp"
|
||||
|
@ -4,11 +4,13 @@
|
||||
#include "natives.hpp"
|
||||
#include "services/player_database/player_database_service.hpp"
|
||||
#include "views/view.hpp"
|
||||
#include "services/gta_data/gta_data_service.hpp"
|
||||
|
||||
#include <network/netConnection.hpp>
|
||||
#include <script/globals/GPBD_FM.hpp>
|
||||
#include <script/globals/GPBD_FM_3.hpp>
|
||||
#include <script/globals/GlobalPlayerBD.hpp>
|
||||
#include <vehicle/CVehicleModelInfo.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -48,7 +50,8 @@ namespace big
|
||||
uint32_t ped_health = 0;
|
||||
uint32_t ped_maxhealth = 0;
|
||||
uint32_t veh_damage_bits = 0;
|
||||
std::string mode_str = "";
|
||||
std::string mode_str{};
|
||||
std::string vehicle_name{};
|
||||
|
||||
if (CPed* ped = g_player_service->get_selected()->get_ped(); ped != nullptr)
|
||||
{
|
||||
@ -209,42 +212,47 @@ namespace big
|
||||
|
||||
ImGui::Text("PLAYER_INFO_PROOFS"_T.data(), mode_str.c_str());
|
||||
|
||||
mode_str = "";
|
||||
|
||||
if (auto vehicle = g_player_service->get_selected()->get_current_vehicle(); vehicle != nullptr)
|
||||
{
|
||||
veh_damage_bits = vehicle->m_damage_bits;
|
||||
}
|
||||
mode_str.clear();
|
||||
|
||||
if (ped_task_flag & (uint8_t)ePedTask::TASK_DRIVING)
|
||||
{
|
||||
if (veh_damage_bits & (uint32_t)eEntityProofs::GOD)
|
||||
if (auto vehicle = g_player_service->get_selected()->get_current_vehicle(); vehicle != nullptr)
|
||||
{
|
||||
mode_str = "PLAYER_INFO_GOD"_T;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (veh_damage_bits & (uint32_t)eEntityProofs::COLLISION)
|
||||
{
|
||||
mode_str += "PLAYER_INFO_COLLISION"_T;
|
||||
}
|
||||
if (veh_damage_bits & (uint32_t)eEntityProofs::EXPLOSION)
|
||||
{
|
||||
mode_str += "PLAYER_INFO_EXPLOSION"_T;
|
||||
}
|
||||
}
|
||||
veh_damage_bits = vehicle->m_damage_bits;
|
||||
|
||||
if (mode_str.empty())
|
||||
{
|
||||
mode_str = "NO"_T;
|
||||
if (CVehicleModelInfo* vehicle_model_info = static_cast<CVehicleModelInfo*>(vehicle->m_model_info))
|
||||
{
|
||||
vehicle_name = g_gta_data_service->vehicles()[vehicle_model_info->m_name].m_display_name;
|
||||
}
|
||||
|
||||
if (veh_damage_bits & (uint32_t)eEntityProofs::GOD)
|
||||
{
|
||||
mode_str = "PLAYER_INFO_GOD"_T;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (veh_damage_bits & (uint32_t)eEntityProofs::COLLISION)
|
||||
{
|
||||
mode_str += "PLAYER_INFO_COLLISION"_T;
|
||||
}
|
||||
if (veh_damage_bits & (uint32_t)eEntityProofs::EXPLOSION)
|
||||
{
|
||||
mode_str += "PLAYER_INFO_EXPLOSION"_T;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode_str.empty())
|
||||
{
|
||||
mode_str = "NO"_T;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mode_str = "PLAYER_INFO_NO_VEHICLE"_T;
|
||||
vehicle_name = "PLAYER_INFO_NO_VEHICLE"_T;
|
||||
}
|
||||
|
||||
ImGui::Text("PLAYER_INFO_VEHICLE_PROOFS"_T.data(), mode_str.c_str());
|
||||
ImGui::Text("PLAYER_INFO_VEHICLE"_T.data(), vehicle_name.c_str(), mode_str.c_str());
|
||||
|
||||
if (auto net_player_data = g_player_service->get_selected()->get_net_data())
|
||||
{
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include "fiber_pool.hpp"
|
||||
#include "services/orbital_drone/orbital_drone.hpp"
|
||||
#include "util/entity.hpp"
|
||||
#include "util/local_player.hpp"
|
||||
#include "util/scripts.hpp"
|
||||
#include "views/view.hpp"
|
||||
|
||||
|
@ -27,7 +27,6 @@ namespace big::helper
|
||||
|
||||
namespace big
|
||||
{
|
||||
static int character_index = 0;
|
||||
static int year, month, day, hour, minute, second, millisecond;
|
||||
|
||||
static char stat_int_read_result[256] = {};
|
||||
@ -100,7 +99,7 @@ namespace big
|
||||
{
|
||||
auto substr = text.substr(1);
|
||||
if (substr.substr(0, 3) == "mpx")
|
||||
substr[2] = character_index + '0';
|
||||
substr[2] = self::char_index + '0';
|
||||
return rage::joaat(substr);
|
||||
}
|
||||
return get_text_value<Hash>(text);
|
||||
@ -440,7 +439,6 @@ namespace big
|
||||
}(), true);
|
||||
|
||||
g_fiber_pool->queue_job([] {
|
||||
STATS::STAT_GET_INT(RAGE_JOAAT("MPPLY_LAST_MP_CHAR"), &character_index, -1);
|
||||
CLOCK::GET_POSIX_TIME(&year, &month, &day, &hour, &minute, &second);
|
||||
if (g.stat_editor.stat.int_read)
|
||||
strcpy_s(stat_int_read_result, sizeof(stat_int_read_result), helper::stat_get_int(stat_int_text).c_str());
|
||||
@ -471,7 +469,7 @@ namespace big
|
||||
});
|
||||
|
||||
components::sub_title(std::format("Posix Time: {}-{}-{} {}:{}:{}", year, month, day, hour, minute, second));
|
||||
components::sub_title(std::format("Character Index: {}", character_index));
|
||||
components::sub_title(std::format("Character Index: {}", self::char_index));
|
||||
components::sub_title("Be aware of stat limits, use with caution, modifying some stats are risky.");
|
||||
|
||||
if (ImGui::BeginTabBar("##stat_editor_tab_bar"))
|
||||
@ -605,7 +603,7 @@ namespace big::helper
|
||||
index_max = index_v[1];
|
||||
int value_n = get_text_value<int>(value);
|
||||
for (int i = index_min; i <= index_max; i++)
|
||||
STATS::SET_PACKED_STAT_INT_CODE(i, value_n, character_index);
|
||||
STATS::SET_PACKED_STAT_INT_CODE(i, value_n, self::char_index);
|
||||
}
|
||||
|
||||
void packed_stat_set_bool(std::string index, std::string value)
|
||||
@ -619,7 +617,7 @@ namespace big::helper
|
||||
index_max = index_v[1];
|
||||
int value_b = get_text_value<bool>(value);
|
||||
for (int i = index_min; i <= index_max; i++)
|
||||
STATS::SET_PACKED_STAT_BOOL_CODE(i, value_b, character_index);
|
||||
STATS::SET_PACKED_STAT_BOOL_CODE(i, value_b, self::char_index);
|
||||
}
|
||||
|
||||
std::string packed_stat_get_int(std::string index)
|
||||
@ -629,7 +627,7 @@ namespace big::helper
|
||||
std::stringstream ss(index);
|
||||
std::getline(ss, str, ' ');
|
||||
if (str != "")
|
||||
result = STATS::GET_PACKED_STAT_INT_CODE(get_text_value<int>(str), character_index);
|
||||
result = STATS::GET_PACKED_STAT_INT_CODE(get_text_value<int>(str), self::char_index);
|
||||
return std::to_string(result);
|
||||
}
|
||||
|
||||
@ -640,7 +638,7 @@ namespace big::helper
|
||||
std::stringstream ss(index);
|
||||
std::getline(ss, str, ' ');
|
||||
if (str != "")
|
||||
result = STATS::GET_PACKED_STAT_BOOL_CODE(get_text_value<int>(str), character_index);
|
||||
result = STATS::GET_PACKED_STAT_BOOL_CODE(get_text_value<int>(str), self::char_index);
|
||||
return std::to_string(result);
|
||||
}
|
||||
}
|
@ -8,32 +8,6 @@
|
||||
|
||||
namespace big
|
||||
{
|
||||
bool is_blacklist_vehicle(Hash vehicle_hash)
|
||||
{
|
||||
switch (vehicle_hash)
|
||||
{
|
||||
case RAGE_JOAAT("avenger"):
|
||||
case RAGE_JOAAT("avenger3"):
|
||||
case RAGE_JOAAT("hauler2"):
|
||||
case RAGE_JOAAT("phantom3"):
|
||||
case RAGE_JOAAT("trailersmall2"):
|
||||
case RAGE_JOAAT("khanjali"):
|
||||
case RAGE_JOAAT("chernobog"):
|
||||
case RAGE_JOAAT("riot2"):
|
||||
case RAGE_JOAAT("thruster"):
|
||||
case RAGE_JOAAT("brickade2"):
|
||||
case RAGE_JOAAT("manchez3"):
|
||||
case RAGE_JOAAT("terbyte"):
|
||||
case RAGE_JOAAT("speedo4"):
|
||||
case RAGE_JOAAT("mule4"):
|
||||
case RAGE_JOAAT("pounder2"):
|
||||
case RAGE_JOAAT("rcbandito"):
|
||||
case RAGE_JOAAT("minitank"):
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void view::pv()
|
||||
{
|
||||
ImGui::SetWindowSize({0.f, (float)*g_pointers->m_gta.m_resolution_y}, ImGuiCond_Always);
|
||||
@ -55,7 +29,10 @@ namespace big
|
||||
|
||||
static char plate_buf[9] = {0};
|
||||
|
||||
ImGui::Checkbox("SPAWN_CLONE"_T.data(), &g.clone_pv.spawn_clone);
|
||||
if (ImGui::Checkbox("SPAWN_CLONE"_T.data(), &g.clone_pv.spawn_clone))
|
||||
{
|
||||
g_mobile_service->refresh_garages();
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("SPAWN_CLONE_DESC"_T.data());
|
||||
if (g.clone_pv.spawn_clone)
|
||||
@ -106,6 +83,28 @@ namespace big
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::SetNextItemWidth(300.f);
|
||||
std::string garage_display = g.clone_pv.garage.empty() ? "ALL"_T.data() : g.clone_pv.garage;
|
||||
if (ImGui::BeginCombo("GARAGE"_T.data(), garage_display.c_str()))
|
||||
{
|
||||
if (ImGui::Selectable("ALL"_T.data(), g.clone_pv.garage.empty()))
|
||||
{
|
||||
g.clone_pv.garage.clear();
|
||||
}
|
||||
for (auto garage : g_mobile_service->garages())
|
||||
{
|
||||
if (ImGui::Selectable(garage.c_str(), garage == g.clone_pv.garage))
|
||||
{
|
||||
g.clone_pv.garage = garage;
|
||||
}
|
||||
if (garage == g.clone_pv.garage)
|
||||
{
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
static char search[64];
|
||||
|
||||
@ -138,7 +137,7 @@ namespace big
|
||||
if ((selected_class == -1 || class_arr[selected_class] == vehicle_class)
|
||||
&& (display_name.find(lower_search) != std::string::npos || display_manufacturer.find(lower_search) != std::string::npos))
|
||||
{
|
||||
if (!g.clone_pv.spawn_clone && is_blacklist_vehicle(personal_veh->get_hash()))
|
||||
if (personal_veh->is_blacklisted_vehicle() || !personal_veh->is_in_selected_garage())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
#include "util/local_player.hpp"
|
||||
#include "views/view.hpp"
|
||||
|
||||
namespace big
|
||||
|
Reference in New Issue
Block a user