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

2622 lines
112 KiB
Python
Executable File

//////////////////////////////////////////////////////////////////////////////////////////
// //
// SCRIPT NAME : building_controller.sc //
// AUTHOR : Kenneth Ross //
// DESCRIPTION : Maintains the current state of all the buildings and doors. //
// This deals with both single and multi-player data. //
// //
//////////////////////////////////////////////////////////////////////////////////////////
USING "rage_builtins.sch"
USING "globals.sch"
USING "script_player.sch"
USING "commands_script.sch"
USING "building_control_public.sch"
USING "code_control_data_gta5.sch"
#IF FEATURE_FREEMODE_ARCADE
USING "mphud_landing_page.sch"
#ENDIF
#IF IS_DEBUG_BUILD
USING "heist_island_loading.sch"
#ENDIF
CONST_INT MAX_FRAMES_TO_PROCESS_DOORS NUMBER_OF_DOORS // 1 a frame for now //90
CONST_INT MAX_FRAMES_TO_PROCESS_BUILDINGS NUMBER_OF_BUILDINGS // 1 a frame for now. //60
ENUM PROCESS_FLAGS_ENUM
RESET_CONTROLLER_WHEN_IN_SP_BIT = 0,
RESET_CONTROLLER_WHEN_IN_MP_BIT,
RESET_CONTROLLER_WHEN_IN_MP_CREATOR_BIT
ENDENUM
INT iProcessFlags
INT iCurrentDoorFrame
INT iCurrentBuildingFrame
INT iFrameAutodoorDistIndex = 0
INT iFrameAutodoorClosestIndex = 0
FLOAT fClosestAutoDoorDist
INT iFrameAutodoorIndex = 0
BOOL bProcessClosestDoor
INT iFrameAutodoorPedIndex = 0
BOOL bToggleDoors
INT iInteriorEnumCount = 0
INT iTriggeredDoorCount
INT iTriggeredDoors[4]
INT iAutoDoordsProcessedThisFrame
ENUM BUILDING_CONTROL_STAGE_ENUM
BC_STAGE_INIT = 0,
BC_STAGE_UPDATE,
BC_STAGE_IDLE
ENDENUM
BUILDING_CONTROL_STAGE_ENUM eStage = BC_STAGE_INIT
BOOL bCleanupPrologueMap
BOOl bPrologueComplete
BUILDING_DATA_STRUCT sTempBuildingData
BOOL bForceBuildingUpdatesOnInit = FALSE
BOOL bInitialHeistIPLsRemoved = FALSE
BOOL bInitialMPDLCIPLsRemoved = FALSE
BOOL bRemoveYachtIPLS = FALSE
BOOl bForceRemoveYachtIPLs = FALSE
CONST_INT PROP_BLOCKER_BITFIELD_FLAG 0
CONST_INT PROP_BLOCKER_BITFIELD_SECRET_DOOR 1
OBJECT_INDEX objPropBlocker[2]
#IF IS_DEBUG_BUILD
INT iWarpToIslandState
BOOL bDisableSelector
BOOL bSetDefaults
BOOL bUseFakeBuildingState, bForceBuildingUpdate
BOOL bUseFakeDoorState, bForceDoorUpdate
INT iBuilding, iDoor
INT iBuildingState, iDoorState
BOOL bWarpToDoor, bWarpToBuilding
INT iTestBuildingStage, iTestBuildingStageActual, iTestBuilding, iTestBuildingActual
INT iTestDoorStage, iTestDoorStageActual, iTestDoor, iTestDoorActual
BOOL bUseTestStates
BOOL bOpenMilitaryBaseGate
BOOL bCloseMilitaryBaseGate
TEXT_WIDGET_ID textID1, textID2
BOOL bLockGateOpen_TRUE
BOOL bLockGateOpen_FALSE
BOOL bLockGateOpen_Snap
#IF FEATURE_FOW_EXPANSION
STRUCT FOW_IN_MP_DATA
BOOL bSetVisibleEnabled
BOOL bSetVisibleDisabled
BOOL bSetRevealEnabled
BOOL bSetRevealDisabled
BOOL bRequestClear
BOOL bRequestReveal
BOOL bSaveDetailsInitialised
BOOL bSave_Enabled
INT iSave_MinX, iSave_MinY, iSave_MaxX, iSave_MaxY, iSave_FillValueForRestOfMap
BOOL bSetSaveDetails
BOOL bGetSaveDetails
BOOL bSetMapOffsetEnabled
BOOL bSetMapOffsetDisabled
FLOAT fMapOffsetX = FOW_MAIN_MAP_OFFSET_X
FLOAT fMapOffsetY = FOW_MAIN_MAP_OFFSET_Y
FLOAT fMapOffsetW = FOW_MAP_WIDTH
FLOAT fMapOffsetH = FOW_MAP_HEIGHT
BOOL bSetMapOffsetDetails
BOOL bCurrentVisibleState
BOOL bCurrentMapOverrideState
ENDSTRUCT
FOW_IN_MP_DATA sFOWInMpData
#ENDIF // FEATURE_FOW_EXPANSION
PROC SETUP_BUILDING_CONTROL_WIDGETS()
START_WIDGET_GROUP("Building Controller")
ADD_BIT_FIELD_WIDGET("Prop Blocker", g_iDisablePropBlockerBitset)
ADD_WIDGET_BOOL("LOCK_AUTOMATIC_DOOR_OPEN(TRUE)", bLockGateOpen_TRUE)
ADD_WIDGET_BOOL("LOCK_AUTOMATIC_DOOR_OPEN(FALSE)", bLockGateOpen_FALSE)
ADD_WIDGET_BOOL("Snap door", bLockGateOpen_Snap)
ADD_WIDGET_BOOL("Use test states", bUseTestStates)
textID1 = ADD_TEXT_WIDGET("Building")
ADD_WIDGET_BOOL("Warp to building", bWarpToBuilding)
ADD_WIDGET_INT_SLIDER("Test building", iTestBuilding, 0, NUMBER_OF_BUILDINGS-1, 1)
ADD_WIDGET_INT_SLIDER("Test building stage", iTestBuildingStage, 0, NUMBER_OF_BUILDING_STATES-1, 1)
ADD_WIDGET_BOOL("Warp to door", bWarpToDoor)
textID2 = ADD_TEXT_WIDGET("Door")
ADD_WIDGET_INT_SLIDER("Test door", iTestDoor, 0, NUMBER_OF_DOORS-1, 1)
ADD_WIDGET_INT_SLIDER("Test door stage", iTestDoorStage, 0, 5, 1)
ADD_WIDGET_BOOL("Set default data", bSetDefaults)
ADD_WIDGET_BOOL("Default MP data set", g_MPBuildingData.bDefaultDataSet)
ADD_WIDGET_BOOL("Default SP data set", g_savedGlobals.sBuildingData.bDefaultDataSet)
ADD_WIDGET_BOOL("disable selector this frmae", bDisableSelector)
ADD_WIDGET_INT_READ_ONLY("MP buildings set", g_iBuildingStatesSetInMP)
ADD_WIDGET_BOOL("Open Military Base",bOpenMilitaryBaseGate)
ADD_WIDGET_BOOL("Close Military Base",bCloseMilitaryBaseGate)
#IF FEATURE_FOW_EXPANSION
START_WIDGET_GROUP("FOW In MP")
ADD_WIDGET_BOOL("Current Visible State", sFOWInMpData.bCurrentVisibleState)
ADD_WIDGET_BOOL("Set Visible Enabled", sFOWInMpData.bSetVisibleEnabled)
ADD_WIDGET_BOOL("Set Visible Disabled", sFOWInMpData.bSetVisibleDisabled)
ADD_WIDGET_BOOL("Set Reveal Enabled", sFOWInMpData.bSetRevealEnabled)
ADD_WIDGET_BOOL("Set Reveal Disabled", sFOWInMpData.bSetRevealDisabled)
ADD_WIDGET_BOOL("Request Clear", sFOWInMpData.bRequestClear)
ADD_WIDGET_BOOL("Request Reveal", sFOWInMpData.bRequestReveal)
START_WIDGET_GROUP("Save Data")
ADD_WIDGET_BOOL("Save Enabled", sFOWInMpData.bSave_Enabled)
ADD_WIDGET_INT_SLIDER("Save Min X", sFOWInMpData.iSave_MinX, -9999, 9999, 1)
ADD_WIDGET_INT_SLIDER("Save Min Y", sFOWInMpData.iSave_MinY, -9999, 9999, 1)
ADD_WIDGET_INT_SLIDER("Save Max X", sFOWInMpData.iSave_MaxX , -9999, 9999, 1)
ADD_WIDGET_INT_SLIDER("Save Max Y", sFOWInMpData.iSave_MaxY, -9999, 9999, 1)
ADD_WIDGET_INT_SLIDER("Save Fill Value", sFOWInMpData.iSave_FillValueForRestOfMap, 0, 255, 1)
ADD_WIDGET_BOOL("Set Save Details", sFOWInMpData.bSetSaveDetails)
ADD_WIDGET_BOOL("Get Save Details", sFOWInMpData.bGetSaveDetails)
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Map Offset")
ADD_WIDGET_BOOL("Current Map Overide State", sFOWInMpData.bCurrentMapOverrideState)
ADD_WIDGET_BOOL("Set Map Offset Enabled", sFOWInMpData.bSetMapOffsetEnabled)
ADD_WIDGET_BOOL("Set Map Offset Disabled", sFOWInMpData.bSetMapOffsetDisabled)
ADD_WIDGET_FLOAT_SLIDER("Map Offset X", sFOWInMpData.fMapOffsetX, -9999.0, 9999.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("Map Offset Y", sFOWInMpData.fMapOffsetY, -9999.0, 9999.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("Map Offset W", sFOWInMpData.fMapOffsetW , -20000.0, 20000.0, 1.0)
ADD_WIDGET_FLOAT_SLIDER("Map Offset H", sFOWInMpData.fMapOffsetH, -20000.0, 20000.0, 1.0)
ADD_WIDGET_BOOL("Set Map Offset Details", sFOWInMpData.bSetMapOffsetDetails)
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
#ENDIF // FEATURE_FOW_EXPANSION
CREATE_PROPERTIES_WIDGETS()
STOP_WIDGET_GROUP()
ENDPROC
PROC MAINTAIN_BUILDING_CONTROL_WIDGETS()
IF bDisableSelector
DISABLE_SELECTOR_THIS_FRAME()
ENDIF
IF bLockGateOpen_TRUE
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_MICHAEL_MANSION_GATE, TRUE, bLockGateOpen_Snap)
bLockGateOpen_TRUE = FALSE
ENDIF
IF bLockGateOpen_FALSE
LOCK_AUTOMATIC_DOOR_OPEN(AUTODOOR_MICHAEL_MANSION_GATE, FALSE, bLockGateOpen_Snap)
bLockGateOpen_FALSE = FALSE
ENDIF
IF bCloseMilitaryBaseGate
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MIL_BASE_GATE_IN, PLAYER_PED_ID())
bCloseMilitaryBaseGate = FALSE
ENDIF
IF bOpenMilitaryBaseGate
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MIL_BASE_GATE_IN, PLAYER_PED_ID())
bOpenMilitaryBaseGate = FALSE
ENDIF
IF bWarpToBuilding
BUILDING_DATA_STRUCT sDebugBuildingData
GET_BUILDING_DATA(sDebugBuildingData, INT_TO_ENUM(BUILDING_NAME_ENUM, iTestBuilding))
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
AND NOT ARE_VECTORS_EQUAL(sDebugBuildingData.coords, <<0,0,0>>)
SET_ENTITY_COORDS(PLAYER_PED_ID(), sDebugBuildingData.coords)
ENDIF
bWarpToBuilding = FALSE
ENDIF
IF bWarpToDoor
DOOR_DATA_STRUCT sDebugDoorData = GET_DOOR_DATA(INT_TO_ENUM(DOOR_NAME_ENUM, iTestDoor))
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
AND NOT ARE_VECTORS_EQUAL(sDebugDoorData.coords, <<0,0,0>>)
SET_ENTITY_COORDS(PLAYER_PED_ID(), sDebugDoorData.coords)
ENDIF
bWarpToDoor = FALSE
ENDIF
IF iTestBuilding != iTestBuildingActual
BUILDING_DATA_STRUCT sDebugBuildingData
GET_BUILDING_DATA(sDebugBuildingData, INT_TO_ENUM(BUILDING_NAME_ENUM, iTestBuilding))
SET_CONTENTS_OF_TEXT_WIDGET(textID1, sDebugBuildingData.dbg_name)
iTestBuildingActual = iTestBuilding
ENDIF
IF iTestDoor != iTestDoorActual
DOOR_DATA_STRUCT sDebugDoorData = GET_DOOR_DATA(INT_TO_ENUM(DOOR_NAME_ENUM, iTestDoor))
SET_CONTENTS_OF_TEXT_WIDGET(textID2, sDebugDoorData.dbg_name)
iTestDoorActual = iTestDoor
ENDIF
IF bUseTestStates
IF iTestBuildingStageActual != iTestBuildingStage
CPRINTLN(DEBUG_BUILDING, "Setting test building state to ", iTestBuildingStage)
SET_BUILDING_STATE(INT_TO_ENUM(BUILDING_NAME_ENUM, iTestBuilding), INT_TO_ENUM(BUILDING_STATE_ENUM, iTestBuildingStage), FALSE, TRUE)
iTestBuildingStageActual = iTestBuildingStage
ENDIF
IF iTestDoorStageActual != iTestDoorStage
CPRINTLN(DEBUG_BUILDING, "Setting test door state to ", iTestDoorStage)
SET_DOOR_STATE(INT_TO_ENUM(DOOR_NAME_ENUM, iTestDoor), INT_TO_ENUM(DOOR_STATE_ENUM, iTestDoorStage))
iTestDoorStageActual = iTestDoorStage
ENDIF
ENDIF
IF bSetDefaults
SETUP_DEFAULT_BUILDING_DATA()
g_bResetBuildingController = TRUE
bSetDefaults = FALSE
ENDIF
IF bUseFakeBuildingState OR bForceBuildingUpdate
BUILDING_NAME_ENUM eBuilding = INT_TO_ENUM(BUILDING_NAME_ENUM, iBuilding)
IF g_eCurrentBuildingState[eBuilding] <> INT_TO_ENUM(BUILDING_STATE_ENUM, iBuildingState) OR bForceBuildingUpdate
SET_BUILDING_STATE(eBuilding, INT_TO_ENUM(BUILDING_STATE_ENUM, iBuildingState), FALSE, TRUE)
ENDIF
bForceBuildingUpdate = FALSE
ENDIF
IF bUseFakeDoorState OR bForceDoorUpdate
DOOR_NAME_ENUM eDoor = INT_TO_ENUM(DOOR_NAME_ENUM, iDoor)
IF g_eCurrentDoorState[eDoor] <> INT_TO_ENUM(DOOR_STATE_ENUM, iDoorState)
OR INT_TO_ENUM(DOOR_STATE_ENUM, iDoorState) = DOORSTATE_FORCE_CLOSED_THIS_FRAME
OR INT_TO_ENUM(DOOR_STATE_ENUM, iDoorState) = DOORSTATE_FORCE_LOCKED_THIS_FRAME
OR INT_TO_ENUM(DOOR_STATE_ENUM, iDoorState) = DOORSTATE_FORCE_OPEN_THIS_FRAME
OR INT_TO_ENUM(DOOR_STATE_ENUM, iDoorState) = DOORSTATE_FORCE_UNLOCKED_THIS_FRAME
OR bForceDoorUpdate
SET_DOOR_STATE(eDoor, INT_TO_ENUM(DOOR_STATE_ENUM, iDoorState))
ENDIF
bForceDoorUpdate = FALSE
ENDIF
#IF FEATURE_FOW_EXPANSION
sFOWInMpData.bCurrentVisibleState = GET_MINIMAP_ALLOW_FOW_IN_MP()
sFOWInMpData.bCurrentMapOverrideState = ARE_MINIMAP_FOW_CUSTOM_WORLD_EXTENTS_ENABLED()
IF sFOWInMpData.bSetVisibleEnabled
SET_MINIMAP_ALLOW_FOW_IN_MP(TRUE)
sFOWInMpData.bSetVisibleEnabled = FALSE
ENDIF
IF sFOWInMpData.bSetVisibleDisabled
SET_MINIMAP_ALLOW_FOW_IN_MP(FALSE)
sFOWInMpData.bSetVisibleDisabled = FALSE
ENDIF
IF sFOWInMpData.bSetRevealEnabled
SET_MINIMAP_FOW_DO_NOT_UPDATE(FALSE)
sFOWInMpData.bSetRevealEnabled = FALSE
ENDIF
IF sFOWInMpData.bSetRevealDisabled
SET_MINIMAP_FOW_DO_NOT_UPDATE(TRUE)
sFOWInMpData.bSetRevealDisabled = FALSE
ENDIF
IF sFOWInMpData.bSetSaveDetails
SET_MINIMAP_FOW_MP_SAVE_DETAILS(sFOWInMpData.bSave_Enabled, sFOWInMpData.iSave_MinX, sFOWInMpData.iSave_MinY, sFOWInMpData.iSave_MaxX, sFOWInMpData.iSave_MaxY, sFOWInMpData.iSave_FillValueForRestOfMap)
sFOWInMpData.bSetSaveDetails = FALSE
ENDIF
IF sFOWInMpData.bGetSaveDetails
sFOWInMpData.bSave_Enabled = GET_MINIMAP_FOW_MP_SAVE_DETAILS(sFOWInMpData.iSave_MinX, sFOWInMpData.iSave_MinY, sFOWInMpData.iSave_MaxX, sFOWInMpData.iSave_MaxY, sFOWInMpData.iSave_FillValueForRestOfMap)
sFOWInMpData.bGetSaveDetails = FALSE
ENDIF
IF sFOWInMpData.bRequestReveal
SET_MINIMAP_REQUEST_REVEAL_FOW(TRUE)
sFOWInMpData.bRequestReveal = FALSE
ENDIF
IF sFOWInMpData.bRequestClear
SET_MINIMAP_REQUEST_CLEAR_FOW(TRUE)
sFOWInMpData.bRequestClear = FALSE
ENDIF
IF sFOWInMpData.bSetMapOffsetEnabled
ENABLE_MINIMAP_FOW_CUSTOM_WORLD_EXTENTS(TRUE)
sFOWInMpData.bSetMapOffsetEnabled = FALSE
ENDIF
IF sFOWInMpData.bSetMapOffsetDisabled
ENABLE_MINIMAP_FOW_CUSTOM_WORLD_EXTENTS(FALSE)
sFOWInMpData.bSetMapOffsetDisabled = FALSE
ENDIF
IF sFOWInMpData.bSetMapOffsetDetails
SET_MINIMAP_FOW_CUSTOM_WORLD_POS_AND_SIZE(sFOWInMpData.fMapOffsetX, sFOWInMpData.fMapOffsetY, sFOWInMpData.fMapOffsetW, sFOWInMpData.fMapOffsetH)
sFOWInMpData.bSetMapOffsetDetails = FALSE
ENDIF
#ENDIF // FEATURE_FOW_EXPANSION
ENDPROC
PROC MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT()
SWITCH iWarpToIslandState
CASE 0
IF GET_COMMANDLINE_PARAM_EXISTS("sc_LoadIslandOnBoot")
PRINTLN("MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT - sc_LoadIslandOnBoot command line present, execute content changeset...")
EXECUTE_CONTENT_CHANGESET(HASH("mpHeist4"), HASH("GROUP_MAP"), HASH("MPHEIST4_MAP_UPDATE"))
iWarpToIslandState++
ELSE
iWarpToIslandState = 99
ENDIF
BREAK
CASE 1
PRINTLN("MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT - loading island ipls...")
IF HEIST_ISLAND_LOADING__LOAD_ISLAND_IPLS()
PRINTLN("MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT - load complete")
iWarpToIslandState++
ENDIF
BREAK
CASE 2
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
PRINTLN("MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT - starting load scene.")
NEW_LOAD_SCENE_START_SPHERE(<<4425.4897, -4486.4077, 3.2277>>, 50)
ENDIF
PRINTLN("MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT - moving player to island...")
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
OR IS_NEW_LOAD_SCENE_LOADED()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<4425.4897, -4486.4077, 3.2277>>)
SET_ENTITY_HEADING(PLAYER_PED_ID(), 220.7071)
ENDIF
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
ENDIF
iWarpToIslandState++
ENDIF
BREAK
CASE 3
PRINTLN("MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT - complete.")
iWarpToIslandState = 99
BREAK
CASE 99
BREAK
ENDSWITCH
ENDPROC
#ENDIF
PROC ADD_ALL_DOORS_TO_SYSTEM()
INT i
REPEAT NUMBER_OF_DOORS i
DOOR_DATA_STRUCT doorData
doorData = GET_DOOR_DATA(INT_TO_ENUM(DOOR_NAME_ENUM, i))
IF NOT IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(doorData.doorHash))
ADD_DOOR_TO_SYSTEM(ENUM_TO_INT(doorData.doorHash),doorData.model, doorData.coords, FALSE, FALSE)
ENDIF
ENDREPEAT
g_bDoorSystemInitialised = TRUE
ENDPROC
PROC REMOVE_ALL_DOORS_FROM_SYSTEM()
INT i
IF g_bDoorSystemInitialised
REPEAT NUMBER_OF_DOORS i
DOOR_DATA_STRUCT doorData
doorData = GET_DOOR_DATA(INT_TO_ENUM(DOOR_NAME_ENUM, i))
IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(doorData.doorHash))
REMOVE_DOOR_FROM_SYSTEM(ENUM_TO_INT(doorData.doorHash))
ENDIF
ENDREPEAT
i=0
REPEAT AUTODOOR_MAX i
IF IS_DOOR_REGISTERED_WITH_SYSTEM(g_sAutoDoorData[i].doorID)
REMOVE_DOOR_FROM_SYSTEM(g_sAutoDoorData[i].doorID)
ENDIF
ENDREPEAT
CPRINTLN(DEBUG_BUILDING, "REMOVE_ALL_DOORS_FROM_SYSTEM - Called.")
ENDIF
g_bDoorSystemInitialised = FALSE
ENDPROC
#IF IS_DEBUG_BUILD
PROC OUTPUT_CONTROLLER_RESET_DEBUG(INT iCall)
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(GET_FM_MISSION_CONTROLLER_SCRIPT_NAME_HASH()) > 0
PRINTLN("building_controller: Controller resetting when FMMC is running!")
PRINTLN("...iCall = ", iCall)
PRINTLN("...GET_CURRENT_GAMEMODE() = ", GET_CURRENT_GAMEMODE())
PRINTLN("...")
PRINTLN("...g_bResetBuildingController = ", g_bResetBuildingController)
PRINTLN("...g_savedGlobals.sBuildingData.bDefaultDataSet = ", g_savedGlobals.sBuildingData.bDefaultDataSet)
PRINTLN("...g_MPBuildingData.bDefaultDataSet = ", g_MPBuildingData.bDefaultDataSet)
PRINTLN("...")
PRINTLN("...IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_SP_BIT)) = ", IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_SP_BIT)))
PRINTLN("...IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_BIT)) = ", IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_BIT)))
PRINTLN("...IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_CREATOR_BIT)) = ", IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_CREATOR_BIT)))
PRINTLN("...")
PRINTLN("...NETWORK_IS_GAME_IN_PROGRESS() = ", NETWORK_IS_GAME_IN_PROGRESS())
PRINTLN("...IS_TRANSITION_SESSION_LAUNCHING() = ", IS_TRANSITION_SESSION_LAUNCHING())
PRINTLN("...IS_TRANSITION_SESSION_KILLING_SESSION() = ", IS_TRANSITION_SESSION_KILLING_SESSION())
ENDIF
ENDPROC
#ENDIF
/// PURPOSE: Checks to see if the building controller should be re-initialised
PROC CHECK_CONTROLLER_RESET()
// Jump back to the initialisation stage if we have switched game modes
IF USE_SP_BUILDING_CONTROLLER_DATA()
IF NOT g_savedGlobals.sBuildingData.bDefaultDataSet
OR IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_SP_BIT))
OR NETWORK_IS_GAME_IN_PROGRESS()
OR g_bResetBuildingController
if !g_b_MPMapIsLoaded // Only do building controller initialise once the sp map is being used.
IF IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_SP_BIT))
or g_bResetBuildingController //Force update of states too if forcing reset of controller
bForceBuildingUpdatesOnInit = TRUE
ENDIF
eStage = BC_STAGE_INIT
#IF IS_DEBUG_BUILD
OUTPUT_CONTROLLER_RESET_DEBUG(0)
#ENDIF
endif
ENDIF
ELSE
IF NOT g_MPBuildingData.bDefaultDataSet
OR IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_BIT))
OR (NOT NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_TRANSITION_SESSION_LAUNCHING() AND NOT IS_TRANSITION_SESSION_KILLING_SESSION())
OR g_bResetBuildingController
IF GET_CURRENT_GAMEMODE() = GAMEMODE_CREATOR
IF IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_CREATOR_BIT))
eStage = BC_STAGE_INIT
#IF IS_DEBUG_BUILD
OUTPUT_CONTROLLER_RESET_DEBUG(1)
#ENDIF
ENDIF
ELSE
eStage = BC_STAGE_INIT
#IF IS_DEBUG_BUILD
OUTPUT_CONTROLLER_RESET_DEBUG(2)
#ENDIF
ENDIF
IF IS_BIT_SET(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_BIT))
bForceBuildingUpdatesOnInit = TRUE
ENDIF
ENDIF
ENDIF
ENDPROC
PROC PROCESS_DOOR(DOOR_NAME_ENUM eDoor)
// Don't perform the update if we have just set an override for frame state
IF IS_BIT_SET(g_iOverrideDoorStateBitset[ENUM_TO_INT(eDoor)/32], ENUM_TO_INT(eDoor)%32)
AND g_eOverrideDoorState[eDoor] != DOORSTATE_FORCE_LOCKED_UNTIL_OUT_OF_AREA
AND NOT IS_BIT_SET(g_iInitialDoorOverrideBitset[ENUM_TO_INT(eDoor)/32], ENUM_TO_INT(eDoor)%32)
g_iOverrideDoorStateCounter[eDoor]--
IF g_iOverrideDoorStateCounter[eDoor] <= 0 // Ensure door has been locked for atleast 1 frame (could be 2 depending on the thread processing order).
CLEAR_BIT(g_iOverrideDoorStateBitset[ENUM_TO_INT(eDoor)/32], ENUM_TO_INT(eDoor)%32)
g_iOverrideDoorStateCounter[eDoor] = 0
ENDIF
ELSE
PERFORM_DOOR_LOCK(eDoor)
ENDIF
ENDPROC
PROC COPY_FORCE_UPDATE_DATA(FORCE_DOOR_UPDATE_STRUCT &eOrigin, FORCE_DOOR_UPDATE_STRUCT &eDestination)
// Copy
eDestination.eDoorToForceUpdate = eOrigin.eDoorToForceUpdate
eDestination.iForceDoorUpdateCount = eOrigin.iForceDoorUpdateCount
// Reset
eOrigin.iForceDoorUpdateCount = 0
eOrigin.iDoorsQueued = eDestination.iDoorsQueued // Resets to 0
ENDPROC
/// PURPOSE: Makes sure all the door states are kept up-to-date
PROC UPDATE_DOOR_STATES()
// Note, we need to work on a copy of the queue so we can start queuing more doors.
FORCE_DOOR_UPDATE_STRUCT sTempForceDoorUpdateData
COPY_FORCE_UPDATE_DATA(g_sForceDoorUpdateData, sTempForceDoorUpdateData)
// Only process 1 door each frame as part of the main door management.
PROCESS_DOOR(INT_TO_ENUM(DOOR_NAME_ENUM, iCurrentDoorFrame))
// Also process any doors that script have requested a change with.
INT i
REPEAT sTempForceDoorUpdateData.iForceDoorUpdateCount i
IF ENUM_TO_INT(sTempForceDoorUpdateData.eDoorToForceUpdate[i]) != iCurrentDoorFrame
PROCESS_DOOR(sTempForceDoorUpdateData.eDoorToForceUpdate[i])
ENDIF
ENDREPEAT
// Update door frame
iCurrentDoorFrame++
IF iCurrentDoorFrame >= NUMBER_OF_DOORS
iCurrentDoorFrame = 0
ENDIF
ENDPROC
PROC CLEANUP_PROLOGUE_MAP()
IF NOT bPrologueComplete
AND IS_BIT_SET(g_savedGlobals.sFlow.strandSavedVars[STRAND_PROLOGUE].savedBitflags,SAVED_BITS_STRAND_TERMINATED)
bPrologueComplete = TRUE
bCleanupPrologueMap = TRUE
ENDIF
IF bCleanupPrologueMap
AND (NOT IS_NEW_LOAD_SCENE_ACTIVE()
OR (IS_PLAYER_SWITCH_IN_PROGRESS() AND GET_PLAYER_SWITCH_STATE() = SWITCH_STATE_WAITFORINPUT))
CPRINTLN(DEBUG_BUILDING, "CLEANUP_PROLOGUE_MAP() - Removing all Prologue IPL groups.")
//IPL Groups
IF IS_IPL_ACTIVE("prologue01") REMOVE_IPL("prologue01") ENDIF
IF IS_IPL_ACTIVE("prologue02") REMOVE_IPL("prologue02") ENDIF
IF IS_IPL_ACTIVE("prologue03") REMOVE_IPL("prologue03") ENDIF
IF IS_IPL_ACTIVE("prologue04") REMOVE_IPL("prologue04") ENDIF
IF IS_IPL_ACTIVE("prologue05") REMOVE_IPL("prologue05") ENDIF
IF IS_IPL_ACTIVE("prologue06") REMOVE_IPL("prologue06") ENDIF
IF IS_IPL_ACTIVE("prologuerd") REMOVE_IPL("prologuerd") ENDIF
IF IS_IPL_ACTIVE("Prologue01c") REMOVE_IPL("Prologue01c") ENDIF
IF IS_IPL_ACTIVE("Prologue01d") REMOVE_IPL("Prologue01d") ENDIF
IF IS_IPL_ACTIVE("Prologue01e") REMOVE_IPL("Prologue01e") ENDIF
IF IS_IPL_ACTIVE("Prologue01f") REMOVE_IPL("Prologue01f") ENDIF
IF IS_IPL_ACTIVE("Prologue01g") REMOVE_IPL("Prologue01g") ENDIF
IF IS_IPL_ACTIVE("prologue01h") REMOVE_IPL("prologue01h") ENDIF
IF IS_IPL_ACTIVE("prologue01i") REMOVE_IPL("prologue01i") ENDIF
IF IS_IPL_ACTIVE("prologue01j") REMOVE_IPL("prologue01j") ENDIF
IF IS_IPL_ACTIVE("prologue01k") REMOVE_IPL("prologue01k") ENDIF
IF IS_IPL_ACTIVE("prologue01z") REMOVE_IPL("prologue01z") ENDIF
IF IS_IPL_ACTIVE("prologue03b") REMOVE_IPL("prologue03b") ENDIF
IF IS_IPL_ACTIVE("prologue04b") REMOVE_IPL("prologue04b") ENDIF
IF IS_IPL_ACTIVE("prologue05b") REMOVE_IPL("prologue05b") ENDIF
IF IS_IPL_ACTIVE("prologue06b") REMOVE_IPL("prologue06b") ENDIF
IF IS_IPL_ACTIVE("prologuerdb") REMOVE_IPL("prologuerdb") ENDIF
IF IS_IPL_ACTIVE("prologue_occl") REMOVE_IPL("prologue_occl") ENDIF
IF IS_IPL_ACTIVE("prologue06_int") REMOVE_IPL("prologue06_int") ENDIF
IF IS_IPL_ACTIVE("prologue04_cover") REMOVE_IPL("prologue04_cover") ENDIF
IF IS_IPL_ACTIVE("prologue03_grv_dug") REMOVE_IPL("prologue03_grv_dug") ENDIF
IF IS_IPL_ACTIVE("prologue03_grv_cov") REMOVE_IPL("prologue03_grv_cov") ENDIF
IF IS_IPL_ACTIVE("prologue03_grv_fun") REMOVE_IPL("prologue03_grv_fun") ENDIF
IF IS_IPL_ACTIVE("prologue_grv_torch") REMOVE_IPL("prologue_grv_torch") ENDIF
IF USE_SP_BUILDING_CONTROLLER_DATA()
REMOVE_IPL_WHEN_SCREEN_IS_FADED_OUT("prologue_DistantLights")
REMOVE_IPL_WHEN_SCREEN_IS_FADED_OUT("prologue_LODLights")
CPRINTLN(DEBUG_BUILDING, "Disabling prologue - SP with fade only.")
ELSE
IF IS_IPL_ACTIVE("prologue_DistantLights")
REMOVE_IPL("prologue_DistantLights")
ENDIF
IF IS_IPL_ACTIVE("prologue_LODLights")
REMOVE_IPL("prologue_LODLights")
ENDIF
CPRINTLN(DEBUG_BUILDING, "Disabling prologue - MP ignore fade.")
ENDIF
REMOVE_IPL("DES_ProTree_start")
REMOVE_IPL("DES_ProTree_start_lod")
//Cullbox
SET_MAPDATACULLBOX_ENABLED("Prologue_Main", FALSE)
//Minimap
SET_MINIMAP_IN_PROLOGUE_AND_HANDLE_STATIC_BLIPS(FALSE)
bCleanupPrologueMap = FALSE
ENDIF
ENDPROC
PROC INIT_PED_SPECIFIC_AUTOMATIC_DOORS()
// This tells the code that when these doors get streamed in, they should be under script control
// and not auto-open. Otherwise, they may open if an entity gets near them, and then if the player
// also gets near, MANAGE_PED_SPECIFIC_AUTOMATIC_DOORS() may make them pop back and open from 0.0 again.
// Technically, it would probably be best to do this with all of the doors (looping to AUTODOOR_MAX),
// but it's safest to start with a few as a test case.
// For reference, see B* 254387: "DH1 - Gate snaps from open on the right side to closed when approaching docks"
/*
Register the door
INT iFrontDoor = HASH("GIVE_THIS_A_UNIQUE_NAME")
ADD_DOOR_TO_SYSTEM(iFrontDoor, V_ILEV_MM_DOORM_L, vCoords)
Get/set door state
DOOR_STATE_ENUM eDoorState = DOOR_SYSTEM_GET_DOOR_STATE(iFrontDoor)
DOOR_SYSTEM_SET_DOOR_STATE(iFrontDoor, DOORSTATE_LOCKED)
FLOAT fDoorOpenRatio = DOOR_SYSTEM_GET_OPEN_RATIO(iFrontDoor)
DOOR_SYSTEM_SET_OPEN_RATIO(iFrontDoor, 0.5)
Cleanup
REMOVE_DOOR_FROM_SYSTEM(iFrontDoor)
*/
INT iAutoDoor
REPEAT AUTODOOR_MAX iAutoDoor
ADD_DOOR_TO_SYSTEM(g_sAutoDoorData[iAutoDoor].doorID, g_sAutoDoorData[iAutoDoor].model, g_sAutoDoorData[iAutoDoor].coords)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[iAutoDoor].doorID, DOORSTATE_LOCKED)
g_sAutoDoorData[iAutoDoor].currentOpenRatio = DOOR_SYSTEM_GET_OPEN_RATIO(g_sAutoDoorData[iAutoDoor].doorID)
CLEAR_BIT(g_sAutoDoorData[iAutoDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
CLEAR_BIT(g_sAutoDoorData[iAutoDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
CLEAR_BIT(g_sAutoDoorData[iAutoDoor].settingsBitset, BIT_AUTODOOR_LOCK_OPEN)
CLEAR_BIT(g_sAutoDoorData[iAutoDoor].settingsBitset, BIT_AUTODOOR_ALWAYS_OPEN)
ENDREPEAT
bToggleDoors = TRUE
ENDPROC
PROC CLEAR_PED_SPECIFIC_AUTOMATIC_DOORS()
// This tells the code that when these doors get streamed in, they should be under script control
// and not auto-open. Otherwise, they may open if an entity gets near them, and then if the player
// also gets near, MANAGE_PED_SPECIFIC_AUTOMATIC_DOORS() may make them pop back and open from 0.0 again.
// Technically, it would probably be best to do this with all of the doors (looping to AUTODOOR_MAX),
// but it's safest to start with a few as a test case.
// For reference, see B* 254387: "DH1 - Gate snaps from open on the right side to closed when approaching docks"
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_DOCKS_FRONT_GATE_IN].doorID, DOORSTATE_UNLOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_DOCKS_FRONT_GATE_OUT].doorID, DOORSTATE_UNLOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_DOCKS_BACK_GATE_IN].doorID, DOORSTATE_UNLOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_DOCKS_BACK_GATE_OUT].doorID, DOORSTATE_UNLOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_MICHAEL_MANSION_GATE].doorID, DOORSTATE_UNLOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_MIL_DOCKS_GATE_IN].doorID, DOORSTATE_UNLOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_MIL_DOCKS_GATE_OUT].doorID, DOORSTATE_UNLOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_CULT_GATE_LEFT].doorID, DOORSTATE_LOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_CULT_GATE_RIGHT].doorID, DOORSTATE_LOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_DTOWN_VINEWOOD_GARAGE].doorID, DOORSTATE_LOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_FRAN_HILLS_GARAGE].doorID, DOORSTATE_LOCKED)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[AUTODOOR_SC1_COP_CARPARK].doorID, DOORSTATE_LOCKED)
bToggleDoors = FALSE
ENDPROC
FUNC BOOL IS_ANY_REGISTERED_PED_ACTIVATING_DOOR(INT iAutoDoorIndex)
INT pedIndex
IF g_sAutoDoorData[iAutoDoorIndex].registeredPedCount > 0
REPEAT g_sAutoDoorData[iAutoDoorIndex].registeredPedCount pedIndex
PED_INDEX pedToCheck = g_sAutoDoorData[iAutoDoorIndex].registeredPed[pedIndex]
IF DOES_ENTITY_EXIST(pedToCheck)
IF NOT IS_PED_INJURED(pedToCheck)
IF VDIST2(g_sAutoDoorData[iAutoDoorIndex].coords, GET_ENTITY_COORDS(pedToCheck)) < g_sAutoDoorData[iAutoDoorIndex].checkRange
IF IS_ENTITY_IN_ANGLED_AREA(pedToCheck,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "].")
RETURN TRUE
ENDIF
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_TWO_LOCATES)
IF IS_ENTITY_IN_ANGLED_AREA(pedToCheck,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "].")
RETURN TRUE
ENDIF
ENDIF
IF IS_PED_IN_ANY_VEHICLE(pedToCheck)
// Get vehicle info
VEHICLE_INDEX vehTest = GET_VEHICLE_PED_IS_IN(pedToCheck)
VECTOR vMin = NULL_VECTOR(), vMax = NULL_VECTOR()
VECTOR vFrontTest = NULL_VECTOR(), vBackTest = NULL_VECTOR()
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(vehTest), vMin, vMax)
vMax.x = 0
vMin.x = 0
vFrontTest = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehTest, vMax)
vBackTest = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehTest, vMin)
// Check vehicle front and back for being in area
IF IS_POINT_IN_ANGLED_AREA(vFrontTest,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by vehicle driven by ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "] (front).")
RETURN TRUE
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vBackTest,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by vehicle driven by ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "] (back).")
RETURN TRUE
ENDIF
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_TWO_LOCATES)
IF IS_POINT_IN_ANGLED_AREA(vFrontTest,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by vehicle driven by ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "] (front).")
RETURN TRUE
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vBackTest,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by vehicle driven by ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "] (back).")
RETURN TRUE
ENDIF
ENDIF
// Check any trailers
IF IS_VEHICLE_ATTACHED_TO_TRAILER(vehTest)
VEHICLE_INDEX vehTrailer = NULL
IF GET_VEHICLE_TRAILER_VEHICLE(vehTest, vehTrailer)
IF IS_ENTITY_IN_ANGLED_AREA(vehTrailer,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate1Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by trailer connected to ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "].")
RETURN TRUE
ENDIF
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_TWO_LOCATES)
IF IS_ENTITY_IN_ANGLED_AREA(vehTrailer,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosA,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2PosB,
g_sAutoDoorData[iAutoDoorIndex].activationLocate2Width)
iFrameAutodoorPedIndex = pedIndex
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " being activated by trailer connected to ped[", NATIVE_TO_INT(pedToCheck), "|", PED_MODEL_NAME(pedToCheck), "].")
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_PED_VEHICLE_WITHIN_RANGE_OF_GATE(PED_INDEX pedToCheck, VECTOR vDoorPos)
VECTOR vMin, vMax
FLOAT fDistance
VEHICLE_INDEX tempTrailer
IF IS_PED_IN_ANY_VEHICLE(pedToCheck)
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(GET_VEHICLE_PED_IS_IN(pedToCheck)), vMin, vMax)
fDistance += vMax.y
IF IS_VEHICLE_ATTACHED_TO_TRAILER(GET_VEHICLE_PED_IS_IN(pedToCheck))
IF GET_VEHICLE_TRAILER_VEHICLE(GET_VEHICLE_PED_IS_IN(pedToCheck), tempTrailer)
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(tempTrailer), vMin, vMax)
fDistance += vMax.y
fDistance += 3
ENDIF
ENDIF
IF IS_ENTITY_AT_COORD(pedToCheck, vDoorPos, <<fDistance, fDistance, 3>>)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC SET_MP_APARTMENT_DOOR_STATE(STRING sDoorName, MODEL_NAMES eModel, VECTOR vCoords, BOOL bLock)
INT iDoorHash = GET_HASH_KEY(sDoorName)
IF bLock
IF NOT IS_DOOR_REGISTERED_WITH_SYSTEM(iDoorHash)
ADD_DOOR_TO_SYSTEM(iDoorHash, eModel, vCoords, FALSE, FALSE)
ENDIF
DOOR_SYSTEM_SET_DOOR_STATE(iDoorHash, DOORSTATE_LOCKED, FALSE, TRUE)
ELSE
IF IS_DOOR_REGISTERED_WITH_SYSTEM(iDoorHash)
DOOR_SYSTEM_SET_DOOR_STATE(iDoorHash, DOORSTATE_UNLOCKED, FALSE, TRUE)
REMOVE_DOOR_FROM_SYSTEM(iDoorHash)
ENDIF
ENDIF
ENDPROC
PROC UPDATE_ALL_MP_APARTMENT_DOORS(BOOL bLock)
// I have no idea what this door is but 1587961 wants me to lock it and apparently it's an MP door
SET_MP_APARTMENT_DOOR_STATE("MPINT_MISC_DOOR", prop_sc1_12_door, <<-58.47, -1530.51, 34.54>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND1_DOOR_L", prop_ss1_mpint_door_l, <<-778.36, 313.54, 86.14>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND1_DOOR_R", prop_ss1_mpint_door_r, <<-776.20, 313.54, 86.14>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND1_DOOR_GARAGE", prop_ss1_mpint_garage, <<-796.08, 313.78, 86.68>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND5_DOOR_L", prop_dt1_20_mp_door_l, <<-263.46, -970.52, 31.61>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND5_DOOR_R", prop_dt1_20_mp_door_r, <<-260.66, -969.21, 31.61>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND5_DOOR_GARAGE", prop_dt1_20_mp_gar, <<-282.55, -995.16, 24.67>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND7_DOOR_L", sm_14_mp_door_l, <<-1444.28, -545.01, 34.98>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND7_DOOR_R", sm_14_mp_door_r, <<-1442.30, -543.63, 34.98>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND7_DOOR_GARAGE", prop_sm_14_mp_gar, <<-1455.81, -503.98, 32.29>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND9_DOOR_L", prop_bh1_09_mp_l, <<-914.06, -453.65, 39.81>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND9_DOOR_R", prop_bh1_09_mp_r, <<-912.91, -455.89, 39.81>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND9_DOOR_GARAGE", prop_bh1_09_mp_gar, <<-820.57, -436.81, 37.44>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND12_DOOR_L", dt1_03_mp_door, <<-47.84, -588.77, 38.36>>, bLock)
//#IF FEATURE_HEIST_PLANNING
//SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND12_DOOR_GARAGE", HEI_Prop_Com_MP_Gar2, <<-33.79, -621.62, 36.11>>, bLock)
//#ENDIF
//#IF NOT FEATURE_HEIST_PLANNING
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND12_DOOR_GARAGE", prop_com_gar_door_01, <<-33.79, -621.62, 36.11>>, bLock)
//#ENDIF
// to do here: 14/15 front doors, if needed (they don't seem to be movable and we don't have rotating doors elsewhere?)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND14_DOOR_GARAGE", prop_bh1_08_mp_gar, <<-878.02, -359.46, 36.27>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND16_DOOR_L", prop_ss1_mpint_door_l, <<-615.80, 38.37, 44.04>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND16_DOOR_R", prop_ss1_mpint_door_r, <<-613.64, 38.37, 44.04>>, bLock)
//#IF FEATURE_HEIST_PLANNING
//SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND16_DOOR_GARAGE", HEI_prop_ss1_mpint_garage2, <<-629.91, 56.57, 44.72>>, bLock)
//#ENDIF
//#IF NOT FEATURE_HEIST_PLANNING
SET_MP_APARTMENT_DOOR_STATE("MPINT_HIGHEND16_DOOR_GARAGE", prop_ss1_mpint_garage, <<-629.91, 56.57, 44.72>>, bLock)
//#ENDIF
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND1_DOOR", p_cut_door_01, <<-40.19, -58.21, 64.21>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND2_DOOR", p_cut_door_03, <<-200.29, 185.60, 80.66>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND3_DOOR_L", prop_kt1_10_mpdoor_l, <<-812.83, -979.01, 14.60>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND3_DOOR_R", prop_kt1_10_mpdoor_r, <<-811.25, -981.27, 14.61>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND4_DOOR", kt1_11_mp_door, <<-661.87, -854.63, 24.69>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND5_DOOR", prop_sm_10_mp_door, <<-1533.58, -327.59, 48.09>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND6_DOOR_L", prop_sm1_11_doorr, <<-1565.58, -406.92, 42.61>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND6_DOOR_R", prop_sm1_11_doorl, <<-1564.01, -405.04, 42.61>>, bLock)
// I think these are low-end 7?
SET_MP_APARTMENT_DOOR_STATE("MP_APARTMENT_DOOR_01", PROP_SM1_11_DOORR, <<-1605.0138, -431.9617, 40.6384>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_LOWEND7_DOOR_GARAGE", prop_sm1_11_garaged, <<-1605.26, -447.18, 38.58>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND1_DOOR_L", prop_bh1_44_door_01l, <<286.91, -159.22, 64.84>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND1_DOOR_R", prop_bh1_44_door_01r, <<285.94, -161.88, 64.84>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND2_DOOR", prop_bh1_44_door_01r, <<4.40, 37.32, 71.75>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND3_DOOR", prop_bh1_44_door_01r, <<8.74, 81.31, 78.65>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND4_DOOR_L", prop_sm1_11_doorl, <<-510.42, 108.00, 64.02>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND4_DOOR_R", prop_sm1_11_doorr, <<-512.84, 107.66, 64.02>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND5_DOOR", prop_ss1_05_mp_door, <<-197.23, 85.16, 69.90>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND6_DOOR_L", prop_ss1_08_mp_door_l, <<-627.34, 170.87, 61.29>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND6_DOOR_R", prop_ss1_08_mp_door_r, <<-627.34, 168.53, 61.29>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND7_DOOR_L", vb_43_door_l_mp, <<-969.36, -1429.98, 7.97>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND7_DOOR_R", vb_43_door_r_mp, <<-968.60, -1432.04, 6.77>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND8_DOOR_L", prop_kt1_10_mpdoor_r, <<-830.05, -862.99, 21.09>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND8_DOOR_R", prop_kt1_10_mpdoor_l, <<-832.81, -862.99, 21.09>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND9_DOOR_L", prop_kt1_06_door_l, <<-763.90, -755.08, 28.19>>, bLock)
SET_MP_APARTMENT_DOOR_STATE("MPINT_MIDEND9_DOOR_R", prop_kt1_06_door_r, <<-763.90, -752.49, 28.19>>, bLock)
ENDPROC
/// PURPOSE:
/// Check several autodoors in the game to see if they need to open (or remain locked) for the player while off-mission
PROC MAINTAIN_AUTODOOR_REGISTRATION(AUTOMATIC_DOOR_ENUM iAutodoor)
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
SWITCH iAutodoor
// Handles cop gates
CASE AUTODOOR_SC1_COP_CARPARK
IF IS_PED_IN_ANY_POLICE_VEHICLE(PLAYER_PED_ID())
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_HEIST_FINALE_PREP_A].scriptHash) = 0 // Big Score Prep A uses this gate, let it control it if running
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), g_sAutoDoorData[AUTODOOR_SC1_COP_CARPARK].coords) <= 100
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_SC1_COP_CARPARK, PLAYER_PED_ID())
// Add more autodoors/gates that should only open if the player is in a cop car here
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_SC1_COP_CARPARK, PLAYER_PED_ID())
ENDIF
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_SC1_COP_CARPARK, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_SC1_COP_CARPARK, PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
ELSE
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_HEIST_FINALE_PREP_A].scriptHash) = 0 // Big Score Prep A uses this gate, let it control it if running
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_SC1_COP_CARPARK, PLAYER_PED_ID())
// Add more autodoors/gates that should only open if the player is in a cop car here
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_SC1_COP_CARPARK, PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
BREAK
// Handle gates to the airport
CASE AUTODOOR_AIRPORT_BARRIER_IN
CASE AUTODOOR_AIRPORT_BARRIER_OUT
// If Car Steal 2 or RC Extreme 2 are running, don't do any of this - these missions will handle these gates themselves
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_MISSION_CARSTEAL_2].scriptHash) = 0
AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("Extreme2")) = 0
// Register the player to open the gates if they've acquired the current character's airport vehicle gen
// Or unregister them if necessary
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), g_sAutoDoorData[AUTODOOR_AIRPORT_BARRIER_IN].coords) <= 100 // No need to check both gates
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
IF GET_VEHICLE_GEN_SAVED_FLAG_STATE(VEHGEN_WEB_HANGAR_MICHAEL, VEHGEN_S_FLAG_ACQUIRED)
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
ENDIF
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
ENDIF
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
CASE CHAR_FRANKLIN
IF GET_VEHICLE_GEN_SAVED_FLAG_STATE(VEHGEN_WEB_HANGAR_FRANKLIN, VEHGEN_S_FLAG_ACQUIRED)
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
ENDIF
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
ENDIF
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
CASE CHAR_TREVOR
IF GET_VEHICLE_GEN_SAVED_FLAG_STATE(VEHGEN_WEB_HANGAR_TREVOR, VEHGEN_S_FLAG_ACQUIRED)
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
ENDIF
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
ENDIF
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
ENDSWITCH
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_IN, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_BARRIER_OUT, PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
BREAK
// The rear gates on the other side of the airport
CASE AUTODOOR_AIRPORT_ALT_GATES_L
// Register the player to open the gates if they've acquired the current character's airport vehicle gen
// Or unregister them if necessary
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), g_sAutoDoorData[AUTODOOR_AIRPORT_ALT_GATES_L].coords) <= 100 // No need to check both gates
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
IF GET_VEHICLE_GEN_SAVED_FLAG_STATE(VEHGEN_WEB_HANGAR_MICHAEL, VEHGEN_S_FLAG_ACQUIRED)
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
ENDIF
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
ENDIF
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
CASE CHAR_FRANKLIN
IF GET_VEHICLE_GEN_SAVED_FLAG_STATE(VEHGEN_WEB_HANGAR_FRANKLIN, VEHGEN_S_FLAG_ACQUIRED)
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
ENDIF
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
ENDIF
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
CASE CHAR_TREVOR
IF GET_VEHICLE_GEN_SAVED_FLAG_STATE(VEHGEN_WEB_HANGAR_TREVOR, VEHGEN_S_FLAG_ACQUIRED)
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
ENDIF
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
ENDIF
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
ENDSWITCH
ELSE
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_L, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_AIRPORT_ALT_GATES_R, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
// Handles gates to Devin's house
CASE AUTODOOR_DEVIN_GATE_L
CASE AUTODOOR_DEVIN_GATE_R
// These gates should be locked all of the time, except where FIB4 and Finale C2 want to do things with them
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_MISSION_FINALE_C2].scriptHash) = 0
//AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_MISSION_FBI_4].scriptHash) = 0 // FBI4 doesn't need these to open now
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DEVIN_GATE_L, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DEVIN_GATE_L, PLAYER_PED_ID())
ENDIF
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DEVIN_GATE_R, PLAYER_PED_ID())
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DEVIN_GATE_R, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
CASE AUTODOOR_HAYES_GARAGE
// If Car Steal 1 or 3 are running or they're in through a switch scene, let the player trigger the garage door - otherwise, ensure they're unregistered
IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), <<480.4354, -1317.9095, 29.5957>>) < 20*20 // Only check this if the player is <15m from Hayes
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_MISSION_CARSTEAL_1].scriptHash) = 0
AND GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_MISSION_CARSTEAL_3].scriptHash) = 0
IF IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_HAYES_GARAGE, PLAYER_PED_ID())
IF GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID()) != GET_INTERIOR_AT_COORDS(<<480.4354, -1317.9095, 29.5957>>) // Make sure the player isn't inside Hayes when we close it
AND NOT IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<486.860046,-1316.603516,27.719374>>, <<484.890594,-1312.647217,31.723122>>, 4.25)
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_HAYES_GARAGE, PLAYER_PED_ID())
ENDIF
ELSE
IF GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID()) = GET_INTERIOR_AT_COORDS_WITH_TYPE(<<480.4354, -1317.9095, 29.5957>>, "v_chopshop") // If the player is inside Hayes (switch scene?), open it
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_HAYES_GARAGE, PLAYER_PED_ID())
ENDIF
ENDIF
ELSE
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_HAYES_GARAGE, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_HAYES_GARAGE, PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
BREAK
CASE AUTODOOR_DRAINSERVICE_L
CASE AUTODOOR_DRAINSERVICE_R
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DRAINSERVICE_L, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DRAINSERVICE_L, PLAYER_PED_ID())
ENDIF
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DRAINSERVICE_R, PLAYER_PED_ID())
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_DRAINSERVICE_R, PLAYER_PED_ID())
ENDIF
BREAK
CASE AUTODOOR_MICHAEL_MANSION_GATE
IF NOT IS_PED_REGISTERED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MICHAEL_MANSION_GATE, PLAYER_PED_ID())
// Only check this if the player isn't registered to open the gate
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
IF VDIST2(g_sAutoDoorData[AUTODOOR_MICHAEL_MANSION_GATE].coords, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) < 100*100
CPRINTLN(DEBUG_DOOR, "Caught Michael not being registered to open his front gate in MAINTAIN_AUTODOOR_REGISTRATION()")
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MICHAEL_MANSION_GATE, PLAYER_PED_ID())
ENDIF
BREAK
CASE CHAR_FRANKLIN
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_ARMENIAN_3)
// More complicated for Franklin - we lock the gate behind him after Fam 1 and don't want it to reopen, but it must open to trigger Fam 3
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_FAMILY_1)
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_FAMILY_3)
OR IS_MISSION_AVAILABLE(SP_MISSION_FAMILY_3)
IF VDIST2(g_sAutoDoorData[AUTODOOR_MICHAEL_MANSION_GATE].coords, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) < 100*100
CPRINTLN(DEBUG_DOOR, "Caught Franklin not being registered to open Michael's front gate in MAINTAIN_AUTODOOR_REGISTRATION() (post Fam 1)")
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MICHAEL_MANSION_GATE, PLAYER_PED_ID())
ENDIF
ENDIF
ELSE
IF VDIST2(g_sAutoDoorData[AUTODOOR_MICHAEL_MANSION_GATE].coords, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) < 100*100
CPRINTLN(DEBUG_DOOR, "Caught Franklin not being registered to open Michael's front gate in MAINTAIN_AUTODOOR_REGISTRATION() (pre Fam 1)")
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MICHAEL_MANSION_GATE, PLAYER_PED_ID())
ENDIF
ENDIF
ENDIF
BREAK
CASE CHAR_TREVOR
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_FAMILY_4)
IF VDIST2(g_sAutoDoorData[AUTODOOR_MICHAEL_MANSION_GATE].coords, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) < 100*100
CPRINTLN(DEBUG_DOOR, "Caught Trevor not being registered to open Michael's front gate in MAINTAIN_AUTODOOR_REGISTRATION()")
REGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(AUTODOOR_MICHAEL_MANSION_GATE, PLAYER_PED_ID())
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ENDPROC
PROC PROCESS_LINKED_AUTO_DOOR(INT iAutoDoorIndex, BOOL bOpen)
AUTOMATIC_DOOR_ENUM iLinkedDoor
IF g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_AIRPORT_ALT_GATES_L")
iLinkedDoor = AUTODOOR_AIRPORT_ALT_GATES_R
ELIF g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_AIRPORT_ALT_GATES_R")
iLinkedDoor = AUTODOOR_AIRPORT_ALT_GATES_L
ELIF g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_DRAINSERVICE_L")
iLinkedDoor = AUTODOOR_DRAINSERVICE_R
ELIF g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_DRAINSERVICE_R")
iLinkedDoor = AUTODOOR_DRAINSERVICE_L
ENDIF
IF bOpen
IF NOT IS_BIT_SET(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
//Open the door.
IF IS_BIT_SET(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_REVERSE_OPEN_RATIO)
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio > -1.0
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = g_sAutoDoorData[iLinkedDoor].currentOpenRatio -@ g_sAutoDoorData[iLinkedDoor].openRate
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio < -1.0
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = -1.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ELSE
CPRINTLN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " is now fully open.")
SET_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio < 1.0
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = g_sAutoDoorData[iLinkedDoor].currentOpenRatio +@ g_sAutoDoorData[iLinkedDoor].openRate
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio > 1.0
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = 1.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ELSE
CPRINTLN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " is now fully open.")
SET_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ENDIF
CDEBUG3LN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " is opening this frame. Open ratio: ", g_sAutoDoorData[iLinkedDoor].currentOpenRatio)
DOOR_SYSTEM_SET_OPEN_RATIO(g_sAutoDoorData[iLinkedDoor].doorID, g_sAutoDoorData[iLinkedDoor].currentOpenRatio, FALSE, FALSE)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[iLinkedDoor].doorID, DOORSTATE_LOCKED, FALSE, TRUE)
ELSE
IF IS_BIT_SET(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_REVERSE_OPEN_RATIO)
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio > -1.0
CPRINTLN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " set to fully open without a valid open ratio. Unflagging door as fully open.")
CLEAR_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio < 1.0
CPRINTLN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " set to fully open without a valid open ratio. Unflagging door as fully open.")
CLEAR_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ENDIF
ENDIF
//Ped not activating.
ELSE
//Attempt to close the door if it isn't already flagged as being fully closed.
IF NOT IS_BIT_SET(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
//Check if it is unsafe to close the gate this frame due to a blocking vehicle.
BOOL bVehicleBlocking = FALSE
VEHICLE_INDEX vehTest = GET_CLOSEST_VEHICLE(g_sAutoDoorData[iLinkedDoor].coords, 15.0, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_LAW_ENFORCER_VEHICLES|VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES|VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_GROUP_MEMBERS|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_PLAYER|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_DEAD_OR_DYING_PED|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_WITH_PEDS_ENTERING_OR_EXITING|VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK)
IF DOES_ENTITY_EXIST(vehTest)
IF IS_VEHICLE_DRIVEABLE(vehTest)
FLOAT fDistanceSquaredBetween = VDIST2(GET_ENTITY_COORDS(vehTest), g_sAutoDoorData[iLinkedDoor].coords)
IF fDistanceSquaredBetween < g_sAutoDoorData[iLinkedDoor].blockedRange
CDEBUG3LN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " is trying to close this frame but is being blocked by a vehicle.")
bVehicleBlocking = TRUE
ENDIF
ENDIF
ENDIF
IF IS_BIT_SET(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_REVERSE_OPEN_RATIO)
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio < 0.0
IF NOT bVehicleBlocking
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = g_sAutoDoorData[iLinkedDoor].currentOpenRatio +@ g_sAutoDoorData[iLinkedDoor].openRate
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio > 0.0
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = 0.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
CPRINTLN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " is now fully closed.")
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = 0.0
SET_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ENDIF
ELSE
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio > 0.0
IF NOT bVehicleBlocking
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = g_sAutoDoorData[iLinkedDoor].currentOpenRatio -@ g_sAutoDoorData[iLinkedDoor].openRate
IF g_sAutoDoorData[iLinkedDoor].currentOpenRatio < 0.0
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = 0.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
CPRINTLN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " is now fully closed.")
g_sAutoDoorData[iLinkedDoor].currentOpenRatio = 0.0
SET_BIT(g_sAutoDoorData[iLinkedDoor].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ENDIF
ENDIF
DOOR_SYSTEM_SET_OPEN_RATIO(g_sAutoDoorData[iLinkedDoor].doorID, g_sAutoDoorData[iLinkedDoor].currentOpenRatio, FALSE, FALSE)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[iLinkedDoor].doorID, DOORSTATE_LOCKED, FALSE, TRUE)
CDEBUG3LN(DEBUG_DOOR, "Door (linked) ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(iLinkedDoor), " is closing this frame. Open ratio: ", g_sAutoDoorData[iLinkedDoor].currentOpenRatio)
ENDIF
ENDIF
ENDPROC
PROC ADD_DOOR_TO_TRIGGERED_LIST(INT iAutoDoorIndex)
IF iTriggeredDoorCount < COUNT_OF(iTriggeredDoors)
INT iTriggerDoor
REPEAT iTriggeredDoorCount iTriggerDoor
IF iTriggeredDoors[iTriggerDoor] = iAutoDoorIndex
// Already added so bail
EXIT
ENDIF
ENDREPEAT
CPRINTLN(DEBUG_DOOR, "ADD_DOOR_TO_TRIGGERED_LIST - adding autodoor ", iAutoDoorIndex, " to triggered list")
iTriggeredDoors[iTriggeredDoorCount] = iAutoDoorIndex
iTriggeredDoorCount++
ENDIF
ENDPROC
PROC REMOVE_DOOR_DROM_TRIGGERED_LIST(INT iAutoDoorIndex)
INT iTriggerDoor
BOOL bDoorFound = FALSE
INT iRepeatCount = iTriggeredDoorCount
REPEAT iRepeatCount iTriggerDoor
IF bDoorFound
//Shift registered doors down one index.
iTriggeredDoors[iTriggerDoor-1] = iTriggeredDoors[iTriggerDoor]
ELSE
IF iTriggeredDoors[iTriggerDoor] = iAutoDoorIndex
// Remove and shift the rest down
CPRINTLN(DEBUG_DOOR, "REMOVE_DOOR_DROM_TRIGGERED_LIST - removing autodoor ", iAutoDoorIndex, " from triggered list")
iTriggeredDoorCount--
bDoorFound = TRUE
ENDIF
ENDIF
ENDREPEAT
ENDPROC
PROC PROCESS_AUTO_DOOR(INT iAutoDoorIndex)
IF IS_BIT_SET(iAutoDoordsProcessedThisFrame, iAutoDoorIndex)
EXIT
ENDIF
SET_BIT(iAutoDoordsProcessedThisFrame, iAutoDoorIndex)
//Does the door need to have it's open state set based on the player being wanted?
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_OPEN_ON_WANTED)
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
IF NOT IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_ALWAYS_OPEN)
FORCE_AUTOMATIC_DOOR_SLIDE_OPEN(INT_TO_ENUM(AUTOMATIC_DOOR_ENUM, iAutoDoorIndex), TRUE)
ENDIF
ELSE
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_ALWAYS_OPEN)
FORCE_AUTOMATIC_DOOR_SLIDE_OPEN(INT_TO_ENUM(AUTOMATIC_DOOR_ENUM, iAutoDoorIndex), FALSE)
ENDIF
ENDIF
ENDIF
ENDIF
// IF g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_HAYES_GARAGE")
// IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_MISSION_CARSTEAL_1].scriptHash) > 0
// OR GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(g_sMissionStaticData[SP_MISSION_CARSTEAL_3].scriptHash) > 0
// EXIT
// ENDIF
// ENDIF
//B*-2333225
IF g_sAutoDoorData[iAutoDoorIndex].registeredPedCount > 0
INT pedIndex
REPEAT g_sAutoDoorData[iAutoDoorIndex].registeredPedCount pedIndex
PED_INDEX pedToUnregister = g_sAutoDoorData[iAutoDoorIndex].registeredPed[pedIndex]
IF NOT DOES_ENTITY_EXIST(pedToUnregister)
//ped doesn't exist B*-2333225
//remove from array
CDEBUG3LN(DEBUG_DOOR, "building controller: registered ped, doesn't exist")
CDEBUG3LN(DEBUG_DOOR, "building controller: iAutoDoorIndex = ",iAutoDoorIndex)
CDEBUG3LN(DEBUG_DOOR, "building controller: pedToUnregister = ",NATIVE_TO_INT(pedToUnregister))
UNREGISTER_PED_TO_ACTIVATE_AUTOMATIC_DOOR(INT_TO_ENUM(AUTOMATIC_DOOR_ENUM,iAutoDoorIndex), pedToUnregister, TRUE)
ENDIF
ENDREPEAT
ENDIF
// Ped activating this door
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_ALWAYS_OPEN)
OR IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_LOCK_OPEN)
OR IS_ANY_REGISTERED_PED_ACTIVATING_DOOR(iAutoDoorIndex)
//Flag a door as being triggered so we keep checking this door every frame until it is no longer being triggered.
ADD_DOOR_TO_TRIGGERED_LIST(iAutoDoorIndex)
iFrameAutodoorIndex = iAutoDoorIndex // make sure we are sticking on this door.
// If Michael's gate is being activated, set SET_SCRIPT_UPDATE_DOOR_AUDIO on it so the audio doesn't get stuck looping (B*1350240)
IF g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_MICHAEL_MANSION_GATE")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_SC1_COP_CARPARK")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_FRAN_HILLS_GARAGE")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_IMPOUND_L")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_IMPOUND_R")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_AIRPORT_BARRIER_IN")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_AIRPORT_BARRIER_OUT")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_DRAINSERVICE_L")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_DRAINSERVICE_R")
// CPRINTLN(DEBUG_DOOR, "Setting SET_SCRIPT_UPDATE_DOOR_AUDIO true on ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex))
SET_SCRIPT_UPDATE_DOOR_AUDIO(g_sAutoDoorData[iAutoDoorIndex].doorID,true)
ENDIF
// If this autodoor is linked with another gate that must also open, call this too so the linked door also moves
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_LINKED_DOORS)
PROCESS_LINKED_AUTO_DOOR(iAutoDoorIndex, TRUE)
ENDIF
//Attempt to open the door if it isn't already flagged as being fully open.
IF NOT IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
//Open the door.
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_REVERSE_OPEN_RATIO)
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio > -1.0
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio -@ g_sAutoDoorData[iAutoDoorIndex].openRate
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio < -1.0
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = -1.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ELSE
CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " is now fully open.")
SET_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio < 1.0
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio +@ g_sAutoDoorData[iAutoDoorIndex].openRate
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio > 1.0
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = 1.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ELSE
CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " is now fully open.")
SET_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ENDIF
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " is opening this frame. Open ratio: ", g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio)
DOOR_SYSTEM_SET_OPEN_RATIO(g_sAutoDoorData[iAutoDoorIndex].doorID, g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio, FALSE, FALSE)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[iAutoDoorIndex].doorID, DOORSTATE_LOCKED, FALSE, TRUE)
ELSE
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_REVERSE_OPEN_RATIO)
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio > -1.0
CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " set to fully open without a valid open ratio. Unflagging door as fully open.")
CLEAR_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio < 1.0
CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " set to fully open without a valid open ratio. Unflagging door as fully open.")
CLEAR_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ENDIF
ENDIF
//Ped not activating.
ELSE
// If this autodoor is linked with another gate that must also open, call this too so the linked door also moves
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_LINKED_DOORS)
PROCESS_LINKED_AUTO_DOOR(iAutoDoorIndex, FALSE)
ENDIF
//Attempt to close the door if it isn't already flagged as being fully closed.
IF NOT IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
//Check if it is unsafe to close the gate this frame due to a blocking vehicle.
BOOL bVehicleBlocking = FALSE
VEHICLE_INDEX vehTest = GET_CLOSEST_VEHICLE(g_sAutoDoorData[iAutoDoorIndex].coords, 15.0, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_LAW_ENFORCER_VEHICLES|VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES|VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_GROUP_MEMBERS|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_PLAYER|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_DEAD_OR_DYING_PED|VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_WITH_PEDS_ENTERING_OR_EXITING|VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK)
IF DOES_ENTITY_EXIST(vehTest)
IF IS_VEHICLE_DRIVEABLE(vehTest)
FLOAT fDistanceSquaredBetween = VDIST2(GET_ENTITY_COORDS(vehTest), g_sAutoDoorData[iAutoDoorIndex].coords)
IF fDistanceSquaredBetween < g_sAutoDoorData[iAutoDoorIndex].blockedRange
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " is trying to close this frame but is being blocked by a vehicle.")
bVehicleBlocking = TRUE
ENDIF
ENDIF
ENDIF
IF IS_BIT_SET(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_REVERSE_OPEN_RATIO)
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio < 0.0
IF NOT bVehicleBlocking
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio +@ g_sAutoDoorData[iAutoDoorIndex].openRate
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio > 0.0
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = 0.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " is now fully closed.")
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = 0.0
SET_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ENDIF
ELSE
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio > 0.0
IF NOT bVehicleBlocking
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio -@ g_sAutoDoorData[iAutoDoorIndex].openRate
IF g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio < 0.0
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = 0.0
ENDIF
CLEAR_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_OPEN)
ENDIF
ELSE
CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " is now fully closed.")
g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio = 0.0
SET_BIT(g_sAutoDoorData[iAutoDoorIndex].settingsBitset, BIT_AUTODOOR_DOOR_FULLY_CLOSED)
ENDIF
ENDIF
DOOR_SYSTEM_SET_OPEN_RATIO(g_sAutoDoorData[iAutoDoorIndex].doorID, g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio, FALSE, FALSE)
DOOR_SYSTEM_SET_DOOR_STATE(g_sAutoDoorData[iAutoDoorIndex].doorID, DOORSTATE_LOCKED, FALSE, TRUE)
CDEBUG3LN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex), " is closing this frame. Open ratio: ", g_sAutoDoorData[iAutoDoorIndex].currentOpenRatio)
ELSE
//The door is fully closed and not being activated.
// If Michael's gate isn't being activated, ensure SET_SCRIPT_UPDATE_DOOR_AUDIO is set to false (B*1350240)
IF g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_MICHAEL_MANSION_GATE")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_SC1_COP_CARPARK")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_FRAN_HILLS_GARAGE")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_IMPOUND_L")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_IMPOUND_R")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_AIRPORT_BARRIER_IN")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_AIRPORT_BARRIER_OUT")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_DRAINSERVICE_L")
OR g_sAutoDoorData[iAutoDoorIndex].doorID = HASH("AUTODOOR_DRAINSERVICE_R")
// CPRINTLN(DEBUG_DOOR, "Setting SET_SCRIPT_UPDATE_DOOR_AUDIO false on ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iAutoDoorIndex))
SET_SCRIPT_UPDATE_DOOR_AUDIO(g_sAutoDoorData[iAutoDoorIndex].doorID,FALSE)
ENDIF
//Unflag door as being triggered so we can check another door/ped pair next frame.
REMOVE_DOOR_DROM_TRIGGERED_LIST(iAutoDoorIndex)
ENDIF
ENDIF
ENDPROC
PROC MANAGE_PED_SPECIFIC_AUTOMATIC_DOORS()
iAutoDoordsProcessedThisFrame = 0
//Render the check spheres when trigger debug is on.
#IF IS_DEBUG_BUILD
IF g_bTriggerDebugOn
IF g_eTriggerDebugMode = TDM_AUTODOOR
OR g_eTriggerDebugMode = TDM_ALL
OR g_eTriggerDebugMode = TDM_AUTODOOR_TEXT
OR g_eTriggerDebugMode = TDM_ALL_TEXT
INT iDebugDoor
REPEAT AUTODOOR_MAX iDebugDoor
DRAW_DEBUG_SPHERE(g_sAutoDoorData[iDebugDoor].coords, SQRT(g_sAutoDoorData[iDebugDoor].checkRange), 75, 150, 255, 40)
DRAW_DEBUG_SPHERE(g_sAutoDoorData[iDebugDoor].coords, SQRT(g_sAutoDoorData[iDebugDoor].blockedRange), 255, 150, 75, 75)
ENDREPEAT
ENDIF
IF g_eTriggerDebugMode = TDM_AUTODOOR_TEXT
OR g_eTriggerDebugMode = TDM_ALL_TEXT
INT iDebugDoor
REPEAT AUTODOOR_MAX iDebugDoor
DRAW_DEBUG_TEXT(GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iDebugDoor), g_sAutoDoorData[iDebugDoor].coords)
ENDREPEAT
ENDIF
ENDIF
#ENDIF
// Track the closest autodoor so we can ensure it gets processed each frame
iFrameAutodoorDistIndex++
IF iFrameAutodoorDistIndex >= ENUM_TO_INT(AUTODOOR_MAX)
iFrameAutodoorDistIndex = 0
ENDIF
IF iFrameAutodoorDistIndex = iFrameAutodoorClosestIndex
fClosestAutoDoorDist = GET_DISTANCE_BETWEEN_COORDS(g_sAutoDoorData[iFrameAutodoorDistIndex].coords, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE))
ELSE
FLOAT fDist = GET_DISTANCE_BETWEEN_COORDS(g_sAutoDoorData[iFrameAutodoorDistIndex].coords, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE))
IF fDist < fClosestAutoDoorDist
fClosestAutoDoorDist = fDist
iFrameAutodoorClosestIndex = iFrameAutodoorDistIndex
CDEBUG1LN(DEBUG_DOOR, "Closest autodoor is now ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iFrameAutodoorClosestIndex))
ENDIF
ENDIF
// To ensure we process the closest door quick enough, alternative between the closest
// and the next door to process - unless we are already triggering a door.
//Work out which door and which registered ped to check this frame.
IF NOT bProcessClosestDoor // Don't iterate this if we're checking the closest door this frame, or we'll skip every other door without checking it! (see b*1510711)
IF g_sAutoDoorData[iFrameAutodoorIndex].registeredPedCount = 0
iFrameAutodoorPedIndex = 0
iFrameAutodoorIndex++
IF iFrameAutodoorIndex >= ENUM_TO_INT(AUTODOOR_MAX)
iFrameAutodoorIndex = 0
ENDIF
ELSE
iFrameAutodoorPedIndex++
IF iFrameAutodoorPedIndex >= g_sAutoDoorData[iFrameAutodoorIndex].registeredPedCount
iFrameAutodoorPedIndex = 0
iFrameAutodoorIndex++
IF iFrameAutodoorIndex >= ENUM_TO_INT(AUTODOOR_MAX)
iFrameAutodoorIndex = 0
ENDIF
ENDIF
ENDIF
ENDIF
// Alternate...
IF bProcessClosestDoor
//CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iFrameAutodoorClosestIndex), " being processed as closest autodoor.")
// Check states for autodoors that have varying behaviour throughout the game...
MAINTAIN_AUTODOOR_REGISTRATION(INT_TO_ENUM(AUTOMATIC_DOOR_ENUM,iFrameAutodoorClosestIndex))
PROCESS_AUTO_DOOR(iFrameAutodoorClosestIndex)
ELSE
//CPRINTLN(DEBUG_DOOR, "Door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_INDEX(iFrameAutodoorIndex), " being processed as iterative autodoor.")
// Check states for autodoors that have varying behaviour throughout the game...
MAINTAIN_AUTODOOR_REGISTRATION(INT_TO_ENUM(AUTOMATIC_DOOR_ENUM, iFrameAutodoorIndex))
PROCESS_AUTO_DOOR(iFrameAutodoorIndex)
ENDIF
bProcessClosestDoor = !bProcessClosestDoor
// Process the doors that are flagged as being triggered.
INT iTriggeredDoor
REPEAT iTriggeredDoorCount iTriggeredDoor
//CPRINTLN(DEBUG_DOOR, "PROCESS_AUTO_DOOR - processing triggered door ", GET_AUTOMATIC_DOOR_DEBUG_STRING_FROM_ID(INT_TO_ENUM(AUTOMATIC_DOOR_ENUM, iTriggeredDoors[iTriggeredDoor])))
PROCESS_AUTO_DOOR(iTriggeredDoors[iTriggeredDoor])
ENDREPEAT
ENDPROC
/// PURPOSE: Makes sure all the interior capping or disabling states are up-to-date.
PROC UPDATE_INTERIOR_STATES()
// No need to process anything if no interiors are flagged to be capped or disabled
INTERIOR_NAME_ENUM eInterior
INTERIOR_DATA_STRUCT sInteriorData
INT i
// Check if there's anything to do.
BOOL bNothingToDo = TRUE
REPEAT MAX_INTERIOR_BITSETS i
IF iInteriorCappingBitset[i] != 0
OR iInteriorDisablingBitset[i] != 0
bNothingToDo = FALSE
ENDIF
ENDREPEAT
// If nothing to do, then quit.
IF bNothingToDo
EXIT
ENDIF
eInterior = INT_TO_ENUM( INTERIOR_NAME_ENUM, iInteriorEnumCount )
sInteriorData = GET_INTERIOR_DATA(eInterior)
#IF IS_DEBUG_BUILD
CDEBUG3LN(DEBUG_BUILDING, "UPDATE_INTERIOR_STATES() - '",GET_THIS_SCRIPT_NAME(), "' Checking ", sInteriorData.sDebugName )
#ENDIF
IF IS_INTERIOR_CAPPED_ON_EXIT(eInterior)
#IF IS_DEBUG_BUILD
CDEBUG3LN(DEBUG_BUILDING, "UPDATE_INTERIOR_STATES() - '",GET_THIS_SCRIPT_NAME(), "' ", sInteriorData.sDebugName, "is to be CAPPED on exit.")
#ENDIF
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), sInteriorData.vPos) > 250
SET_INTERIOR_CAPPED_ON_EXIT( eInterior, FALSE ) // Clears the bitset
SET_INTERIOR_CAPPED(eInterior, TRUE)
// Fix for # 1855859 - Closing chemical lab doors when we cap interior.
IF eInterior = INTERIOR_V_LAB
// Inside left shutter door
IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L))
DOOR_SYSTEM_SET_HOLD_OPEN(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L), false)
DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L), 0.0, false, false) //1.0
DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L), DOORSTATE_LOCKED, false, true)
ENDIF
// Inside right shutter door
IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R))
DOOR_SYSTEM_SET_HOLD_OPEN(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R), false)
DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R), 0.0, false, false) //1.0
DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R), DOORSTATE_LOCKED, false, true)
ENDIF
ENDIF
ENDIF
ENDIF
IF IS_INTERIOR_DISABLED_ON_EXIT(eInterior)
AND NOT ARE_STRINGS_EQUAL(g_tlIgnoreBuildingControllerChecks, sInteriorData.sInteriorName)
#IF IS_DEBUG_BUILD
CDEBUG3LN(DEBUG_BUILDING, "UPDATE_INTERIOR_STATES() - '",GET_THIS_SCRIPT_NAME(), "' ", sInteriorData.sDebugName, "is to be DISABLED on exit.")
#ENDIF
BOOL bRunningOnlineIntroCut = FALSE
IF NETWORK_IS_GAME_IN_PROGRESS()
IF NATIVE_TO_INT(PLAYER_ID()) > -1
IF IS_BIT_SET(GlobalplayerBD_FM[NATIVE_TO_INT(PLAYER_ID())].iFmTutProgBitset, biTrigTut_RunningIntroCut)
bRunningOnlineIntroCut = TRUE
ENDIF
ENDIF
ENDIF
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), sInteriorData.vPos) > 250
AND NOT bRunningOnlineIntroCut
SET_INTERIOR_DISABLED(eInterior, TRUE)
SET_INTERIOR_DISABLED_ON_EXIT( eInterior, FALSE ) // Clears the bitset
// Fix for # 1855859 - Closing chemical lab doors when we cap interior.
IF eInterior = INTERIOR_V_LAB
// Inside left shutter door
IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L))
DOOR_SYSTEM_SET_HOLD_OPEN(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L), false)
DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L), 0.0, false, false) //1.0
DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_L), DOORSTATE_LOCKED, false, true)
ENDIF
// Inside right shutter door
IF IS_DOOR_REGISTERED_WITH_SYSTEM(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R))
DOOR_SYSTEM_SET_HOLD_OPEN(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R), false)
DOOR_SYSTEM_SET_OPEN_RATIO(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R), 0.0, false, false) //1.0
DOOR_SYSTEM_SET_DOOR_STATE(ENUM_TO_INT(DOORHASH_CHEMICAL_FACTORY_R), DOORSTATE_LOCKED, false, true)
ENDIF
ENDIF
ELSE
IF bRunningOnlineIntroCut
CDEBUG3LN(DEBUG_BUILDING, "UPDATE_INTERIOR_STATES() NOT DISABLING AS bRunningOnlineIntroCut")
ENDIF
ENDIF
ENDIF
++ iInteriorEnumCount
IF iInteriorEnumCount = ENUM_TO_INT(INTERIOR_MAX_NUM)
iInteriorEnumCount = 0
ENDIF
ENDPROC
FUNC BOOL PROCESS_BUILDING(BUILDING_NAME_ENUM eBuilding)
BOOL bGrabbedData = FALSE
BOOL bUpdatePerformed = FALSE
g_bPerformingBuildingSwap = FALSE
IF g_bUpdateBuildingState[eBuilding]
OR (NOT USE_SP_BUILDING_CONTROLLER_DATA() AND NOT g_bBuildingStateSetInMP[eBuilding])
IF PERFORM_BUILDING_SWAP(eBuilding, FALSE)
bUpdatePerformed = TRUE
g_bPerformingBuildingSwap = FALSE
ENDIF
ENDIF
// Put a building into the cleanup state if the player is out of range
IF g_eCurrentBuildingState[eBuilding] = BUILDINGSTATE_DESTROYED
GET_BUILDING_DATA(sTempBuildingData, eBuilding)
bGrabbedData = TRUE
IF sTempBuildingData.auto_cleanup
IF GET_HASH_KEY(sTempBuildingData.name[BUILDINGSTATE_CLEANUP]) != GET_HASH_KEY("")
#IF IS_DEBUG_BUILD
CDEBUG3LN(DEBUG_BUILDING, "UPDATE_BUILDING_STATES() - Building '", sTempBuildingData.dbg_name, "' is waiting for player to leave so it can be cleaned up.")
#ENDIF
IF GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), sTempBuildingData.coords) > 250
SET_BUILDING_STATE(eBuilding, BUILDINGSTATE_CLEANUP, FALSE, TRUE)
ENDIF
ENDIF
ENDIF
ENDIF
IF g_bBuildingRoadNodeBlockUpdate[eBuilding]
IF NOT bGrabbedData
GET_BUILDING_DATA(sTempBuildingData, eBuilding)
bGrabbedData = TRUE
ENDIF
UPDATE_ROAD_NODES_FOR_BUILDING_STATE(sTempBuildingData, eBuilding, g_eCurrentBuildingState[eBuilding])
g_bBuildingRoadNodeBlockUpdate[eBuilding] = FALSE
ENDIF
IF g_bBuildingScenarioBlockUpdate[eBuilding]
IF NOT bGrabbedData
GET_BUILDING_DATA(sTempBuildingData, eBuilding)
bGrabbedData = TRUE
ENDIF
UPDATE_SCENARIO_BLOCKING_FOR_BUILDING_STATE(sTempBuildingData, eBuilding, g_eCurrentBuildingState[eBuilding])
g_bBuildingScenarioBlockUpdate[eBuilding] = FALSE
ENDIF
RETURN bUpdatePerformed
ENDFUNC
#IF FEATURE_HEIST_ISLAND
PROC HIDE_HEIST_ISLAND_MANSION_PROPS()
CREATE_MODEL_HIDE(<<-1785.1890, 444.5226, 127.1124>>, 0.5, PROP_PARASOL_01, TRUE)
CREATE_MODEL_HIDE(<<-1785.2925, 432.9928, 127.1134>>, 0.5, PROP_PARASOL_01, TRUE)
CREATE_MODEL_HIDE(<<-1784.2349, 444.5237, 127.6224>>, 0.5, INT_TO_ENUM(MODEL_NAMES, HASH("PROP_YAUGHT_CHAIR_01")), TRUE)
CREATE_MODEL_HIDE(<<-1785.3584, 445.6732, 127.6216>>, 0.5, INT_TO_ENUM(MODEL_NAMES, HASH("PROP_YAUGHT_CHAIR_01")), TRUE)
CREATE_MODEL_HIDE(<<-1783.1411, 446.3715, 127.6272>>, 0.5, INT_TO_ENUM(MODEL_NAMES, HASH("PROP_YAUGHT_CHAIR_01")), TRUE)
REQUEST_IPL("h4_CH2_Mansion_Final")
PRINTLN("\n building_controller: hidden island props and requested mansion ipl")
ENDPROC
#ENDIF
/// PURPOSE: Makes sure all the building states are kept up-to-date
PROC UPDATE_BUILDING_STATES()
// Add IPL's when no load scene is active
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
INT iIPL
REPEAT MAX_IPLS_TO_TRACK_FOR_ADD iIPL
IF NOT IS_STRING_NULL_OR_EMPTY(g_tlIPLsToAddOnNoLoadScene[iIPL])
IF NOT IS_IPL_ACTIVE(g_tlIPLsToAddOnNoLoadScene[iIPL])
REQUEST_IPL(g_tlIPLsToAddOnNoLoadScene[iIPL])
ENDIF
g_tlIPLsToAddOnNoLoadScene[iIPL] = ""
ENDIF
ENDREPEAT
ENDIF
// Building states do not change during MP so only perform updates on the first pass.
IF NOT USE_SP_BUILDING_CONTROLLER_DATA()
IF g_iBuildingStatesSetInMP >= NUMBER_OF_BUILDINGS
IF NOT bCleanupPrologueMap
//g_bPerformingBuildingSwap = FALSE
REMOVE_ALL_DOORS_FROM_SYSTEM()
eStage = BC_STAGE_IDLE
PRINTLN("UPDATE_BUILDING_STATES:building_controller: eStage = BC_STAGE_IDLE ")
EXIT
ENDIF
ENDIF
ENDIF
// Update the frame that we are processing
iCurrentBuildingFrame = (iCurrentBuildingFrame+1) % MAX_FRAMES_TO_PROCESS_BUILDINGS
INT i, j
REPEAT (NUMBER_OF_BUILDINGS / MAX_FRAMES_TO_PROCESS_BUILDINGS)+1 j
i = iCurrentBuildingFrame+(j*MAX_FRAMES_TO_PROCESS_BUILDINGS)
// Only perform an update if this building is within the range
IF i < NUMBER_OF_BUILDINGS
IF PROCESS_BUILDING(INT_TO_ENUM(BUILDING_NAME_ENUM, i))
// Process linked building enums...
IF INT_TO_ENUM(BUILDING_NAME_ENUM, i) = BUILDINGNAME_ES_CAR_SHOWROOOM_SHUTTERS
OR INT_TO_ENUM(BUILDING_NAME_ENUM, i) = BUILDINGNAME_ES_CAR_SHOWROOOM_WINDOWS
OR INT_TO_ENUM(BUILDING_NAME_ENUM, i) = BUILDINGNAME_IPL_CAR_SHOWROOM_LOD_BOARD
OR INT_TO_ENUM(BUILDING_NAME_ENUM, i) = BUILDINGNAME_ES_CAR_SHOWROOOM_RUBBLE1
OR INT_TO_ENUM(BUILDING_NAME_ENUM, i) = BUILDINGNAME_ES_CAR_SHOWROOOM_RUBBLE2
OR INT_TO_ENUM(BUILDING_NAME_ENUM, i) = BUILDINGNAME_ES_CAR_SHOWROOOM_RUBBLE3
PROCESS_BUILDING(BUILDINGNAME_ES_CAR_SHOWROOOM_SHUTTERS)
PROCESS_BUILDING(BUILDINGNAME_ES_CAR_SHOWROOOM_WINDOWS)
PROCESS_BUILDING(BUILDINGNAME_IPL_CAR_SHOWROOM_LOD_BOARD)
PROCESS_BUILDING(BUILDINGNAME_ES_CAR_SHOWROOOM_RUBBLE1)
PROCESS_BUILDING(BUILDINGNAME_ES_CAR_SHOWROOOM_RUBBLE2)
PROCESS_BUILDING(BUILDINGNAME_ES_CAR_SHOWROOOM_RUBBLE3)
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF g_bBuildingScenarioBlocksUpdateThisFrame
CPRINTLN(DEBUG_BUILDING, "UPDATE_BUILDING_STATES() - Building controller requested to update all scenario blocks this frame.")
REPEAT NUMBER_OF_BUILDINGS i
GET_BUILDING_DATA(sTempBuildingData, INT_TO_ENUM(BUILDING_NAME_ENUM, i))
UPDATE_ROAD_NODES_FOR_BUILDING_STATE(sTempBuildingData, INT_TO_ENUM(BUILDING_NAME_ENUM, i), g_eCurrentBuildingState[INT_TO_ENUM(BUILDING_NAME_ENUM, i)])
UPDATE_SCENARIO_BLOCKING_FOR_BUILDING_STATE(sTempBuildingData, INT_TO_ENUM(BUILDING_NAME_ENUM, i), g_eCurrentBuildingState[INT_TO_ENUM(BUILDING_NAME_ENUM, i)])
g_bBuildingScenarioBlockUpdate[i] = FALSE
ENDREPEAT
g_bBuildingScenarioBlocksUpdateThisFrame = FALSE
ENDIF
// Remove IPLs on fade
IF IS_SCREEN_FADED_OUT()
INT iIPL
REPEAT MAX_IPLS_TO_TRACK_FOR_REMOVAL iIPL
IF NOT IS_STRING_NULL_OR_EMPTY(g_tlIPLsToRemoveOnFadeOut[iIPL])
IF IS_IPL_ACTIVE(g_tlIPLsToRemoveOnFadeOut[iIPL])
REMOVE_IPL(g_tlIPLsToRemoveOnFadeOut[iIPL])
ENDIF
g_tlIPLsToRemoveOnFadeOut[iIPL] = ""
ENDIF
ENDREPEAT
ENDIF
ENDPROC
PROC DO_INITIALISE()
IF USE_SP_BUILDING_CONTROLLER_DATA()
IF NETWORK_IS_GAME_IN_PROGRESS()
CDEBUG3LN(DEBUG_BUILDING, "building_controller: Waiting for network game to end before initialising.")
EXIT
ENDIF
IF GET_CONFIRM_INVITE_INTO_GAME_STATE()
CDEBUG3LN(DEBUG_BUILDING, "building_controller: Waiting for player invite state to end before initialising.")
EXIT
ENDIF
ELSE
IF NOT NETWORK_IS_GAME_IN_PROGRESS()
AND GET_CURRENT_GAMEMODE() != GAMEMODE_CREATOR
CDEBUG3LN(DEBUG_BUILDING, "building_controller: Waiting for network game to start before initialising.")
EXIT
ENDIF
ENDIF
IF g_bForceBuildingControllerToClearDoorsInInit
REMOVE_ALL_DOORS_FROM_SYSTEM()
UPDATE_ALL_MP_APARTMENT_DOORS(FALSE)
g_bForceBuildingControllerToClearDoorsInInit = FALSE
ENDIF
IF IS_NEW_LOAD_SCENE_ACTIVE()
AND (NOT IS_PLAYER_SWITCH_IN_PROGRESS() OR GET_PLAYER_SWITCH_STATE() != SWITCH_STATE_WAITFORINPUT)
CDEBUG3LN(DEBUG_BUILDING, "building_controller: Waiting for new load scene to end before initialising.")
EXIT
ENDIF
CPRINTLN(DEBUG_BUILDING, "building_controller: eStage = BC_STAGE_INIT.")
// Remove some IPL's that we missed.
REMOVE_IPL("SUNK_SHIP_FIRE") //2274331
REMOVE_IPL("SpaceInterior")
IF IS_IPL_ACTIVE("PO1_08_sub_waterplane") REMOVE_IPL("PO1_08_sub_waterplane") ENDIF // 1985471
// Clear the building data each time we enter a multiplayer mode.
// We dont save any of the states out.
g_MPBuildingData.bDefaultDataSet = FALSE
IF NOT HAS_DEFAULT_BUILDING_DATA_BEEN_SET()
SETUP_DEFAULT_BUILDING_DATA()
bForceBuildingUpdatesOnInit = TRUE
ENDIF
// Force all buildings and doors to update
g_sForceDoorUpdateData.iForceDoorUpdateCount = 0
INT i
REPEAT NUMBER_OF_DOORS i
SET_BIT(g_iUpdateDoorStateBitset[i/32], (i%32))
g_iOverrideDoorStateCounter[i] = 0
CLEAR_BIT(g_iOverrideDoorStateBitset[i/32], i%32)
g_eOverrideDoorState[i] = DOORSTATE_UNLOCKED
g_eCurrentDoorState[i] = DOORSTATE_LOCKED
SET_BIT(g_iInitialDoorOverrideBitset[i/32], (i%32))
ENDREPEAT
REPEAT NUMBER_OF_BUILDINGS i
g_bBuildingStateUpdateDelay[i] = FALSE
// Fix for bug 1304136 - Blocking areas automatically reset when transitioning between sp/mp
IF g_bBuildingNavmeshBlockSet[i]
REMOVE_NAVMESH_BLOCKING_OBJECT(g_bBuildingNavmeshBlockingID[i])
g_bBuildingNavmeshBlockSet[i] = FALSE
ENDIF
IF g_bBuildingScenarioBlockSet[i]
REMOVE_SCENARIO_BLOCKING_AREA(g_scenarioBuildingBlock[i])
g_bBuildingScenarioBlockSet[i] = FALSE
ENDIF
g_bBuildingStateSetInMP[i] = FALSE
ENDREPEAT
g_iBuildingStatesSetInMP = 0
// Only run in SP
IF USE_SP_BUILDING_CONTROLLER_DATA()
SETUP_AUTOMATIC_DOOR_DATA()
INIT_PED_SPECIFIC_AUTOMATIC_DOORS()
UPDATE_ALL_MP_APARTMENT_DOORS(TRUE)
ADD_ALL_DOORS_TO_SYSTEM()
#IF FEATURE_FOW_EXPANSION
CONFIGURE_FOW_FOR_SP()
#ENDIF
ELSE
REMOVE_ALL_DOORS_FROM_SYSTEM()
UPDATE_ALL_MP_APARTMENT_DOORS(FALSE)
#IF FEATURE_FOW_EXPANSION
CONFIGURE_FOW_FOR_MP_MAIN()
#ENDIF
ENDIF
// Reset the flags
iProcessFlags = 0
iCurrentDoorFrame = 0
iCurrentBuildingFrame = 0
bCleanupPrologueMap = TRUE
bPrologueComplete = FALSE
bForceRemoveYachtIPLs = TRUE // force IPL's to reload.
g_bResetBuildingController = FALSE
// Set the reset flag depending on what mode we are running
IF USE_SP_BUILDING_CONTROLLER_DATA()
SET_BIT(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_BIT))
SET_BIT(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_MP_CREATOR_BIT))
ELSE
SET_BIT(iProcessFlags, ENUM_TO_INT(RESET_CONTROLLER_WHEN_IN_SP_BIT))
ENDIF
IF bForceBuildingUpdatesOnInit
INITIALISE_STORED_BUILDING_STATES_ON_STARTUP(TRUE)
bForceBuildingUpdatesOnInit = FALSE
ENDIF
INT iAddIpl = 0
REPEAT MAX_IPLS_TO_TRACK_FOR_ADD iAddIpl
g_tlIPLsToAddOnNoLoadScene[iAddIpl] = ""
ENDREPEAT
CLEANUP_EXTENDED_PICKUP_PROBE_AREAS()
IF NOT USE_SP_BUILDING_CONTROLLER_DATA()
// Add pickup probe areas around facilities.
INITIALISE_EXTENDED_PICKUP_PROBE_AREAS()
ENDIF
eStage = BC_STAGE_UPDATE
ENDPROC
PROC MAINTAIN_PROP_BLOCKERS()
IF NOT IS_BIT_SET(g_iDisablePropBlockerBitset, PROP_BLOCKER_BITFIELD_FLAG)
IF NOT DOES_ENTITY_EXIST(objPropBlocker[PROP_BLOCKER_BITFIELD_FLAG])
REQUEST_MODEL(XM_PROP_X17DLC_REP_SIGN_01A)
IF HAS_MODEL_LOADED(XM_PROP_X17DLC_REP_SIGN_01A)
CPRINTLN(DEBUG_BUILDING, "Creating prop blocker - flag")
objPropBlocker[PROP_BLOCKER_BITFIELD_FLAG] = CREATE_OBJECT_NO_OFFSET(XM_PROP_X17DLC_REP_SIGN_01A, <<2222.883, 5612.299, 55.291>>, FALSE, FALSE, TRUE)
SET_ENTITY_ROTATION(objPropBlocker[PROP_BLOCKER_BITFIELD_FLAG], <<0.500, 0.0, 15.325>>)
//SET_ENTITY_ALPHA(objPropBlocker[PROP_BLOCKER_BITFIELD_FLAG], 255, TRUE)
FREEZE_ENTITY_POSITION(objPropBlocker[PROP_BLOCKER_BITFIELD_FLAG], TRUE)
SET_MODEL_AS_NO_LONGER_NEEDED(XM_PROP_X17DLC_REP_SIGN_01A)
ENDIF
ENDIF
ELSE
IF DOES_ENTITY_EXIST(objPropBlocker[PROP_BLOCKER_BITFIELD_FLAG])
CPRINTLN(DEBUG_BUILDING, "Removing prop blocker - flag")
DELETE_OBJECT(objPropBlocker[PROP_BLOCKER_BITFIELD_FLAG])
ENDIF
ENDIF
IF NOT IS_BIT_SET(g_iDisablePropBlockerBitset, PROP_BLOCKER_BITFIELD_SECRET_DOOR)
AND GET_CURRENT_GAMEMODE() = GAMEMODE_FM
AND NOT (NETWORK_IS_ACTIVITY_SESSION() AND (GANGOPS_FLOW_GET_GANG_OPS_MISSION_CONST_FROM_ROOT_ID(g_FMMC_STRUCT.iRootContentIDHash) = ciGANGOPS_FLOW_MISSION_MISSILE_SILO_FINALE OR GANGOPS_FLOW_GET_GANG_OPS_MISSION_CONST_FROM_ROOT_ID(g_FMMC_STRUCT.iRootContentIDHash) = ciGANGOPS_FLOW_MISSION_MISSILE_SILO_FINALE_P2))
IF NOT DOES_ENTITY_EXIST(objPropBlocker[PROP_BLOCKER_BITFIELD_SECRET_DOOR])
REQUEST_MODEL(XM_PROP_BASE_CABINET_DOOR_01)
IF HAS_MODEL_LOADED(XM_PROP_BASE_CABINET_DOOR_01)
CPRINTLN(DEBUG_BUILDING, "Creating prop blocker - secret door")
objPropBlocker[PROP_BLOCKER_BITFIELD_SECRET_DOOR] = CREATE_OBJECT_NO_OFFSET(XM_PROP_BASE_CABINET_DOOR_01, << -362.402, 4829.890, 142.477 >>, FALSE, FALSE, TRUE)
SET_ENTITY_ROTATION(objPropBlocker[PROP_BLOCKER_BITFIELD_SECRET_DOOR], << 0.0, 0.0, 320.000 >>)
//SET_ENTITY_ALPHA(objPropBlocker[PROP_BLOCKER_BITFIELD_SECRET_DOOR], 255, TRUE)
FREEZE_ENTITY_POSITION(objPropBlocker[PROP_BLOCKER_BITFIELD_SECRET_DOOR], TRUE)
SET_MODEL_AS_NO_LONGER_NEEDED(XM_PROP_BASE_CABINET_DOOR_01)
ENDIF
ENDIF
ELSE
IF DOES_ENTITY_EXIST(objPropBlocker[PROP_BLOCKER_BITFIELD_SECRET_DOOR])
CPRINTLN(DEBUG_BUILDING, "Removing prop blocker - secret door")
DELETE_OBJECT(objPropBlocker[PROP_BLOCKER_BITFIELD_SECRET_DOOR])
ENDIF
ENDIF
ENDPROC
#IF FEATURE_FIXER
PROC ADD_AGENCY_SF_BILLBOARDS()
IF NOT IS_IPL_ACTIVE("sf_billboards")
REQUEST_IPL("sf_billboards")
PRINTLN("building_controller: enabling sf_billboards")
ENDIF
ENDPROC
////may not be needed
//PROC REMOVE_AGENCY_SF_BILLBOARDS()
// REMOVE_IPL("sf_billboards")
//ENDPROC
#ENDIF
PROC MAINTAIN_MP_IPLS()
// Removing Heist IPL groups on MP startup - needs to be done when the map content change has been executed (ON_ENTER_MP())
IF NOT bInitialHeistIPLsRemoved
AND NOT IS_NEW_LOAD_SCENE_ACTIVE()
AND IS_MP_MAP_LOADED()
IF NOT g_bBlockBuildingControllerOnMission
PRINTSTRING("\n building_controller: g_bRemoveInitialHeistIPLs = TRUE - removing heist IPLs")
REMOVE_IPL("hei_carrier")
REMOVE_IPL("hei_carrier_int1")
REMOVE_IPL("hei_carrier_int2")
REMOVE_IPL("hei_carrier_int3")
REMOVE_IPL("hei_carrier_int4")
REMOVE_IPL("hei_carrier_int5")
REMOVE_IPL("hei_carrier_int6")
REMOVE_IPL("hei_carrier_DistantLights")
REMOVE_IPL("hei_carrier_LODLights")
REMOVE_IPL("hei_yacht_heist")
REMOVE_IPL("hei_yacht_heist_enginrm")
REMOVE_IPL("hei_yacht_heist_Lounge")
REMOVE_IPL("hei_yacht_heist_Bridge")
REMOVE_IPL("hei_yacht_heist_Bar")
REMOVE_IPL("hei_yacht_heist_Bedrm")
ENDIF
bInitialHeistIPLsRemoved = TRUE
ENDIF
// Removing Lowrider IPL groups on MP startup - needs to be done when the map content change has been executed (ON_ENTER_MP())
IF NOT bInitialMPDLCIPLsRemoved
AND IS_MP_MAP_LOADED()
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
IF NOT g_bBlockBuildingControllerOnMission
PRINTSTRING("\n building_controller: Initialising MP DLC IPLs")
REMOVE_IPL("lr_cs6_08_grave_open")
REQUEST_IPL("lr_cs6_08_grave_closed")
REQUEST_IPL("hei_bi_hw1_13_door")
REQUEST_IPL("bkr_bi_id1_23_door")
INT iCounter
TEXT_LABEL_23 tlBunkerClosed
REPEAT ciMAX_BUNKER_PROPERTIES iCounter
IF iCounter != 8 // 8 got the chop
tlBunkerClosed = "GR_case"
tlBunkerClosed+=iCounter
tlBunkerClosed+="_BunkerClosed"
REQUEST_IPL(tlBunkerClosed)
ENDIF
ENDREPEAT
ENDIF
#IF FEATURE_HEIST_ISLAND
HIDE_HEIST_ISLAND_MANSION_PROPS()
#ENDIF
bInitialMPDLCIPLsRemoved = TRUE
ENDIF
ENDIF
IF bInitialMPDLCIPLsRemoved
AND NOT IS_MP_MAP_LOADED()
bInitialMPDLCIPLsRemoved = FALSE
ENDIF
IF IS_MP_MAP_LOADED()
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
IF NOT g_bBlockBuildingControllerOnMission
#IF IS_DEBUG_BUILD
AND NOT g_bDebugPlacedArenaBox
#ENDIF
IF IS_IPL_ACTIVE("Xs_arena_interior")
REMOVE_IPL("Xs_arena_interior")
PRINTLN("\n building_controller: removing arena ipl Xs_arena_interior ")
ENDIF
IF IS_IPL_ACTIVE("xs_arena_interior_vip")
REMOVE_IPL("xs_arena_interior_vip")
PRINTLN("\n building_controller: removing arena ipl xs_arena_interior_vip ")
ENDIF
ENDIF
ENDIF
ENDIF
// MP SPECIFIC MAP DATA.
// DO NOT TRY AND REMOVE THESE IPL GROUPS IF IS_MP_MAP_LOADED() = FALSE
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
AND IS_MP_MAP_LOADED()
IF NOT NETWORK_IS_ACTIVITY_SESSION()
OR GANGOPS_FLOW_IS_CURRENT_MISSION_GANGOPS_FLOW()
IF NOT g_bBlockBuildingControllerHatches
IF NOT IS_IPL_ACTIVE("xm_hatch_closed")
REQUEST_IPL("xm_hatch_closed")
ENDIF
IF NOT IS_BIT_SET(g_FMMC_STRUCT.iIPLOptions, IPL_REMOVE_IAA_FACILITY_SATELITE_ENTRY_DOOR)
IF NOT IS_IPL_ACTIVE("xm_bunkerentrance_door")
REQUEST_IPL("xm_bunkerentrance_door")
ENDIF
ELSE
PRINTLN("Not requesting xm_bunkerentrance_door due to IPL_REMOVE_IAA_FACILITY_SATELITE_ENTRY_DOOR in g_FMMC_STRUCT.iIPLOptions")
ENDIF
IF NOT IS_IPL_ACTIVE("xm_siloentranceclosed_x17")
REQUEST_IPL("xm_siloentranceclosed_x17")
ENDIF
IF NOT IS_IPL_ACTIVE("xm_hatches_terrain")
REQUEST_IPL("xm_hatches_terrain")
ENDIF
ENDIF
ELIF IS_BIT_SET(g_FMMC_STRUCT.iIPLOptions, IPL_SILO)
IF NOT IS_IPL_ACTIVE("xm_siloentranceclosed_x17")
REQUEST_IPL("xm_siloentranceclosed_x17")
ENDIF
IF NOT IS_IPL_ACTIVE("xm_hatches_terrain")
REQUEST_IPL("xm_hatches_terrain")
ENDIF
ELSE
IF IS_IPL_ACTIVE("xm_hatch_closed")
REMOVE_IPL("xm_hatch_closed")
ENDIF
IF IS_IPL_ACTIVE("xm_bunkerentrance_door")
REMOVE_IPL("xm_bunkerentrance_door")
ENDIF
IF IS_IPL_ACTIVE("xm_siloentranceclosed_x17")
REMOVE_IPL("xm_siloentranceclosed_x17")
ENDIF
IF IS_IPL_ACTIVE("xm_hatches_terrain")
REMOVE_IPL("xm_hatches_terrain")
ENDIF
ENDIF
IF IS_BIT_SET(g_SimpleInteriorData.iBSipl, BS_SIMPLE_INTERIOR_GLOBAL_DATA_IPL_CORONER_CLEANUP_NEEDED)
REMOVE_IPL("Coroner_Int_on")
REQUEST_IPL("Coroner_Int_off")
CLEAR_BIT(g_SimpleInteriorData.iBSipl, BS_SIMPLE_INTERIOR_GLOBAL_DATA_IPL_CORONER_CLEANUP_NEEDED)
CPRINTLN(DEBUG_BUILDING, "REMOVE_ALL_DOORS_FROM_SYSTEM - BS_SIMPLE_INTERIOR_GLOBAL_DATA_IPL_CORONER_CLEANUP_NEEDED, done ")
ENDIF
IF NOT g_bBlockBuildingControllerCasinoClubIPLs
IF g_sMPTunables.bDISABLE_CASINO_NIGHTCLUB_DJ_KEINEMUSIK
IF IS_IPL_ACTIVE("h4_ClubPoster_KeineMusik")
REMOVE_IPL("h4_ClubPoster_KeineMusik")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("h4_ClubPoster_KeineMusik")
REQUEST_IPL("h4_ClubPoster_KeineMusik")
ENDIF
ENDIF
IF g_sMPTunables.bDISABLE_CASINO_NIGHTCLUB_DJ_MOODYMANN
IF IS_IPL_ACTIVE("h4_ClubPoster_MoodyMann")
REMOVE_IPL("h4_ClubPoster_MoodyMann")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("h4_ClubPoster_MoodyMann")
REQUEST_IPL("h4_ClubPoster_MoodyMann")
ENDIF
ENDIF
IF g_sMPTunables.bDISABLE_CASINO_NIGHTCLUB_DJ_PALMS_TRAX
IF IS_IPL_ACTIVE("h4_ClubPoster_PalmsTraxx")
REMOVE_IPL("h4_ClubPoster_PalmsTraxx")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("h4_ClubPoster_PalmsTraxx")
REQUEST_IPL("h4_ClubPoster_PalmsTraxx")
ENDIF
ENDIF
ENDIF
IF g_bBlockBuildingControllerPlayerAutoShopIPLs
IF IS_IPL_ACTIVE("tr_tuner_shop_burton")
REMOVE_IPL("tr_tuner_shop_burton")
ENDIF
IF IS_IPL_ACTIVE("tr_tuner_shop_mesa")
REMOVE_IPL("tr_tuner_shop_mesa")
ENDIF
IF IS_IPL_ACTIVE("tr_tuner_shop_mission")
REMOVE_IPL("tr_tuner_shop_mission")
ENDIF
IF IS_IPL_ACTIVE("tr_tuner_shop_rancho")
REMOVE_IPL("tr_tuner_shop_rancho")
ENDIF
IF IS_IPL_ACTIVE("tr_tuner_shop_strawberry")
REMOVE_IPL("tr_tuner_shop_strawberry")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("tr_tuner_shop_burton")
REQUEST_IPL("tr_tuner_shop_burton")
ENDIF
IF NOT IS_IPL_ACTIVE("tr_tuner_shop_mesa")
REQUEST_IPL("tr_tuner_shop_mesa")
ENDIF
IF NOT IS_IPL_ACTIVE("tr_tuner_shop_mission")
REQUEST_IPL("tr_tuner_shop_mission")
ENDIF
IF NOT IS_IPL_ACTIVE("tr_tuner_shop_rancho")
REQUEST_IPL("tr_tuner_shop_rancho")
ENDIF
IF NOT IS_IPL_ACTIVE("tr_tuner_shop_strawberry")
REQUEST_IPL("tr_tuner_shop_strawberry")
ENDIF
ENDIF
IF g_bBlockBuildingControllerCarMeetIPLs
IF IS_IPL_ACTIVE("tr_tuner_meetup")
REMOVE_IPL("tr_tuner_meetup")
ENDIF
IF IS_IPL_ACTIVE("tr_tuner_race_line")
REMOVE_IPL("tr_tuner_race_line")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("tr_tuner_meetup")
REQUEST_IPL("tr_tuner_meetup")
ENDIF
IF NOT IS_IPL_ACTIVE("tr_tuner_race_line")
REQUEST_IPL("tr_tuner_race_line")
ENDIF
ENDIF
#IF FEATURE_FIXER
IF g_bBlockBuildingControllerFixerPackIPLs
IF IS_IPL_ACTIVE("sf_musicrooftop")
REMOVE_IPL("sf_musicrooftop")
ENDIF
IF IS_IPL_ACTIVE("sf_phones")
REMOVE_IPL("sf_phones")
ENDIF
IF IS_IPL_ACTIVE("sf_franklin")
REMOVE_IPL("sf_franklin")
ENDIF
IF IS_IPL_ACTIVE("sf_mansionroof")
REMOVE_IPL("sf_mansionroof")
ENDIF
IF IS_IPL_ACTIVE("sf_plaque_hw1_08")
REMOVE_IPL("sf_plaque_hw1_08")
ENDIF
IF IS_IPL_ACTIVE("sf_plaque_bh1_05")
REMOVE_IPL("sf_plaque_bh1_05")
ENDIF
IF IS_IPL_ACTIVE("sf_plaque_kt1_08")
REMOVE_IPL("sf_plaque_kt1_08")
ENDIF
IF IS_IPL_ACTIVE("sf_plaque_kt1_05")
REMOVE_IPL("sf_plaque_kt1_05")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("sf_musicrooftop")
REQUEST_IPL("sf_musicrooftop")
ENDIF
IF NOT IS_IPL_ACTIVE("sf_phones")
REQUEST_IPL("sf_phones")
ENDIF
IF NOT IS_IPL_ACTIVE("sf_franklin")
REQUEST_IPL("sf_franklin")
ENDIF
IF NOT IS_IPL_ACTIVE("sf_mansionroof")
REQUEST_IPL("sf_mansionroof")
ENDIF
ENDIF
IF NOT IS_IPL_ACTIVE("sf_franklin_slidefix")
REQUEST_IPL("sf_franklin_slidefix")
ENDIF
IF NOT IS_IPL_ACTIVE("reh_simeonFix")
REQUEST_IPL("reh_simeonFix")
ENDIF
#ENDIF
#IF FEATURE_DLC_1_2022
IF NOT g_bBlockBuildingControllerSum2PackIPLs
IF NOT g_sMPTunables.bDISABLE_LUXURY_SHOWROOM
IF IS_IPL_ACTIVE("hei_showroom_closed")
REMOVE_IPL("hei_showroom_closed")
ENDIF
IF NOT IS_IPL_ACTIVE("hei_showroom_open")
REQUEST_IPL("hei_showroom_open")
ENDIF
IF NOT IS_IPL_ACTIVE("hei_showroom_open_props")
REQUEST_IPL("hei_showroom_open_props")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("hei_showroom_closed")
REQUEST_IPL("hei_showroom_closed")
ENDIF
IF IS_IPL_ACTIVE("hei_showroom_open")
REMOVE_IPL("hei_showroom_open")
ENDIF
IF IS_IPL_ACTIVE("hei_showroom_open_props")
REMOVE_IPL("hei_showroom_open_props")
ENDIF
ENDIF
ENDIF
#ENDIF
#IF FEATURE_DLC_2_2022
IF NOT g_bBlockBuildingControllerWinter22PackIPLs
IF NOT IS_IPL_ACTIVE("xm3_garage_fix")
REQUEST_IPL("xm3_garage_fix")
ENDIF
IF NOT IS_IPL_ACTIVE("xm3_warehouse")
REQUEST_IPL("xm3_warehouse")
ENDIF
IF g_sMPTunables.bWINTER_22_DISABLE_MEDICAL_SIGN_IPL
IF IS_IPL_ACTIVE("xm3_doc_sign")
REMOVE_IPL("xm3_doc_sign")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("xm3_doc_sign")
REQUEST_IPL("xm3_doc_sign")
ENDIF
ENDIF
ENDIF
#ENDIF
IF g_bBlockBuildingControllerArenaPackIPLs
IF IS_IPL_ACTIVE("xs_arena_banners_ipl")
REMOVE_IPL("xs_arena_banners_ipl")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("xs_arena_banners_ipl")
REQUEST_IPL("xs_arena_banners_ipl")
ENDIF
ENDIF
//Casino property main doors
IF NOT g_bBlockBuildingControllerCasinoIPLs
IF IS_BIT_SET(g_SimpleInteriorData.iSixthBS, BS6_SIMPLE_INTERIOR_HIDE_CASINO_PENTHOUSE_WINDOWS)
IF IS_IPL_ACTIVE("hei_dlc_windows_casino")
REMOVE_IPL("hei_dlc_windows_casino")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("hei_dlc_windows_casino")
REQUEST_IPL("hei_dlc_windows_casino")
ENDIF
ENDIF
IF IS_BIT_SET(g_SimpleInteriorData.iSixthBS, BS6_SIMPLE_INTERIOR_HIDE_CASINO_FRONT_DOORS)
IF IS_IPL_ACTIVE("hei_dlc_casino_door")
REMOVE_IPL("hei_dlc_casino_door")
ENDIF
IF IS_IPL_ACTIVE("vw_dlc_casino_door")
REMOVE_IPL("vw_dlc_casino_door")
ENDIF
IF NOT IS_IPL_ACTIVE("hei_dlc_casino_door_broken")
REQUEST_IPL("hei_dlc_casino_door_broken")
ENDIF
ELSE
IF NOT IS_IPL_ACTIVE("hei_dlc_casino_door")
REQUEST_IPL("hei_dlc_casino_door")
ENDIF
IF NOT IS_IPL_ACTIVE("vw_dlc_casino_door")
REQUEST_IPL("vw_dlc_casino_door")
ENDIF
IF IS_IPL_ACTIVE("hei_dlc_casino_door_broken")
REMOVE_IPL("hei_dlc_casino_door_broken")
ENDIF
ENDIF
IF IS_IPL_ACTIVE("hei_dlc_casino_aircon")
REMOVE_IPL("hei_dlc_casino_aircon")
ENDIF
IF NOT IS_IPL_ACTIVE("ch_dlc_casino_aircon_broken")
REQUEST_IPL("ch_dlc_casino_aircon_broken")
ENDIF
IF NOT g_bBlockBuildingControllerOnMission
IF NOT IS_IPL_ACTIVE("ch_h3_casino_cameras")
REQUEST_IPL("ch_h3_casino_cameras")
ENDIF
ENDIF
ENDIF
#IF FEATURE_FIXER
IF g_sMPTunables.bFIXER_ENABLE_SF_BILLBOARDS
#IF IS_DEBUG_BUILD
OR GET_COMMANDLINE_PARAM_EXISTS("sc_ForceAgencySFBillboards")
#ENDIF
ADD_AGENCY_SF_BILLBOARDS()
ENDIF
#ENDIF
ENDIF
IF NOT IS_MP_MAP_LOADED()
g_bBlockBuildingControllerHatches = FALSE
ENDIF
IF NOT bRemoveYachtIPLS
IF IS_MP_MAP_LOADED()
bRemoveYachtIPLS = TRUE
ENDIF
ELSE
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
AND NOT IS_MP_MAP_LOADED()
PRINTSTRING("\n building_controller: Removing yacht IPLs")
REMOVE_ALL_PRIVATE_YACHTS_IPLS_NOW()
bRemoveYachtIPLS = FALSE
ENDIF
ENDIF
IF bForceRemoveYachtIPLs
AND IS_MP_MAP_LOADED()
PRINTSTRING("\n building_controller: Force removing yacht IPLs")
REMOVE_ALL_PRIVATE_YACHTS_IPLS_NOW()
bForceRemoveYachtIPLs = FALSE
ENDIF
ENDPROC
SCRIPT
//g_bEmailSystemContentCallback = TRUE
//g_EmailContentCallback = &PROPERTY_EMAIL_CALLBACK
CPRINTLN(DEBUG_BUILDING, "Starting building_controller.")
NETWORK_SET_SCRIPT_IS_SAFE_FOR_NETWORK_GAME()
// Setup some debug widgets
#IF IS_DEBUG_BUILD
SETUP_BUILDING_CONTROL_WIDGETS()
#ENDIF
INT iIPL
REPEAT MAX_IPLS_TO_TRACK_FOR_REMOVAL iIPL
g_tlIPLsToRemoveOnFadeOut[iIPL] = ""
ENDREPEAT
WAIT(0)
// Main loop
WHILE (TRUE)
IF IS_PLAYING_DLC_INTRO_BINK()
CPRINTLN(DEBUG_BUILDING, "casino bink playing")
ELSE
CHECK_CONTROLLER_RESET()
SWITCH eStage
CASE BC_STAGE_INIT
DO_INITIALISE()
BREAK
CASE BC_STAGE_UPDATE
CLEANUP_PROLOGUE_MAP()
UPDATE_BUILDING_STATES()
// Only run in SP
IF USE_SP_BUILDING_CONTROLLER_DATA()
// Block door updates on all minigames except property missions.
IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_MINIGAME)
OR g_PropertySystemData.propertyManagementState = PROPERTY_MANAGEMENT_STATE_RUNNING
UPDATE_DOOR_STATES()
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF NOT IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
IF NOT bToggleDoors
//INIT_PED_SPECIFIC_AUTOMATIC_DOORS()
ENDIF
ELSE
IF bToggleDoors
//CLEAR_PED_SPECIFIC_AUTOMATIC_DOORS()
ENDIF
ENDIF
ENDIF
MANAGE_PED_SPECIFIC_AUTOMATIC_DOORS()
//CHECK_FOR_TREVOR_AS_DOCK_WORKER_FOR_AUTODOORS() // Kenneth R. - moved to player controller as it deals with clothes.
ENDIF
ENDIF
BREAK
CASE BC_STAGE_IDLE
// Wait for game to change mode.
// Required for B* 1630268 - Steve R. LDS
IF g_bCleanupMultiplayerMissionInteriors
if not is_new_load_scene_active()
OR (IS_PLAYER_SWITCH_IN_PROGRESS() AND GET_PLAYER_SWITCH_STATE() = SWITCH_STATE_WAITFORINPUT)
CPRINTLN(DEBUG_BUILDING, "building_controller: g_bCleanupMultiplayerMissionInteriors = TRUE - cleaning up MP mission interiors.")
g_bCleanupMultiplayerMissionInteriors = FALSE
IF IS_IPL_ACTIVE("TrevorsMP")
REMOVE_IPL("TrevorsMP")
ENDIF
IF NOT IS_IPL_ACTIVE("TrevorsTrailer")
REQUEST_IPL("TrevorsTrailer")
ENDIF
IF IS_IPL_ACTIVE("shr_int")
REMOVE_IPL("shr_int")
ENDIF
IF NOT IS_IPL_ACTIVE("fakeint")
REQUEST_IPL("fakeint")
ENDIF
endif
ENDIF
BREAK
ENDSWITCH
UPDATE_INTERIOR_STATES() // This handles disabling/capping on exit, and needs to run all the time.
MAINTAIN_MP_IPLS()
MAINTAIN_PROP_BLOCKERS()
// Maintain the debug widgets
#IF IS_DEBUG_BUILD
MAINTAIN_BUILDING_CONTROL_WIDGETS()
MAINTAIN_ISLAND_HEIST_DEBUG_WARP_ON_BOOT()
#ENDIF
ENDIF
WAIT(0)
ENDWHILE
ENDSCRIPT