Files
2025-09-29 00:52:08 +02:00

251 lines
11 KiB
Python
Executable File

//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
// ******************************************************************************************************************
// ******************************************************************************************************************
//
// MISSION NAME : Maude_PostBailBond.sc
// AUTHOR : Ahron Mason
// DESCRIPTION : Handles cleanup of Bail Bond buddies if player kills bail jumper at the barn
//
// ******************************************************************************************************************
// ******************************************************************************************************************
USING "rage_builtins.sch"
USING "globals.sch"
USING "RC_Helper_Functions.sch"
USING "RC_Threat_Public.sch"
USING "BailBond_common.sch"
//-------------------------------------------------------------------------------------------------------------------------------------------------
// VARIABLES
//-------------------------------------------------------------------------------------------------------------------------------------------------
BAIL_BOND_POST_KILLED_JUMPER_DATA sPostMissionData
VECTOR vVehicleInitialCoords[5]
AI_BLIP_STRUCT enemyBlipsStruct[5]
REL_GROUP_HASH HASH_BAILBOND_TARGET
//-------------------------------------------------------------------------------------------------------------------------------------------------
// FUNCTIONS
//-------------------------------------------------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// Does any necessary cleanup and terminates the script
PROC SCRIPT_CLEANUP()
INT i
CLEAR_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, HASH_BAILBOND_TARGET)
CLEAR_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, HASH_BAILBOND_TARGET, RELGROUPHASH_PLAYER)
FOR i = 0 TO (COUNT_OF(sPostMissionData.pedEnemies) - 1)
CLEANUP_AI_PED_BLIP(enemyBlipsStruct[i])
SAFE_RELEASE_PED(sPostMissionData.pedEnemies[i])
ENDFOR
FOR i = 0 TO (COUNT_OF(sPostMissionData.vehEnemies) - 1)
SAFE_RELEASE_VEHICLE(sPostMissionData.vehEnemies[i])
ENDFOR
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : Terminate thread - Script Cleanup #")
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// check if all entities have been released
/// RETURNS:
/// TRUE if all entities no longer exist
FUNC BOOL HAVE_ALL_ENTITIES_BEEN_RELEASE()
INT i
FOR i = 0 TO (COUNT_OF(sPostMissionData.vehEnemies) - 1)
IF DOES_ENTITY_EXIST(sPostMissionData.vehEnemies[i])
//CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAVE_ALL_ENTITIES_BEEN_RELEASE : return FALSE : sPostMissionData.vehEnemies[", i, "] still exists")
RETURN FALSE
ENDIF
ENDFOR
FOR i = 0 TO (COUNT_OF(sPostMissionData.pedEnemies) - 1)
IF DOES_ENTITY_EXIST(sPostMissionData.pedEnemies[i])
//CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : HAVE_ALL_ENTITIES_BEEN_RELEASE : return FALSE : sPostMissionData.pedEnemies[", i, "] still exists")
RETURN FALSE
ENDIF
ENDFOR
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// check if script should terminate
/// RETURNS:
/// TRUE if script should terminate
FUNC BOOL IS_POST_KILLED_SRIPT_SAFE_TO_RUN()
// on mission - but not the mission bail bond script
IF (GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("bailbond2")) = 0)
IF NOT CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE(MISSION_TYPE_RANDOM_CHAR)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_POST_KILLED_SRIPT_SAFE_TO_RUN() return FALSE : CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE(MISSION_TYPE_RANDOM_CHAR) check")
RETURN FALSE
ENDIF
ENDIF
// script cannot be holding onto assets when a lead in is playing out
IF g_bPlayerLockedInToTrigger = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_POST_KILLED_SRIPT_SAFE_TO_RUN() return FALSE : g_bPlayerLockedInToTrigger check")
RETURN FALSE
ENDIF
// script cannot be holding onto assets when a mocap is playing out
IF IS_CUTSCENE_PLAYING()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_POST_KILLED_SRIPT_SAFE_TO_RUN() return FALSE : IS_CUTSCENE_PLAYING check")
RETURN FALSE
ENDIF
// player went on rampage
IF g_bIsOnRampage
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_POST_KILLED_SRIPT_SAFE_TO_RUN() return FALSE : g_bIsOnRampage check")
RETURN FALSE
ENDIF
// player switched characters
IF (GET_CURRENT_PLAYER_PED_ENUM() != CHAR_TREVOR)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : IS_POST_KILLED_SRIPT_SAFE_TO_RUN() return FALSE : Trevor char check")
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// set the valid entities as mission entities and grab the start coords of the vehicles
PROC INIT_SCRIPT()
INT i
ADD_RELATIONSHIP_GROUP("ENEMIES", HASH_BAILBOND_TARGET)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, HASH_BAILBOND_TARGET)
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, HASH_BAILBOND_TARGET, RELGROUPHASH_PLAYER)
// set vehicles
FOR i = 0 TO (COUNT_OF(sPostMissionData.vehEnemies) - 1)
IF IS_VEHICLE_OK(sPostMissionData.vehEnemies[i])
SET_ENTITY_AS_MISSION_ENTITY(sPostMissionData.vehEnemies[i], TRUE, TRUE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_SCRIPT : sPostMissionData.vehEnemies[", i, "] set as Mission Entity")
vVehicleInitialCoords[i] = GET_ENTITY_COORDS(sPostMissionData.vehEnemies[i], FALSE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_SCRIPT : grabbed vVehicleInitialCoords sPostMissionData.vehEnemies[", i, "] ",
" vVehicleInitialCoords[i] = ", vVehicleInitialCoords[i], " : framecount = ", GET_FRAME_COUNT())
ENDIF
ENDFOR
// set peds
FOR i = 0 TO (COUNT_OF(sPostMissionData.pedEnemies) - 1)
IF IS_PED_UNINJURED(sPostMissionData.pedEnemies[i])
SET_ENTITY_AS_MISSION_ENTITY(sPostMissionData.pedEnemies[i], TRUE, TRUE)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_SCRIPT : sPostMissionData.pedEnemies[", i, "] set as Mission Entity")
// B*1514985 - maintain blips until released
SET_PED_RELATIONSHIP_GROUP_HASH(sPostMissionData.pedEnemies[i], HASH_BAILBOND_TARGET)
UPDATE_AI_PED_BLIP(sPostMissionData.pedEnemies[i], enemyBlipsStruct[i])
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : INIT_SCRIPT : sPostMissionData.pedEnemies[", i, "] set up with AI blip")
ENDIF
ENDFOR
ENDPROC
SCRIPT(BAIL_BOND_POST_KILLED_JUMPER_DATA postMissionData)
//Grab handle to the mission data set by the launcher
sPostMissionData = postMissionData
// Default callbacks
IF HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU)
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : FORCE CLEANUP returned TRUE")
SCRIPT_CLEANUP()
ENDIF
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
INIT_SCRIPT()
ENDIF
VECTOR vPlayerPos
INT iIndex_PedCheckThisFrame = 0
INT iIndex_VehicleCheckThisFrame = 0
INT iReleaseEntityRange = 200 // needs to be far because you can see them from the hill tops
INT iTimer_CheckDelay = GET_GAME_TIMER()
// Loop within here until Maude is safe to cleanup
WHILE (TRUE)
IF NOT IS_POST_KILLED_SRIPT_SAFE_TO_RUN()
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : IS_POST_KILLED_SRIPT_SAFE_TO_RUN CLEANUP returned FALSE")
SCRIPT_CLEANUP()
ENDIF
// don't check every frame
IF (GET_GAME_TIMER() - iTimer_CheckDelay) > 100
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)
// check when to cleanup the ped
IF IS_PED_UNINJURED(sPostMissionData.pedEnemies[iIndex_PedCheckThisFrame])
IF (VDIST2(vPlayerPos, GET_ENTITY_COORDS(sPostMissionData.pedEnemies[iIndex_PedCheckThisFrame], FALSE)) >= (iReleaseEntityRange * iReleaseEntityRange))
AND IS_ENTITY_OCCLUDED(sPostMissionData.pedEnemies[iIndex_PedCheckThisFrame])
CLEANUP_AI_PED_BLIP(enemyBlipsStruct[iIndex_PedCheckThisFrame])
SAFE_RELEASE_PED(sPostMissionData.pedEnemies[iIndex_PedCheckThisFrame])
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : released dist check sPostMissionData.pedEnemies[", iIndex_PedCheckThisFrame, "] : framecount = ", GET_FRAME_COUNT())
ELSE
UPDATE_AI_PED_BLIP(sPostMissionData.pedEnemies[iIndex_PedCheckThisFrame], enemyBlipsStruct[iIndex_PedCheckThisFrame])
ENDIF
ELSE
IF DOES_ENTITY_EXIST(sPostMissionData.pedEnemies[iIndex_PedCheckThisFrame])
SAFE_RELEASE_PED(sPostMissionData.pedEnemies[iIndex_PedCheckThisFrame])
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : released injured sPostMissionData.pedEnemies[", iIndex_PedCheckThisFrame, "] : framecount = ", GET_FRAME_COUNT())
ENDIF
ENDIF
// check when to cleanup the vehicles
IF IS_VEHICLE_OK(sPostMissionData.vehEnemies[iIndex_VehicleCheckThisFrame])
IF (VDIST2(vPlayerPos, vVehicleInitialCoords[iIndex_VehicleCheckThisFrame]) >= (iReleaseEntityRange * iReleaseEntityRange))
IF IS_ENTITY_OCCLUDED(sPostMissionData.vehEnemies[iIndex_VehicleCheckThisFrame])
OR IS_PED_IN_VEHICLE(PLAYER_PED_ID(), sPostMissionData.vehEnemies[iIndex_VehicleCheckThisFrame]) // if player has driven it away release handle
SAFE_RELEASE_VEHICLE(sPostMissionData.vehEnemies[iIndex_VehicleCheckThisFrame])
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : released dist check sPostMissionData.vehEnemies[", iIndex_VehicleCheckThisFrame, "] : framecount = ", GET_FRAME_COUNT())
ENDIF
ENDIF
ELSE
IF DOES_ENTITY_EXIST(sPostMissionData.vehEnemies[iIndex_VehicleCheckThisFrame])
SAFE_RELEASE_VEHICLE(sPostMissionData.vehEnemies[iIndex_VehicleCheckThisFrame])
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : released undriveable sPostMissionData.vehEnemies[", iIndex_VehicleCheckThisFrame, "] : framecount = ", GET_FRAME_COUNT())
ENDIF
ENDIF
iIndex_PedCheckThisFrame++
IF iIndex_PedCheckThisFrame = COUNT_OF(sPostMissionData.pedEnemies)
iIndex_PedCheckThisFrame = 0
ENDIF
iIndex_VehicleCheckThisFrame++
IF iIndex_VehicleCheckThisFrame = COUNT_OF(sPostMissionData.vehEnemies)
iIndex_VehicleCheckThisFrame = 0
ENDIF
// check if all eneities have been released, if so terminate script
IF HAVE_ALL_ENTITIES_BEEN_RELEASE()
CPRINTLN(DEBUG_BAIL_BOND, GET_THIS_SCRIPT_NAME(), " : all entites released -> SCRIPT_CLEANUP")
SCRIPT_CLEANUP()
ENDIF
ENDIF
iTimer_CheckDelay = GET_GAME_TIMER()
ENDIF
WAIT(0)
ENDWHILE
// Script should never reach here. Always terminate with cleanup function.
ENDSCRIPT