2023-07-09 17:01:42 -04:00
# include "persist_weapons.hpp"
2024-07-23 20:15:19 +02:00
2023-07-09 17:01:42 -04:00
# include "gta/weapons.hpp"
# include "natives.hpp"
2024-07-23 20:15:19 +02:00
# include "services/gta_data/gta_data_service.hpp"
2023-07-09 17:01:42 -04:00
namespace big
{
static weaponloadout_json persist_weapon_loadout ;
void persist_weapons : : save_weapons ( std : : string loadout_name )
{
2024-07-23 20:15:19 +02:00
Player player = self : : id ;
2023-07-09 17:01:42 -04:00
Ped player_ped = self : : ped ;
weaponloadout_json weapon_json { } ;
2024-07-23 20:15:19 +02:00
for ( const auto & [ name , weapon ] : g_gta_data_service . weapons ( ) )
2023-07-09 17:01:42 -04:00
{
Hash weapon_hash = weapon . m_hash ;
if ( weapon_hash ! = WEAPON_UNARMED & & WEAPON : : HAS_PED_GOT_WEAPON ( player_ped , weapon_hash , FALSE ) )
{
weaponloadout_weapon_json weapon_loadout ;
weapon_loadout . weapon = weapon_hash ;
weapon_loadout . group = rage : : joaat ( " GROUP_ " + weapon . m_weapon_type ) ;
weapon_loadout . tint = WEAPON : : GET_PED_WEAPON_TINT_INDEX ( player_ped , weapon_hash ) ;
for ( auto component : weapon . m_attachments )
{
Hash component_hash = rage : : joaat ( component ) ;
if ( WEAPON : : HAS_PED_GOT_WEAPON_COMPONENT ( player_ped , weapon_hash , component_hash ) )
weapon_loadout . component_array . push_back ( component_hash ) ;
}
weapon_json . weapons . push_back ( weapon_loadout ) ;
}
}
if ( WEAPON : : HAS_PED_GOT_WEAPON ( player_ped , GADGET_PARACHUTE , FALSE ) )
{
weapon_json . parachutes = 1 ;
int parachute_tint , parachute_pack_tint , reserve_pack_tint , smoke_trail [ 3 ] { } ;
bool hasReserve = PLAYER : : GET_PLAYER_HAS_RESERVE_PARACHUTE ( player ) ;
PLAYER : : GET_PLAYER_PARACHUTE_TINT_INDEX ( player , & parachute_tint ) ;
PLAYER : : GET_PLAYER_PARACHUTE_PACK_TINT_INDEX ( player , & parachute_pack_tint ) ;
weapon_json . parachute_tint = parachute_tint ;
weapon_json . parachute_pack_tint = parachute_pack_tint ;
if ( hasReserve = = true )
{
weapon_json . parachutes = 2 ;
PLAYER : : GET_PLAYER_RESERVE_PARACHUTE_TINT_INDEX ( player , & reserve_pack_tint ) ;
weapon_json . reserve_pack_tint = reserve_pack_tint ;
}
PLAYER : : GET_PLAYER_PARACHUTE_SMOKE_TRAIL_COLOR ( player ,
& weapon_json . smoke_trail [ 0 ] ,
& weapon_json . smoke_trail [ 1 ] ,
& weapon_json . smoke_trail [ 2 ] ) ;
}
nlohmann : : json json_output_file = weapon_json ;
const auto file = get_weapon_config_folder ( ) . get_file ( loadout_name + " .json " ) ;
std : : ofstream file_stream ( file . get_path ( ) , std : : ios : : out | std : : ios : : trunc ) ;
file_stream < < json_output_file . dump ( 4 ) ;
file_stream . close ( ) ;
}
void persist_weapons : : set_weapon_loadout ( std : : string loadout_name )
{
if ( loadout_name . empty ( ) )
return ;
g . persist_weapons . weapon_loadout_file = loadout_name ;
persist_weapon_loadout = get_loadout ( loadout_name ) ;
}
void persist_weapons : : check_player_has_weapons ( )
{
if ( ! g . persist_weapons . enabled )
{
return ;
}
if ( persist_weapon_loadout . weapons . empty ( ) )
{
if ( g . persist_weapons . weapon_loadout_file . empty ( ) )
{
return ;
}
persist_weapon_loadout = get_loadout ( g . persist_weapons . weapon_loadout_file ) ;
}
2024-04-22 19:48:22 +02:00
if ( g_local_player = = nullptr | | g_local_player - > m_player_info = = nullptr | | g_local_player - > m_player_info - > m_game_state = = eGameState : : InMPCutscene | | STREAMING : : IS_PLAYER_SWITCH_IN_PROGRESS ( ) | | DLC : : GET_IS_LOADING_SCREEN_ACTIVE ( ) ) [[unlikely]]
2023-07-09 17:01:42 -04:00
{
return ;
}
give_Loadout ( persist_weapon_loadout ) ;
}
void persist_weapons : : give_player_loadout ( std : : string loadout_name )
{
give_Loadout ( get_loadout ( loadout_name ) ) ;
}
weaponloadout_json persist_weapons : : get_loadout ( std : : string loadout_name )
{
auto file = get_weapon_config_folder ( ) . get_file ( loadout_name ) ;
if ( file . exists ( ) )
{
std : : ifstream file_stream ( file . get_path ( ) ) ;
try
{
nlohmann : : json json_input_file ;
file_stream > > json_input_file ;
file_stream . close ( ) ;
weaponloadout_json loadout = json_input_file ;
return loadout ;
}
catch ( std : : exception & e )
{
2024-03-23 00:04:49 +01:00
g_notification_service . push_warning ( " Persist Weapons " , " Failed to load JSON file from disk. " ) ;
2023-07-09 17:01:42 -04:00
LOG ( WARNING ) < < " Persist Weapons failed to load JSON file: " < < g . persist_weapons . weapon_loadout_file < < " because " < < e . what ( ) ;
}
}
else
{
g . persist_weapons . weapon_loadout_file . clear ( ) ;
LOG ( WARNING ) < < " persist_weapons cannot open file " < < g . persist_weapons . weapon_loadout_file ;
}
return { } ;
}
big : : folder persist_weapons : : get_weapon_config_folder ( )
{
const auto folder = g_file_manager . get_project_folder ( " ./weapon_loadouts " ) ;
return folder ;
}
std : : vector < std : : string > persist_weapons : : list_weapon_loadouts ( )
{
std : : vector < std : : string > file_paths ;
const auto file_path = get_weapon_config_folder ( ) ;
for ( const auto & directory_entry : std : : filesystem : : directory_iterator ( file_path . get_path ( ) ) )
if ( directory_entry . path ( ) . extension ( ) = = " .json " )
file_paths . push_back ( directory_entry . path ( ) . filename ( ) . generic_string ( ) ) ;
return file_paths ;
}
void persist_weapons : : give_Loadout ( const weaponloadout_json & loadout )
{
Player player = self : : id ;
Ped player_ped = self : : ped ;
2024-04-22 19:48:22 +02:00
if ( PED : : IS_PED_DEAD_OR_DYING ( player_ped , true ) ) [[unlikely]]
2023-07-09 17:01:42 -04:00
return ;
for ( auto weapon : loadout . weapons )
{
Hash weapon_hash = weapon . weapon ;
bool is_gun = ( weapon . group ! = GROUP_MELEE ) ;
if ( WEAPON : : HAS_PED_GOT_WEAPON ( player_ped , weapon_hash , FALSE ) = = false
| | ( is_gun & & ( WEAPON : : GET_PED_WEAPON_TINT_INDEX ( player_ped , weapon_hash ) ! = weapon . tint | | ( WEAPON : : GET_AMMO_IN_PED_WEAPON ( player_ped , weapon_hash ) = = 0 ) ) ) )
{
int maxAmmo ;
if ( WEAPON : : GET_MAX_AMMO ( player_ped , weapon_hash , & maxAmmo ) = = FALSE )
maxAmmo = 9999 ;
WEAPON : : GIVE_WEAPON_TO_PED ( player_ped , weapon_hash , maxAmmo , FALSE , FALSE ) ;
if ( weapon . group ! = GROUP_MELEE )
{
WEAPON : : SET_PED_WEAPON_TINT_INDEX ( player_ped , weapon_hash , weapon . tint ) ;
2024-07-23 20:15:19 +02:00
for ( auto component : g_gta_data_service . weapon_by_hash ( weapon_hash ) . m_attachments )
2023-07-09 17:01:42 -04:00
WEAPON : : REMOVE_WEAPON_COMPONENT_FROM_PED ( player_ped , weapon_hash , rage : : joaat ( component ) ) ;
for ( auto component : weapon . component_array )
WEAPON : : GIVE_WEAPON_COMPONENT_TO_PED ( player_ped , weapon_hash , component ) ;
WEAPON : : GIVE_WEAPON_TO_PED ( player_ped , weapon_hash , ( WEAPON : : GET_MAX_AMMO ( player_ped , weapon_hash , & maxAmmo ) = = TRUE ) ? maxAmmo : 9999 , FALSE , FALSE ) ; //Mk II weapons require giving the weapon to the player twice for them to work, because reasons.
}
}
}
if ( loadout . parachutes ! = 0 )
{
WEAPON : : GIVE_WEAPON_TO_PED ( player_ped , GADGET_PARACHUTE , 1 , FALSE , FALSE ) ;
PLAYER : : SET_PLAYER_PARACHUTE_TINT_INDEX ( player , loadout . parachute_tint ) ;
PLAYER : : SET_PLAYER_PARACHUTE_PACK_TINT_INDEX ( player , loadout . parachute_pack_tint ) ;
if ( loadout . parachutes = = 2 )
{
PLAYER : : SET_PLAYER_HAS_RESERVE_PARACHUTE ( player ) ;
PLAYER : : SET_PLAYER_RESERVE_PARACHUTE_TINT_INDEX ( player , loadout . reserve_pack_tint ) ;
}
auto smoke_trail = loadout . smoke_trail ;
if ( ( smoke_trail [ 0 ] + smoke_trail [ 1 ] + smoke_trail [ 2 ] ) ! = 765 ) //255 + 255 + 255
{
PLAYER : : SET_PLAYER_CAN_LEAVE_PARACHUTE_SMOKE_TRAIL ( player , TRUE ) ;
PLAYER : : SET_PLAYER_PARACHUTE_SMOKE_TRAIL_COLOR ( player , smoke_trail [ 0 ] , smoke_trail [ 1 ] , smoke_trail [ 2 ] ) ;
}
}
}
2024-03-23 00:04:49 +01:00
}