Files
gtav-src/script/dev_ng/singleplayer/scripts/RandomChar/Ambient/epsCars.sc
T
2025-09-29 00:52:08 +02:00

1730 lines
53 KiB
Python
Executable File

//////////////////////////////////////////////////////////////////////////////////////////
// //
// SCRIPT NAME : epsCars.sc //
// AUTHOR : //
// DESCRIPTION : Manages the progress of the Epsilon 3 car pickup request //
// emails and objectives. //
// //
//////////////////////////////////////////////////////////////////////////////////////////
//----------------------
// INCLUDES
//----------------------
USING "email_public.sch"
USING "rgeneral_include.sch"
USING "RC_Helper_Functions.sch"
//----------------------
// ENUMS
//----------------------
ENUM STAGE_ENUM
SE_GET_VEHICLE = 0,
SE_APPROACH_GARAGE,
SE_DELIVER_VEHICLE,
SE_VEHICLE_OCCUPIED,
SE_PLAYER_WANTED,
SE_LEAVE_VEHICLE,
SE_MISSION_CLEAR
ENDENUM
ENUM GARAGE_DOOR_STATE
GDS_NULL,
GDS_OPEN,
GDS_CLOSED,
GDS_CLOSING,
GDS_OPENING
ENDENUM
//----------------------
// CONSTS
//----------------------
CONST_INT XVERSION_NUMBER 216
CONST_FLOAT GARAGE_DOOR_SPEED 0.05
CONST_FLOAT GARAGE_DOOR_OPEN_RATIO 1.0
CONST_FLOAT GARAGE_DOOR_CLOSED_RATIO 0.0
CONST_INT DAMAGE_THRESHOLD 750 // if the vehicles hp is less than this help text comes up and the offer to grab a car will be rejected
CONST_INT QUALITY_THRESHOLD 875 // if the vehicles hp is less this a bad e-mail gets sent
CONST_INT MAX_CARS 5
CONST_INT NO_MIDSIZED_MESSAGE 99
CONST_FLOAT DOOR_DIST_THRESHOLD 15.0
//---------------------
// STRUCTS
//----------------------
STRUCT EMAIL_HELPER
EMAIL_MESSAGE_ENUMS eMailID
STRING sEmailBody
STRING sEmailBadBody
ENDSTRUCT
STRUCT GARAGE_DOOR_HELPER
GARAGE_DOOR_STATE doorState
GARAGE_DOOR_STATE doorDesiredState
MODEL_NAMES doorModel
VECTOR vDoorPosition
VECTOR vCenterPosition
FLOAT fDoorRatio = 0.0
FLOAT fDoorSpeed = 0.015
FLOAT fGarageRadius = 7.25
ENDSTRUCT
STRUCT GARAGE_HELPER
VECTOR vDoorPosition
MODEL_NAMES doorModel
GARAGE_DOOR_STATE doorState
GARAGE_DOOR_STATE doorDesiredState
ANGLED_AREA garageArea // make sure the width goes along the door axis
VECTOR vCenterPosition
FLOAT fDoorRatio = 0.0
FLOAT fDoorSpeed = 0.015
VECTOR vDoorEdge[2]
BOOL bIsBlocked = FALSE
ENDSTRUCT
//---------------------
// VARIABLES
//----------------------
VECTOR vDropOffPoint = <<-690.938049,512.270325,109.363853>> // 3meter radius
GARAGE_HELPER dropOffGarage
EMAIL_HELPER eMailHelper[MAX_CARS]
MODEL_NAMES carModels[MAX_CARS]
BLIP_INDEX vLocationBlip
STAGE_PROGRESS stageProgress
STAGE_ENUM stageEnum
INT SoundID
BOOL bPlayingLoopedSound = FALSE
INT iNextDay
INT iSubState = 0
INT iCarsDelivered = 0
INT iLastIndexDelivered = -1
BOOL bHelpDisplayed = FALSE
BOOL bDmgHelpDisplayed = FALSE
BOOL bMessHelpDisplayed = FALSE
BOOL bExitCarHelpDisplayed = FALSE
BOOL bBeenWanted = FALSE
INT iBlockedTimer
INT iEmailTimer = 0
INT EMAIL_DELAY = 60000 // ONE_MINUTE
ANGLED_AREA noGarageRoadArea
VEHICLE_INDEX currentEpsilonVehicle
SCENARIO_BLOCKING_INDEX sScenarioBlockIndex
structPedsForConversation convoMichael
SCALEFORM_INDEX sFormMidSized
INT iMidSizedMessageStage = NO_MIDSIZED_MESSAGE
INT iMidSizedMessageTimer
#IF IS_DEBUG_BUILD
WIDGET_GROUP_ID mWidgetGroup
BLIP_INDEX vVehicleGenBlip[7]
BLIP_INDEX blipDropOff
INT iCurrentDay = GET_CLOCK_DAY_OF_MONTH()
BOOL bAdvanceTime = FALSE
BOOL bForceQuitWin = FALSE
BOOL bForceQuitFail = FALSE
INT iShowState = 0
BOOL bTestOpenDoor = FALSE
BOOL bTestCloseDoor = FALSE
BOOL bIsInStopArea = FALSE
BOOL bIsGarageOccupied = FALSE
BOOL bIsDoorBlocked = FALSE
BOOL bTempCarDelivered[MAX_CARS]
BOOL bTempCarBadCondition[MAX_CARS]
BOOL bBlipDropOffPoint = FALSE
BOOL bShowVehicleGens = FALSE
BOOL bHideVehicleGens = FALSE
BOOL bHideVehicleGenCarbon = FALSE
BOOL bHideVehicleGenVacca = FALSE
BOOL bHideVehicleGenSurano = FALSE
BOOL bHideVehicleGenSuperD = FALSE
BOOL bHideVehicleGenTornado = FALSE
BOOL bShowDebugStuff = FALSE
BOOL bWarpToGarage = FALSE
BOOL bSendTestEmail
INT iFakeCarsLeftCount = 0
BOOL bCreatePedInCar = FALSE
FLOAT fDistDoor
FLOAT fDistCenter
INT iCarHP = 0
INT iCarBrokeParts = 0
INT iCarLooseParts = 0
VECTOR vGarageSafePoint = <<-690.156982,511.264130,109.363853>> // 7.25 radius
#ENDIF
FUNC BOOL IS_DYNAMIC_EMAIL_ARRIVED_YET(DYNAMIC_EMAIL_THREAD_NAMES thread)
INT index = GET_DYNAMIC_EMAIL_THREAD_BUFFER_INDEX(thread)
IF index = -1
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC: Buffer no longer exists")
RETURN TRUE
ENDIF
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC: iProgress on this buffer is = ", g_DynamicEmailThreadBuffers[index].iProgress)
RETURN FALSE
ENDFUNC
//----------------------
// GARAGE FUNCTIONS
//----------------------
/// PURPOSE:
/// Setups a garage
/// PARAMS:
/// gdh -
/// mdl -
/// doorPos -
/// p1 -
/// p2 -
/// width -
PROC SETUP_GARAGE_HELPER(GARAGE_HELPER &gdh, MODEL_NAMES mdl, VECTOR doorPos, VECTOR cpos, VECTOR p1, VECTOR p2, FLOAT width, VECTOR d1, VECTOR d2)
gdh.doorModel = mdl
gdh.vDoorPosition = doorPos
gdh.doorDesiredState = GDS_CLOSED
gdh.doorState = GDS_NULL
gdh.vDoorEdge[0] = d1
gdh.vDoorEdge[1] = d2
gdh.vCenterPosition = cpos
SET_ANGLED_AREA(gdh.garageArea, p1, p2, width)
ENDPROC
/// PURPOSE:
/// Checks if garage has finished closing
/// PARAMS:
/// gdh - reference
FUNC BOOL HAS_GARAGE_HELPER_FINISHED_CLOSING(GARAGE_HELPER &gdh)
RETURN (gdh.doorDesiredState = GDS_CLOSED) AND (gdh.doorState = GDS_CLOSED)
ENDFUNC
/// PURPOSE:
/// Checks if garage has finished moving
/// PARAMS:
/// gdh - reference
FUNC BOOL HAS_GARAGE_HELPER_FINISHED_MOVING(GARAGE_HELPER &gdh)
RETURN gdh.doorDesiredState = gdh.doorState
ENDFUNC
/// PURPOSE:
/// Checks if garage has finished opening
/// PARAMS:
/// gdh - reference
FUNC BOOL HAS_GARAGE_HELPER_FINISHED_OPENING(GARAGE_HELPER &gdh)
RETURN (gdh.doorDesiredState = GDS_OPEN) AND (gdh.doorState = GDS_OPEN)
ENDFUNC
FUNC BOOL IS_PLAYER_CLEAR_OF_GARAGE(GARAGE_HELPER &gdh)
RETURN NOT (gdh.bIsBlocked) AND NOT IS_POSITION_OCCUPIED(gdh.vCenterPosition, 6.2, FALSE, FALSE, TRUE, FALSE, FALSE)
ENDFUNC
/// PURPOSE:
/// Sets the Garage State
/// PARAMS:
/// gdh - reference
/// state - new state
PROC SET_DESIRED_GARAGE_HELPER_STATE(GARAGE_HELPER &gdh, GARAGE_DOOR_STATE state)
gdh.doorDesiredState = state
ENDPROC
/// PURPOSE:
/// Locks the garage
/// PARAMS:
/// gdh - reference
PROC FORCE_LOCK_GARAGE_HELPER(GARAGE_HELPER &gdh)
IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(gdh.vDoorPosition, 20.0, gdh.doorModel)
SET_STATE_OF_CLOSEST_DOOR_OF_TYPE(gdh.doorModel, gdh.vDoorPosition, TRUE, GARAGE_DOOR_CLOSED_RATIO)
ENDIF
ENDPROC
/// PURPOSE:
/// Unlocks the garage
/// PARAMS:
/// gdh - reference
PROC FORCE_UNLOCK_GARAGE_HELPER(GARAGE_HELPER &gdh)
IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(gdh.vDoorPosition, 20.0, gdh.doorModel)
SET_STATE_OF_CLOSEST_DOOR_OF_TYPE(gdh.doorModel, gdh.vDoorPosition, FALSE, -1.0)
ENDIF
ENDPROC
/// PURPOSE:
/// Update Garage
/// PARAMS:
/// gdh - reference
PROC UPDATE_GARAGE_HELPER(GARAGE_HELPER &gdh)
VECTOR v
// do blocked check - should do these on odd and even frames
gdh.bIsBlocked = FALSE
IF IS_POSITION_OCCUPIED(gdh.vDoorEdge[0], 1.2, FALSE, TRUE, TRUE, FALSE, FALSE, PLAYER_PED_ID())
gdh.bIsBlocked = TRUE
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: Garage is blocked (gdh.vDoorEdge[0] occupied)")
ELIF IS_POSITION_OCCUPIED(gdh.vDoorEdge[1], 1.2, FALSE, TRUE, TRUE, FALSE, FALSE, PLAYER_PED_ID())
gdh.bIsBlocked = TRUE
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: Garage is blocked (gdh.vDoorEdge[1] occupied)")
ELSE
v = INTERPOLATE_VECTOR(gdh.vDoorEdge[0], gdh.vDoorEdge[1], 0.5)
gdh.bIsBlocked = IS_POSITION_OCCUPIED(v, 1.2, FALSE, TRUE, TRUE, FALSE, FALSE, PLAYER_PED_ID())
IF gdh.bIsBlocked
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: Garage is blocked (INTERPOLATE_VECTOR occupied)")
ENDIF
ENDIF
// update closing off door
IF (gdh.doorDesiredState = GDS_CLOSED) AND ((gdh.doorState <> GDS_CLOSED) OR (gdh.doorState = GDS_CLOSING))
gdh.fDoorRatio -= gdh.fDoorSpeed
IF (gdh.fDoorRatio <= GARAGE_DOOR_CLOSED_RATIO)
gdh.fDoorRatio = GARAGE_DOOR_CLOSED_RATIO
gdh.doorState = GDS_CLOSED
STOP_SOUND(SoundID)
CPRINTLN(DEBUG_AMBIENT, "Stopping Closing sound ID")
bPlayingLoopedSound = FALSE
PLAY_SOUND_FROM_COORD(-1, "CLOSED", gdh.vDoorPosition, "DOOR_GARAGE", DEFAULT, DEFAULT, TRUE)
ELSE
IF NOT bPlayingLoopedSound
PLAY_SOUND_FROM_COORD(SoundID, "CLOSING", gdh.vDoorPosition, "DOOR_GARAGE", DEFAULT, DEFAULT, TRUE)
CPRINTLN(DEBUG_AMBIENT, "Playing Closing audio loop")
bPlayingLoopedSound = TRUE
ENDIF
ENDIF
ENDIF
IF (gdh.doorDesiredState = GDS_OPEN) AND ((gdh.doorState <> GDS_OPEN) OR (gdh.doorState = GDS_OPENING))
gdh.fDoorRatio += gdh.fDoorSpeed
IF (gdh.fDoorRatio >= GARAGE_DOOR_OPEN_RATIO)
gdh.fDoorRatio = GARAGE_DOOR_OPEN_RATIO
gdh.doorState = GDS_OPEN
STOP_SOUND(SoundID)
CPRINTLN(DEBUG_AMBIENT, "Stopping Opening sound ID")
bPlayingLoopedSound = FALSE
PLAY_SOUND_FROM_COORD(-1, "OPENED", gdh.vDoorPosition, "DOOR_GARAGE", DEFAULT, DEFAULT, TRUE)
ELSE
IF NOT bPlayingLoopedSound
PLAY_SOUND_FROM_COORD(SoundID, "OPENING", gdh.vDoorPosition, "DOOR_GARAGE", DEFAULT, DEFAULT, TRUE)
CPRINTLN(DEBUG_AMBIENT, "Playing Opening audio loop")
bPlayingLoopedSound = TRUE
ENDIF
ENDIF
ENDIF
IF DOES_OBJECT_OF_TYPE_EXIST_AT_COORDS(gdh.vDoorPosition, 20.0, gdh.doorModel)
SET_STATE_OF_CLOSEST_DOOR_OF_TYPE(gdh.doorModel, gdh.vDoorPosition, TRUE, gdh.fDoorRatio)
ENDIF
ENDPROC
//----------------------
// CARCHECK FUNCTIONS
//----------------------
//------------------------------------------------------------------------------
// FUNCTION: GET_CARS_DELIVERED_COUNT()
// PURPOSE: TELLS US HOW MANY CARS ARE DELIVERED
//------------------------------------------------------------------------------
FUNC INT GET_CARS_DELIVERED_COUNT()
INT i = 0
INT cnt = 0
REPEAT MAX_CARS i
IF IS_BIT_SET(iCarsDelivered, i)
cnt ++
ENDIF
ENDREPEAT
RETURN cnt
ENDFUNC
PROC FORCE_ALL_CARS_DELIVERED()
INT i
iCarsDelivered = 0
REPEAT MAX_CARS i
SET_BIT(iCarsDelivered, i)
ENDREPEAT
ENDPROC
FUNC INT GET_CARS_LEFT_COUNT()
RETURN MAX_CARS - GET_CARS_DELIVERED_COUNT()
ENDFUNC
//------------------------------------------------------------------------------
// FUNCTION: ARE_ALL_CARS_DELIVERED()
// PURPOSE: RETURNS TRUE IF ALL CARS ARE DELIVERED
//------------------------------------------------------------------------------
FUNC BOOL ARE_ALL_CARS_DELIVERED()
RETURN (GET_CARS_DELIVERED_COUNT() = MAX_CARS)
ENDFUNC
//------------------------------------------------------------------------------
// FUNCTION: IS_CAR_INDEX_DELIVERED()
// PURPOSE: RETURNS CAR INDEX IS DELIVERED
//------------------------------------------------------------------------------
FUNC BOOL IS_CAR_INDEX_DELIVERED(INT i)
RETURN IS_BIT_SET(iCarsDelivered, i)
ENDFUNC
//------------------------------------------------------------------------------
// FUNCTION: IS_CAR_INDEX_DELIVERED()
// PURPOSE: RETURNS CAR INDEX IS DELIVERED
//------------------------------------------------------------------------------
FUNC BOOL IS_CAR_INDEX_CONDITION_BAD(INT i)
IF (i < 0)
RETURN TRUE
ENDIF
RETURN IS_BIT_SET(iCarsDelivered, i + MAX_CARS)
ENDFUNC
/// PURPOSE:
/// Checks if player is any car which hasn't been delivered and is good enough for Epsilon
/// RETURNS:
///
FUNC BOOL IS_CAR_ON_REQUIRED_LIST(VEHICLE_INDEX v)
INT i
REPEAT MAX_CARS i
IF GET_ENTITY_MODEL(v) = carModels[i]
IF NOT IS_CAR_INDEX_DELIVERED(i)
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
//------------------------------------------------------------------------------
// FUNCTION: IS_CAR_TOO_BUST_FOR_EPSILON(()
// PURPOSE: RETURNS TRUE IF A CAR IS NO GOOD
//------------------------------------------------------------------------------
FUNC BOOL IS_CAR_TOO_BUST_FOR_EPSILON(VEHICLE_INDEX v)
IF NOT IS_ENTITY_OK(v)
RETURN TRUE
ENDIF
IF (GET_ENTITY_HEALTH(v) < DAMAGE_THRESHOLD)
RETURN TRUE
ENDIF
IF IS_VEHICLE_BUMPER_BROKEN_OFF(v, TRUE) OR IS_VEHICLE_BUMPER_BROKEN_OFF(v, FALSE)
RETURN TRUE
ENDIF
RETURN GET_VEHICLE_NUM_OF_BROKEN_OFF_PARTS(v) > 0
ENDFUNC
//------------------------------------------------------------------------------
// FUNCTION: IS_CAR_INDEX_DELIVERED()
// PURPOSE: RETURNS CAR INDEX IS DELIVERED
//------------------------------------------------------------------------------
PROC SET_CAR_INDEX_DELIVERED(INT i, BOOL del)
IF (del)
SET_BIT(iCarsDelivered, i)
iLastIndexDelivered = i
ELSE
CLEAR_BIT(iCarsDelivered, i)
ENDIF
ENDPROC
//------------------------------------------------------------------------------
// FUNCTION: IS_CAR_INDEX_DELIVERED()
// PURPOSE: RETURNS CAR INDEX IS DELIVERED
//------------------------------------------------------------------------------
PROC SET_CAR_INDEX_CONDITION_BAD(INT i, BOOL con)
IF (con)
SET_BIT(iCarsDelivered, i + MAX_CARS)
ELSE
CLEAR_BIT(iCarsDelivered, i + MAX_CARS)
ENDIF
ENDPROC
//------------------------------------------------------------------------------
// FUNCTION: FORCE_SET_ALL_CARS_DELIVERED()
// PURPOSE: SETS ALL CARS TO BE DELIVERED - FOR 'S' SKIP
//------------------------------------------------------------------------------
PROC FORCE_SET_ALL_CARS_DELIVERED()
INT i
REPEAT MAX_CARS i
SET_CAR_INDEX_DELIVERED(i, TRUE)
ENDREPEAT
g_savedGlobals.sAmbient.iEpsilonCarStage = iCarsDelivered
ENDPROC
FUNC BOOL CHECK_CARMODEL(MODEL_NAMES carModel, INT ind)
IF (carModel = carModels[ind])
RETURN TRUE
ENDIF
IF (carModels[ind] <> TORNADO2)
RETURN FALSE
ENDIF
IF (carModel = TORNADO)
RETURN TRUE
ENDIF
IF (carModel = TORNADO2)
RETURN TRUE
ENDIF
IF (carModel = TORNADO3)
RETURN TRUE
ENDIF
IF (carModel = TORNADO4)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Marks off Delivered Car
/// PARAMS:
/// v - Car index
/// RETURNS:
/// Returns true if it has been delivered
FUNC BOOL MARK_OFF_DELIVERED_CAR(VEHICLE_INDEX v)
INT i
MODEL_NAMES carModel = GET_ENTITY_MODEL(v)
IF IS_CAR_TOO_BUST_FOR_EPSILON(v)
RETURN FALSE
ENDIF
REPEAT MAX_CARS i
IF CHECK_CARMODEL(carModel, i)
IF NOT IS_CAR_INDEX_DELIVERED(i)
SET_CAR_INDEX_CONDITION_BAD(i, (GET_ENTITY_HEALTH(v) < QUALITY_THRESHOLD))
SET_CAR_INDEX_DELIVERED(i, TRUE)
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks if player is any car which hasn't been delivered and is good enough for Epsilon
/// RETURNS:
///
FUNC BOOL IS_PLAYER_IN_ANY_UNDELIVERED_CAR()
INT i = 0
VEHICLE_INDEX v
IF NOT IS_ENTITY_OK(PLAYER_PED_ID())
RETURN FALSE
ENDIF
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
bDmgHelpDisplayed = FALSE
RETURN FALSE
ENDIF
v = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID())
IF NOT IS_ENTITY_OK(v)
RETURN FALSE
ENDIF
REPEAT MAX_CARS i
IF NOT IS_CAR_INDEX_DELIVERED(i)
IF CHECK_CARMODEL(GET_ENTITY_MODEL(v), i)
IF IS_CAR_TOO_BUST_FOR_EPSILON(v)
IF NOT (bDmgHelpDisplayed)
PRINT_HELP("EPS_DROP_FAIL")
bDmgHelpDisplayed = TRUE
ENDIF
RETURN FALSE
ENDIF
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
//------------------------------------------------------------------------------
// FUNCTION: IS_PLAYER_IN_ANY_UNDELIVERED_CAR()
// PURPOSE: RETURNS IF PLAYER IS NOT IN A DELIVERED CAR
//------------------------------------------------------------------------------
FUNC BOOL MARK_OFF_ANY_UNDELIVERED_CARS_IN_GARAGE(GARAGE_HELPER &gdh)
INT i
INT iCnt
BOOL ok = FALSE
VEHICLE_INDEX carArray[20]
iCnt = GET_PED_NEARBY_VEHICLES(PLAYER_PED_ID(), carArray)
IF (iCnt = 0)
RETURN FALSE
ENDIF
REPEAT iCnt i
IF IS_ENTITY_OK(carArray[i])
IF IS_ENTITY_IN_ANGLED_AREA(carArray[i], gdh.garageArea.vPosition[0], gdh.garageArea.vPosition[1], gdh.garageArea.fWidth)
AND NOT gdh.bIsBlocked
IF MARK_OFF_DELIVERED_CAR(carArray[i])
ok = TRUE
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF (ok = TRUE)
g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay = GET_CLOCK_DAY_OF_MONTH()
CPRINTLN(DEBUG_AMBIENT, "NEXT E-MAIL WILL BE SEND OUT ON THE ", (g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay + 14) % GET_NUMBER_OF_DAYS_IN_MONTH(INT_TO_ENUM(MONTH_OF_YEAR, GET_CLOCK_MONTH()), GET_CLOCK_YEAR()))
iEmailTimer = GET_GAME_TIMER() + EMAIL_DELAY
ENDIF
RETURN ok
ENDFUNC
//----------------------
// FUNCTIONS
//----------------------
PROC START_VEHICLE_DELIVERED_MESSAGE()
iMidSizedMessageStage = 0
//Set epsilon step stat
INT iCurrent
STAT_GET_INT(NUM_EPSILON_STEP,iCurrent)
IF iCurrent < 6+GET_CARS_DELIVERED_COUNT()
STAT_SET_INT(NUM_EPSILON_STEP,6+GET_CARS_DELIVERED_COUNT())
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH20),6+GET_CARS_DELIVERED_COUNT())
ENDIF
ENDPROC
/// PURPOSE:
// Print a message stating how many signs have been destroyed if this is needed...
// Now using the Midsized message UI as per Les request
/// PARAMS:
// data - contains needed data
// iMessageStage - the stage of the message displaying (for the case statement)
// siMessage - scaleform index
// sTitle - the message string to display (e.g so many scraps collected/ destroyed)
PROC UPDATE_VEHICLE_DELIVERED_MESSAGE(SCALEFORM_INDEX &siMessage, INT &iMessageTimer, INT &iMessageStage)
INT iSplashSoundID
SWITCH iMessageStage
CASE 0
siMessage = REQUEST_SCALEFORM_MOVIE("MIDSIZED_MESSAGE")
IF HAS_SCALEFORM_MOVIE_LOADED(siMessage)
iSplashSoundID = GET_SOUND_ID()
PLAY_SOUND_FRONTEND(iSplashSoundID, "CHECKPOINT_UNDER_THE_BRIDGE", "HUD_MINI_GAME_SOUNDSET")
iMessageStage++
ENDIF
BREAK
CASE 1
BEGIN_SCALEFORM_MOVIE_METHOD(siMessage, "SHOW_SHARD_MIDSIZED_MESSAGE")
BEGIN_TEXT_COMMAND_SCALEFORM_STRING("EPS_CAR_TITLE")
END_TEXT_COMMAND_SCALEFORM_STRING()
BEGIN_TEXT_COMMAND_SCALEFORM_STRING("EPS_CAR_NOTE")
ADD_TEXT_COMPONENT_INTEGER(GET_CARS_DELIVERED_COUNT())
END_TEXT_COMMAND_SCALEFORM_STRING()
END_SCALEFORM_MOVIE_METHOD()
iMessageTimer = GET_GAME_TIMER()
iMessageStage++
BREAK
CASE 2
IF (GET_GAME_TIMER() - iMessageTimer) > DEFAULT_GOD_TEXT_TIME - 500
BEGIN_SCALEFORM_MOVIE_METHOD(siMessage, "SHARD_ANIM_OUT")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(HUD_COLOUR_WHITE))
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(0.33)
END_SCALEFORM_MOVIE_METHOD()
iMessageStage++
ELSE
IF NOT IS_RESULT_SCREEN_DISPLAYING()
IF HAS_SCALEFORM_MOVIE_LOADED(siMessage)
DRAW_SCALEFORM_MOVIE_FULLSCREEN(siMessage, 100, 100, 100, 255)
ENDIF
ENDIF
ENDIF
BREAK
CASE 3
IF (GET_GAME_TIMER() - iMessageTimer) > DEFAULT_GOD_TEXT_TIME
iMessageStage++
ELSE
IF NOT IS_RESULT_SCREEN_DISPLAYING()
IF HAS_SCALEFORM_MOVIE_LOADED(siMessage)
DRAW_SCALEFORM_MOVIE_FULLSCREEN(siMessage, 100, 100, 100, 255)
ENDIF
ENDIF
ENDIF
BREAK
CASE 4
IF HAS_SCALEFORM_MOVIE_LOADED(siMessage)
SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(siMessage)
ENDIF
iMessageStage = NO_MIDSIZED_MESSAGE
BREAK
CASE NO_MIDSIZED_MESSAGE
BREAK
ENDSWITCH
ENDPROC
//----------------------
// EMAIL FUNCTIONS
//----------------------
FUNC STRING GET_VEHICLE_TEXT_KEY_FROM_INDEX(MODEL_NAMES mdl)
IF (mdl = carModels[0])
RETURN "EPS_CARNME_0"
ENDIF
IF (mdl = carModels[1])
RETURN "EPS_CARNME_1"
ENDIF
IF (mdl = carModels[2])
RETURN "EPS_CARNME_2"
ENDIF
IF (mdl = carModels[3])
RETURN "EPS_CARNME_3"
ENDIF
IF (mdl = carModels[4])
RETURN "EPS_CARNME_4"
ENDIF
SCRIPT_ASSERT("THE LIST OF VEHICLES HAS CHANGED")
RETURN "EPS_CARNME_N"
ENDFUNC
PROC SEND_INITIAL_EMAIL()
// setup first e-mail detialing cars
INT i
CPRINTLN(DEBUG_AMBIENT, "SENDING INITIAL E-MAIL")
FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, CULTINITIAL, TRUE)//bool added to denote that you're about to override the content
OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, "EPS_GMAIL_G5", FALSE)
REPEAT COUNT_OF (carModels) i
ADD_CONTENT_FOR_DYNAMIC_THREAD_SUBSTRING(DYNAMIC_THREAD_EPSILON3, GET_VEHICLE_TEXT_KEY_FROM_INDEX(carModels[i]))
#IF IS_DEBUG_BUILD
CPRINTLN(DEBUG_AMBIENT, "ADDING STRING:", GET_MODEL_NAME_FOR_DEBUG(carModels[i]))
#ENDIF
ENDREPEAT
PUSH_FEEDIFICATION_OF_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3)
g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay = GET_CLOCK_DAY_OF_MONTH()
ENDPROC
PROC SEND_EMAIL_FOR_CARS_LEFT(INT i)
// setup first e-mail detialing cars
INT iCarsLeft
IF (i <= 0)
EXIT
ENDIF
CPRINTLN(DEBUG_AMBIENT, "CARS LEFT:", i)
CPRINTLN(DEBUG_AMBIENT, "EMAIL INDEX:", MAX_CARS - i)
FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, eMailHelper[MAX_CARS - i].eMailID,TRUE)//bool added to denote that you're about to override the content
IF (IS_CAR_INDEX_CONDITION_BAD(iLastIndexDelivered))
OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, eMailHelper[MAX_CARS - i].sEmailBadBody,FALSE)
ELSE
OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, eMailHelper[MAX_CARS - i].sEmailBody,FALSE)
ENDIF
i = 0
iCarsLeft = 0
REPEAT COUNT_OF (carModels) i
IF NOT IS_CAR_INDEX_DELIVERED(i)
ADD_CONTENT_FOR_DYNAMIC_THREAD_SUBSTRING(DYNAMIC_THREAD_EPSILON3, GET_VEHICLE_TEXT_KEY_FROM_INDEX(carModels[i]))
#IF IS_DEBUG_BUILD
CPRINTLN(DEBUG_AMBIENT, "ADDING STRING:", GET_MODEL_NAME_FOR_DEBUG(carModels[i]))
#ENDIF
iCarsLeft ++
ENDIF
ENDREPEAT
PUSH_FEEDIFICATION_OF_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3)
g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay = GET_CLOCK_DAY_OF_MONTH()
// just to stop the release build from crting
IF (iCarsLeft = 0)
ENDIF
#IF IS_DEBUG_BUILD
i = 0
REPEAT (MAX_CARS - iCarsLeft) i
CPRINTLN(DEBUG_AMBIENT, "SANITY CHECK")
ENDREPEAT
#ENDIF
ENDPROC
//----------------------
// STATE FUNCTIONS
//----------------------
PROC SET_MISSION_STATE(STAGE_ENUM in)
// Setup new mission state
stageEnum = in
stageProgress = SP_SETUP
ENDPROC
/// PURPOSE: Triggers the mocap cutscene and completes mission once finished
PROC UPDATE_STATE_GET_VEHICLE(STAGE_PROGRESS &prog)
SWITCH (prog)
CASE SP_SETUP
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: In GET_VEHICLE")
prog = SP_RUNNING
bHelpDisplayed = FALSE
bMessHelpDisplayed = FALSE
SAFE_REMOVE_BLIP(vLocationBlip)
BREAK
CASE SP_RUNNING
// Fix for B*2202890 - quicksave saved player's position inside the garage while no car was around to keep the garage door open
// You shouldn't be able to get in here without a vehicle anyway so if you're in this area and still "looking for a car", something's gone wrong
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), dropOffGarage.garageArea.vPosition[0], dropOffGarage.garageArea.vPosition[1], dropOffGarage.garageArea.fWidth)
AND HAS_GARAGE_HELPER_FINISHED_CLOSING(dropOffGarage)
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - Player was inside garage when door was closed and trying to get a vehicle... teleporting player!")
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-687.6668, 500.5980, 109.0364>>)
SET_ENTITY_HEADING(PLAYER_PED_ID(), 200.7367)
ENDIF
ENDIF
IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), dropOffGarage.vDoorPosition, FALSE) > (DOOR_DIST_THRESHOLD + 5.0))
SET_DESIRED_GARAGE_HELPER_STATE(dropOffGarage, GDS_CLOSED)
IF dropOffGarage.doorState != GDS_CLOSED // Prevents the garage door update from constantly trying to close the door when you're close to it
dropOffGarage.doorState = GDS_CLOSING
ENDIF
ENDIF
IF IS_PLAYER_IN_ANY_UNDELIVERED_CAR()
IF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0)
SET_MISSION_STATE(SE_PLAYER_WANTED)
EXIT
ENDIF
prog = SP_CLEANUP
EXIT
ENDIF
BREAK
CASE SP_CLEANUP
IF (bHelpDisplayed = FALSE)
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
IF (currentEpsilonVehicle <> GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE))
currentEpsilonVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
PRINT_HELP("EPS_DROP_HELP")
bHelpDisplayed = TRUE
ENDIF
ENDIF
bDmgHelpDisplayed = FALSE
SET_MISSION_STATE(SE_APPROACH_GARAGE)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Update Delivery
/// PARAMS:
/// prog - stage
PROC UPDATE_STATE_PLAYER_WANTED(STAGE_PROGRESS &prog)
SWITCH (prog)
CASE SP_SETUP
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: In PLAYER_WANTED")
SAFE_REMOVE_BLIP(vLocationBlip)
IF bBeenWanted = FALSE
PRINT_HELP("EPS_DROP_WANTED")
ENDIF
prog = SP_RUNNING
BREAK
CASE SP_RUNNING
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0
prog = SP_CLEANUP
ENDIF
BREAK
CASE SP_CLEANUP
IF NOT IS_PLAYER_IN_ANY_UNDELIVERED_CAR()
SET_MISSION_STATE(SE_GET_VEHICLE)
ELSE
IF bBeenWanted = FALSE
PRINT_HELP("EPS_DROP_ESCAPE")
ENDIF
SET_MISSION_STATE(SE_DELIVER_VEHICLE)
ENDIF
bBeenWanted = TRUE
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Update Delivery
/// PARAMS:
/// prog - stage
PROC UPDATE_STATE_VEHICLE_OCCUPIED(STAGE_PROGRESS &prog)
VEHICLE_INDEX veh
SWITCH (prog)
CASE SP_SETUP
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: In VEHICLE_OCCUPIED")
SAFE_REMOVE_BLIP(vLocationBlip)
PRINT_HELP("EPS_DROP_PERSON")
prog = SP_RUNNING
BREAK
CASE SP_RUNNING
IF NOT IS_PLAYER_IN_ANY_UNDELIVERED_CAR()
prog = SP_CLEANUP
EXIT
ENDIF
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
IF IS_ENTITY_OK(veh)
IF (GET_VEHICLE_NUMBER_OF_PASSENGERS(veh) = 0)
prog = SP_CLEANUP
ENDIF
ENDIF
ENDIF
BREAK
CASE SP_CLEANUP
IF NOT IS_PLAYER_IN_ANY_UNDELIVERED_CAR()
SET_MISSION_STATE(SE_GET_VEHICLE)
ELSE
PRINT_HELP("EPS_DROP_ESCAPE")
SET_MISSION_STATE(SE_DELIVER_VEHICLE)
ENDIF
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Update Delivery
/// PARAMS:
/// prog - stage
PROC UPDATE_STATE_APPROACH_GARAGE(STAGE_PROGRESS &prog)
VEHICLE_INDEX veh
SWITCH (prog)
CASE SP_SETUP
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: In APPROACH_GARAGE")
IF NOT DOES_BLIP_EXIST(vLocationBlip)
vLocationBlip = ADD_BLIP_FOR_COORD(vDropOffPoint)
IF DOES_BLIP_EXIST(vLocationBlip)
SET_BLIP_SPRITE(vLocationBlip, RADAR_TRACE_EPSILON)
SET_BLIP_COLOUR(vLocationBlip, BLIP_COLOUR_MICHAEL)
ENDIF
ENDIF
prog = SP_RUNNING
iSubState = 0
BREAK
CASE SP_RUNNING
IF NOT IS_PLAYER_IN_ANY_UNDELIVERED_CAR()
SET_MISSION_STATE(SE_GET_VEHICLE)
EXIT
ENDIF
IF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0)
SET_MISSION_STATE(SE_PLAYER_WANTED)
EXIT
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
ENDIF
IF IS_ENTITY_OK(veh) AND (GET_VEHICLE_NUMBER_OF_PASSENGERS(veh) > 0)
IF GET_PED_IN_VEHICLE_SEAT(veh, VS_FRONT_RIGHT) <> PLAYER_PED_ID()
SET_MISSION_STATE(SE_VEHICLE_OCCUPIED)
EXIT
ENDIF
ENDIF
IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), dropOffGarage.vDoorPosition, FALSE) < DOOR_DIST_THRESHOLD)
prog = SP_CLEANUP
EXIT
ENDIF
BREAK
CASE SP_CLEANUP
SET_MISSION_STATE(SE_DELIVER_VEHICLE)
BREAK
ENDSWITCH
ENDPROC
/// PURPOSE:
/// Update Delivery
/// PARAMS:
/// prog - stage
PROC UPDATE_STATE_DELIVER_VEHICLE(STAGE_PROGRESS &prog)
VEHICLE_INDEX veh
SWITCH (prog)
CASE SP_SETUP
CPRINTLN(DEBUG_AMBIENT, "Eps Cars: In DELIVER_VEHICLE")
SET_DESIRED_GARAGE_HELPER_STATE(dropOffGarage, GDS_OPEN)
dropOffGarage.doorState = GDS_OPENING
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
STOP_FIRE_IN_RANGE(GET_ENTITY_COORDS(PLAYER_PED_ID()), 1.5)
ENDIF
prog = SP_RUNNING
iSubState = 0
iBlockedTimer = 0
BREAK
CASE SP_RUNNING
SWITCH (iSubState)
CASE 0 // wait for player to get in range
IF (bMessHelpDisplayed = TRUE) AND NOT (dropOffGarage.bIsBlocked)
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EPS_DROP_MESS")
CLEAR_HELP()
ENDIF
ENDIF
IF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0)
SET_MISSION_STATE(SE_PLAYER_WANTED)
EXIT
ENDIF
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
AND IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
ENDIF
IF IS_ENTITY_OK(veh) AND (GET_VEHICLE_NUMBER_OF_PASSENGERS(veh) > 0)
IF GET_PED_IN_VEHICLE_SEAT(veh, VS_FRONT_RIGHT) <> PLAYER_PED_ID()
SET_MISSION_STATE(SE_VEHICLE_OCCUPIED)
EXIT
ENDIF
ENDIF
IF NOT (dropOffGarage.bIsBlocked)
IF bExitCarHelpDisplayed = FALSE
IF IS_VEHICLE_OK(veh)
IF IS_ENTITY_IN_ANGLED_AREA(veh, dropOffGarage.garageArea.vPosition[0], dropOffGarage.garageArea.vPosition[1], dropOffGarage.garageArea.fWidth)
PRINT_NOW("EPS_DROP_EXIT", DEFAULT_GOD_TEXT_TIME, 1)
iBlockedTimer = 0
bExitCarHelpDisplayed = TRUE
bMessHelpDisplayed = FALSE
ENDIF
ENDIF
ENDIF
IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), dropOffGarage.vCenterPosition, FALSE) < 3.0)
SAFE_REMOVE_BLIP(vLocationBlip)
ENDIF
IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), dropOffGarage.vDoorPosition, FALSE) > (DOOR_DIST_THRESHOLD + 5.0))
SET_DESIRED_GARAGE_HELPER_STATE(dropOffGarage, GDS_CLOSED)
dropOffGarage.doorState = GDS_CLOSING
bExitCarHelpDisplayed = FALSE
bMessHelpDisplayed = FALSE
iBlockedTimer = 0
SET_MISSION_STATE(SE_APPROACH_GARAGE)
EXIT
ENDIF
IF IS_PLAYER_CLEAR_OF_GARAGE(dropOffGarage) AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
SET_DESIRED_GARAGE_HELPER_STATE(dropOffGarage, GDS_CLOSED)
dropOffGarage.doorState = GDS_CLOSING
iBlockedTimer = 0
SET_MISSION_STATE(SE_GET_VEHICLE)
EXIT
ENDIF
ENDIF
IF (dropOffGarage.bIsBlocked)
AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
AND IS_PED_ON_FOOT(PLAYER_PED_ID())
IF iBlockedTimer = 0
iBlockedTimer = GET_GAME_TIMER()
ELIF (GET_GAME_TIMER() - iBlockedTimer) > 500
IF (bMessHelpDisplayed = FALSE)
CLEAR_PRINTS()
PRINT_HELP("EPS_DROP_MESS")
CPRINTLN(DEBUG_AMBIENT, "CLEAR STUFF AWAY FROM THE GARAGE")
bMessHelpDisplayed = TRUE
bExitCarHelpDisplayed = FALSE
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
BREAK
ENDSWITCH
ENDPROC
//----------------------
// DEBUG FUNCTIONS
//----------------------
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Setups Debug Widgets
PROC SETUP_DEBUG_WIDGETS()
INT i
mWidgetGroup = START_WIDGET_GROUP("Epsilon Cargrab Controller")
ADD_WIDGET_BOOL("Quit Win Script", bForceQuitWin)
ADD_WIDGET_BOOL("Quit Fail Script", bForceQuitWin)
ADD_WIDGET_BOOL("Warp To Garage", bWarpToGarage)
ADD_WIDGET_BOOL("Show Debug Stuff", bShowDebugStuff)
ADD_WIDGET_BOOL("Create Dude", bCreatePedInCar)
START_WIDGET_GROUP("Door Stuff")
ADD_WIDGET_BOOL("Open Door", bTestOpenDoor)
ADD_WIDGET_BOOL("Close Door", bTestCloseDoor)
ADD_WIDGET_BOOL("Is In Stop Area", bIsInStopArea)
ADD_WIDGET_BOOL("Garage Occupied", bIsGarageOccupied)
ADD_WIDGET_BOOL("Door Blocked", bIsDoorBlocked)
ADD_WIDGET_BOOL("Help Displayed", bHelpDisplayed)
ADD_WIDGET_BOOL("Damage Help Displayed", bDmgHelpDisplayed)
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Blip Display")
ADD_WIDGET_BOOL("Blip Route", bBlipDropOffPoint)
ADD_WIDGET_BOOL("Show Vehicle Gens", bShowVehicleGens)
ADD_WIDGET_BOOL("Hide Vehicle Gens", bHideVehicleGens)
ADD_WIDGET_BOOL("Hide Vehicle Gen Surano", bHideVehicleGenSurano)
ADD_WIDGET_BOOL("Hide Vehicle Gen SuperD", bHideVehicleGenSuperD)
ADD_WIDGET_BOOL("Hide Vehicle Gen Carbon", bHideVehicleGenCarbon)
ADD_WIDGET_BOOL("Hide Vehicle Gen Vacca", bHideVehicleGenVacca)
ADD_WIDGET_BOOL("Hide Vehicle Gen Tornado", bHideVehicleGenTornado)
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("E-Mail")
ADD_WIDGET_BOOL("Advance Time", bAdvanceTime)
ADD_WIDGET_BOOL("Send Test E-Mail", bSendTestEmail)
ADD_WIDGET_INT_SLIDER("E-Mail Delay Timer", EMAIL_DELAY, 0, 60000, 1000 )
ADD_WIDGET_INT_SLIDER("Fake Cars Left Count", iFakeCarsLeftCount, 0, MAX_CARS, 1 )
ADD_WIDGET_INT_READ_ONLY("Day E-Mail Sent", g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay)
ADD_WIDGET_INT_READ_ONLY("Current Day", iCurrentDay)
ADD_WIDGET_INT_READ_ONLY("Next E-Mail Day", iNextDay)
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Stats")
ADD_WIDGET_INT_READ_ONLY("Vehicle HP", iCarHP)
ADD_WIDGET_INT_READ_ONLY("Vehicle Broke Parts", iCarBrokeParts)
ADD_WIDGET_INT_READ_ONLY("Vehicle Loose Parts", iCarLooseParts)
ADD_WIDGET_FLOAT_READ_ONLY("Door Ratio", dropOffGarage.fDoorRatio)
ADD_WIDGET_INT_READ_ONLY("Last Index Delivered", iLastIndexDelivered)
ADD_WIDGET_FLOAT_READ_ONLY("Player to Door", fDistDoor)
ADD_WIDGET_FLOAT_READ_ONLY("Player to Center", fDistCenter)
ADD_WIDGET_INT_READ_ONLY("Last Index Delivered", iLastIndexDelivered)
ADD_WIDGET_FLOAT_READ_ONLY("Player to Door", fDistDoor)
ADD_WIDGET_FLOAT_READ_ONLY("Player to Center", fDistCenter)
ADD_WIDGET_INT_READ_ONLY("Mission State", iShowState)
ADD_WIDGET_INT_READ_ONLY("Mission Sub State", iSubState)
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Collected Car List")
REPEAT (COUNT_OF(carModels)) i
ADD_WIDGET_BOOL(GET_MODEL_NAME_FOR_DEBUG(carModels[i]), bTempCarDelivered[i])
ENDREPEAT
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Bad Car Condition List")
REPEAT (COUNT_OF(carModels)) i
ADD_WIDGET_BOOL(GET_MODEL_NAME_FOR_DEBUG(carModels[i]), bTempCarBadCondition[i])
ENDREPEAT
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
ENDPROC
/// PURPOSE:
/// Updates all The Widgets
PROC UPDATE_DEBUG_WIDGETS()
INT i
VEHICLE_INDEX v
IF (bAdvanceTime)
ADD_TO_CLOCK_TIME(4, 0, 0)
ENDIF
IF (bShowDebugStuff)
DRAW_DEBUG_AREA(dropOffGarage.garageArea.vPosition[0], dropOffGarage.garageArea.vPosition[1], dropOffGarage.garageArea.fWidth)
DRAW_DEBUG_CIRCLE(dropOffGarage.vCenterPosition, 3.0)
DRAW_DEBUG_CIRCLE(dropOffGarage.vDoorEdge[0], 2.0)
DRAW_DEBUG_CIRCLE(dropOffGarage.vDoorEdge[1], 2.0)
ENDIF
iShowState = ENUM_TO_INT(stageEnum)
REPEAT MAX_CARS i
bTempCarDelivered[i] = IS_CAR_INDEX_DELIVERED(i)
bTempCarBadCondition[i] = IS_CAR_INDEX_CONDITION_BAD(i)
ENDREPEAT
IF (bCreatePedInCar)
AND DOES_ENTITY_EXIST(PLAYER_PED_ID())
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_OK(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE))
CREATE_PED_INSIDE_VEHICLE_AUTO_SEAT(GET_ENTITY_MODEL(PLAYER_PED_ID()), GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE))
bCreatePedInCar = FALSE
ENDIF
ENDIF
ENDIF
IF (bSendTestEmail)
SEND_EMAIL_FOR_CARS_LEFT(iFakeCarsLeftCount)
bSendTestEmail = FALSE
ENDIF
IF (bWarpToGarage)
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<-686.3673, 499.3271, 109.0014>>, 16.6346)
bWarpToGarage = FALSE
ENDIF
bIsDoorBlocked = dropOffGarage.bIsBlocked
IF (bShowVehicleGens) OR (bHideVehicleGens)
i = 0
REPEAT COUNT_OF(vVehicleGenBlip) i
SAFE_REMOVE_BLIP(vVehicleGenBlip[i])
ENDREPEAT
bHideVehicleGens = FALSE
ENDIF
IF (bBlipDropOffPoint)
SAFE_REMOVE_BLIP(blipDropOff)
blipDropOff = CREATE_COORD_BLIP(dropOffGarage.vCenterPosition, BLIPPRIORITY_MED, TRUE)
bBlipDropOffPoint = FALSE
ENDIF
IF (bShowVehicleGens)
IF (NOT bHideVehicleGenVacca)
vVehicleGenBlip[0] = CREATE_COORD_BLIP(GET_VEHICLE_GEN_COORDS(VEHGEN_EPS3_VACCA), BLIPPRIORITY_MED, FALSE)
ENDIF
IF (NOT bHideVehicleGenVacca)
vVehicleGenBlip[1] = CREATE_COORD_BLIP(GET_VEHICLE_GEN_COORDS(VEHGEN_EPS3_SURANO), BLIPPRIORITY_MED, FALSE)
ENDIF
IF (NOT bHideVehicleGenTornado)
vVehicleGenBlip[2] = CREATE_COORD_BLIP(GET_VEHICLE_GEN_COORDS(VEHGEN_EPS3_TORNADO2), BLIPPRIORITY_MED, FALSE)
ENDIF
IF (NOT bHideVehicleGenSuperD)
vVehicleGenBlip[3] = CREATE_COORD_BLIP(GET_VEHICLE_GEN_COORDS(VEHGEN_EPS3_SUPERD), BLIPPRIORITY_MED, FALSE)
ENDIF
IF (NOT bHideVehicleGenCarbon)
vVehicleGenBlip[4] = CREATE_COORD_BLIP(GET_VEHICLE_GEN_COORDS(VEHGEN_EPS3_DOUBLE), BLIPPRIORITY_MED, FALSE)
vVehicleGenBlip[5] = CREATE_COORD_BLIP(GET_VEHICLE_GEN_COORDS(VEHGEN_EPS3_DOUBLE_2), BLIPPRIORITY_MED, FALSE)
vVehicleGenBlip[6] = CREATE_COORD_BLIP(GET_VEHICLE_GEN_COORDS(VEHGEN_EPS3_DOUBLE_3), BLIPPRIORITY_MED, FALSE)
ENDIF
bShowVehicleGens = FALSE
ENDIF
IF (bTestOpenDoor)
SET_DESIRED_GARAGE_HELPER_STATE(dropOffGarage, GDS_OPEN)
dropOffGarage.doorState = GDS_OPENING
bTestOpenDoor = FALSE
ENDIF
IF (bTestCloseDoor)
SET_DESIRED_GARAGE_HELPER_STATE(dropOffGarage, GDS_CLOSED)
dropOffGarage.doorState = GDS_OPENING
bTestCloseDoor = FALSE
ENDIF
IF NOT IS_ENTITY_OK(PLAYER_PED_ID())
EXIT
ENDIF
bIsInStopArea = FALSE
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
v = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
IF IS_ENTITY_OK(v)
bIsInStopArea = IS_ENTITY_IN_RANGE_COORDS(v, vDropOffPoint, 3.0)
ENDIF
ENDIF
fDistDoor = GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), dropOffGarage.vDoorPosition, FALSE)
fDistCenter = GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), dropOffGarage.vCenterPosition, FALSE)
bIsGarageOccupied = IS_POSITION_OCCUPIED(vGarageSafePoint, 7.25, FALSE, FALSE, TRUE, FALSE, FALSE)
iCarHP = 0
IF IS_ENTITY_OK(PLAYER_PED_ID())
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
VEHICLE_INDEX ind = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)
IF IS_ENTITY_OK(ind)
iCarHP = GET_ENTITY_HEALTH(ind)
iCarBrokeParts = GET_VEHICLE_NUM_OF_BROKEN_OFF_PARTS(ind)
iCarLooseParts = GET_VEHICLE_NUM_OF_BROKEN_LOOSEN_PARTS(ind)
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Cleans up All The Widgets
PROC CLEANUP_DEBUG_WIDGETS()
INT i
i = 0
REPEAT COUNT_OF(vVehicleGenBlip) i
SAFE_REMOVE_BLIP(vVehicleGenBlip[i])
ENDREPEAT
IF DOES_WIDGET_GROUP_EXIST(mWidgetGroup)
DELETE_WIDGET_GROUP(mWidgetGroup)
ENDIF
ENDPROC
#ENDIF
//----------------------
// SCRIPT FUNCTIONS
//----------------------
/// PURPOSE:
/// Loads Car Models
PROC REQUEST_CAR_MODELS()
//INT i = 0
carModels[0] = VACCA
carModels[1] = SURANO
carModels[2] = TORNADO2
carModels[3] = SUPERD
carModels[4] = DOUBLE
eMailHelper[0].eMailID = CULT1
eMailHelper[0].sEmailBody = "EPS_GMAIL_G5"
eMailHelper[0].sEmailBadBody = "EPS_BMAIL_G5"
eMailHelper[1].eMailID = CULT2
eMailHelper[1].sEmailBody = "EPS_GMAIL_G4"
eMailHelper[1].sEmailBadBody = "EPS_BMAIL_G4"
eMailHelper[2].eMailID = CULT3
eMailHelper[2].sEmailBody = "EPS_GMAIL_G3"
eMailHelper[2].sEmailBadBody = "EPS_BMAIL_G3"
eMailHelper[3].eMailID = CULT4
eMailHelper[3].sEmailBody = "EPS_GMAIL_G2"
eMailHelper[3].sEmailBadBody = "EPS_BMAIL_G2"
eMailHelper[4].eMailID = CULT5
eMailHelper[4].sEmailBody = "EPS_GMAIL_G1"
eMailHelper[4].sEmailBadBody = "EPS_BMAIL_G1"
/* DON'T REQUEST THE MODELS ANYMORE - B*1072740
REPEAT MAX_CARS i
IF NOT IS_BIT_SET(iCarsDelivered, i)
SECURE_REQUEST_AND_LOAD_MODEL(carModels[i], FALSE)
ENDIF
ENDREPEAT
*/
//SECURE_REQUEST_AND_LOAD_TEXTURE_DICT("Epsilon_Cars", TRUE)
ENDPROC
/// PURPOSE:
/// Turn on or off mission vehicle gens
/// PARAMS:
/// ok -
PROC SET_MISSION_VEHICLE_GENS_AVAILABLE(BOOL ok)
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - MISSION VEHICLE GENS ARE:", ok)
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPS3_VACCA, ok)
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPS3_SURANO, ok)
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPS3_TORNADO2, ok)
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPS3_SUPERD, ok)
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPS3_DOUBLE, ok)
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPS3_DOUBLE_2, ok)
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPS3_DOUBLE_3, ok)
ENDPROC
/// PURPOSE:
/// Releases Car Models
PROC RELEASE_CAR_MODELS()
INT i = 0
REPEAT MAX_CARS i
SET_MODEL_AS_NO_LONGER_NEEDED(carModels[i])
ENDREPEAT
//SECURE_UNLOAD_TEXTURE_DICT("Epsilon_Cars")
ENDPROC
/// PURPOSE:
/// Script Cleanup
PROC SCRIPT_CLEANUP()
#IF IS_DEBUG_BUILD
CLEANUP_DEBUG_WIDGETS()
#ENDIF
SAFE_REMOVE_BLIP(vLocationBlip)
SET_MISSION_VEHICLE_GENS_AVAILABLE(FALSE)
RELEASE_CAR_MODELS()
FORCE_LOCK_GARAGE_HELPER(dropOffGarage)
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - SCRIPT CLEANUP")
//RELEASE_DYNAMIC_THREAD_HOLD_ON_BUFFER(DYNAMIC_THREAD_EPSILON3)
g_savedGlobals.sAmbient.iEpsilonCarStage = iCarsDelivered
// Register completion stats when completing normally or via debug
IF ARE_ALL_CARS_DELIVERED()
OR GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_CARS_DONE) = TRUE
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - ALL CARS DELIVERED - SET THE FLOW FLAG")
// Set the flow flag so the Epsilon 4 mission can be started.
Set_Mission_Flow_Flag_State(FLOWFLAG_EPSILON_CARS_DONE, TRUE)
// No longer require the script to be relaunched when loading from a savegame.
Remove_Script_From_Relaunch_List(LAUNCH_BIT_RC_AMB_EPSILON_CARS)
ENDIF
SET_ROADS_BACK_TO_ORIGINAL_IN_ANGLED_AREA(<<-683.450317,492.992249,108.873665>>, <<-688.835693,506.999664,112.192780>>, 11.250000)
SET_ROADS_BACK_TO_ORIGINAL_IN_ANGLED_AREA(noGarageRoadArea.vPosition[0], noGarageRoadArea.vPosition[1], 8.250000)
REMOVE_SCENARIO_BLOCKING_AREA(sScenarioBlockIndex)
IF (sFormMidSized <> NULL)
SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(sFormMidSized)
sFormMidSized = NULL
ENDIF
//Set epsilon step stat
INT iCurrent
STAT_GET_INT(NUM_EPSILON_STEP,iCurrent)
IF iCurrent < 6+GET_CARS_DELIVERED_COUNT()
STAT_SET_INT(NUM_EPSILON_STEP,6+GET_CARS_DELIVERED_COUNT())
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH20),6+GET_CARS_DELIVERED_COUNT())
ENDIF
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - CARS DELIVERED:", GET_CARS_DELIVERED_COUNT())
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - TERMINATING EPSCARS.SC AMBIENT SCRIPT")
TERMINATE_THIS_THREAD()
ENDPROC
PROC SCRIPT_RESUME()
VECTOR vmin, vmax
IF NOT IS_ENTITY_OK(PLAYER_PED_ID())
ENDIF
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - RESUMING EPSCARS.SC AMBIENT SCRIPT")
SET_ROADS_IN_ANGLED_AREA(<<-683.450317,492.992249,108.873665>>, <<-688.835693,506.999664,112.192780>>, 11.250000, FALSE, FALSE)
CALCULATE_MIN_MAX_FROM_POSITION_AND_RADIUS(<<-688.5, 503.7, 110.2>>, 30.0, vmin, vmax)
sScenarioBlockIndex = ADD_SCENARIO_BLOCKING_AREA(vmin, vmax)
iCarsDelivered = g_savedGlobals.sAmbient.iEpsilonCarStage
REQUEST_CAR_MODELS()
IF ARE_ALL_CARS_DELIVERED()
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - NUM OF DELIVERED CARS >= 5, CLEANUP SCRIPT SO FLOW FLAG IS SET")
SCRIPT_CLEANUP()
ENDIF
SET_MISSION_VEHICLE_GENS_AVAILABLE(TRUE)
// check to see if the thread already exists - if not send the email out
IF (GET_DYNAMIC_EMAIL_THREAD_BUFFER_INDEX(DYNAMIC_THREAD_EPSILON3) = -1)
SEND_EMAIL_FOR_CARS_LEFT(GET_CARS_LEFT_COUNT())
ELSE
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - E-MAIL ALREADY EXISTS IN THREAD")
ENDIF
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - CARS DELIVERED:", GET_CARS_DELIVERED_COUNT())
SET_MISSION_STATE(SE_GET_VEHICLE)
#IF IS_DEBUG_BUILD
UPDATE_DEBUG_WIDGETS()
SETUP_DEBUG_WIDGETS()
#ENDIF
ENDPROC
PROC SCRIPT_TIDY()
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - TIDYING UP EPSCARS.SC AMBIENT SCRIPT FOR SUSPEND")
IF DOES_BLIP_EXIST(vLocationBlip)
SAFE_REMOVE_BLIP(vLocationBlip)
vLocationBlip = NULL
ENDIF
#IF IS_DEBUG_BUILD
CLEANUP_DEBUG_WIDGETS()
#ENDIF
g_savedGlobals.sAmbient.iEpsilonCarStage = iCarsDelivered
SAFE_REMOVE_BLIP(vLocationBlip)
SET_MISSION_VEHICLE_GENS_AVAILABLE(FALSE)
RELEASE_CAR_MODELS()
FORCE_LOCK_GARAGE_HELPER(dropOffGarage)
// turn road nodes in garage back on
REMOVE_SCENARIO_BLOCKING_AREA(sScenarioBlockIndex)
SET_ROADS_BACK_TO_ORIGINAL_IN_ANGLED_AREA(<<-683.450317,492.992249,108.873665>>, <<-688.835693,506.999664,112.192780>>, 11.250000)
SET_ROADS_BACK_TO_ORIGINAL_IN_ANGLED_AREA(noGarageRoadArea.vPosition[0], noGarageRoadArea.vPosition[1], 8.250000)
ENDPROC
PROC SCRIPT_SUSPEND()
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - SUSPENDING AMBIENT SCRIPT")
SCRIPT_TIDY()
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - CARS DELIVERED:", GET_CARS_DELIVERED_COUNT())
WHILE GET_MISSION_FLAG() OR (GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_MICHAEL)
WAIT(0)
ENDWHILE
SCRIPT_RESUME()
ENDPROC
SCRIPT
VECTOR vmin, vmax
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - INIT EPSCARS.SC AMBIENT SCRIPT")
IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_DIRECTOR)
SCRIPT_CLEANUP()
ENDIF
IF (GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_CARS_DONE) = TRUE)
FORCE_ALL_CARS_DELIVERED()
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - ALL CARS HAVE BEEN GOT BEFORE EXECUTING SCRIPT - TERMINATE")
TERMINATE_THIS_THREAD()
ENDIF
// get the save number from save game
iCarsDelivered = g_savedGlobals.sAmbient.iEpsilonCarStage
// load cars and setup the mission
REQUEST_CAR_MODELS()
IF ARE_ALL_CARS_DELIVERED()
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - NUM OF DELIVERED CARS >= 5, CLEANUP SCRIPT SO FLOW FLAG IS SET")
SCRIPT_CLEANUP()
ENDIF
// Register the script so that it can be relaunched when loading from a savegame.
Register_Script_To_Relaunch_List(LAUNCH_BIT_RC_AMB_EPSILON_CARS)
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - STARTING EPSCARS.SC AMBIENT SCRIPT #:", XVERSION_NUMBER)
SETUP_GARAGE_HELPER(dropOffGarage, PROP_CH2_09C_GARAGE_DOOR, <<-689.81, 510.34, 109.98>>, vDropOffPoint,
<<-688.491882,507.254944,108.918564>>, <<-691.883484,516.268860,113.431572>>, 9.250000,
//<<-689.047424,507.330627,109.364105>>, <<-691.816345,516.054688,112.113853>>, 8.000000,
<<-687.455261,507.517944,109.363510>>, <<-690.948364,506.278290,109.363121>>)
SET_DESIRED_GARAGE_HELPER_STATE(dropOffGarage, GDS_CLOSED)
dropOffGarage.doorState = GDS_CLOSING
CLEAR_AREA_OF_VEHICLES(vDropOffPoint, 5.0)
// turn off road nodes around garage B*760390
SET_ANGLED_AREA(noGarageRoadArea, <<-691.905884,515.824890,108.613853>>, <<-684.060547,493.017120,110.850395>>, 8.250000)
SET_ROADS_IN_ANGLED_AREA(noGarageRoadArea.vPosition[0], noGarageRoadArea.vPosition[1], 8.250000, FALSE, FALSE)
SET_ROADS_IN_ANGLED_AREA(<<-683.450317,492.992249,108.873665>>, <<-688.835693,506.999664,112.192780>>, 11.250000, FALSE, FALSE)
CALCULATE_MIN_MAX_FROM_POSITION_AND_RADIUS(<<-688.5, 503.7, 110.2>>, 30.0, vmin, vmax)
sScenarioBlockIndex = ADD_SCENARIO_BLOCKING_AREA(vmin, vmax)
/* waiting until auto save is done with
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - INIT - WAITING TILL AUTO SAVE IS DONE")
WHILE IS_AUTOSAVE_REQUEST_IN_PROGRESS() OR IS_AUTO_SAVE_IN_PROGRESS()
WAIT(0)
ENDWHILE
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - INIT - AUTO SAVE COMPLETE")
*/
IF (GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_CARS_DONE) = TRUE)
FORCE_ALL_CARS_DELIVERED()
CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - ALL CARS HAVE BEEN GOT BEFORE EXECUTING SCRIPT - TERMINATE")
SCRIPT_CLEANUP()
ENDIF
#IF IS_DEBUG_BUILD
SETUP_DEBUG_WIDGETS()
#ENDIF
IF (g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay = 0)
g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay = GET_CLOCK_DAY_OF_MONTH()
ENDIF
// also don't send out the e-mail if we are debug skipping
// check to see if the thread already exists - if not send the email out
// IF (GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_CARS_DONE) = FALSE)
// IF (GET_DYNAMIC_EMAIL_THREAD_BUFFER_INDEX(DYNAMIC_THREAD_EPSILON3) = -1)
//
// primeEmail = TRUE
//
// #IF IS_DEBUG_BUILD
// primeEmail = (g_flowUnsaved.bUpdatingGameflow = FALSE)
// #ENDIF
//
// IF (primeEmail)
// CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - PRIMING E-MAIL")
// ASSIGN_BUFFER_TO_DYNAMIC_EMAIL_THREAD(DYNAMIC_THREAD_EPSILON3)
//
// //FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, CULTINITIAL)
// //OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, "EPS_1STEMAIL")
//
// CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - WAITING TO SEND")
//
// FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, CULTINITIAL)
// OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, "EPS_1STEMAIL")
// ELSE
//
// ENDIF
// bInitialEmailBuffer = TRUE
// CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - INITIAL E-MAIL SENT")
// ELSE
// CPRINTLN(DEBUG_AMBIENT, "EPSCARS.SC - EPSILON E-MAIL THREAD ALL READY EXISTS")
// ENDIF
// ENDIF
SET_MISSION_VEHICLE_GENS_AVAILABLE(TRUE)
SET_MISSION_STATE(SE_GET_VEHICLE)
WHILE (TRUE)
// Immediately cleanup if this script has been completed via debug
IF GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_CARS_DONE) = TRUE
FORCE_ALL_CARS_DELIVERED()
SCRIPT_CLEANUP()
ENDIF
IS_ENTITY_OK(PLAYER_PED_ID())
IF GET_MISSION_FLAG() OR (GET_CURRENT_PLAYER_PED_ENUM() <> CHAR_MICHAEL)
SCRIPT_SUSPEND()
ENDIF
SWITCH (stageEnum)
CASE SE_GET_VEHICLE
UPDATE_STATE_GET_VEHICLE(stageProgress)
BREAK
CASE SE_PLAYER_WANTED
UPDATE_STATE_PLAYER_WANTED(stageProgress)
BREAK
CASE SE_APPROACH_GARAGE
UPDATE_STATE_APPROACH_GARAGE(stageProgress)
BREAK
CASE SE_DELIVER_VEHICLE
UPDATE_STATE_DELIVER_VEHICLE(stageProgress)
BREAK
CASE SE_VEHICLE_OCCUPIED
UPDATE_STATE_VEHICLE_OCCUPIED(stageProgress)
BREAK
CASE SE_MISSION_CLEAR
FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, CULTFINALE)
OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON3, "EPS_LSTEMAIL")
RELEASE_DYNAMIC_THREAD_HOLD_ON_BUFFER(DYNAMIC_THREAD_EPSILON3)
//MISSION_FLOW_PLAY_END_OF_MISSION_MUSIC(TRUE)
SCRIPT_CLEANUP()
BREAK
ENDSWITCH
UPDATE_GARAGE_HELPER(dropOffGarage)
IF HAS_GARAGE_HELPER_FINISHED_CLOSING(dropOffGarage)
IF MARK_OFF_ANY_UNDELIVERED_CARS_IN_GARAGE(dropOffGarage)
IF GET_LAST_DRIVEN_VEHICLE() = g_vCarToTrackForImpound
CPRINTLN(DEBUG_AMBIENT, "Delivered car was being tracked for impound: cleared it")
g_vCarToTrackForImpound = NULL
g_savedGlobals.sVehicleGenData.bTrackingImpoundVehicle = FALSE
ENDIF
CLEAR_AREA_OF_VEHICLES(dropOffGarage.vCenterPosition, 8.5)
g_savedGlobals.sAmbient.iEpsilonCarStage = iCarsDelivered
MAKE_AUTOSAVE_REQUEST()
ADD_PED_FOR_DIALOGUE(convoMichael, ENUM_TO_INT(CHAR_MICHAEL), PLAYER_PED_ID(), "MICHAEL")
CREATE_CONVERSATION(convoMichael, "EPS3AUD", "EP3_MCS1", CONV_PRIORITY_LOW)
/*
BEGIN_TEXT_COMMAND_THEFEED_POST("EPS_CAR_NOTE")
ADD_TEXT_COMPONENT_INTEGER(GET_CARS_DELIVERED_COUNT())
END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE)
*/
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EPS_DROP_HELP")
CLEAR_HELP()
ENDIF
START_VEHICLE_DELIVERED_MESSAGE()
ENDIF
ENDIF
IF (g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay <> 0)
iNextDay = (g_savedGlobals.sAmbient.iEpsilonLastEmailSentDay + 14) % GET_NUMBER_OF_DAYS_IN_MONTH(INT_TO_ENUM(MONTH_OF_YEAR, GET_CLOCK_MONTH()), GET_CLOCK_YEAR())
IF (GET_CLOCK_DAY_OF_MONTH() = iNextDay)
AND NOT IS_PHONE_ONSCREEN()
AND NOT IS_PLAYER_DEAD(PLAYER_ID())
AND IS_PLAYER_PLAYING(PLAYER_ID())
CPRINTLN(DEBUG_AMBIENT, "TIME TO SEND OUT EMAIL")
SEND_EMAIL_FOR_CARS_LEFT(GET_CARS_LEFT_COUNT())
ENDIF
ENDIF
UPDATE_VEHICLE_DELIVERED_MESSAGE(sFormMidSized, iMidSizedMessageTimer, iMidSizedMessageStage)
IF (iEmailTimer > 0) AND (GET_GAME_TIMER() > iEmailTimer) AND (iMidSizedMessageStage = NO_MIDSIZED_MESSAGE)
iEmailTimer = 0
IF ARE_ALL_CARS_DELIVERED()
SET_MISSION_STATE(SE_MISSION_CLEAR)
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
UPDATE_DEBUG_WIDGETS()
// 'S' skip will pass the mission with all cars delivered
#IF IS_DEBUG_BUILD
IF (bForceQuitWin)
FORCE_SET_ALL_CARS_DELIVERED()
RELEASE_DYNAMIC_THREAD_HOLD_ON_BUFFER(DYNAMIC_THREAD_EPSILON3)
SCRIPT_CLEANUP()
ENDIF
// fail the scripts and reset the save game value
IF (bForceQuitFail)
RELEASE_DYNAMIC_THREAD_HOLD_ON_BUFFER(DYNAMIC_THREAD_EPSILON3)
iCarsDelivered = 0
g_savedGlobals.sAmbient.iEpsilonCarStage = iCarsDelivered
SCRIPT_CLEANUP()
ENDIF
#ENDIF
#ENDIF
WAIT(0)
ENDWHILE
ENDSCRIPT