Files
gtav-src/script/dev_ng/singleplayer/include/public/vehicle_gen_public.sch
T
2025-09-29 00:52:08 +02:00

1107 lines
49 KiB
XML
Executable File

//////////////////////////////////////////////////////////////////////////////////////////
// //
// SCRIPT NAME : vehicle_gen_public.sc //
// AUTHOR : Kenneth Ross //
// DESCRIPTION : Commands to set the vehicle gen state. //
// //
//////////////////////////////////////////////////////////////////////////////////////////
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_script.sch"
USING "vehicle_gen_private.sch"
#IF USE_CLF_DLC
using "spy_vehicle_system.sch"
#endif
/// PURPOSE: Returns TRUE if the vehicle gen controller is prevented from creating vehicles when on mission.
FUNC BOOL IS_VEHCILE_GEN_DISABLED_ON_MISSION()
RETURN g_sVehicleGenNSData.bDisabledForMissions
ENDFUNC
/// PURPOSE: Resets the counter we use to track if all vehicle gens have loaded
PROC RESET_VEHICLE_GEN_LOADED_CHECKS()
g_sVehicleGenNSData.bCheckVehGensLoaded = TRUE
g_sVehicleGenNSData.iCheckVehGensLoadedCounter = 0
ENDPROC
/// PURPOSE: Checks to see if we are in the process of creating vehicles gens.
/// NOTE: Based on current player position, script must call RESET_VEHICLE_GEN_LOADED_CHECKS() to start.
FUNC BOOL HAVE_ALL_VEHICLE_GENS_LOADED_NEAR_PLAYER()
RETURN (NOT g_sVehicleGenNSData.bCheckVehGensLoaded)
ENDFUNC
/// PURPOSE: This will block the vehicle gen controller from creating vehicles.
/// NOTE: This should only be used when streaming is an issue on a mission.
PROC DISABLE_VEHICLE_GEN_ON_MISSION(BOOL bDisableVehGen)
#IF IS_DEBUG_BUILD
IF bDisableVehGen
PRINTSTRING("\n DISABLE_VEHICLE_GEN_ON_MISSION(TRUE) called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL()
ELSE
PRINTSTRING("\n DISABLE_VEHICLE_GEN_ON_MISSION(FALSE) called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL()
ENDIF
#ENDIF
g_sVehicleGenNSData.bDisabledForMissions = bDisableVehGen
ENDPROC
/// PURPOSE: This will mark the vehicle gen vehicle as no longer needed
PROC CLEANUP_VEHICLE_GEN_VEHICLE(VEHICLE_GEN_NAME_ENUM eVehicleGen)
IF eVehicleGen = VEHGEN_NONE
EXIT
ENDIF
// g_sVehicleGenNSData.sRuntimeStruct[0] Gets used in UPDATE_DYNAMIC but works on same vehicle so safe to re-use here.
IF GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], eVehicleGen)
IF DOES_ENTITY_EXIST(g_sVehicleGenNSData.vehicleID[eVehicleGen])
#IF IS_DEBUG_BUILD
PRINTLN("[, ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name, "] - CLEANUP_VEHICLE_GEN_VEHICLE - marking as no longer needed for script ", GET_THIS_SCRIPT_NAME())
#ENDIF
SET_ENTITY_AS_MISSION_ENTITY(g_sVehicleGenNSData.vehicleID[eVehicleGen], TRUE, TRUE)
SET_VEHICLE_AS_NO_LONGER_NEEDED(g_sVehicleGenNSData.vehicleID[eVehicleGen])
g_sVehicleGenNSData.vehicleID[eVehicleGen] = NULL
ENDIF
// Mark as unavailable
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_ONLY_AVAILABLE_ONCE))
SET_VEHICLE_GEN_AVAILABLE(eVehicleGen, FALSE)
ENDIF
ENDIF
ENDPROC
func int get_vehicle_setup_array_size(VEHICLE_SETUP_STRUCT &array[])
UNUSED_PARAMETER(array)
return count_of(array)
endfunc
FUNC BOOL IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(INT iSlot, enumCharacterList eImpoundChar)
INT i
SWITCH eImpoundChar
CASE CHAR_MICHAEL
i = 0
BREAK
CASE CHAR_FRANKLIN
i = 1
BREAK
CASE CHAR_TREVOR
i = 2
BREAK
ENDSWITCH
#if USE_CLF_DLC
IF iSlot < 0
OR iSlot >= get_vehicle_setup_array_size(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i])
RETURN FALSE
ENDIF
RETURN IS_VEHICLE_AVAILABLE_FOR_GAME(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
#endif
#if USE_NRM_DLC
IF iSlot < 0
OR iSlot >= get_vehicle_setup_array_size(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i])
RETURN FALSE
ENDIF
RETURN IS_VEHICLE_AVAILABLE_FOR_GAME(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
IF iSlot < 0
OR iSlot >= get_vehicle_setup_array_size(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i])
RETURN FALSE
ENDIF
RETURN IS_VEHICLE_AVAILABLE_FOR_GAME(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
#endif
#endif
ENDFUNC
/// PURPOSE: This will delete the vehicle created at this vehicle gen location
PROC DELETE_VEHICLE_GEN_VEHICLE(VEHICLE_GEN_NAME_ENUM eVehicleGen)
IF eVehicleGen = VEHGEN_NONE
EXIT
ENDIF
IF GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], eVehicleGen)
IF DOES_ENTITY_EXIST(g_sVehicleGenNSData.vehicleID[eVehicleGen])
#IF IS_DEBUG_BUILD
PRINTLN("[, ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name, "] - DELETE_VEHICLE_GEN_VEHICLE - deleting vehicle for script ", GET_THIS_SCRIPT_NAME())
#ENDIF
BOOL bDelete = TRUE
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_VEHICLE_DRIVEABLE(g_sVehicleGenNSData.vehicleID[eVehicleGen])
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_sVehicleGenNSData.vehicleID[eVehicleGen])
bDelete = FALSE
ENDIF
ENDIF
ENDIF
IF bDelete
SET_ENTITY_AS_MISSION_ENTITY(g_sVehicleGenNSData.vehicleID[eVehicleGen], TRUE, TRUE)
DELETE_VEHICLE(g_sVehicleGenNSData.vehicleID[eVehicleGen])
ENDIF
ELSE
#IF IS_DEBUG_BUILD
PRINTLN("[, ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name, "] - DELETE_VEHICLE_GEN_VEHICLE - vehicle doesn't exist, ", GET_THIS_SCRIPT_NAME())
#ENDIF
ENDIF
// Make player leave area, even if the vehicle didn't exist.
g_sVehicleGenNSData.bLeaveAreaBeforeCreating[eVehicleGen] = TRUE
// Mark as unavailable
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_ONLY_AVAILABLE_ONCE))
#if USE_CLF_DLC
// [IMPOUND] Send mission vehicle gen to impound as it's getting removed
IF eVehicleGen = VEHGEN_MISSION_VEH
AND GET_VEHICLE_GEN_SAVED_FLAG_STATE(eVehicleGen, VEHGEN_S_FLAG_AVAILABLE)
AND sTempImpoundVehData.eModel = DUMMY_MODEL_FOR_SCRIPT
AND g_savedGlobalsClifford.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] != 0 // +1 so we dont have to initiailise to -1
AND g_savedGlobalsClifford.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] > NUM_OF_PLAYABLE_PEDS //
AND (NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(0, g_sVehicleGenNSData.sRuntimeStruct[0].ped) OR NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(1, g_sVehicleGenNSData.sRuntimeStruct[0].ped))
PRINTLN("DELETE_VEHICLE_GEN_VEHICLE - deleting mission veghgen so send to impound")
CLONE_VEHICLE_SETUP_STRUCT(g_savedGlobalsClifford.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex], sTempImpoundVehData)
eTempImpoundChar = g_savedGlobalsClifford.sVehicleGenData.eLastCharToUseMissionVehGen
ENDIF
#endif
#IF USE_NRM_DLC
// [IMPOUND] Send mission vehicle gen to impound as it's getting removed
IF eVehicleGen = VEHGEN_MISSION_VEH
AND GET_VEHICLE_GEN_SAVED_FLAG_STATE(eVehicleGen, VEHGEN_S_FLAG_AVAILABLE)
AND sTempImpoundVehData.eModel = DUMMY_MODEL_FOR_SCRIPT
AND g_savedGlobalsnorman.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] != 0 // +1 so we dont have to initiailise to -1
AND g_savedGlobalsnorman.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] > NUM_OF_PLAYABLE_PEDS //
AND (NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(0, g_sVehicleGenNSData.sRuntimeStruct[0].ped) OR NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(1, g_sVehicleGenNSData.sRuntimeStruct[0].ped))
PRINTLN("DELETE_VEHICLE_GEN_VEHICLE - deleting mission veghgen so send to impound")
CLONE_VEHICLE_SETUP_STRUCT(g_savedGlobalsnorman.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex], sTempImpoundVehData)
eTempImpoundChar = g_savedGlobalsnorman.sVehicleGenData.eLastCharToUseMissionVehGen
ENDIF
#endif
#if not USE_CLF_DLC
#if not use_NRM_dlc
// [IMPOUND] Send mission vehicle gen to impound as it's getting removed
IF eVehicleGen = VEHGEN_MISSION_VEH
AND GET_VEHICLE_GEN_SAVED_FLAG_STATE(eVehicleGen, VEHGEN_S_FLAG_AVAILABLE)
AND sTempImpoundVehData.eModel = DUMMY_MODEL_FOR_SCRIPT
AND g_savedGlobals.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] != 0 // +1 so we dont have to initiailise to -1
AND g_savedGlobals.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] > NUM_OF_PLAYABLE_PEDS //
AND (NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(0, g_sVehicleGenNSData.sRuntimeStruct[0].ped) OR NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(1, g_sVehicleGenNSData.sRuntimeStruct[0].ped))
PRINTLN("DELETE_VEHICLE_GEN_VEHICLE - deleting mission veghgen so send to impound")
CLONE_VEHICLE_SETUP_STRUCT(g_savedGlobals.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex], sTempImpoundVehData)
eTempImpoundChar = g_savedGlobals.sVehicleGenData.eLastCharToUseMissionVehGen
ENDIF
#endif
#endif
SET_VEHICLE_GEN_AVAILABLE(eVehicleGen, FALSE)
ENDIF
ENDIF
ENDPROC
/// PURPOSE: Forces any vehicles created by the vehicle gen controller to be deleted
PROC DELETE_VEHICLE_GEN_VEHICLES_IN_AREA(VECTOR vCoords, FLOAT fRadius, BOOL bCheck3d = FALSE)
INT iVehicle
REPEAT NUMBER_OF_VEHICLES_TO_GEN iVehicle
IF GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], INT_TO_ENUM(VEHICLE_GEN_NAME_ENUM, iVehicle))
IF GET_DISTANCE_BETWEEN_COORDS(vCoords, g_sVehicleGenNSData.sRuntimeStruct[0].coords, bCheck3d) <= fRadius
DELETE_VEHICLE_GEN_VEHICLE(INT_TO_ENUM(VEHICLE_GEN_NAME_ENUM, iVehicle))
ENDIF
ENDIF
ENDREPEAT
ENDPROC
/// PURPOSE: Clears the flag which states the player must leave the area before the vehicle gen vehicle can be created
PROC CLEAR_MUST_LEAVE_AREA_VEHICLE_GEN_FLAG(VEHICLE_GEN_NAME_ENUM eVehicleGen)
IF eVehicleGen = VEHGEN_NONE
EXIT
ENDIF
g_sVehicleGenNSData.bLeaveAreaBeforeCreating[eVehicleGen] = FALSE
g_sVehicleGenNSData.bCheckPlayerVehicleCleanupTimer[eVehicleGen] = FALSE // Script is forcing the vehicle to create so make sure we ignore the cleanup timer check
ENDPROC
/// PURPOSE: Sets the flag which states the player must leave the area before the vehicle gen vehicle can be created
PROC SET_MUST_LEAVE_AREA_VEHICLE_GEN_FLAG(VEHICLE_GEN_NAME_ENUM eVehicleGen)
IF eVehicleGen = VEHGEN_NONE
EXIT
ENDIF
g_sVehicleGenNSData.bLeaveAreaBeforeCreating[eVehicleGen] = TRUE
ENDPROC
/// PURPOSE: Clears the flag which states the player must leave the area before the vehicle gen vehicle can be created.
PROC CLEAR_ALL_MUST_LEAVE_AREA_VEHICLE_GEN_FLAGS()
INT i
REPEAT NUMBER_OF_VEHICLES_TO_GEN i
g_sVehicleGenNSData.bLeaveAreaBeforeCreating[i] = FALSE
ENDREPEAT
ENDPROC
/// PURPOSE: Reuturns the vehicle index of the vehicle gen.
/// NOTE: This gets set to NULL when the vehicle is marked as no longer needed.
FUNC VEHICLE_INDEX GET_VEHICLE_GEN_VEHICLE_INDEX(VEHICLE_GEN_NAME_ENUM eVehicleGen)
IF eVehicleGen = VEHGEN_NONE
RETURN NULL
ENDIF
RETURN (g_sVehicleGenNSData.vehicleID[eVehicleGen])
ENDFUNC
/// PURPOSE: Allows a script to set a vehicle that already exists as a vehicle gen vehicle.
PROC SET_VEHICLE_GEN_VEHICLE(VEHICLE_GEN_NAME_ENUM eVehicleGen, VEHICLE_INDEX vehIndex, BOOL bUseVehicleCoords = TRUE)
IF eVehicleGen = VEHGEN_NONE
SCRIPT_ASSERT("SET_VEHICLE_GEN_VEHICLE: VEHGEN_NONE is not a valid vehicle generator to pass.")
EXIT
ENDIF
IF NOT GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], eVehicleGen)
SCRIPT_ASSERT("SET_VEHICLE_GEN_VEHICLE: Could not retrieve vehicle gen data for the given vehicle generator.")
EXIT
ENDIF
IF NOT IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_IGNORE_HANDOVER_MODEL_CHECKS))
AND NOT IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_DATA))
IF g_sVehicleGenNSData.sRuntimeStruct[0].model != GET_ENTITY_MODEL(vehIndex)
SCRIPT_ASSERT("SET_VEHICLE_GEN_VEHICLE: The vehicle index passed had a model that did not match the vehicle gen. Could not bind this to the cargen.")
EXIT
ENDIF
ENDIF
IF g_eVehGenToRecieveVehicle != VEHGEN_NONE
AND g_eVehGenToRecieveVehicle != eVehicleGen
SCRIPT_ASSERT("SET_VEHICLE_GEN_VEHICLE: Tried to handover a vehicle while a previous handover was still active. Could not perform handover.")
EXIT
ENDIF
IF DOES_ENTITY_EXIST(vehIndex)
IF IS_VEHICLE_DRIVEABLE(vehIndex)
// Make sure it is a mission vehicle so that it doesn't get cleaned up until we process handover.
IF NOT IS_ENTITY_A_MISSION_ENTITY(vehIndex)
SET_ENTITY_AS_MISSION_ENTITY(vehIndex, TRUE, TRUE)
ENDIF
// [IMPOUND] Reset the mision vehgen timestamp so we can send to impound if player doesn't use it.
IF eVehicleGen = VEHGEN_MISSION_VEH
#if USE_CLF_DLC
g_savedGlobalsClifford.sVehicleGenData.eMissionVehTimeStamp = GET_CURRENT_TIMEOFDAY()
#endif
#if USE_NRM_DLC
g_savedGlobalsnorman.sVehicleGenData.eMissionVehTimeStamp = GET_CURRENT_TIMEOFDAY()
#endif
#if not USE_CLF_DLC
#if not use_NRM_dlc
g_savedGlobals.sVehicleGenData.eMissionVehTimeStamp = GET_CURRENT_TIMEOFDAY()
#endif
#endif
ENDIF
// Not same vehicle
IF vehIndex != g_sVehicleGenNSData.vehicleID[eVehicleGen]
#IF IS_DEBUG_BUILD
PRINTLN("Script ", GET_THIS_SCRIPT_NAME(), " is handing over a vehicle to veh gen ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name, " with model ", GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(GET_ENTITY_MODEL(vehIndex)))
#ENDIF
// [IMPOUND] Start tracking old vehicle for impound
IF eVehicleGen = VEHGEN_MISSION_VEH
VEHICLE_INDEX vehTemp = GET_VEHICLE_GEN_VEHICLE_INDEX(eVehicleGen)
IF DOES_ENTITY_EXIST(vehTemp)
AND IS_VEHICLE_DRIVEABLE(vehTemp)
AND vehIndex != vehTemp
TRACK_VEHICLE_FOR_IMPOUND(vehTemp)
ENDIF
ENDIF
g_vehHandoverToGen = vehIndex
g_eVehGenToRecieveVehicle = eVehicleGen
g_bVehHandoverUseVehicleCoords = bUseVehicleCoords
ENDIF
ELSE
SCRIPT_ASSERT("SET_VEHICLE_GEN_VEHICLE: Passed vehicle index pointed to a vehicle that was destroyed. Could not bind this to the cargen.")
ENDIF
ELSE
SCRIPT_ASSERT("SET_VEHICLE_GEN_VEHICLE: Passed vehicle index pointed to a vehicle that didn't exist. Could not bind this to the cargen.")
ENDIF
ENDPROC
/// PURPOSE: Sets the vehicle data that should be used when creating the specified vehicle gen
/// NOTE: Vehicle gen must have the VEHGEN_NS_FLAG_DYNAMIC_DATA setup flag
/// Set vCoords to <<0,0,0>> if you do not want to update the coords
/// Set fHeading to -1 if you do not want to update the heading
PROC UPDATE_DYNAMIC_VEHICLE_GEN_DATA(VEHICLE_GEN_NAME_ENUM eVehicleGen, VEHICLE_SETUP_STRUCT &sVehicleSetup, VECTOR vCoords, FLOAT fHeading, enumCharacterList ePlayerVehicle = NO_CHARACTER)
IF GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], eVehicleGen)
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_DATA))
// Free the last vehicle.
CLEANUP_VEHICLE_GEN_VEHICLE(eVehicleGen)
#if USE_CLF_DLC
CLONE_VEHICLE_SETUP_STRUCT(sVehicleSetup, g_savedGlobalsClifford.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_COORDS))
g_savedGlobalsClifford.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = vCoords
g_savedGlobalsClifford.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = fHeading
ELSE
g_savedGlobalsClifford.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = <<0,0,0>>
g_savedGlobalsClifford.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = -1
ENDIF
g_savedGlobalsClifford.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = ENUM_TO_INT(ePlayerVehicle)+1
#IF IS_DEBUG_BUILD
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_DATA_CLF() - Updating vehicle gen data")
PRINTLN("...vehicle gen = ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name)
PRINTLN("...vehicle model = ", GET_MODEL_NAME_FOR_DEBUG(g_savedGlobalsClifford.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel))
PRINTLN("...dynamic slot = ", g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex)
PRINTLN("...dynamic coords = ", g_savedGlobalsClifford.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...dynamic heading = ", g_savedGlobalsClifford.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...player vehicle = ", ePlayerVehicle)
#ENDIF
#endif
#if USE_NRM_DLC
CLONE_VEHICLE_SETUP_STRUCT(sVehicleSetup, g_savedGlobalsnorman.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_COORDS))
g_savedGlobalsnorman.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = vCoords
g_savedGlobalsnorman.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = fHeading
ELSE
g_savedGlobalsnorman.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = <<0,0,0>>
g_savedGlobalsnorman.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = -1
ENDIF
g_savedGlobalsnorman.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = ENUM_TO_INT(ePlayerVehicle)+1
#IF IS_DEBUG_BUILD
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_DATA_NRM() - Updating vehicle gen data")
PRINTLN("...vehicle gen = ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name)
PRINTLN("...vehicle model = ", GET_MODEL_NAME_FOR_DEBUG(g_savedGlobalsnorman.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel))
PRINTLN("...dynamic slot = ", g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex)
PRINTLN("...dynamic coords = ", g_savedGlobalsnorman.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...dynamic heading = ", g_savedGlobalsnorman.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...player vehicle = ", ePlayerVehicle)
#ENDIF
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
CLONE_VEHICLE_SETUP_STRUCT(sVehicleSetup, g_savedGlobals.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_COORDS))
g_savedGlobals.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = vCoords
g_savedGlobals.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = fHeading
ELSE
g_savedGlobals.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = <<0,0,0>>
g_savedGlobals.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = -1
ENDIF
g_savedGlobals.sVehicleGenData.iPlayerVehicle[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = ENUM_TO_INT(ePlayerVehicle)+1
#IF IS_DEBUG_BUILD
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_DATA() - Updating vehicle gen data")
PRINTLN("...vehicle gen = ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name)
#IF USE_TU_CHANGES
IF g_savedGlobals.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel = DUMMY_MODEL_FOR_SCRIPT
PRINTLN("...vehicle model = DUMMY_MODEL_FOR_SCRIPT")
ELSE
PRINTLN("...vehicle model = ", GET_MODEL_NAME_FOR_DEBUG(g_savedGlobals.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel))
ENDIF
#ENDIF
#IF NOT USE_TU_CHANGES
PRINTLN("...vehicle model = ", GET_MODEL_NAME_FOR_DEBUG(g_savedGlobals.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel))
#ENDIF
PRINTLN("...dynamic slot = ", g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex)
PRINTLN("...dynamic coords = ", g_savedGlobals.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...dynamic heading = ", g_savedGlobals.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...player vehicle = ", ePlayerVehicle)
#ENDIF
#endif
#endif
// Make sure it is available.
SET_VEHICLE_GEN_AVAILABLE(eVehicleGen, TRUE)
ELSE
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_DATA() - Vehicle gen does not use dynamic data, ", ENUM_TO_INT(eVehicleGen))
#IF IS_DEBUG_BUILD
SCRIPT_ASSERT("UPDATE_DYNAMIC_VEHICLE_GEN_DATA() - Vehicle gen does not use dynamic data. Tell Kenneth R.")
#ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE: Sets the vehicle coords that should be used when creating the specified vehicle gen
/// NOTE: Vehicle gen must have the VEHGEN_NS_FLAG_DYNAMIC_DATA setup flag
/// Set vCoords to <<0,0,0>> if you do not want to update the coords
/// Set fHeading to -1 if you do not want to update the heading
PROC UPDATE_DYNAMIC_VEHICLE_GEN_POSITION(VEHICLE_GEN_NAME_ENUM eVehicleGen, VECTOR vCoords, FLOAT fHeading)
IF GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], eVehicleGen)
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_DATA))
//AND IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_COORDS)) // Allow scripts to set this ovveride.
#if USE_CLF_DLC
g_savedGlobalsClifford.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = vCoords
g_savedGlobalsClifford.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = fHeading
#IF IS_DEBUG_BUILD
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_POSITION() - Updating vehicle gen position")
PRINTLN("...vehicle gen = ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name)
PRINTLN("...vehicle model = ", GET_MODEL_NAME_FOR_DEBUG(g_savedGlobalsClifford.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel))
PRINTLN("...dynamic slot = ", g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex)
PRINTLN("...dynamic coords = ", g_savedGlobalsClifford.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...dynamic heading = ", g_savedGlobalsClifford.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
#ENDIF
#endif
#if USE_NRM_DLC
g_savedGlobalsnorman.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = vCoords
g_savedGlobalsnorman.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = fHeading
#IF IS_DEBUG_BUILD
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_POSITION() - Updating vehicle gen position")
PRINTLN("...vehicle gen = ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name)
PRINTLN("...vehicle model = ", GET_MODEL_NAME_FOR_DEBUG(g_savedGlobalsnorman.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel))
PRINTLN("...dynamic slot = ", g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex)
PRINTLN("...dynamic coords = ", g_savedGlobalsnorman.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...dynamic heading = ", g_savedGlobalsnorman.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
#ENDIF
#endif
#if not USE_CLF_DLC
#if not use_NRM_dlc
g_savedGlobals.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = vCoords
g_savedGlobals.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex] = fHeading
#IF IS_DEBUG_BUILD
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_POSITION() - Updating vehicle gen position")
PRINTLN("...vehicle gen = ", g_sVehicleGenNSData.sRuntimeStruct[0].dbg_name)
PRINTLN("...vehicle model = ", GET_MODEL_NAME_FOR_DEBUG(g_savedGlobals.sVehicleGenData.sDynamicData[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex].eModel))
PRINTLN("...dynamic slot = ", g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex)
PRINTLN("...dynamic coords = ", g_savedGlobals.sVehicleGenData.vDynamicCoords[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
PRINTLN("...dynamic heading = ", g_savedGlobals.sVehicleGenData.fDynamicHeading[g_sVehicleGenNSData.sRuntimeStruct[0].dynamicSlotIndex])
#ENDIF
#endif
#endif
ELSE
PRINTLN("UPDATE_DYNAMIC_VEHICLE_GEN_POSITION() - Vehicle gen does not use dynamic data, ", ENUM_TO_INT(eVehicleGen))
#IF IS_DEBUG_BUILD
SCRIPT_ASSERT("UPDATE_DYNAMIC_VEHICLE_GEN_POSITION() - Vehicle gen does not use dynamic data. Tell Kenneth R.")
#ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE: Ties the vehicle to a vehicle gen so that it remains in place until the player uses it.
/// NOTE: eVehGen should be VEHGEN_MISSION_VEH or VEHGEN_MISSION_VEH_FBI4_PREP
PROC CLEANUP_MISSION_VEHICLE_GEN_VEHICLE(VEHICLE_GEN_NAME_ENUM eVehGen = VEHGEN_MISSION_VEH)
IF eVehGen != VEHGEN_MISSION_VEH
AND eVehGen != VEHGEN_MISSION_VEH_FBI4_PREP
#IF IS_DEBUG_BUILD
PRINTLN("CLEANUP_MISSION_VEHICLE_GEN_VEHICLE() - Invalid vehgen specified: ", ENUM_TO_INT(eVehGen))
SCRIPT_ASSERT("CLEANUP_MISSION_VEHICLE_GEN_VEHICLE() - Invalid vehgen specified. See Kenneth R.")
#ENDIF
ENDIF
CLEANUP_VEHICLE_GEN_VEHICLE(eVehGen)
SET_VEHICLE_GEN_AVAILABLE(eVehGen, FALSE)
ENDPROC
PROC TRIGGER_IMPOUND_HELP(enumCharacterList eCurrentChar, STRING sVehString)
IF NOT IS_PLAYER_PED_PLAYABLE(eCurrentChar)
EXIT
ENDIF
#if USE_CLF_DLC
IF NOT g_savedGlobalsClifford.sVehicleGenData.bImpoundVehicleHelp[eCurrentChar]
#IF USE_TU_CHANGES
#IF IS_DEBUG_BUILD
OR g_bAlwaysDisplayImpoundHelp
#ENDIF
#ENDIF
SWITCH eCurrentChar
CASE CHAR_MICHAEL
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPM", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_MICHAEL)
BREAK
CASE CHAR_FRANKLIN
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPF", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_FRANKLIN)
BREAK
CASE CHAR_TREVOR
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPT", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_TREVOR)
BREAK
ENDSWITCH
g_savedGlobalsClifford.sVehicleGenData.bImpoundVehicleHelp[eCurrentChar] = TRUE
ENDIF
#endif
#if USE_NRM_dlc
IF NOT g_savedGlobalsnorman.sVehicleGenData.bImpoundVehicleHelp[eCurrentChar]
#IF USE_TU_CHANGES
#IF IS_DEBUG_BUILD
OR g_bAlwaysDisplayImpoundHelp
#ENDIF
#ENDIF
SWITCH eCurrentChar
CASE CHAR_MICHAEL
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPM", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_MICHAEL)
BREAK
CASE CHAR_FRANKLIN
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPF", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_FRANKLIN)
BREAK
CASE CHAR_TREVOR
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPT", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_TREVOR)
BREAK
ENDSWITCH
g_savedGlobalsnorman.sVehicleGenData.bImpoundVehicleHelp[eCurrentChar] = TRUE
ENDIF
#endif
#if not USE_CLF_DLC
#if not use_NRM_dlc
IF NOT g_savedGlobals.sVehicleGenData.bImpoundVehicleHelp[eCurrentChar]
#IF USE_TU_CHANGES
#IF IS_DEBUG_BUILD
OR g_bAlwaysDisplayImpoundHelp
#ENDIF
#ENDIF
SWITCH eCurrentChar
CASE CHAR_MICHAEL
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPM", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_MICHAEL)
BREAK
CASE CHAR_FRANKLIN
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPF", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_FRANKLIN)
BREAK
CASE CHAR_TREVOR
ADD_HELP_WITH_SUBSTRING_TO_FLOW_QUEUE("IMPOUND_HELPT", sVehString, FHP_HIGH, GET_RANDOM_INT_IN_RANGE(1000, 6000), FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, BIT_TREVOR)
BREAK
ENDSWITCH
g_savedGlobals.sVehicleGenData.bImpoundVehicleHelp[eCurrentChar] = TRUE
ENDIF
#endif
#endif
ENDPROC
FUNC BOOL SEND_VEHICLE_DATA_TO_IMPOUND_USING_VEHICLE(VEHICLE_INDEX vehID, BOOL bVehGenControllerException = FALSE, enumCharacterList CharToImpound = NO_CHARACTER)
// Making this impound function ignore vehicles owned by the vehicle gen controller was to fix B*1426116
// But we call this function within the vehicle gen controller if the player recovers the vehicle and then leaves it!!
// So here is a special bool exception for the impound recovery script to use so that doesn't happen...
IF bVehGenControllerException = FALSE
INT iInstanceID
STRING sScriptName = GET_ENTITY_SCRIPT(vehID, iInstanceID)
IF NOT IS_STRING_NULL_OR_EMPTY(sScriptName)
IF GET_HASH_KEY(sScriptName) = GET_HASH_KEY("vehicle_gen_controller")
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_VEHICLE - Vehicle is owned by vehicle gen controller, not sending to impound.")
RETURN FALSE
ENDIF
ENDIF
ENDIF
// Lets just track this then send to impound when it gets removed from the world
TRACK_VEHICLE_FOR_IMPOUND(vehID, CharToImpound)
RETURN TRUE
ENDFUNC
/// PURPOSE: ONLY USE THIS IF YOU KNOW IT'S NOT A PLAYER VEHICLE SETUP
FUNC BOOL SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP(VEHICLE_SETUP_STRUCT &sVehicleData, enumCharacterList eImpoundChar)
IF NOT IS_VEHICLE_MODEL_SAFE_FOR_IMPOUND(sVehicleData.eModel)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - Not safe to send vehicle to impound.")
RETURN FALSE
ENDIF
IF DOES_ENTITY_EXIST(g_vehHandoverToGen)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - g_vehHandoverToGen exists - we're currently handing over a vehicle to the veh gen controller, not safe to impound.")
RETURN FALSE
ENDIF
INT i
SWITCH eImpoundChar
CASE CHAR_MICHAEL
i = 0
BREAK
CASE CHAR_FRANKLIN
i = 1
BREAK
CASE CHAR_TREVOR
i = 2
BREAK
DEFAULT
// We have an invalid character so bail.
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - Not safe to send vehicle to impound, invalid character.")
RETURN FALSE
BREAK
ENDSWITCH
#if USE_CLF_DLC
IF NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(0, eImpoundChar)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - impound slot 0 is free, setting vehicle into that")
g_savedGlobalsClifford.sVehicleGenData.iImpoundVehicleSlot[i] = 0
ELIF NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(1, eImpoundChar)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - impound slot 1 is free, setting vehicle into that")
g_savedGlobalsClifford.sVehicleGenData.iImpoundVehicleSlot[i] = 1
ELSE
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - both impound slots are full, will overwrite current set")
ENDIF
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - Adding vehicle to impound")
CPRINTLN(DEBUG_AMBIENT,"...ped = ", i)
CPRINTLN(DEBUG_AMBIENT,"...slot = ", g_savedGlobalsClifford.sVehicleGenData.iImpoundVehicleSlot[i])
CPRINTLN(DEBUG_AMBIENT,"...model = ", GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(sVehicleData.eModel))
TRIGGER_IMPOUND_HELP(eImpoundChar, GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(sVehicleData.eModel))
CLONE_VEHICLE_SETUP_STRUCT(sVehicleData, g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][g_savedGlobalsClifford.sVehicleGenData.iImpoundVehicleSlot[i]])
g_savedGlobalsClifford.sVehicleGenData.iImpoundVehicleSlot[i]++
IF g_savedGlobalsClifford.sVehicleGenData.iImpoundVehicleSlot[i] >= get_vehicle_setup_array_size(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i])
g_savedGlobalsClifford.sVehicleGenData.iImpoundVehicleSlot[i]=0
ENDIF
#endif
#if USE_NRM_DLC
IF NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(0, eImpoundChar)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - impound slot 0 is free, setting vehicle into that")
g_savedGlobalsnorman.sVehicleGenData.iImpoundVehicleSlot[i] = 0
ELIF NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(1, eImpoundChar)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - impound slot 1 is free, setting vehicle into that")
g_savedGlobalsnorman.sVehicleGenData.iImpoundVehicleSlot[i] = 1
ELSE
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - both impound slots are full, will overwrite current set")
ENDIF
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - Adding vehicle to impound")
CPRINTLN(DEBUG_AMBIENT,"...ped = ", i)
CPRINTLN(DEBUG_AMBIENT,"...slot = ", g_savedGlobalsnorman.sVehicleGenData.iImpoundVehicleSlot[i])
CPRINTLN(DEBUG_AMBIENT,"...model = ", GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(sVehicleData.eModel))
TRIGGER_IMPOUND_HELP(eImpoundChar, GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(sVehicleData.eModel))
CLONE_VEHICLE_SETUP_STRUCT(sVehicleData, g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][g_savedGlobalsnorman.sVehicleGenData.iImpoundVehicleSlot[i]])
g_savedGlobalsnorman.sVehicleGenData.iImpoundVehicleSlot[i]++
IF g_savedGlobalsnorman.sVehicleGenData.iImpoundVehicleSlot[i] >= get_vehicle_setup_array_size(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i])
g_savedGlobalsnorman.sVehicleGenData.iImpoundVehicleSlot[i]=0
ENDIF
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
IF NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(0, eImpoundChar)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - impound slot 0 is free, setting vehicle into that")
g_savedGlobals.sVehicleGenData.iImpoundVehicleSlot[i] = 0
ELIF NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(1, eImpoundChar)
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - impound slot 1 is free, setting vehicle into that")
g_savedGlobals.sVehicleGenData.iImpoundVehicleSlot[i] = 1
ELSE
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - both impound slots are full, will overwrite current set")
ENDIF
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - Adding vehicle to impound")
CPRINTLN(DEBUG_AMBIENT,"...ped = ", i)
CPRINTLN(DEBUG_AMBIENT,"...slot = ", g_savedGlobals.sVehicleGenData.iImpoundVehicleSlot[i])
CPRINTLN(DEBUG_AMBIENT,"...model = ", GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(sVehicleData.eModel))
TRIGGER_IMPOUND_HELP(eImpoundChar, GET_DISPLAY_NAME_FROM_VEHICLE_MODEL(sVehicleData.eModel))
CLONE_VEHICLE_SETUP_STRUCT(sVehicleData, g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][g_savedGlobals.sVehicleGenData.iImpoundVehicleSlot[i]])
g_savedGlobals.sVehicleGenData.iImpoundVehicleSlot[i]++
IF g_savedGlobals.sVehicleGenData.iImpoundVehicleSlot[i] >= get_vehicle_setup_array_size(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i])
g_savedGlobals.sVehicleGenData.iImpoundVehicleSlot[i]=0
ENDIF
#endif
#endif
// We need to ensure the player switch setup doesn't create this vehicle, otherwise we will end up with duplicate.
// To prevent this, check if the model+plate are the same, if so set a dummy model.
REPEAT NUM_OF_PLAYABLE_PEDS i
IF g_sPlayerLastVeh[i].model = sVehicleData.eModel
AND ARE_STRINGS_EQUAL(g_sPlayerLastVeh[i].tlNumberPlate, sVehicleData.tlPlateText)
g_sPlayerLastVeh[i].model = DUMMY_MODEL_FOR_SCRIPT
CPRINTLN(DEBUG_AMBIENT,"SEND_VEHICLE_DATA_TO_IMPOUND_USING_SETUP - Clearing player switch vehicle model to prevent duplicate vehicles, ped slot = ", i)
ENDIF
ENDREPEAT
RETURN TRUE
ENDFUNC
PROC CLEAR_VEHICLE_IMPOUND_SLOT(INT iSlot)
INT i
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
i = 0
BREAK
CASE CHAR_FRANKLIN
i = 1
BREAK
CASE CHAR_TREVOR
i = 2
BREAK
ENDSWITCH
#if USE_CLF_DLC
IF iSlot < 0
OR iSlot >= get_vehicle_setup_array_size(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i])
EXIT
ENDIF
g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel = DUMMY_MODEL_FOR_SCRIPT
#endif
#if USE_NRM_DLC
IF iSlot < 0
OR iSlot >= get_vehicle_setup_array_size(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i])
EXIT
ENDIF
g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel = DUMMY_MODEL_FOR_SCRIPT
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
IF iSlot < 0
OR iSlot >= get_vehicle_setup_array_size(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i])
EXIT
ENDIF
g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel = DUMMY_MODEL_FOR_SCRIPT
#endif
#endif
ENDPROC
FUNC BOOL CREATE_IMPOUND_VEHICLE(VEHICLE_INDEX &ReturnVeh, INT iSlot, VECTOR vCoords, FLOAT fHeading, BOOL bCleanupModel)
IF NOT IS_VEHICLE_IMPOUND_SLOT_OCCUPIED(iSlot, GET_CURRENT_PLAYER_PED_ENUM())
OR DOES_ENTITY_EXIST(ReturnVeh)
RETURN FALSE
ENDIF
INT i
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
i = 0
BREAK
CASE CHAR_FRANKLIN
i = 1
BREAK
CASE CHAR_TREVOR
i = 2
BREAK
ENDSWITCH
#if USE_CLF_DLC
REQUEST_MODEL(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
IF HAS_MODEL_LOADED(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
CPRINTLN(DEBUG_AMBIENT,GET_THIS_SCRIPT_NAME(), ": CREATE_IMPOUND_VEHICLE() Using data in slot ", iSlot)
ReturnVeh = CREATE_VEHICLE(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel, vCoords, fHeading, FALSE, FALSE)
SET_VEHICLE_SETUP(ReturnVeh, g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][iSlot])
SET_VEHICLE_ON_GROUND_PROPERLY(ReturnVeh)
SET_VEHICLE_NOT_STEALABLE_AMBIENTLY(ReturnVeh, FALSE)
SET_VEHICLE_HAS_STRONG_AXLES(ReturnVeh, TRUE)
IF bCleanupModel
SET_MODEL_AS_NO_LONGER_NEEDED(g_savedGlobalsClifford.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
ENDIF
RETURN TRUE
ENDIF
#endif
#if USE_NRM_DLC
REQUEST_MODEL(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
IF HAS_MODEL_LOADED(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
CPRINTLN(DEBUG_AMBIENT,GET_THIS_SCRIPT_NAME(), ": CREATE_IMPOUND_VEHICLE() Using data in slot ", iSlot)
ReturnVeh = CREATE_VEHICLE(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel, vCoords, fHeading, FALSE, FALSE)
SET_VEHICLE_SETUP(ReturnVeh, g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][iSlot])
SET_VEHICLE_ON_GROUND_PROPERLY(ReturnVeh)
SET_VEHICLE_NOT_STEALABLE_AMBIENTLY(ReturnVeh, FALSE)
SET_VEHICLE_HAS_STRONG_AXLES(ReturnVeh, TRUE)
IF bCleanupModel
SET_MODEL_AS_NO_LONGER_NEEDED(g_savedGlobalsnorman.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
ENDIF
RETURN TRUE
ENDIF
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
REQUEST_MODEL(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
IF HAS_MODEL_LOADED(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
CPRINTLN(DEBUG_AMBIENT,GET_THIS_SCRIPT_NAME(), ": CREATE_IMPOUND_VEHICLE() Using data in slot ", iSlot)
ReturnVeh = CREATE_VEHICLE(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel, vCoords, fHeading, FALSE, FALSE)
SET_VEHICLE_SETUP(ReturnVeh, g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][iSlot])
SET_VEHICLE_ON_GROUND_PROPERLY(ReturnVeh)
SET_VEHICLE_NOT_STEALABLE_AMBIENTLY(ReturnVeh, FALSE)
SET_VEHICLE_HAS_STRONG_AXLES(ReturnVeh, TRUE)
IF bCleanupModel
SET_MODEL_AS_NO_LONGER_NEEDED(g_savedGlobals.sVehicleGenData.sImpoundVehicles[i][iSlot].eModel)
ENDIF
RETURN TRUE
ENDIF
#endif
#endif
RETURN FALSE
ENDFUNC
/// PURPOSE: Ties the vehicle to a vehicle gen so that it remains in place until the player uses it.
/// NOTE: eVehGen should be VEHGEN_MISSION_VEH or VEHGEN_MISSION_VEH_FBI4_PREP
/// vPos = where to set the vehicle as a vehicle gen (if set to <<0.0,0.0,0.0>> it will use the vehicle's current pos and heading
/// fHeading: the heading to use when setting vehicle as a vehicle gen
PROC SET_MISSION_VEHICLE_GEN_VEHICLE(VEHICLE_INDEX vehID, VECTOR vPos, FLOAT fHeading, VEHICLE_GEN_NAME_ENUM eVehGen = VEHGEN_MISSION_VEH, BOOL bAllowBigVehicles = FALSE)
IF DOES_ENTITY_EXIST(vehID)
AND IS_VEHICLE_DRIVEABLE(vehID)
IF eVehGen != VEHGEN_MISSION_VEH
AND eVehGen != VEHGEN_MISSION_VEH_FBI4_PREP
#IF IS_DEBUG_BUILD
PRINTLN("SET_MISSION_VEHICLE_GEN_VEHICLE() - Invalid vehgen specified: ", ENUM_TO_INT(eVehGen))
SCRIPT_ASSERT("SET_MISSION_VEHICLE_GEN_VEHICLE() - Invalid vehgen specified. See Kenneth R.")
#ENDIF
EXIT
ENDIF
// Dont allow the prep vehicle to be set as a mission vehicle gen!
IF eVehGen = VEHGEN_MISSION_VEH
IF DOES_ENTITY_EXIST(g_sVehicleGenNSData.vehicleSelectID[VEHGEN_MISSION_VEH_FBI4_PREP])
AND IS_VEHICLE_DRIVEABLE(g_sVehicleGenNSData.vehicleSelectID[VEHGEN_MISSION_VEH_FBI4_PREP])
IF g_sVehicleGenNSData.vehicleSelectID[VEHGEN_MISSION_VEH_FBI4_PREP] = vehID
PRINTLN("SET_MISSION_VEHICLE_GEN_VEHICLE() - Trying to set the prep vehicle as VEHGEN_MISSION_VEH, lets ignore")
EXIT
ENDIF
ENDIF
ENDIF
// Check if mission vehgen model is suitable
IF NOT bAllowBigVehicles
IF IS_BIG_VEHICLE(vehID)
OR GET_ENTITY_MODEL(vehID) = BUS
OR GET_ENTITY_MODEL(vehID) = TOURBUS
PRINTLN("[VEHGEN_MISSION_VEH] Cannot set new mission vehicle: Vehicle is too big and bAllowBigVehicles is set to FALSE")
EXIT
ENDIF
ENDIF
#IF USE_CLF_DLC
if spy_vehicle_is_this_vehicle_the_spy_vehicle(vehID)
PRINTLN("[VEHGEN_MISSION_VEH] Cannot set new mission vehicle: Vehicle passed in is the SPY VEHICLE")
exit
endif
#endif
// Cleanup any existing vehgen.
CLEANUP_MISSION_VEHICLE_GEN_VEHICLE(eVehGen)
PRINTLN("[VEHGEN_MISSION_VEH] Setting new mission vehicle: SET_MISSION_VEHICLE_GEN_VEHICLE() called by ", GET_THIS_SCRIPT_NAME())
// No hand over the new vehicle.
VEHICLE_SETUP_STRUCT sTempVehStruct
GET_VEHICLE_SETUP(vehID, sTempVehStruct)
IF ARE_VECTORS_EQUAL(vPos, <<0.0,0.0,0.0>>)
vPos =GET_ENTITY_COORDS(vehID)
fHeading =GET_ENTITY_HEADING(vehID)
ENDIf
IF eVehGen = VEHGEN_MISSION_VEH
IF GET_HASH_KEY(GET_THIS_SCRIPT_NAME()) != HASH("vehicle_gen_controller")
g_iLastMissionVehgenOwnerHash = GET_HASH_KEY(GET_THIS_SCRIPT_NAME())
PRINTLN("[VEHGEN_MISSION_VEH] Setting last mission vehgen owner script to ", GET_THIS_SCRIPT_NAME())
ENDIF
ENDIF
UPDATE_DYNAMIC_VEHICLE_GEN_DATA(eVehGen, sTempVehStruct, vPos, fHeading, GET_PLAYER_PED_PERSONAL_VEHICLE_BELONGS_TO(vehID))
SET_VEHICLE_GEN_VEHICLE(eVehGen, vehID, FALSE)
ENDIF
ENDPROC
/// PURPOSE: Returns the default allowable size for checking if a vehicle is an acceptable size.
FUNC VECTOR GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR()
//RETURN <<2.55, 5.59, 2.55>>
// b* 2380876 - bumped the Y-axis size from 5.59 to 5.665 to allow Vapid Chino(luxe2) to be allowed.
RETURN <<2.55, 5.665, 2.55>>
ENDFUNC
/// PURPOSE: Checks to see if the vehicle is in the tracked list of garage vehicles
FUNC BOOL IS_VEHICLE_STORED_VEHGEN_GARAGE_VEHICLE(VEHICLE_INDEX vehID, VEHICLE_GEN_NAME_ENUM &eVehicleGen)
INT iVeh
REPEAT NUMBER_OF_VEHICLES_TO_GEN iVeh
IF g_sVehicleGenNSData.vehicleSelectID[iVeh] = vehID
IF GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], INT_TO_ENUM(VEHICLE_GEN_NAME_ENUM, iVeh))
IF IS_BIT_SET(g_sVehicleGenNSData.sRuntimeStruct[0].flags, ENUM_TO_INT(VEHGEN_NS_FLAG_DYNAMIC_DATA))
AND g_sVehicleGenNSData.sRuntimeStruct[0].model = GET_ENTITY_MODEL(vehID)
eVehicleGen = INT_TO_ENUM(VEHICLE_GEN_NAME_ENUM, iVeh)
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
FUNC BOOL IS_VEHICLE_GEN_AVAILABLE(VEHICLE_GEN_NAME_ENUM eVehicleGen)
RETURN GET_VEHICLE_GEN_SAVED_FLAG_STATE(eVehicleGen, VEHGEN_S_FLAG_AVAILABLE)
ENDFUNC
FUNC VEHICLE_GEN_NAME_ENUM GET_FREE_VEHICLE_GEN_SLOT_IN_GARAGE(VEHICLE_GEN_NAME_ENUM eVehicleGen)
GET_VEHICLE_GEN_DATA(g_sVehicleGenNSData.sRuntimeStruct[0], eVehicleGen)
SWITCH eVehicleGen
CASE VEHGEN_WEB_CAR_MICHAEL
IF g_sVehicleGenNSData.sRuntimeStruct[0].model = DUMMY_MODEL_FOR_SCRIPT RETURN eVehicleGen ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_MICHAEL_GARAGE_1) RETURN VEHGEN_MICHAEL_GARAGE_1 ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_MICHAEL_GARAGE_2) RETURN VEHGEN_MICHAEL_GARAGE_2 ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_MICHAEL_GARAGE_3) RETURN VEHGEN_MICHAEL_GARAGE_3 ENDIF
BREAK
CASE VEHGEN_WEB_CAR_FRANKLIN
IF g_sVehicleGenNSData.sRuntimeStruct[0].model = DUMMY_MODEL_FOR_SCRIPT RETURN eVehicleGen ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_FRANKLIN_GARAGE_1) RETURN VEHGEN_FRANKLIN_GARAGE_1 ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_FRANKLIN_GARAGE_2) RETURN VEHGEN_FRANKLIN_GARAGE_2 ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_FRANKLIN_GARAGE_3) RETURN VEHGEN_FRANKLIN_GARAGE_3 ENDIF
BREAK
CASE VEHGEN_WEB_CAR_TREVOR
IF g_sVehicleGenNSData.sRuntimeStruct[0].model = DUMMY_MODEL_FOR_SCRIPT RETURN eVehicleGen ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_TREVOR_GARAGE_1) RETURN VEHGEN_TREVOR_GARAGE_1 ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_TREVOR_GARAGE_2) RETURN VEHGEN_TREVOR_GARAGE_2 ENDIF
IF NOT IS_VEHICLE_GEN_AVAILABLE(VEHGEN_TREVOR_GARAGE_3) RETURN VEHGEN_TREVOR_GARAGE_3 ENDIF
BREAK
ENDSWITCH
RETURN VEHGEN_NONE
ENDFUNC
FUNC BOOL IS_DLC_VEHICLE_LOCKED_BY_SCRIPT(MODEL_NAMES eModel)
// Fix for bug 2071357 - Don't allow insurgent vehicles in SP.
SWITCH eModel
CASE CASCO
CASE ENDURO
CASE GBURRITO2
CASE GUARDIAN
CASE HYDRA
CASE INSURGENT
CASE INSURGENT2
CASE KURUMA
CASE KURUMA2
CASE LECTRO
CASE SAVAGE
CASE TECHNICAL
// CASE TUG
CASE VALKYRIE
CASE VELUM2
RETURN TRUE
BREAK
ENDSWITCH
// We don't want to add the CGtoNG vehicles to the menu.
INT iModelHash = ENUM_TO_INT(eModel)
SWITCH iModelHash
CASE HASH("DODO")
CASE HASH("DUKES")
CASE HASH("DUKES2")
CASE HASH("DOMINATOR2")
CASE HASH("BUFFALO3")
CASE HASH("GAUNTLET2")
CASE HASH("BUCCANE2")
CASE HASH("BLIMP2")
CASE HASH("STALION")
RETURN TRUE // LOCKED
BREAK
ENDSWITCH
// Fix for 1905170 - Independence vehicles now available by default
/*SWITCH eModel
CASE MONSTER
IF NOT g_sMPTunables.bToggle_activate_Monster_truck
RETURN TRUE // LOCKED
ENDIF
BREAK
CASE SOVEREIGN
IF NOT g_sMPTunables.bToggle_activate_Western_sovereign
RETURN TRUE // LOCKED
ENDIF
BREAK
ENDSWITCH
*/
// Fix for 2152217 - Christmas 2014 DLC - In CG SP, three of the stock racing cars are available for access in the players garage, these vehicles should be GTAO only.
#if IS_NEXTGEN_BUILD
SWITCH eModel
CASE BUFFALO3
CASE DOMINATOR2
CASE GAUNTLET2
CASE STALION2
RETURN TRUE // LOCKED
BREAK
ENDSWITCH
#endif
// Fix for 2152217 - Christmas 2014 DLC - In CG SP, three of the stock racing cars are available for access in the players garage, these vehicles should be GTAO only.
#if IS_NEXTGEN_BUILD
SWITCH eModel
CASE BUFFALO3
CASE DOMINATOR2
CASE GAUNTLET2
CASE STALION2
RETURN TRUE // LOCKED
BREAK
ENDSWITCH
#endif
SWITCH ENUM_TO_INT(eModel)
CASE HASH("GBURRITO3")
CASE HASH("SLAMVAN2")
RETURN TRUE // LOCKED
BREAK
ENDSWITCH
SWITCH eModel
CASE BUCCANEER2
CASE CHINO2
CASE FACTION2
CASE MOONBEAM2
CASE PRIMO2
CASE VOODOO
CASE FACTION
CASE MOONBEAM
RETURN TRUE // Locked
BREAK
CASE BTYPE2
CASE LURCHER
RETURN TRUE // Locked
BREAK
CASE BANSHEE2
CASE SULTANRS
RETURN TRUE // Locked
BREAK
CASE BTYPE3
RETURN TRUE // Locked
BREAK
CASE FACTION3
CASE MINIVAN2
CASE SABREGT2
CASE SLAMVAN3
CASE TORNADO5
CASE VIRGO2
CASE VIRGO3
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE // UNLOCKED
ENDFUNC