1837 lines
58 KiB
Python
Executable File
1837 lines
58 KiB
Python
Executable File
//|=======================================================================================|
|
|
//| Author: Lukasz Bogaj Date: 22/02/2013 |
|
|
//|=======================================================================================|
|
|
//| PM_DEFEND.sc |
|
|
//| PROPERTY MANAGEMENT DEFEND |
|
|
//|=======================================================================================|
|
|
//| Player has to protect a selected property from waves of enemies of various difficulty,|
|
|
//| number and weapons that spawn randomly in the property area. | |
|
|
//|=======================================================================================|
|
|
|
|
//Compile out Title Update changes to header functions.
|
|
//Must be before includes.
|
|
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
|
|
|
|
|
|
//|==================================== INCLUDE FILES ====================================|
|
|
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
USING "brains.sch"
|
|
USING "script_player.sch"
|
|
USING "commands_script.sch"
|
|
USING "properties_public.sch"
|
|
USING "script_blips.sch"
|
|
|
|
//|======================================= CONSTANTS =====================================|
|
|
|
|
CONST_INT MAX_PED_MODELS 3
|
|
CONST_INT MAX_WEAPON_MODELS 3
|
|
CONST_INT MAX_VEHCILE_MODELS 2
|
|
CONST_INT MAX_WANDER_AREAS 3
|
|
CONST_INT MAX_ENEMY_SQUADS 5
|
|
CONST_INT MAX_PEDS_IN_SQUAD 4
|
|
CONST_INT MAX_VEHICLES_IN_SQUAD 3
|
|
CONST_INT MAX_ENEMY_SPAWNPOINTS 6
|
|
CONST_INT MAX_SPAWNPOINTS_RESULTS 3
|
|
CONST_INT MAX_SPAWN_POSITIONS 10
|
|
|
|
CONST_FLOAT MAX_COMBAT_RANGE 300.0
|
|
|
|
//|===================================== END CONSTANTS ===================================|
|
|
|
|
//===================================== ENUMS & STRUCTS ==================================|
|
|
|
|
/// PURPOSE: Main states of property management defend game.
|
|
ENUM DEFEND_GAME_STATES
|
|
DEFEND_GAME_STATE_SETUP = 0,
|
|
DEFEND_GAME_STATE_RUNNING = 1,
|
|
DEFEND_GAME_STATE_END = 2
|
|
ENDENUM
|
|
|
|
ENUM DEFEND_GAME_AREA_SETUP_STATES
|
|
DEFEND_GAME_AREA_SETUP_FAR = 0,
|
|
DEFEND_GAME_AREA_SETUP_MEDIUM = 1,
|
|
DEFEND_GAME_AREA_SETUP_NEAR = 2
|
|
ENDENUM
|
|
|
|
/// PURPOSE: Difficulty levels of property management defend game.
|
|
ENUM DEFEND_GAME_DIFFICULTY
|
|
DEFEND_GAME_EASY = 0,
|
|
DEFEND_GAME_MEDIUM = 1,
|
|
DEFEND_GAME_HARD = 2
|
|
ENDENUM
|
|
|
|
/// PURPOSE: End reasons for property management defend game.
|
|
ENUM DEFEND_GAME_END_REASONS
|
|
DEFEND_GAME_NOT_FINISHED = 0,
|
|
DEFEND_GAME_AREA_DEFENDED = 1,
|
|
DEFEND_GAME_AREA_LEFT = 2
|
|
ENDENUM
|
|
|
|
/// PURPOSE: Enemy gangs in property management defend game.
|
|
ENUM DEFEND_GAME_ENEMY_GANGS
|
|
DEFEND_GAME_ENEMY_GANG_BALLAS = 0,
|
|
DEFEND_GAME_ENEMY_GANG_CULT = 1,
|
|
DEFEND_GAME_ENEMY_GANG_FAMILY = 2,
|
|
DEFEND_GAME_ENEMY_GANG_HILLBILLY = 3,
|
|
DEFEND_GAME_ENEMY_GANG_LOST = 4,
|
|
DEFEND_GAME_ENEMY_GANG_MARABUNTE = 5,
|
|
DEFEND_GAME_ENEMY_GANG_MEXICAN = 6,
|
|
DEFEND_GAME_ENEMY_GANG_SALVA = 7,
|
|
DEFEND_GAME_ENEMY_GANG_WEICHEN = 8
|
|
ENDENUM
|
|
|
|
ENUM SQUAD_TYPES
|
|
SQUAD_TYPE_STATIONARY = 0,
|
|
SQUAD_TYPE_DYNAMIC = 1
|
|
ENDENUM
|
|
|
|
/// PURPOSE:
|
|
ENUM SQUAD_STATES
|
|
SQUAD_STATE_IDLE = 0,
|
|
SQUAD_STATE_CHECKING_SPAWNPOINTS = 1,
|
|
SQUAD_STATE_SPAWNING = 2,
|
|
SQUAD_STATE_ACTIVE = 3,
|
|
SQUAD_STATE_DEAD = 4,
|
|
SQUAD_STATE_RESETTING = 5
|
|
ENDENUM
|
|
|
|
/// PURPOSE:
|
|
ENUM ENEMY_STATES
|
|
ENEMY_STATE_SPAWNING = 0,
|
|
ENEMY_STATE_ENTERING = 1,
|
|
ENEMY_STATE_UNALERTED = 2,
|
|
ENEMY_STATE_COMBAT = 3
|
|
ENDENUM
|
|
|
|
/// PURPOSE: Stores information about current property management defend game
|
|
STRUCT DEFEND_GAME_INFO
|
|
DEFEND_GAME_STATES eGameState
|
|
DEFEND_GAME_END_REASONS eGameEndReason
|
|
DEFEND_GAME_ENEMY_GANGS eEnemyGang
|
|
PROPERTY_ENUM eProperty
|
|
DEFEND_MISSION_VARIATION_ENUM eVariation
|
|
VECTOR vPropertyCenter
|
|
VECTOR vSpawnPositions[MAX_SPAWN_POSITIONS]
|
|
FLOAT fSpawnHeadings[MAX_SPAWN_POSITIONS]
|
|
INT iSpawnPositions
|
|
INT iSetupProgress
|
|
REL_GROUP_HASH RelGroupHash
|
|
MODEL_NAMES PedModels[MAX_PED_MODELS]
|
|
MODEL_NAMES VehicleModels[MAX_VEHCILE_MODELS]
|
|
WEAPON_TYPE WeaponTypes[MAX_WEAPON_MODELS]
|
|
INT iStationaryPeds
|
|
INT iStationaryVehicles
|
|
INT iStationaryPedsSpawned
|
|
INT iStationaryVehiclesSpawned
|
|
INT iSquadIterator
|
|
INT iRequiredKills
|
|
INT iTotalKills
|
|
BOOL bObjectivePrinted
|
|
VECTOR vClearAreaPosition
|
|
FLOAT fClearAreaRadius
|
|
VECTOR vScenarioBlockingAreaPosition
|
|
VECTOR vScenarioBlockingAreaSize
|
|
SCENARIO_BLOCKING_INDEX ScenarioBlockingIndex
|
|
INT iProgress
|
|
BOOL bEnemiesAlerted
|
|
STRING sMusicEventStart
|
|
STRING sMusicEventGunfight
|
|
STRING sMusicEventStop
|
|
STRING sMusicEventFail
|
|
BOOL bMusicEventStartTriggered
|
|
BOOL bMusicEventGunfightTriggered
|
|
ENDSTRUCT
|
|
|
|
STRUCT SPAWN_DATA
|
|
INT iNumOfResults
|
|
FLOAT fSpawnSearchResults[MAX_SPAWNPOINTS_RESULTS]
|
|
VECTOR vSpawnSearchResults[MAX_SPAWNPOINTS_RESULTS]
|
|
ENDSTRUCT
|
|
|
|
STRUCT PED_INFO
|
|
PED_INDEX PedIndex
|
|
AI_BLIP_STRUCT EnemyBlipData
|
|
ENEMY_STATES eEnemyState
|
|
VECTOR vPosition
|
|
FLOAT fHeading
|
|
MODEL_NAMES ModelName
|
|
WEAPON_TYPE WeaponType
|
|
BOOL bHasTask
|
|
INT iTimer
|
|
INT iSquadVehicle = -1
|
|
VEHICLE_SEAT eVehicleSeat
|
|
ENDSTRUCT
|
|
|
|
STRUCT VEHICLE_INFO
|
|
VEHICLE_INDEX VehicleIndex
|
|
VECTOR vPosition
|
|
VECTOR vDestination
|
|
FLOAT fHeading
|
|
MODEL_NAMES ModelName
|
|
ENDSTRUCT
|
|
|
|
STRUCT ENEMY_SQUAD_INFO
|
|
SQUAD_TYPES eType
|
|
SQUAD_STATES eSquadState
|
|
PED_INFO Peds[MAX_PEDS_IN_SQUAD]
|
|
VEHICLE_INFO Vehicles[MAX_VEHICLES_IN_SQUAD]
|
|
INT iNumberOfPeds
|
|
INT iNumberOfVehicles
|
|
INT iPedsSpawned
|
|
INT iVehiclesSpawned
|
|
INT iPedsKilled
|
|
INT iTrigger
|
|
INT iLeader
|
|
VECTOR vSpawnPosition
|
|
FLOAT fSpawnHeading
|
|
ENDSTRUCT
|
|
|
|
STRUCT WANDER_AREA_INFO
|
|
VECTOR vPosition
|
|
FLOAT fRadius
|
|
ENDSTRUCT
|
|
|
|
//=================================== END ENUMS & STRUCTS ================================|
|
|
|
|
//======================================== VARIABLES =====================================|
|
|
|
|
DEFEND_GAME_INFO DefendGameInfo
|
|
SPAWN_DATA SpawnData
|
|
INT iDisableReplayCameraTimer //Fix for bug 2227738
|
|
|
|
//|========================================= ARRAYS ======================================|
|
|
|
|
ENEMY_SQUAD_INFO EnemySquads[MAX_ENEMY_SQUADS]
|
|
WANDER_AREA_INFO WanderAreas[MAX_WANDER_AREAS]
|
|
|
|
//================================== FUNCTIONS & PROCEDURES ==============================|
|
|
|
|
PROC REQUEST_DEFEND_GAME_ASSETS(DEFEND_GAME_INFO GameInfo)
|
|
|
|
INT i
|
|
|
|
REPEAT MAX_PED_MODELS i
|
|
IF ( GameInfo.PedModels[i] <> DUMMY_MODEL_FOR_SCRIPT )
|
|
REQUEST_MODEL(GameInfo.PedModels[i])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
REPEAT MAX_VEHCILE_MODELS i
|
|
IF ( GameInfo.VehicleModels[i] <> DUMMY_MODEL_FOR_SCRIPT )
|
|
REQUEST_MODEL(GameInfo.VehicleModels[i])
|
|
REQUEST_VEHICLE_ASSET(GameInfo.VehicleModels[i])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
REPEAT MAX_WEAPON_MODELS i
|
|
IF ( GameInfo.WeaponTypes[i] <> WEAPONTYPE_INVALID )
|
|
REQUEST_WEAPON_ASSET(GameInfo.WeaponTypes[i])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
REQUEST_ADDITIONAL_TEXT("PMD", MISSION_TEXT_SLOT)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Requesting assets for property management defend game for ",
|
|
GET_PROPERTY_NAME_FOR_DEBUG(GameInfo.eProperty), ".")
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
FUNC BOOL ARE_DEFEND_GAME_ASSETS_LOADED(DEFEND_GAME_INFO GameInfo)
|
|
|
|
IF ( GameInfo.PedModels[0] = DUMMY_MODEL_FOR_SCRIPT OR HAS_MODEL_LOADED(GameInfo.PedModels[0]) )
|
|
AND ( GameInfo.PedModels[1] = DUMMY_MODEL_FOR_SCRIPT OR HAS_MODEL_LOADED(GameInfo.PedModels[1]) )
|
|
AND ( GameInfo.PedModels[2] = DUMMY_MODEL_FOR_SCRIPT OR HAS_MODEL_LOADED(GameInfo.PedModels[2]) )
|
|
AND ( GameInfo.VehicleModels[0] = DUMMY_MODEL_FOR_SCRIPT OR HAS_MODEL_LOADED(GameInfo.VehicleModels[0]) )
|
|
AND ( GameInfo.VehicleModels[1] = DUMMY_MODEL_FOR_SCRIPT OR HAS_MODEL_LOADED(GameInfo.VehicleModels[1]) )
|
|
AND ( GameInfo.VehicleModels[0] = DUMMY_MODEL_FOR_SCRIPT OR HAS_VEHICLE_ASSET_LOADED(GameInfo.VehicleModels[0]) )
|
|
AND ( GameInfo.VehicleModels[1] = DUMMY_MODEL_FOR_SCRIPT OR HAS_VEHICLE_ASSET_LOADED(GameInfo.VehicleModels[1]) )
|
|
AND ( GameInfo.WeaponTypes[0] = WEAPONTYPE_INVALID OR HAS_WEAPON_ASSET_LOADED(GameInfo.WeaponTypes[0]) )
|
|
AND ( GameInfo.WeaponTypes[1] = WEAPONTYPE_INVALID OR HAS_WEAPON_ASSET_LOADED(GameInfo.WeaponTypes[1]) )
|
|
AND ( GameInfo.WeaponTypes[2] = WEAPONTYPE_INVALID OR HAS_WEAPON_ASSET_LOADED(GameInfo.WeaponTypes[2]) )
|
|
AND HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Assets loaded for property management defend game for ",
|
|
GET_PROPERTY_NAME_FOR_DEBUG(GameInfo.eProperty), ".")
|
|
#ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
PROC RELEASE_DEFEND_GAME_ASSETS(DEFEND_GAME_INFO GameInfo)
|
|
|
|
INT i
|
|
|
|
REPEAT MAX_PED_MODELS i
|
|
IF ( GameInfo.PedModels[i] <> DUMMY_MODEL_FOR_SCRIPT )
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(GameInfo.PedModels[i])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
REPEAT MAX_VEHCILE_MODELS i
|
|
IF ( GameInfo.VehicleModels[i] <> DUMMY_MODEL_FOR_SCRIPT )
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(GameInfo.VehicleModels[i])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
REPEAT MAX_WEAPON_MODELS i
|
|
IF ( GameInfo.WeaponTypes[i] <> WEAPONTYPE_INVALID )
|
|
REMOVE_WEAPON_ASSET(GameInfo.WeaponTypes[i])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
PROC CLEANUP_SQUAD_PED(ENEMY_SQUAD_INFO &array[], INT iSquad, INT iPed)
|
|
|
|
IF DOES_ENTITY_EXIST(array[iSquad].Peds[iPed].PedIndex)
|
|
|
|
IF NOT IS_ENTITY_DEAD(array[iSquad].Peds[iPed].PedIndex)
|
|
SET_PED_KEEP_TASK(array[iSquad].Peds[iPed].PedIndex, TRUE)
|
|
ENDIF
|
|
|
|
SET_PED_AS_NO_LONGER_NEEDED(array[iSquad].Peds[iPed].PedIndex)
|
|
|
|
CLEANUP_AI_PED_BLIP(array[iSquad].Peds[iPed].EnemyBlipData)
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC CLEANUP_DEFEND_GAME_PEDS(ENEMY_SQUAD_INFO &array[])
|
|
|
|
INT iSquad
|
|
INT iPed
|
|
|
|
REPEAT MAX_ENEMY_SQUADS iSquad
|
|
REPEAT MAX_PEDS_IN_SQUAD iPed
|
|
CLEANUP_SQUAD_PED(array, iSquad, iPed)
|
|
ENDREPEAT
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
PROC CLEANUP_DEFEND_GAME_VEHICLES(ENEMY_SQUAD_INFO &array[])
|
|
|
|
INT iSquad
|
|
INT iVehicle
|
|
|
|
REPEAT MAX_ENEMY_SQUADS iSquad
|
|
|
|
REPEAT MAX_VEHICLES_IN_SQUAD iVehicle
|
|
|
|
IF DOES_ENTITY_EXIST(array[iSquad].Vehicles[iVehicle].VehicleIndex)
|
|
|
|
SET_VEHICLE_AS_NO_LONGER_NEEDED(array[iSquad].Vehicles[iVehicle].VehicleIndex)
|
|
|
|
ENDIF
|
|
|
|
ENDREPEAT
|
|
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
PROC DEFEND_GAME_CLEANUP(DEFEND_GAME_INFO &GameInfo)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting cleanup property management defend for ", GET_PROPERTY_NAME_FOR_DEBUG(DefendGameInfo.eProperty), ".")
|
|
#ENDIF
|
|
|
|
RELEASE_DEFEND_GAME_ASSETS(GameInfo)
|
|
CLEANUP_DEFEND_GAME_PEDS(EnemySquads)
|
|
CLEANUP_DEFEND_GAME_VEHICLES(EnemySquads)
|
|
|
|
IF ( GameInfo.ScenarioBlockingIndex <> NULL )
|
|
REMOVE_SCENARIO_BLOCKING_AREA(GameInfo.ScenarioBlockingIndex)
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished cleanup property management defend for ", GET_PROPERTY_NAME_FOR_DEBUG(DefendGameInfo.eProperty), ".")
|
|
#ENDIF
|
|
|
|
TERMINATE_THIS_THREAD()
|
|
|
|
ENDPROC
|
|
|
|
PROC DEFEND_GAME_PASSED()
|
|
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(DefendGameInfo.sMusicEventStop)
|
|
TRIGGER_MUSIC_EVENT(DefendGameInfo.sMusicEventStop)
|
|
ENDIF
|
|
|
|
SET_PROPERTY_MANAGEMENT_RESULT(PROPERTY_MANAGEMENT_RESULT_SUCCESS)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Property management defend for property ",
|
|
GET_PROPERTY_NAME_FOR_DEBUG(DefendGameInfo.eProperty), " passed.")
|
|
#ENDIF
|
|
DEFEND_GAME_CLEANUP(DefendGameInfo)
|
|
ENDPROC
|
|
|
|
PROC DEFEND_GAME_FAILED()
|
|
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(DefendGameInfo.sMusicEventFail)
|
|
TRIGGER_MUSIC_EVENT(DefendGameInfo.sMusicEventFail)
|
|
ENDIF
|
|
|
|
SET_PROPERTY_MANAGEMENT_RESULT(PROPERTY_MANAGEMENT_RESULT_FAILURE)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Property management defend for property ",
|
|
GET_PROPERTY_NAME_FOR_DEBUG(DefendGameInfo.eProperty), " failed.")
|
|
#ENDIF
|
|
DEFEND_GAME_CLEANUP(DefendGameInfo)
|
|
ENDPROC
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
DEBUGONLY PROC RUN_DEBUG_PASS_AND_FAIL_CHECK()
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)
|
|
DEFEND_GAME_PASSED()
|
|
ENDIF
|
|
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
|
|
DEFEND_GAME_FAILED()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
DEBUGONLY FUNC STRING GET_ENEMY_STATE_NAME_FOR_DEBUG(ENEMY_STATES eEnemyState)
|
|
|
|
SWITCH eEnemyState
|
|
CASE ENEMY_STATE_SPAWNING
|
|
RETURN "ENEMY_STATE_SPAWNING"
|
|
BREAK
|
|
CASE ENEMY_STATE_ENTERING
|
|
RETURN "ENEMY_STATE_ENTERING"
|
|
BREAK
|
|
CASE ENEMY_STATE_UNALERTED
|
|
RETURN "ENEMY_STATE_UNALERTED"
|
|
BREAK
|
|
CASE ENEMY_STATE_COMBAT
|
|
RETURN "ENEMY_STATE_COMBAT"
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN "INVALID_ENEMY_STATE"
|
|
|
|
ENDFUNC
|
|
|
|
DEBUGONLY PROC DRAW_SPAWNPOINTS(DEFEND_GAME_INFO GameInfo)
|
|
|
|
INT i
|
|
|
|
REPEAT GameInfo.iSpawnPositions i
|
|
|
|
DRAW_DEBUG_SPHERE(GameInfo.vSpawnPositions[i], 0.25, 255, 0, 0, 255)
|
|
DRAW_DEBUG_TEXT_ABOVE_COORDS(GameInfo.vSpawnPositions[i], GET_STRING_FROM_INT(i), 0.3)
|
|
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
DEBUGONLY PROC DRAW_SQUAD_PEDS_DEBUG_INFO(ENEMY_SQUAD_INFO &array[])
|
|
|
|
INT iPed
|
|
INT iSquad
|
|
|
|
REPEAT MAX_ENEMY_SQUADS iSquad
|
|
REPEAT MAX_PEDS_IN_SQUAD iPed
|
|
DRAW_DEBUG_TEXT_ABOVE_ENTITY(array[iSquad].Peds[iPed].PedIndex, GET_ENEMY_STATE_NAME_FOR_DEBUG(array[iSquad].Peds[iPed].eEnemyState), 1.2)
|
|
DRAW_DEBUG_TEXT_ABOVE_ENTITY(array[iSquad].Peds[iPed].PedIndex, GET_STRING_FROM_INT(iSquad), 1.0)
|
|
DRAW_DEBUG_TEXT_ABOVE_ENTITY(array[iSquad].Peds[iPed].PedIndex, GET_STRING_FROM_INT(iPed), 0.8)
|
|
ENDREPEAT
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
#ENDIF
|
|
|
|
PROC GET_DEFEND_GAME_PED_AND_VEHCILE_NUMBERS(DEFEND_GAME_INFO &GameInfo)
|
|
|
|
INT i
|
|
|
|
REPEAT MAX_ENEMY_SQUADS i
|
|
IF ( EnemySquads[i].eType = SQUAD_TYPE_STATIONARY )
|
|
GameInfo.iStationaryPeds += EnemySquads[i].iNumberOfPeds
|
|
GameInfo.iStationaryVehicles += EnemySquads[i].iNumberOfVehicles
|
|
ENDIF
|
|
GameInfo.iRequiredKills += EnemySquads[i].iNumberOfPeds
|
|
ENDREPEAT
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": ********************** PROPERTY MANAGEMENT DEFEND GAME NUMBERS ************************")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Required kills : ", GameInfo.iRequiredKills, ".")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Stationary peds : ", GameInfo.iStationaryPeds, ".")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Stationary vehicles : ", GameInfo.iStationaryVehicles, ".")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": ***************************************************************************************")
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC GET_DEFEND_GAME_MUSIC_EVENTS(DEFEND_GAME_INFO &GameInfo)
|
|
|
|
SWITCH GameInfo.eProperty
|
|
|
|
/*
|
|
CASE PROPERTY_PLANE_SCRAP_YARD
|
|
|
|
SWITCH GameInfo.eVariation
|
|
|
|
CASE DEFEND_MISSION_VARIATION_1
|
|
|
|
GameInfo.sMusicEventStart = "PM_PV1_START"
|
|
GameInfo.sMusicEventGunfight = "PM_PV1_GF"
|
|
GameInfo.sMusicEventStop = "PM_PV1_STOP"
|
|
GameInfo.sMusicEventFail = "PM_PV1_FAIL"
|
|
|
|
GameInfo.bMusicEventStartTriggered = FALSE
|
|
GameInfo.bMusicEventGunfightTriggered = FALSE
|
|
|
|
BREAK
|
|
|
|
CASE DEFEND_MISSION_VARIATION_2
|
|
|
|
GameInfo.sMusicEventStart = "PM_PV2_START"
|
|
GameInfo.sMusicEventGunfight = "PM_PV2_GF"
|
|
GameInfo.sMusicEventStop = "PM_PV2_STOP"
|
|
GameInfo.sMusicEventFail = "PM_PV2_FAIL"
|
|
|
|
GameInfo.bMusicEventStartTriggered = FALSE
|
|
GameInfo.bMusicEventGunfightTriggered = FALSE
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
*/
|
|
|
|
CASE PROPERTY_CAR_SCRAP_YARD
|
|
|
|
SWITCH GameInfo.eVariation
|
|
|
|
CASE DEFEND_MISSION_VARIATION_1
|
|
|
|
GameInfo.sMusicEventStart = "PM_CV1_START"
|
|
GameInfo.sMusicEventGunfight = "PM_CV1_GF"
|
|
GameInfo.sMusicEventStop = "PM_CV1_STOP"
|
|
GameInfo.sMusicEventFail = "PM_CV1_FAIL"
|
|
|
|
GameInfo.bMusicEventStartTriggered = FALSE
|
|
GameInfo.bMusicEventGunfightTriggered = FALSE
|
|
|
|
BREAK
|
|
|
|
CASE DEFEND_MISSION_VARIATION_2
|
|
|
|
GameInfo.sMusicEventStart = "PM_CV2_START"
|
|
GameInfo.sMusicEventGunfight = "PM_CV2_GF"
|
|
GameInfo.sMusicEventStop = "PM_CV2_STOP"
|
|
GameInfo.sMusicEventFail = "PM_CV2_FAIL"
|
|
|
|
GameInfo.bMusicEventStartTriggered = FALSE
|
|
GameInfo.bMusicEventGunfightTriggered = FALSE
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
PROC GET_DEFEND_GAME_INFO(DEFEND_GAME_INFO &GameInfo, PROPERTY_ENUM eProperty)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting property management defend game setup for ", GET_PROPERTY_NAME_FOR_DEBUG(eProperty), ".")
|
|
#ENDIF
|
|
|
|
SWITCH eProperty
|
|
|
|
/*
|
|
CASE PROPERTY_PLANE_SCRAP_YARD
|
|
|
|
GameInfo.eProperty = PROPERTY_PLANE_SCRAP_YARD
|
|
GameInfo.eVariation = GET_CURRENT_DEFEND_VARIATION()
|
|
GameInfo.vPropertyCenter = << 2381.66, 3093.17, 47.15 >>
|
|
GameInfo.eEnemyGang = DEFEND_GAME_ENEMY_GANG_LOST
|
|
GameInfo.PedModels[0] = G_M_Y_LOST_01
|
|
GameInfo.PedModels[1] = DUMMY_MODEL_FOR_SCRIPT
|
|
GameInfo.PedModels[2] = DUMMY_MODEL_FOR_SCRIPT
|
|
GameInfo.VehicleModels[0] = GBURRITO
|
|
GameInfo.VehicleModels[1] = HEXER
|
|
GameInfo.WeaponTypes[0] = WEAPONTYPE_PISTOL
|
|
GameInfo.WeaponTypes[1] = WEAPONTYPE_SAWNOFFSHOTGUN
|
|
GameInfo.WeaponTypes[2] = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
GameInfo.vClearAreaPosition = << 2381.66, 3093.17, 47.15 >>
|
|
GameInfo.fClearAreaRadius = 90.0
|
|
GameInfo.vScenarioBlockingAreaPosition = << 2381.66, 3093.17, 47.15 >>
|
|
GameInfo.vScenarioBlockingAreaSize = << 54.0, 68.0, 8.0>>
|
|
|
|
//block PLANE_WRECK scenario group
|
|
//allow PLANE_WRECK_DOG scenario group
|
|
|
|
GameInfo.iSpawnPositions = 10
|
|
GameInfo.vSpawnPositions[0] = <<2449.2949, 3090.4990, 46.2809>>
|
|
GameInfo.fSpawnHeadings[0] = 40.0873
|
|
GameInfo.vSpawnPositions[1] = <<2370.8997, 3140.7888, 47.2704>>
|
|
GameInfo.fSpawnHeadings[1] = 242.9508
|
|
GameInfo.vSpawnPositions[2] = << 2456.50, 3109.05, 47.24 >>
|
|
GameInfo.fSpawnHeadings[2] = 82.5337
|
|
GameInfo.vSpawnPositions[3] = <<2366.9919, 3100.9253, 46.8814>>
|
|
GameInfo.fSpawnHeadings[3] = 306.3424
|
|
GameInfo.vSpawnPositions[4] = <<2380.0427, 3142.1187, 46.6913>>
|
|
GameInfo.fSpawnHeadings[4] = 194.1393
|
|
GameInfo.vSpawnPositions[5] = <<2456.9529, 3125.1848, 47.8240>>
|
|
GameInfo.fSpawnHeadings[5] = 129.3712
|
|
GameInfo.vSpawnPositions[6] = <<2352.4404, 3099.1150, 46.9404>>
|
|
GameInfo.fSpawnHeadings[6] = 296.6261
|
|
GameInfo.vSpawnPositions[7] = <<2459.4766, 3119.7717, 47.5936>>
|
|
GameInfo.fSpawnHeadings[7] = 119.7956
|
|
GameInfo.vSpawnPositions[8] = <<2351.6853, 3090.1433, 47.0721>>
|
|
GameInfo.fSpawnHeadings[8] = 305.9977
|
|
GameInfo.vSpawnPositions[9] = << 2450.97, 3097.95, 46.66 >>
|
|
GameInfo.fSpawnHeadings[9] = 55.7607
|
|
|
|
//squads
|
|
EnemySquads[0].eType = SQUAD_TYPE_STATIONARY
|
|
EnemySquads[0].iNumberOfPeds = 4
|
|
EnemySquads[0].iNumberOfVehicles = 2
|
|
|
|
EnemySquads[0].Vehicles[0].vPosition = <<2395.8093, 3117.3870, 47.2097>>
|
|
EnemySquads[0].Vehicles[0].fHeading = 3.4938
|
|
EnemySquads[0].Vehicles[0].ModelName = GBURRITO
|
|
|
|
EnemySquads[0].Vehicles[1].vPosition = <<2377.4355, 3068.1887, 47.1528>>
|
|
EnemySquads[0].Vehicles[1].fHeading = 32.7103
|
|
EnemySquads[0].Vehicles[1].ModelName = GBURRITO
|
|
|
|
EnemySquads[0].Peds[0].vPosition = <<2398.2551, 3118.2932, 47.1679>>
|
|
EnemySquads[0].Peds[0].fHeading = 217.7723
|
|
|
|
EnemySquads[0].Peds[1].vPosition = <<2398.1587, 3115.3931, 47.1539>>
|
|
EnemySquads[0].Peds[1].fHeading = 301.8444
|
|
|
|
EnemySquads[0].Peds[2].vPosition = <<2425.1733, 3099.2117, 51.4251>>
|
|
EnemySquads[0].Peds[2].fHeading = 67.0656
|
|
EnemySquads[0].Peds[2].WeaponType = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
EnemySquads[0].Peds[3].vPosition = <<2376.8198, 3065.0352, 47.1527>>
|
|
EnemySquads[0].Peds[3].fHeading = 73.5416
|
|
|
|
|
|
EnemySquads[1].eType = SQUAD_TYPE_STATIONARY
|
|
EnemySquads[1].iNumberOfPeds = 4
|
|
EnemySquads[1].iNumberOfVehicles = 0
|
|
|
|
EnemySquads[1].Peds[0].vPosition = <<2429.7893, 3122.4861, 47.2321>>
|
|
EnemySquads[1].Peds[0].fHeading = 41.3063
|
|
|
|
EnemySquads[1].Peds[1].vPosition = <<2431.0244, 3123.6172, 47.2349>>
|
|
EnemySquads[1].Peds[1].fHeading = 66.287
|
|
|
|
EnemySquads[1].Peds[2].vPosition = <<2426.9817, 3121.6086, 47.2215>>
|
|
EnemySquads[1].Peds[2].fHeading = 343.8260
|
|
|
|
EnemySquads[1].Peds[3].vPosition = <<2404.0938, 3137.2078, 47.1533>>
|
|
EnemySquads[1].Peds[3].fHeading = 293.2100
|
|
|
|
EnemySquads[2].eType = SQUAD_TYPE_DYNAMIC
|
|
EnemySquads[2].iNumberOfPeds = 4
|
|
EnemySquads[2].iNumberOfVehicles = 1
|
|
EnemySquads[2].iTrigger = 6
|
|
|
|
EnemySquads[2].Vehicles[0].ModelName = HEXER
|
|
EnemySquads[2].Vehicles[0].vDestination = << 2403.79, 3107.63, 47.16 >>
|
|
|
|
EnemySquads[2].Peds[0].iSquadVehicle = 0
|
|
EnemySquads[2].Peds[0].eVehicleSeat = VS_DRIVER
|
|
EnemySquads[2].Peds[0].WeaponType = WEAPONTYPE_SAWNOFFSHOTGUN
|
|
|
|
EnemySquads[2].Peds[1].iSquadVehicle = 0
|
|
EnemySquads[2].Peds[1].eVehicleSeat = VS_FRONT_RIGHT
|
|
EnemySquads[2].Peds[1].WeaponType = WEAPONTYPE_PISTOL
|
|
|
|
EnemySquads[3].eType = SQUAD_TYPE_DYNAMIC
|
|
EnemySquads[3].iNumberOfPeds = 4
|
|
EnemySquads[3].iNumberOfVehicles = 0
|
|
EnemySquads[3].iTrigger = 10
|
|
|
|
EnemySquads[4].eType = SQUAD_TYPE_DYNAMIC
|
|
EnemySquads[4].iNumberOfPeds = 4
|
|
EnemySquads[4].iNumberOfVehicles = 1
|
|
EnemySquads[4].iTrigger = 14
|
|
|
|
EnemySquads[4].Vehicles[0].ModelName = GBURRITO
|
|
|
|
EnemySquads[4].Peds[0].iSquadVehicle = 0
|
|
EnemySquads[4].Peds[0].eVehicleSeat = VS_DRIVER
|
|
EnemySquads[4].Peds[0].WeaponType = WEAPONTYPE_PISTOL
|
|
|
|
EnemySquads[4].Peds[1].iSquadVehicle = 0
|
|
EnemySquads[4].Peds[1].eVehicleSeat = VS_FRONT_RIGHT
|
|
EnemySquads[4].Peds[1].WeaponType = WEAPONTYPE_PISTOL
|
|
|
|
EnemySquads[4].Peds[2].iSquadVehicle = 0
|
|
EnemySquads[4].Peds[2].eVehicleSeat = VS_BACK_LEFT
|
|
EnemySquads[4].Peds[2].WeaponType = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
EnemySquads[4].Peds[3].iSquadVehicle = 0
|
|
EnemySquads[4].Peds[3].eVehicleSeat = VS_BACK_RIGHT
|
|
EnemySquads[4].Peds[3].WeaponType = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
WanderAreas[0].vPosition = << 2424.82, 3153.86, 47.19 >>
|
|
WanderAreas[0].fRadius = 15.0
|
|
|
|
WanderAreas[1].vPosition = << 2432.83, 3112.63, 47.15 >>
|
|
WanderAreas[1].fRadius = 25.0
|
|
|
|
WanderAreas[2].vPosition = << 2365.88, 3057.55, 47.15 >>
|
|
WanderAreas[2].fRadius = 25.0
|
|
|
|
BREAK
|
|
*/
|
|
|
|
CASE PROPERTY_CAR_SCRAP_YARD
|
|
|
|
GameInfo.eProperty = PROPERTY_CAR_SCRAP_YARD
|
|
GameInfo.eVariation = GET_CURRENT_DEFEND_VARIATION()
|
|
GameInfo.vPropertyCenter = << 1533.77, -2135.35, 82.04 >>
|
|
GameInfo.eEnemyGang = DEFEND_GAME_ENEMY_GANG_LOST
|
|
GameInfo.PedModels[0] = G_M_Y_LOST_01
|
|
GameInfo.PedModels[1] = DUMMY_MODEL_FOR_SCRIPT
|
|
GameInfo.PedModels[2] = DUMMY_MODEL_FOR_SCRIPT
|
|
GameInfo.VehicleModels[0] = GBURRITO
|
|
GameInfo.VehicleModels[1] = HEXER
|
|
GameInfo.WeaponTypes[0] = WEAPONTYPE_PISTOL
|
|
GameInfo.WeaponTypes[1] = WEAPONTYPE_SAWNOFFSHOTGUN
|
|
GameInfo.WeaponTypes[2] = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
GameInfo.vClearAreaPosition = << 1533.77, -2135.35, 82.04 >>
|
|
GameInfo.fClearAreaRadius = 90.0
|
|
GameInfo.vScenarioBlockingAreaPosition = << 1533.77, -2135.35, 82.04 >>
|
|
GameInfo.vScenarioBlockingAreaSize = << 54.0, 72.0, 8.0>>
|
|
|
|
GameInfo.iSpawnPositions = 9
|
|
GameInfo.vSpawnPositions[0] = <<1578.1343, -2317.8584, 86.6360>>
|
|
GameInfo.fSpawnHeadings[0] = 36.2503
|
|
GameInfo.vSpawnPositions[1] = <<1571.4139, -2314.3787, 86.0904>>
|
|
GameInfo.fSpawnHeadings[1] = 37.4325
|
|
GameInfo.vSpawnPositions[2] = <<1555.6738, -2321.8572, 85.2531>>
|
|
GameInfo.fSpawnHeadings[2] = 2.4637
|
|
GameInfo.vSpawnPositions[3] = <<1516.6940, -1980.2734, 70.1538>>
|
|
GameInfo.fSpawnHeadings[3] = 203.6018
|
|
GameInfo.vSpawnPositions[4] = <<1505.0770, -1978.4091, 69.7940>>
|
|
GameInfo.fSpawnHeadings[4] = 217.0733
|
|
GameInfo.vSpawnPositions[5] = <<1498.1658, -1981.4690, 69.5705>>
|
|
GameInfo.fSpawnHeadings[5] = 256.7048
|
|
GameInfo.vSpawnPositions[6] = <<1670.8583, -2022.8442, 99.5899>>
|
|
GameInfo.fSpawnHeadings[6] = 142.5751
|
|
GameInfo.vSpawnPositions[7] = <<1677.0851, -2035.7852, 98.5593>>
|
|
GameInfo.fSpawnHeadings[7] = 109.2985
|
|
|
|
GameInfo.vSpawnPositions[8] = <<1659.1873, -2090.0271, 99.2239>>
|
|
GameInfo.fSpawnHeadings[8] = 9.0974
|
|
|
|
|
|
//squads
|
|
EnemySquads[0].eType = SQUAD_TYPE_STATIONARY
|
|
EnemySquads[0].iNumberOfPeds = 4
|
|
EnemySquads[0].iNumberOfVehicles = 2
|
|
|
|
EnemySquads[0].Vehicles[0].vPosition = <<1533.3752, -2087.2095, 76.0832>>
|
|
EnemySquads[0].Vehicles[0].fHeading = 152.9678
|
|
EnemySquads[0].Vehicles[0].ModelName = GBURRITO
|
|
|
|
EnemySquads[0].Vehicles[1].vPosition = <<1547.8243, -2091.3652, 76.1018>>
|
|
EnemySquads[0].Vehicles[1].fHeading = 55.5566
|
|
EnemySquads[0].Vehicles[1].ModelName = GBURRITO
|
|
|
|
EnemySquads[0].Peds[0].vPosition = <<1525.7605, -2092.8384, 76.0174>>
|
|
EnemySquads[0].Peds[0].fHeading = 232.9176
|
|
|
|
EnemySquads[0].Peds[1].vPosition = <<1527.1383, -2091.8323, 76.0310>>
|
|
EnemySquads[0].Peds[1].fHeading = 190.6337
|
|
|
|
EnemySquads[0].Peds[2].vPosition = <<1523.1084, -2115.1338, 75.6351>>
|
|
EnemySquads[0].Peds[2].fHeading = 350.4627
|
|
|
|
EnemySquads[0].Peds[3].vPosition = <<1522.6289, -2112.7676, 75.6853>>
|
|
EnemySquads[0].Peds[3].fHeading = 264.9478
|
|
|
|
EnemySquads[1].eType = SQUAD_TYPE_DYNAMIC
|
|
EnemySquads[1].iNumberOfPeds = 4
|
|
EnemySquads[1].iNumberOfVehicles = 1
|
|
EnemySquads[1].iTrigger = 2
|
|
|
|
EnemySquads[1].Vehicles[0].ModelName = GBURRITO
|
|
|
|
EnemySquads[1].Peds[0].iSquadVehicle = 0
|
|
EnemySquads[1].Peds[0].eVehicleSeat = VS_DRIVER
|
|
EnemySquads[1].Peds[0].WeaponType = WEAPONTYPE_PISTOL
|
|
|
|
EnemySquads[1].Peds[1].iSquadVehicle = 0
|
|
EnemySquads[1].Peds[1].eVehicleSeat = VS_FRONT_RIGHT
|
|
EnemySquads[1].Peds[1].WeaponType = WEAPONTYPE_PISTOL
|
|
|
|
EnemySquads[1].Peds[2].iSquadVehicle = 0
|
|
EnemySquads[1].Peds[2].eVehicleSeat = VS_BACK_LEFT
|
|
EnemySquads[1].Peds[2].WeaponType = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
EnemySquads[1].Peds[3].iSquadVehicle = 0
|
|
EnemySquads[1].Peds[3].eVehicleSeat = VS_BACK_RIGHT
|
|
EnemySquads[1].Peds[3].WeaponType = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
EnemySquads[2].eType = SQUAD_TYPE_DYNAMIC
|
|
EnemySquads[2].iNumberOfPeds = 4
|
|
EnemySquads[2].iNumberOfVehicles = 1
|
|
EnemySquads[2].iTrigger = 3
|
|
|
|
EnemySquads[2].Vehicles[0].ModelName = GBURRITO
|
|
|
|
EnemySquads[2].Peds[0].iSquadVehicle = 0
|
|
EnemySquads[2].Peds[0].eVehicleSeat = VS_DRIVER
|
|
EnemySquads[2].Peds[0].WeaponType = WEAPONTYPE_PISTOL
|
|
|
|
EnemySquads[2].Peds[1].iSquadVehicle = 0
|
|
EnemySquads[2].Peds[1].eVehicleSeat = VS_FRONT_RIGHT
|
|
EnemySquads[2].Peds[1].WeaponType = WEAPONTYPE_PISTOL
|
|
|
|
EnemySquads[2].Peds[2].iSquadVehicle = 0
|
|
EnemySquads[2].Peds[2].eVehicleSeat = VS_BACK_LEFT
|
|
EnemySquads[2].Peds[2].WeaponType = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
EnemySquads[2].Peds[3].iSquadVehicle = 0
|
|
EnemySquads[2].Peds[3].eVehicleSeat = VS_BACK_RIGHT
|
|
EnemySquads[2].Peds[3].WeaponType = WEAPONTYPE_ASSAULTRIFLE
|
|
|
|
BREAK
|
|
|
|
|
|
DEFAULT
|
|
|
|
GameInfo.eEnemyGang = DEFEND_GAME_ENEMY_GANG_MEXICAN
|
|
GameInfo.PedModels[0] = G_M_Y_MEXGOON_01
|
|
GameInfo.PedModels[1] = G_M_Y_MEXGOON_02
|
|
GameInfo.PedModels[2] = G_M_Y_MEXGOON_03
|
|
GameInfo.WeaponTypes[0] = WEAPONTYPE_PISTOL
|
|
GameInfo.WeaponTypes[1] = WEAPONTYPE_MICROSMG
|
|
GameInfo.WeaponTypes[2] = WEAPONTYPE_ASSAULTRIFLE
|
|
GameInfo.iRequiredKills = 10
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
GET_DEFEND_GAME_MUSIC_EVENTS(GameInfo)
|
|
GET_DEFEND_GAME_PED_AND_VEHCILE_NUMBERS(GameInfo)
|
|
|
|
ENDPROC
|
|
|
|
FUNC VEHICLE_INDEX CREATE_SQUAD_VEHICLE(ENEMY_SQUAD_INFO &array[], INT iSquadIndex, INT iVehicleIndex)
|
|
|
|
VEHICLE_INDEX VehicleIndex
|
|
|
|
VehicleIndex = CREATE_VEHICLE(array[iSquadIndex].Vehicles[iVehicleIndex].ModelName,
|
|
array[iSquadIndex].Vehicles[iVehicleIndex].vPosition,
|
|
array[iSquadIndex].Vehicles[iVehicleIndex].fHeading)
|
|
|
|
SET_VEHICLE_INFLUENCES_WANTED_LEVEL(VehicleIndex, FALSE)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created squad ", iSquadIndex, " vehicle ", iVehicleIndex, " with model ",
|
|
GET_MODEL_NAME_FOR_DEBUG(GET_ENTITY_MODEL(VehicleIndex)), " at coordinates ",
|
|
array[iSquadIndex].Vehicles[iVehicleIndex].vPosition, ".")
|
|
#ENDIF
|
|
|
|
RETURN VehicleIndex
|
|
|
|
ENDFUNC
|
|
|
|
FUNC PED_INDEX CREATE_SQUAD_PED(ENEMY_SQUAD_INFO &array[], INT iSquad, INT iPed)
|
|
|
|
PED_INDEX PedIndex
|
|
|
|
PedIndex = CREATE_PED(PEDTYPE_MISSION, DefendGameInfo.PedModels[0],
|
|
array[iSquad].Peds[iPed].vPosition,
|
|
array[iSquad].Peds[iPed].fHeading)
|
|
|
|
SET_PED_DIES_WHEN_INJURED(PedIndex, TRUE)
|
|
|
|
SET_PED_AS_ENEMY(PedIndex, TRUE)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(PedIndex, DefendGameInfo.RelGroupHash)
|
|
|
|
SET_ENTITY_IS_TARGET_PRIORITY(PedIndex, TRUE)
|
|
|
|
SET_PED_COMBAT_ATTRIBUTES(PedIndex, CA_ALWAYS_FIGHT, TRUE)
|
|
SET_PED_TARGET_LOSS_RESPONSE(PedIndex, TLR_NEVER_LOSE_TARGET)
|
|
|
|
SET_PED_CONFIG_FLAG(PedIndex, PCF_DontInfluenceWantedLevel, TRUE)
|
|
SET_PED_CONFIG_FLAG(PedIndex, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
|
|
|
|
SET_COMBAT_FLOAT(PedIndex, CCF_TIME_TO_INVALIDATE_INJURED_TARGET, 30.0)
|
|
|
|
|
|
//set the enemy ped accuracy low in general for now
|
|
|
|
SET_PED_ACCURACY(PedIndex, 5)
|
|
|
|
IF (array[iSquad].Peds[iPed].iSquadVehicle <> -1)
|
|
AND (array[iSquad].Peds[iPed].eVehicleSeat <> VS_ANY_PASSENGER)
|
|
|
|
INT i
|
|
|
|
i = array[iSquad].Peds[iPed].iSquadVehicle
|
|
|
|
IF DOES_ENTITY_EXIST(array[iSquad].Vehicles[i].VehicleIndex)
|
|
IF NOT IS_ENTITY_DEAD(array[iSquad].Vehicles[i].VehicleIndex)
|
|
SET_PED_INTO_VEHICLE(PedIndex, array[iSquad].Vehicles[i].VehicleIndex, array[iSquad].Peds[iPed].eVehicleSeat)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created squad ", iSquad, " ped ", iPed, " with model ",
|
|
GET_MODEL_NAME_FOR_DEBUG(GET_ENTITY_MODEL(PedIndex)), " at coordinates ",
|
|
array[iSquad].Peds[iPed].vPosition, ".")
|
|
#ENDIF
|
|
|
|
iDisableReplayCameraTimer = GET_GAME_TIMER() + 1000 //Fix for bug 2227738
|
|
|
|
RETURN PedIndex
|
|
|
|
ENDFUNC
|
|
|
|
PROC GIVE_WEAPON_TO_ENEMY_PED(PED_INDEX PedIndex, DEFEND_GAME_INFO GameInfo, WEAPON_TYPE OverrideWeapon = WEAPONTYPE_INVALID)
|
|
|
|
IF DOES_ENTITY_EXIST(PedIndex)
|
|
IF NOT IS_ENTITY_DEAD(PedIndex)
|
|
|
|
WEAPON_TYPE eWeapon
|
|
|
|
eWeapon = GameInfo.WeaponTypes[GET_RANDOM_INT_IN_RANGE(0, 3)]
|
|
|
|
IF ( OverrideWeapon <> WEAPONTYPE_INVALID )
|
|
eWeapon = OverrideWeapon
|
|
ENDIF
|
|
|
|
GIVE_WEAPON_TO_PED(PedIndex, eWeapon, INFINITE_AMMO, TRUE)
|
|
SET_CURRENT_PED_WEAPON(PedIndex, eWeapon, TRUE)
|
|
SET_PED_INFINITE_AMMO(PedIndex, TRUE, eWeapon)
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC UPDATE_SQUAD_PED_BLIP(ENEMY_SQUAD_INFO &array[], INT iSquad, INT iPed, BOOL bPlayerDetected)
|
|
UPDATE_AI_PED_BLIP(array[iSquad].Peds[iPed].PedIndex, array[iSquad].Peds[iPed].EnemyBlipData, -1, NULL, NOT bPlayerDetected, FALSE, MAX_COMBAT_RANGE)
|
|
ENDPROC
|
|
|
|
//=========================== ENEMY SPAWNING FUNCTIONS & PROCEDURES ======================|
|
|
|
|
FUNC BOOL IS_POSITION_SAFE_FOR_ENTITY_CREATION(VECTOR vPosition, FLOAT fVehicleRadius = 6.0, FLOAT fPedRadius = 1.0, FLOAT fObjectRadius = 1.0,
|
|
FLOAT fViewRadius = 5.0, BOOL bCheckPlayerSight = TRUE, FLOAT fVisibleDistance = 120.0,
|
|
BOOL bCheckFires = TRUE, FLOAT fPlayerRadius = 25.0)
|
|
|
|
IF IS_VECTOR_ZERO(vPosition)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_POSITION_SAFE_FOR_ENTITY_CREATION() - FALSE - The position is a zero vector.")
|
|
#ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF ( fVehicleRadius > 0 )
|
|
IF IS_ANY_VEHICLE_NEAR_POINT(vPosition, fVehicleRadius)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_POSITION_SAFE_FOR_ENTITY_CREATION() - FALSE - A vehicle is near position ", vPosition, ".")
|
|
#ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ( fPedRadius > 0 )
|
|
IF IS_ANY_PED_NEAR_POINT(<< vPosition.x, vPosition.y, vPosition.z + 1.0 >>, fPedRadius)
|
|
OR IS_ANY_PED_NEAR_POINT(vPosition, fPedRadius)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_POSITION_SAFE_FOR_ENTITY_CREATION() - FALSE - A ped is near position ", vPosition, ".")
|
|
#ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ( fObjectRadius > 0 )
|
|
IF IS_ANY_OBJECT_NEAR_POINT(vPosition, fObjectRadius)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_POSITION_SAFE_FOR_ENTITY_CREATION() - FALSE - An object is near position ", vPosition, ".")
|
|
#ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ( bCheckFires = TRUE )
|
|
IF GET_NUMBER_OF_FIRES_IN_RANGE(vPosition, 1.5) > 0
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_POSITION_SAFE_FOR_ENTITY_CREATION() - FALSE - A fires is near position ", vPosition, ".")
|
|
#ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ( bCheckPlayerSight = TRUE )
|
|
IF ( fViewRadius > 0 )
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPosition) <= fVisibleDistance + fViewRadius
|
|
IF IS_SPHERE_VISIBLE(vPosition, fViewRadius)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_POSITION_SAFE_FOR_ENTITY_CREATION() - FALSE - The player can see position ", vPosition, ".")
|
|
#ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ( fPlayerRadius > 0 )
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPosition) < fPlayerRadius
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": IS_POSITION_SAFE_FOR_ENTITY_CREATION() - FALSE - The player is near position ", vPosition, ".")
|
|
#ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CAN_GET_SPAWNPOINT_FOR_ENTITY_CREATION(VECTOR vCentrePosition, FLOAT fRadius, VECTOR &vReturnPosition, FLOAT &fReturnHeading)
|
|
|
|
IF NOT SPAWNPOINTS_IS_SEARCH_ACTIVE()
|
|
|
|
SPAWNPOINTS_START_SEARCH(vCentrePosition, fRadius, 5.0, SPAWNPOINTS_FLAG_MAY_SPAWN_IN_EXTERIOR, 2.0)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Starting spawnpoint search in position ", vCentrePosition, " and radius ", fRadius, ".")
|
|
#ENDIF
|
|
|
|
ELSE
|
|
|
|
IF SPAWNPOINTS_IS_SEARCH_COMPLETE()
|
|
|
|
INT k
|
|
|
|
SpawnData.iNumOfResults = 0
|
|
|
|
REPEAT MAX_SPAWNPOINTS_RESULTS k
|
|
SpawnData.fSpawnSearchResults[k] = 0.0
|
|
SpawnData.vSpawnSearchResults[k] = << 0.0, 0.0, 0.0 >>
|
|
ENDREPEAT
|
|
|
|
SpawnData.iNumOfResults = SPAWNPOINTS_GET_NUM_SEARCH_RESULTS()
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Spawnpoint search completed in position ", vCentrePosition, " and radius ", fRadius, " with ", SpawnData.iNumOfResults, " results.")
|
|
#ENDIF
|
|
|
|
IF ( SpawnData.iNumOfResults > 0 )
|
|
|
|
INT i
|
|
|
|
REPEAT SpawnData.iNumOfResults i
|
|
|
|
IF ( i < MAX_SPAWNPOINTS_RESULTS )
|
|
|
|
SPAWNPOINTS_GET_SEARCH_RESULT(i, vReturnPosition.x, vReturnPosition.y, vReturnPosition.z)
|
|
|
|
SpawnData.fSpawnSearchResults[i] = 0.0
|
|
SpawnData.vSpawnSearchResults[i] = vReturnPosition
|
|
|
|
ENDIF
|
|
|
|
|
|
ENDREPEAT
|
|
|
|
fReturnHeading = 0.0
|
|
|
|
SPAWNPOINTS_CANCEL_SEARCH()
|
|
|
|
RETURN TRUE
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CAN_GET_SAFE_POSITION_IN_AREA_FOR_ENTITY_CREATION(VECTOR vCentrePosition, FLOAT fRadius, VECTOR &vReturnPosition,
|
|
FLOAT &fReturnHeading)
|
|
|
|
IF CAN_GET_SPAWNPOINT_FOR_ENTITY_CREATION(vCentrePosition, fRadius, vReturnPosition, fReturnHeading)
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_GET_SAFE_POSITION_IN_AREA_FOR_ENTITY_CREATION() - Returning position ", vReturnPosition, " and heading ", fReturnHeading, ".")
|
|
#ENDIF
|
|
RETURN TRUE
|
|
ELSE
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": CAN_GET_SAFE_POSITION_IN_AREA_FOR_ENTITY_CREATION() - Waiting for safe position and heading in area to spawn.")
|
|
#ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CAN_GET_SAFE_POSITION_FOR_SQUAD_CREATION(VECTOR &vSquadPosition, FLOAT &fSquadHeading #IF IS_DEBUG_BUILD, INT iSquad #ENDIF)
|
|
|
|
INT i
|
|
VECTOR vRandomPosition
|
|
|
|
i = GET_RANDOM_INT_IN_RANGE(0, MAX_SPAWN_POSITIONS)
|
|
vRandomPosition = DefendGameInfo.vSpawnPositions[i]
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Picking random spawn point for squad ", iSquad, " at coords ", vRandomPosition, " and index ", i, ".")
|
|
#ENDIF
|
|
|
|
IF IS_POSITION_SAFE_FOR_ENTITY_CREATION(vRandomPosition)
|
|
|
|
vSquadPosition = vRandomPosition
|
|
fSquadHeading = DefendGameInfo.fSpawnHeadings[i]
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Selecting spawn point for squad ", iSquad, " at coords ", vSquadPosition, " and index ", i, ".")
|
|
#ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
//========================= END ENEMY SPAWNING FUNCTIONS & PROCEDURES ====================|
|
|
|
|
PROC UPDATE_KILL_COUNTER(DEFEND_GAME_INFO &GameInfo)
|
|
|
|
GameInfo.iTotalKills++
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": ********************** PROPERTY MANAGEMENT DEFEND KILL COUNTER ************************")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Total kills : ", GameInfo.iTotalKills, ".")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Remaining kills : ", GameInfo.iRequiredKills - GameInfo.iTotalKills, ".")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": ***************************************************************************************")
|
|
#ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC PRINT_OBJECTIVE()
|
|
|
|
IF ( DefendGameInfo.bObjectivePrinted = FALSE )
|
|
|
|
INT i
|
|
BOOL bPrinted
|
|
|
|
REPEAT MAX_PEDS_IN_SQUAD i
|
|
|
|
IF ( bPrinted = FALSE )
|
|
IF DOES_BLIP_EXIST(EnemySquads[0].Peds[i].EnemyBlipData.BlipID)
|
|
PRINT("PMD_OBJ", DEFAULT_GOD_TEXT_TIME, 1)
|
|
bPrinted = TRUE
|
|
DefendGameInfo.bObjectivePrinted = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDREPEAT
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC HANDLE_MUSIC_EVENTS()
|
|
|
|
IF ( DefendGameInfo.bMusicEventStartTriggered = FALSE )
|
|
IF ( DefendGameInfo.bObjectivePrinted = TRUE )
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(DefendGameInfo.sMusicEventStart)
|
|
IF TRIGGER_MUSIC_EVENT(DefendGameInfo.sMusicEventStart)
|
|
DefendGameInfo.bMusicEventStartTriggered = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ( DefendGameInfo.bMusicEventGunfightTriggered = FALSE )
|
|
IF ( DefendGameInfo.bEnemiesAlerted = TRUE )
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(DefendGameInfo.sMusicEventGunfight)
|
|
IF TRIGGER_MUSIC_EVENT(DefendGameInfo.sMusicEventGunfight)
|
|
DefendGameInfo.bMusicEventGunfightTriggered = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC CLEAR_DEFEND_GAME_AREA(DEFEND_GAME_INFO &GameInfo)
|
|
|
|
IF NOT IS_VECTOR_ZERO(GameInfo.vScenarioBlockingAreaPosition)
|
|
AND NOT IS_VECTOR_ZERO(GameInfo.vScenarioBlockingAreaSize)
|
|
|
|
GameInfo.ScenarioBlockingIndex = ADD_SCENARIO_BLOCKING_AREA(
|
|
<< GameInfo.vScenarioBlockingAreaPosition.x - GameInfo.vScenarioBlockingAreaSize.x,
|
|
GameInfo.vScenarioBlockingAreaPosition.y - GameInfo.vScenarioBlockingAreaSize.y,
|
|
GameInfo.vScenarioBlockingAreaPosition.z - GameInfo.vScenarioBlockingAreaSize.z >>,
|
|
<< GameInfo.vScenarioBlockingAreaPosition.x + GameInfo.vScenarioBlockingAreaSize.x,
|
|
GameInfo.vScenarioBlockingAreaPosition.y + GameInfo.vScenarioBlockingAreaSize.y,
|
|
GameInfo.vScenarioBlockingAreaPosition.z + GameInfo.vScenarioBlockingAreaSize.z >>)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Adding scenario blocking area for property management defend game for ",
|
|
GET_PROPERTY_NAME_FOR_DEBUG(GameInfo.eProperty), ".")
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF NOT IS_VECTOR_ZERO(GameInfo.vClearAreaPosition)
|
|
AND NOT ( GameInfo.fClearAreaRadius <= 0.0 )
|
|
|
|
CLEAR_AREA(GameInfo.vClearAreaPosition, GameInfo.fClearAreaRadius, TRUE)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Calling clear_area() area for property management defend game for ",
|
|
GET_PROPERTY_NAME_FOR_DEBUG(GameInfo.eProperty), ".")
|
|
#ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
//================================ MAIN FUNCTIONS & PROCEDURES ===========================|
|
|
|
|
FUNC BOOL CREATE_STATIONARY_SQUAD_VEHICLES(DEFEND_GAME_INFO &GameInfo)
|
|
|
|
IF ( GameInfo.iStationaryVehiclesSpawned = GameInfo.iStationaryVehicles )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created all stationary vehicles. Created ", GameInfo.iStationaryVehiclesSpawned,
|
|
"/", GameInfo.iStationaryVehicles, " stationary vehicles.")
|
|
#ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ELSE
|
|
|
|
IF ( EnemySquads[GameInfo.iSquadIterator].eType = SQUAD_TYPE_STATIONARY )
|
|
|
|
IF ( EnemySquads[GameInfo.iSquadIterator].iVehiclesSpawned = EnemySquads[GameInfo.iSquadIterator].iNumberOfVehicles )
|
|
|
|
GameInfo.iSquadIterator++
|
|
|
|
ELSE
|
|
|
|
INT i = EnemySquads[GameInfo.iSquadIterator].iVehiclesSpawned
|
|
|
|
IF NOT DOES_ENTITY_EXIST(EnemySquads[GameInfo.iSquadIterator].Vehicles[i].VehicleIndex)
|
|
|
|
EnemySquads[GameInfo.iSquadIterator].Vehicles[i].VehicleIndex = CREATE_SQUAD_VEHICLE(EnemySquads, GameInfo.iSquadIterator, i)
|
|
|
|
EnemySquads[GameInfo.iSquadIterator].iVehiclesSpawned++
|
|
|
|
GameInfo.iStationaryVehiclesSpawned++
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Squad ", GameInfo.iSquadIterator, " has ",
|
|
EnemySquads[GameInfo.iSquadIterator].iVehiclesSpawned, "/",
|
|
EnemySquads[GameInfo.iSquadIterator].iNumberOfVehicles, " vehicles.")
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
GameInfo.iSquadIterator++
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CREATE_STATIONARY_SQUAD_PEDS(DEFEND_GAME_INFO &GameInfo)
|
|
|
|
IF ( GameInfo.iStationaryPedsSpawned = GameInfo.iStationaryPeds )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created all stationary peds. Created ", GameInfo.iStationaryPedsSpawned,
|
|
"/", GameInfo.iStationaryPeds, " stationary peds.")
|
|
#ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ELSE
|
|
|
|
IF ( EnemySquads[GameInfo.iSquadIterator].eType = SQUAD_TYPE_STATIONARY )
|
|
|
|
IF ( EnemySquads[GameInfo.iSquadIterator].iPedsSpawned = EnemySquads[GameInfo.iSquadIterator].iNumberOfPeds )
|
|
|
|
GameInfo.iSquadIterator++
|
|
|
|
ELSE
|
|
|
|
INT i = EnemySquads[GameInfo.iSquadIterator].iPedsSpawned
|
|
|
|
IF NOT DOES_ENTITY_EXIST(EnemySquads[GameInfo.iSquadIterator].Peds[i].PedIndex)
|
|
|
|
EnemySquads[GameInfo.iSquadIterator].Peds[i].PedIndex = CREATE_SQUAD_PED(EnemySquads, GameInfo.iSquadIterator, i)
|
|
|
|
GIVE_WEAPON_TO_ENEMY_PED(EnemySquads[GameInfo.iSquadIterator].Peds[i].PedIndex, DefendGameInfo, EnemySquads[GameInfo.iSquadIterator].Peds[i].WeaponType)
|
|
|
|
EnemySquads[GameInfo.iSquadIterator].Peds[i].eEnemyState = ENEMY_STATE_UNALERTED
|
|
|
|
EnemySquads[GameInfo.iSquadIterator].iPedsSpawned++
|
|
|
|
GameInfo.iStationaryPedsSpawned++
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Squad ", GameInfo.iSquadIterator, " has ",
|
|
EnemySquads[GameInfo.iSquadIterator].iPedsSpawned, "/",
|
|
EnemySquads[GameInfo.iSquadIterator].iNumberOfPeds, " peds.")
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Total of ", GameInfo.iStationaryPedsSpawned, " stationary peds spawned.")
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
GameInfo.iSquadIterator++
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
PROC GIVE_STATIONARY_TASKS()
|
|
|
|
IF DOES_ENTITY_EXIST(EnemySquads[1].Peds[3].PedIndex)
|
|
IF NOT IS_ENTITY_DEAD(EnemySquads[1].Peds[3].PedIndex)
|
|
TASK_WANDER_IN_AREA(EnemySquads[1].Peds[3].PedIndex, WanderAreas[0].vPosition, WanderAreas[0].fRadius)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF DOES_ENTITY_EXIST(EnemySquads[1].Peds[2].PedIndex)
|
|
IF NOT IS_ENTITY_DEAD(EnemySquads[1].Peds[2].PedIndex)
|
|
TASK_WANDER_IN_AREA(EnemySquads[1].Peds[2].PedIndex, WanderAreas[1].vPosition, WanderAreas[1].fRadius)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
IF DOES_ENTITY_EXIST(EnemySquads[0].Peds[3].PedIndex)
|
|
IF NOT IS_ENTITY_DEAD(EnemySquads[0].Peds[3].PedIndex)
|
|
TASK_WANDER_IN_AREA(EnemySquads[0].Peds[3].PedIndex, WanderAreas[2].vPosition, WanderAreas[2].fRadius)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF DOES_ENTITY_EXIST(EnemySquads[0].Peds[2].PedIndex)
|
|
IF NOT IS_ENTITY_DEAD(EnemySquads[0].Peds[2].PedIndex)
|
|
TASK_START_SCENARIO_IN_PLACE(EnemySquads[0].Peds[2].PedIndex, "WORLD_HUMAN_BINOCULARS")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
FUNC BOOL CREATE_DYNAMIC_SQUAD_VEHICLES(ENEMY_SQUAD_INFO &array[], INT iSquad)
|
|
|
|
IF ( array[iSquad].iVehiclesSpawned = array[iSquad].iNumberOfVehicles )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created all squad ", iSquad, " vehicles. Created ", array[iSquad].iVehiclesSpawned,
|
|
"/", array[iSquad].iNumberOfVehicles, " squad vehicles.")
|
|
#ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ELSE
|
|
|
|
INT i = array[iSquad].iVehiclesSpawned
|
|
|
|
IF NOT DOES_ENTITY_EXIST(array[iSquad].Vehicles[i].VehicleIndex)
|
|
|
|
array[iSquad].Vehicles[i].vPosition = array[iSquad].vSpawnPosition
|
|
array[iSquad].Vehicles[i].fHeading = array[iSquad].fSpawnHeading
|
|
|
|
array[iSquad].Vehicles[i].VehicleIndex = CREATE_SQUAD_VEHICLE(array, iSquad, i)
|
|
|
|
array[iSquad].iVehiclesSpawned++
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Squad ", iSquad, " has ", array[iSquad].iVehiclesSpawned, "/",
|
|
array[iSquad].iNumberOfVehicles, " vehicles.")
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CREATE_DYNAMIC_SQUAD_PEDS(ENEMY_SQUAD_INFO &array[], INT iSquad)
|
|
|
|
IF ( array[iSquad].iPedsSpawned = array[iSquad].iNumberOfPeds )
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Created all squad ", iSquad, " peds. Created ", array[iSquad].iPedsSpawned,
|
|
"/", array[iSquad].iNumberOfPeds, " squad peds.")
|
|
#ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
ELSE
|
|
|
|
INT i = array[iSquad].iPedsSpawned
|
|
|
|
IF NOT DOES_ENTITY_EXIST(array[iSquad].Peds[i].PedIndex)
|
|
|
|
array[iSquad].Peds[i].vPosition = array[iSquad].vSpawnPosition
|
|
array[iSquad].Peds[i].fHeading = array[iSquad].fSpawnHeading
|
|
|
|
array[iSquad].Peds[i].PedIndex = CREATE_SQUAD_PED(array, iSquad, i)
|
|
|
|
GIVE_WEAPON_TO_ENEMY_PED(array[iSquad].Peds[i].PedIndex, DefendGameInfo, array[iSquad].Peds[i].WeaponType)
|
|
|
|
array[iSquad].iPedsSpawned++
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Squad ", iSquad, " has ", array[iSquad].iPedsSpawned, "/",
|
|
array[iSquad].iNumberOfPeds, " peds.")
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
PROC GIVE_TASKS_TO_SQUAD(ENEMY_SQUAD_INFO &array[], INT iSquad)
|
|
|
|
INT iPed
|
|
|
|
REPEAT array[iSquad].iNumberOfPeds iPed
|
|
|
|
array[iSquad].Peds[iPed].eEnemyState = ENEMY_STATE_ENTERING
|
|
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
PROC SETUP_DEFEND_GAME()
|
|
|
|
SWITCH DefendGameInfo.iSetupProgress
|
|
|
|
CASE 0
|
|
|
|
GET_DEFEND_GAME_INFO(DefendGameInfo, GET_CURRENT_PROPERTY_MANAGEMENT_PROPERTY())
|
|
|
|
CLEAR_DEFEND_GAME_AREA(DefendGameInfo)
|
|
|
|
DefendGameInfo.iSetupProgress++
|
|
|
|
BREAK
|
|
|
|
CASE 1
|
|
|
|
REQUEST_DEFEND_GAME_ASSETS(DefendGameInfo)
|
|
|
|
DefendGameInfo.iSetupProgress++
|
|
|
|
BREAK
|
|
|
|
CASE 2
|
|
|
|
IF ARE_DEFEND_GAME_ASSETS_LOADED(DefendGameInfo)
|
|
|
|
DefendGameInfo.iSetupProgress++
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE 3
|
|
|
|
IF ADD_RELATIONSHIP_GROUP("PMD_ENEMIES", DefendGameInfo.RelGroupHash)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, RELGROUPHASH_PLAYER, DefendGameInfo.RelGroupHash)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, DefendGameInfo.RelGroupHash, RELGROUPHASH_COP)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE, DefendGameInfo.RelGroupHash, RELGROUPHASH_PLAYER)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, DefendGameInfo.RelGroupHash, DefendGameInfo.RelGroupHash)
|
|
ENDIF
|
|
|
|
DefendGameInfo.eGameState = DEFEND_GAME_STATE_RUNNING
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Finished property management defend game setup for ",
|
|
GET_PROPERTY_NAME_FOR_DEBUG(DefendGameInfo.eProperty), ".")
|
|
#ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
PROC RUN_STATIONARY_SQUADS(ENEMY_SQUAD_INFO &array[])
|
|
|
|
INT iSquad
|
|
INT iPed
|
|
|
|
REPEAT MAX_ENEMY_SQUADS iSquad
|
|
|
|
SWITCH array[iSquad].eType
|
|
|
|
CASE SQUAD_TYPE_STATIONARY //update stationary squads
|
|
|
|
REPEAT MAX_PEDS_IN_SQUAD iPed
|
|
|
|
IF DOES_ENTITY_EXIST(array[iSquad].Peds[iPed].PedIndex)
|
|
IF NOT IS_ENTITY_DEAD(array[iSquad].Peds[iPed].PedIndex)
|
|
|
|
SWITCH array[iSquad].Peds[iPed].eEnemyState
|
|
|
|
CASE ENEMY_STATE_UNALERTED
|
|
|
|
IF IS_PED_IN_COMBAT(array[iSquad].Peds[iPed].PedIndex)
|
|
OR ( DefendGameInfo.bEnemiesAlerted = TRUE )
|
|
|
|
DefendGameInfo.bEnemiesAlerted = TRUE
|
|
array[iSquad].Peds[iPed].bHasTask = FALSE
|
|
array[iSquad].Peds[iPed].eEnemyState = ENEMY_STATE_COMBAT
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE ENEMY_STATE_COMBAT
|
|
|
|
IF ( array[iSquad].Peds[iPed].bHasTask = FALSE )
|
|
TASK_COMBAT_HATED_TARGETS_AROUND_PED(array[iSquad].Peds[iPed].PedIndex, 150.0)
|
|
array[iSquad].Peds[iPed].bHasTask = TRUE
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
UPDATE_SQUAD_PED_BLIP(array, iSquad, iPed, DefendGameInfo.bEnemiesAlerted)
|
|
ELSE
|
|
CLEANUP_SQUAD_PED(array, iSquad, iPed)
|
|
UPDATE_KILL_COUNTER(DefendGameInfo)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDREPEAT
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
PROC RUN_DYNAMIC_SQUADS(ENEMY_SQUAD_INFO &array[])
|
|
|
|
INT iPed
|
|
INT iSquad
|
|
VECTOR vSquadPosition
|
|
FLOAT fSquadHeading
|
|
|
|
REPEAT MAX_ENEMY_SQUADS iSquad
|
|
|
|
SWITCH array[iSquad].eType
|
|
|
|
CASE SQUAD_TYPE_DYNAMIC
|
|
|
|
SWITCH array[iSquad].eSquadState
|
|
|
|
CASE SQUAD_STATE_IDLE
|
|
|
|
IF ( DefendGameInfo.iTotalKills >= array[iSquad].iTrigger )
|
|
|
|
array[iSquad].eSquadState = SQUAD_STATE_CHECKING_SPAWNPOINTS
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
PRINTLN(GET_THIS_SCRIPT_NAME(), ": Triggering dynamic squad ", iSquad, ". Squad trigger count is ",
|
|
array[iSquad].iTrigger, " and total kills are ", DefendGameInfo.iTotalKills, ".")
|
|
#ENDIF
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SQUAD_STATE_CHECKING_SPAWNPOINTS
|
|
|
|
IF CAN_GET_SAFE_POSITION_FOR_SQUAD_CREATION(vSquadPosition, fSquadHeading #IF IS_DEBUG_BUILD, iSquad #ENDIF)
|
|
|
|
array[iSquad].eSquadState = SQUAD_STATE_SPAWNING
|
|
array[iSquad].vSpawnPosition = vSquadPosition
|
|
array[iSquad].fSpawnHeading = fSquadHeading
|
|
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SQUAD_STATE_SPAWNING
|
|
|
|
IF CREATE_DYNAMIC_SQUAD_VEHICLES(array, iSquad)
|
|
IF CREATE_DYNAMIC_SQUAD_PEDS(array, iSquad)
|
|
GIVE_TASKS_TO_SQUAD(array, iSquad)
|
|
array[iSquad].eSquadState = SQUAD_STATE_ACTIVE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SQUAD_STATE_ACTIVE
|
|
|
|
REPEAT MAX_PEDS_IN_SQUAD iPed
|
|
|
|
IF DOES_ENTITY_EXIST(array[iSquad].Peds[iPed].PedIndex)
|
|
IF NOT IS_ENTITY_DEAD(array[iSquad].Peds[iPed].PedIndex)
|
|
|
|
SWITCH array[iSquad].Peds[iPed].eEnemyState
|
|
|
|
CASE ENEMY_STATE_ENTERING
|
|
|
|
IF ( array[iSquad].Peds[iPed].bHasTask = FALSE )
|
|
|
|
SET_PED_COMBAT_RANGE(array[iSquad].Peds[iPed].PedIndex, CR_NEAR)
|
|
SET_PED_COMBAT_MOVEMENT(array[iSquad].Peds[iPed].PedIndex, CM_WILLADVANCE)
|
|
SET_PED_COMBAT_ATTRIBUTES(array[iSquad].Peds[iPed].PedIndex, CA_USE_VEHICLE, IS_PED_IN_ANY_VEHICLE(array[iSquad].Peds[iPed].PedIndex))
|
|
SET_PED_COMBAT_ATTRIBUTES(array[iSquad].Peds[iPed].PedIndex, CA_LEAVE_VEHICLES, NOT IS_PED_IN_ANY_VEHICLE(array[iSquad].Peds[iPed].PedIndex))
|
|
|
|
IF ( array[iSquad].iLeader = iPed )
|
|
SET_COMBAT_FLOAT(array[iSquad].Peds[iPed].PedIndex, CCF_MIN_DISTANCE_TO_TARGET, 10.0)
|
|
SET_PED_COMBAT_ATTRIBUTES(array[iSquad].Peds[iPed].PedIndex, CA_MAINTAIN_MIN_DISTANCE_TO_TARGET, TRUE)
|
|
ENDIF
|
|
|
|
IF ( array[iSquad].iLeader <> iPed )
|
|
SET_PED_DEFENSIVE_SPHERE_ATTACHED_TO_PED(array[iSquad].Peds[iPed].PedIndex, array[iSquad].Peds[array[iSquad].iLeader].PedIndex,
|
|
<< 0.0, 0.0, 0.0 >>, 5.0)
|
|
ENDIF
|
|
|
|
TASK_COMBAT_HATED_TARGETS_AROUND_PED(array[iSquad].Peds[iPed].PedIndex, MAX_COMBAT_RANGE)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(array[iSquad].Peds[iPed].PedIndex, FALSE)
|
|
|
|
array[iSquad].Peds[iPed].iTimer = GET_GAME_TIMER()
|
|
array[iSquad].Peds[iPed].bHasTask = TRUE
|
|
|
|
ENDIF
|
|
|
|
IF ( array[iSquad].iLeader <> iPed )
|
|
IF ( array[iSquad].Peds[iPed].iTimer <> 0 )
|
|
|
|
IF GET_GAME_TIMER() - array[iSquad].Peds[iPed].iTimer > 10000
|
|
array[iSquad].Peds[iPed].bHasTask = FALSE
|
|
array[iSquad].Peds[iPed].eEnemyState = ENEMY_STATE_COMBAT
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF ( array[iSquad].iLeader = iPed )
|
|
IF ( array[iSquad].Peds[iPed].iTimer <> 0 )
|
|
|
|
IF GET_GAME_TIMER() - array[iSquad].Peds[iPed].iTimer > 25000
|
|
OR GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(array[iSquad].Peds[iPed].PedIndex)) < 25.0
|
|
array[iSquad].Peds[iPed].bHasTask = FALSE
|
|
array[iSquad].Peds[iPed].eEnemyState = ENEMY_STATE_COMBAT
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE ENEMY_STATE_COMBAT
|
|
|
|
IF ( array[iSquad].Peds[iPed].bHasTask = FALSE )
|
|
REMOVE_PED_DEFENSIVE_AREA(array[iSquad].Peds[iPed].PedIndex)
|
|
SET_PED_COMBAT_MOVEMENT(array[iSquad].Peds[iPed].PedIndex, CM_WILLADVANCE)
|
|
SET_PED_COMBAT_ATTRIBUTES(array[iSquad].Peds[iPed].PedIndex, CA_USE_VEHICLE, FALSE)
|
|
SET_PED_COMBAT_ATTRIBUTES(array[iSquad].Peds[iPed].PedIndex, CA_LEAVE_VEHICLES, TRUE)
|
|
TASK_COMBAT_HATED_TARGETS_AROUND_PED(array[iSquad].Peds[iPed].PedIndex, MAX_COMBAT_RANGE)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(array[iSquad].Peds[iPed].PedIndex, FALSE)
|
|
array[iSquad].Peds[iPed].bHasTask = TRUE
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
UPDATE_SQUAD_PED_BLIP(array, iSquad, iPed, DefendGameInfo.bEnemiesAlerted)
|
|
ELSE
|
|
CLEANUP_SQUAD_PED(array, iSquad, iPed)
|
|
UPDATE_KILL_COUNTER(DefendGameInfo)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDREPEAT
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDREPEAT
|
|
|
|
ENDPROC
|
|
|
|
PROC RUN_DEFEND_GAME()
|
|
|
|
SWITCH DefendGameInfo.eProperty
|
|
CASE PROPERTY_CAR_SCRAP_YARD
|
|
REQUEST_PATH_NODES_IN_AREA_THIS_FRAME(1435.0, -2385.0, 1690.0, -1885.0)
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
SWITCH DefendGameInfo.iProgress
|
|
|
|
CASE 0
|
|
|
|
IF CREATE_STATIONARY_SQUAD_VEHICLES(DefendGameInfo)
|
|
DefendGameInfo.iSquadIterator = 0
|
|
DefendGameInfo.iProgress++
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE 1
|
|
|
|
IF CREATE_STATIONARY_SQUAD_PEDS(DefendGameInfo)
|
|
//SWITCH DefendGameInfo.eProperty
|
|
// CASE PROPERTY_PLANE_SCRAP_YARD
|
|
// GIVE_STATIONARY_TASKS()
|
|
// BREAK
|
|
//ENDSWITCH
|
|
DefendGameInfo.iSquadIterator = 0
|
|
DefendGameInfo.iProgress++
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE 2
|
|
|
|
PRINT_OBJECTIVE()
|
|
HANDLE_MUSIC_EVENTS()
|
|
RUN_STATIONARY_SQUADS(EnemySquads)
|
|
RUN_DYNAMIC_SQUADS(EnemySquads)
|
|
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
IF ( DefendGameInfo.iTotalKills >= DefendGameInfo.iRequiredKills )
|
|
DefendGameInfo.eGameState = DEFEND_GAME_STATE_END
|
|
DefendGameInfo.eGameEndReason = DEFEND_GAME_AREA_DEFENDED
|
|
ENDIF
|
|
|
|
IF GET_DISTANCE_BETWEEN_COORDS(GET_PROPERTY_PURCHASE_COORDS(DefendGameInfo.eProperty), GET_ENTITY_COORDS(PLAYER_PED_ID())) > 300.0
|
|
DefendGameInfo.eGameState = DEFEND_GAME_STATE_END
|
|
DefendGameInfo.eGameEndReason = DEFEND_GAME_AREA_LEFT
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC END_DEFEND_GAME()
|
|
|
|
SWITCH DefendGameInfo.eGameEndReason
|
|
CASE DEFEND_GAME_AREA_DEFENDED
|
|
DEFEND_GAME_PASSED()
|
|
BREAK
|
|
CASE DEFEND_GAME_AREA_LEFT
|
|
DEFEND_GAME_FAILED()
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
//============================== END MAIN FUNCTIONS & PROCEDURES =========================|
|
|
|
|
//===================================== MAIN SCRIPT LOOP =================================|
|
|
|
|
SCRIPT
|
|
|
|
SET_MISSION_FLAG(TRUE)
|
|
|
|
IF HAS_FORCE_CLEANUP_OCCURRED()
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(DefendGameInfo.sMusicEventFail)
|
|
TRIGGER_MUSIC_EVENT(DefendGameInfo.sMusicEventFail)
|
|
ENDIF
|
|
SET_PROPERTY_MANAGEMENT_RESULT(PROPERTY_MANAGEMENT_RESULT_FAILURE)
|
|
DEFEND_GAME_CLEANUP(DefendGameInfo)
|
|
ENDIF
|
|
|
|
WHILE TRUE
|
|
|
|
IF iDisableReplayCameraTimer > GET_GAME_TIMER()
|
|
REPLAY_DISABLE_CAMERA_MOVEMENT_THIS_FRAME() //Fix for bug 2227738
|
|
ENDIF
|
|
|
|
SWITCH DefendGameInfo.eGameState
|
|
|
|
CASE DEFEND_GAME_STATE_SETUP
|
|
SETUP_DEFEND_GAME()
|
|
BREAK
|
|
|
|
CASE DEFEND_GAME_STATE_RUNNING
|
|
RUN_DEFEND_GAME()
|
|
BREAK
|
|
|
|
CASE DEFEND_GAME_STATE_END
|
|
END_DEFEND_GAME()
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
DRAW_SQUAD_PEDS_DEBUG_INFO(EnemySquads)
|
|
DRAW_SPAWNPOINTS(DefendGameInfo)
|
|
RUN_DEBUG_PASS_AND_FAIL_CHECK()
|
|
#ENDIF
|
|
|
|
WAIT(0)
|
|
|
|
ENDWHILE
|
|
|
|
ENDSCRIPT
|
|
|
|
//=================================== END MAIN SCRIPT LOOP ===============================|
|