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

2701 lines
94 KiB
XML
Executable File

//************************************************************************************
// +---------------------------------------------------------------------------------+
// +--------------------------¦ADAM WESTWOOD - HEADER FILE ¦----------------+
// +--------------------------¦12/05/2011 ¦----------------+
// +---------------------------------------------------------------------------------+
//************************************************************************************
//INCLUDE FILES
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_ped.sch"
USING "commands_hud.sch"
USING "commands_script.sch"
USING "dialogue_public.sch"
USING "script_maths.sch"
USING "selector_public.sch"
USING "commands_itemsets.sch"
USING "commands_misc.sch"
USING "commands_pad.sch"
USING "commands_player.sch"
USING "commands_vehicle.sch"
USING "commands_object.sch"
USING "commands_graphics.sch"
USING "commands_physics.sch"
USING "commands_entity.sch"
//USING "player_ped_public.sch"
// +--------------------------¦ Speech queue ¦----------------------------+
//VECTOR VECTOR_ZERO = <<0,0,0>>
//BOOL
//BOOL bSpeechTimer
//BOOL bPauseTextQueue
//INT
//INT iTextDelayTimer
//INT iNumberInStringQueue
//INT iNumberofStringsTriggeredaac
INT i_triggered_text_hashes[120]
CONST_FLOAT THIS_ROPE_LENGTH 8.0//6.0
CONST_FLOAT CHOPPER_ROPE_OFFSET_X 0.7
CONST_FLOAT CHOPPER_ROPE_OFFSET_Y 0.7
CONST_FLOAT CHOPPER_ROPE_OFFSET_Z -0.85
CONST_FLOAT CONTAINER_ROPE_OFFSET_X 1.85
CONST_FLOAT CONTAINER_ROPE_OFFSET_Y 2.9564
CONST_FLOAT CONTAINER_ROPE_OFFSET_YALT 0.1271
CONST_FLOAT CONTAINER_ROPE_OFFSET_Z 1.0640
//structPedsForConversation s_conversation_peds
//BOOL bHelpTextIs3D
ENUM SPEECH_TEXT_TYPE
TYPE_GOD,
TYPE_HELP,
TYPE_HELP_LOCATION,
TYPE_SPEECH
ENDENUM
STRUCT OLD_FLOATING_HELP_DATA
STRING s_current_label
INT i_timer
ENTITY_INDEX entity
VECTOR v_pos
BOOL b_in_3d
BOOL b_has_been_looked_at
HELP_MESSAGE_STYLE message_style
eARROW_DIRECTION arrow_direction
ENDSTRUCT
OLD_FLOATING_HELP_DATA s_floating_help
STRUCT sQUEUED_STRING_STRUCT
STRING sSpeechString
BOOL bDsiplayWithTextOnScreen
INT iTextDelay
INT iDuration
SPEECH_TEXT_TYPE eType
enumConversationPriority ePriority
// locational help text stuff
BOOL b3D
VECTOR vSpeechLocation
ENTITY_INDEX ei
eARROW_DIRECTION eDirection
HELP_MESSAGE_STYLE hlpStyle
ENDSTRUCT
PROC SAFE_CLEANUP_PED(PED_INDEX ped,MODEL_NAMES model, BOOL bDelete = TRUE, BOOL bWithSafeDistance = FALSE, INT iDistance = 0)
IF DOES_ENTITY_EXIST(ped)
IF NOT IS_ENTITY_ON_SCREEN(ped)
IF bWithSafeDistance = FALSE
IF bDelete
DELETE_PED(ped)
ELSE
SET_PED_AS_NO_LONGER_NEEDED(ped)
ENDIF
SET_MODEL_AS_NO_LONGER_NEEDED(model)
ELSE
//FINISH
IF iDistance = 0
IF bDelete
DELETE_PED(ped)
ELSE
SET_PED_AS_NO_LONGER_NEEDED(ped)
ENDIF
SET_MODEL_AS_NO_LONGER_NEEDED(model)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC SAFE_CLEANUP_VEHICLE(VEHICLE_INDEX veh,MODEL_NAMES model,BOOL bDelete = TRUE)
IF DOES_ENTITY_EXIST(veh)
IF NOT IS_ENTITY_ON_SCREEN(veh)
IF bDelete
DELETE_VEHICLE(veh)
ELSE
SET_VEHICLE_AS_NO_LONGER_NEEDED(veh)
ENDIF
SET_MODEL_AS_NO_LONGER_NEEDED(model)
ENDIF
ENDIF
ENDPROC
//sQUEUED_STRING_STRUCT sQUEUED_TEXT[MAX_QUEUED_TEXT]
//Text hashes
/// PURPOSE:
/// Sorts the triggered label array such that all the empty elements are at the end.
PROC REMOVE_LABEL_ARRAY_SPACES()
INT i = 0
REPEAT (COUNT_OF(i_triggered_text_hashes) - 1) i
IF i_triggered_text_hashes[i] = 0
IF i_triggered_text_hashes[i+1] != 0
i_triggered_text_hashes[i] = i_triggered_text_hashes[i+1]
i_triggered_text_hashes[i+1] = 0
ENDIF
ENDIF
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Finds the array index of a particular triggered label, or -1 if the label hasn't been added.
FUNC INT GET_LABEL_INDEX(INT i_label_hash)
INT i = 0
REPEAT COUNT_OF(i_triggered_text_hashes) i
IF i_triggered_text_hashes[i] = 0 //We've reached the end of the filled section of the array, no need to continue.
RETURN -1
ELIF i_triggered_text_hashes[i] = i_label_hash
RETURN i
ENDIF
ENDREPEAT
RETURN -1
ENDFUNC
/// PURPOSE:
/// Returns TRUE if the given label has been triggered.
FUNC BOOL HAS_LABEL_BEEN_TRIGGERED(STRING str_label)
RETURN (GET_LABEL_INDEX(GET_HASH_KEY(str_label)) != -1)
ENDFUNC
/// PURPOSE:
/// Adds/removes a text label to/from the list of labels that have been triggered.
PROC SET_LABEL_AS_TRIGGERED(STRING str_label, BOOL b_trigger)
INT i_hash = GET_HASH_KEY(str_label)
INT i = 0
IF b_trigger
BOOL b_added = FALSE
WHILE NOT b_added AND i < COUNT_OF(i_triggered_text_hashes)
IF i_triggered_text_hashes[i] = i_hash //The label is already in the array, don't add it again.
b_added = TRUE
ELIF i_triggered_text_hashes[i] = 0
i_triggered_text_hashes[i] = i_hash
b_added = TRUE
ENDIF
i++
ENDWHILE
#IF IS_DEBUG_BUILD
IF NOT b_added
SCRIPT_ASSERT("SET_LABEL_AS_TRIGGERED: Failed to add label, array is full.")
ENDIF
#ENDIF
ELSE
INT i_index = GET_LABEL_INDEX(i_hash)
IF i_index != -1
i_triggered_text_hashes[i_index] = 0
REMOVE_LABEL_ARRAY_SPACES()
ENDIF
ENDIF
ENDPROC
PROC CLEAR_TRIGGERED_LABELS()
INT i = 0
REPEAT COUNT_OF(i_triggered_text_hashes) i
i_triggered_text_hashes[i] = 0
ENDREPEAT
ENDPROC
// +--------------------------¦ Misc Speech Functions ¦----------------------------+
//PURPOSE: Checks to see if text of speech has been Queued
//FUNC BOOL IS_STRING_QUEUED(STRING strLabel)
// INT iHash = GET_HASH_KEY(strLabel)
// INT i = 0
// IF iNumberInStringQueue <= MAX_QUEUED_TEXT
// FOR i = 0 TO (iNumberInStringQueue-1)
// IF GET_HASH_KEY(sQUEUED_TEXT[i].sSpeechString) = iHash
// RETURN TRUE
// ENDIF
// ENDFOR
// ENDIF
// PRINTSTRING("Not in the Queue ++")//PRINTNL()
// RETURN FALSE
//ENDFUNC
//PURPOSE: checks if it is ok to play dialog.
FUNC BOOL IS_IT_SAFE_TO_PLAY_DIALOG(BOOL bDsiplayWithTextOnScreen = FALSE)
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
IF bDsiplayWithTextOnScreen
RETURN TRUE
ELSE
IF NOT IS_MESSAGE_BEING_DISPLAYED()
AND NOT IS_HELP_MESSAGE_BEING_DISPLAYED() //AND NOT IS_SPEECH_CURRENTLY_PLAYING(myScriptedSpeech) AND NOT IS_SPEECH_PAUSED(myScriptedSpeech)
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// +--------------------------¦ Print Speech Functions ¦----------------------------+
//PURPOSE:prints god text
PROC PRINT_ADV(STRING sPrint, INT iDuration = DEFAULT_GOD_TEXT_TIME)
PRINT(sPrint, iDuration, 1)
ENDPROC
//PURPOSE: Prints help text
PROC PRINT_HELP_ADV(STRING sPrint, INT iDuration = DEFAULT_GOD_TEXT_TIME)
s_floating_help.s_current_label = sPrint
s_floating_help.i_timer = GET_GAME_TIMER() + iDuration
s_floating_help.v_pos = <<0.0,0.0,0.0>>
s_floating_help.entity = NULL
s_floating_help.message_style = HELP_MESSAGE_STYLE_NORMAL
s_floating_help.b_in_3d = TRUE
s_floating_help.arrow_direction = HELP_TEXT_SOUTH
s_floating_help.b_has_been_looked_at = TRUE
//SET_HELP_MESSAGE_STYLE(HELP_MESSAGE_STYLE_NORMAL, INT_TO_ENUM(HUD_COLOURS, 40), 80)
PRINT_HELP_FOREVER(sPrint)
ENDPROC
//PURPOSE: Prints help text at a location
PROC PRINT_HELP_ADV_POS(STRING sPrint, INT i_time, HELP_MESSAGE_STYLE message_style, VECTOR v_pos, ENTITY_INDEX entity = NULL, BOOL b_in_3d = TRUE, eARROW_DIRECTION arrow_direction = 0)
s_floating_help.s_current_label = sPrint
s_floating_help.i_timer = GET_GAME_TIMER() + i_time
s_floating_help.v_pos = v_pos
s_floating_help.entity = entity
s_floating_help.message_style = message_style
s_floating_help.b_in_3d = b_in_3d
s_floating_help.arrow_direction = arrow_direction
s_floating_help.b_has_been_looked_at = FALSE
IF s_floating_help.message_style = HELP_MESSAGE_STYLE_NORMAL
SET_HELP_MESSAGE_STYLE(HELP_MESSAGE_STYLE_NORMAL, INT_TO_ENUM(HUD_COLOURS, 40), 80)
ELSE
SET_HELP_MESSAGE_STYLE(s_floating_help.message_style, INT_TO_ENUM(HUD_COLOURS, 40), 80, s_floating_help.arrow_direction)
ENDIF
PRINT_HELP_FOREVER(sPrint)
ENDPROC
PROC OLD_HELP_TEXT_UPDATE()
IF s_floating_help.i_timer != 0
IF GET_GAME_TIMER() > s_floating_help.i_timer
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(s_floating_help.s_current_label)
CLEAR_HELP()
ENDIF
s_floating_help.i_timer = 0
ELSE
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED(s_floating_help.s_current_label)
//If the help text is still off screen, increment the timer so it doesn't count down until the player has viewed the text.
IF NOT s_floating_help.b_has_been_looked_at
s_floating_help.i_timer += ROUND(GET_FRAME_TIME() * 1000.0)
IF IS_HELP_MESSAGE_ON_SCREEN()
s_floating_help.b_has_been_looked_at = TRUE
ENDIF
ENDIF
IF s_floating_help.b_in_3d
VECTOR v_display_pos = <<0.0, 0.0, 0.0>>
IF s_floating_help.entity != NULL
IF NOT IS_ENTITY_DEAD(s_floating_help.entity)
v_display_pos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(s_floating_help.entity, s_floating_help.v_pos)
ENDIF
ELSE
v_display_pos = s_floating_help.v_pos
ENDIF
IF (v_display_pos.x != 0.0 OR v_display_pos.y != 0.0 OR v_display_pos.z != 0.0)
SET_HELP_MESSAGE_WORLD_POSITION(v_display_pos)
ENDIF
ELSE
SET_HELP_MESSAGE_SCREEN_POSITION(s_floating_help.v_pos.x, s_floating_help.v_pos.y)
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
//PURPOSE: Starts a conversation,
// Same as CREATE_CONVERSATION, but it checks to see if the conversation has already been played.
//PROC CREATE_CONVERSATION_ADV(STRING sLabel, enumConversationPriority eConvPriority = CONV_PRIORITY_HIGH)
// CREATE_CONVERSATION(sSpeech, sConversationBlock, sLabel, eConvPriority)
//ENDPROC
// +--------------------------¦ Speeech Queue PROCS ¦----------------------------+
//PURPOSE: Clears a line of text
//PROC CLEAR_TEXT_OLD_TEXT_QUEUEITEM(INT i)
// STRING NullString
// sQUEUED_TEXT[i].sSpeechString = NullString
// sQUEUED_TEXT[i].bDsiplayWithTextOnScreen = FALSE
// sQUEUED_TEXT[i].iTextDelay = 0
// sQUEUED_TEXT[i].iDuration = 0
//ENDPROC
//PURPOSE: moves the array down one
//PROC MOVE_TEXT_OLD_TEXT_QUEUEDOWN_ONE(INT iStartPos)
// INT i = 0
// FOR i = iStartPos To (iNumberInStringQueue-2)
// sQUEUED_TEXT[i].sSpeechString = sQUEUED_TEXT[i+1].sSpeechString
// IF IS_STRING_NULL(sQUEUED_TEXT[i].sSpeechString)
// CLEAR_TEXT_OLD_TEXT_QUEUEITEM(i)
// ELSE
// sQUEUED_TEXT[i].sSpeechString = sQUEUED_TEXT[i+1].sSpeechString
// sQUEUED_TEXT[i].bDsiplayWithTextOnScreen = sQUEUED_TEXT[i+1].bDsiplayWithTextOnScreen
// sQUEUED_TEXT[i].iTextDelay = sQUEUED_TEXT[i+1].iTextDelay
// sQUEUED_TEXT[i].iDuration = sQUEUED_TEXT[i+1].iDuration
// sQUEUED_TEXT[i].ePriority = sQUEUED_TEXT[i+1].ePriority
// sQUEUED_TEXT[i].eType = sQUEUED_TEXT[i+1].eType
// sQUEUED_TEXT[i].vSpeechLocation = sQUEUED_TEXT[i+1].vSpeechLocation
// sQUEUED_TEXT[i].ei = sQUEUED_TEXT[i+1].ei
// sQUEUED_TEXT[i].eDirection = sQUEUED_TEXT[i+1].eDirection
// sQUEUED_TEXT[i].b3D = sQUEUED_TEXT[i+1].b3D
// sQUEUED_TEXT[i].hlpStyle = sQUEUED_TEXT[i+1].hlpStyle
//
// ENDIF
// ENDFOR
// IF iNumberInStringQueue > 0
// CLEAR_TEXT_OLD_TEXT_QUEUEITEM(iNumberInStringQueue -1)
// ENDIF
//ENDPROC
//PURPOSE: Clears a single lable from the lable queue
//PROC CLEAR_SINGLE_TEXT(STRING strLabel)
// INT iHash = GET_HASH_KEY(strLabel)
// INT i = 0
// INT iHashCleared = -1
// IF iNumberInStringQueue > 0
// FOR i = 0 to (iNumberInStringQueue-1)
// IF NOT IS_STRING_NULL(sQUEUED_TEXT[i].sSpeechString)
// IF GET_HASH_KEY(sQUEUED_TEXT[i].sSpeechString) = iHash
// iHashCleared = i
// CLEAR_TEXT_OLD_TEXT_QUEUEITEM(i)
// ENDIF
// ENDIF
// ENDFOR
// ENDIF
// IF iHashCleared >= 0
// MOVE_TEXT_OLD_TEXT_QUEUEDOWN_ONE(iHashCleared)
// iNumberInStringQueue--
// ENDIF
//ENDPROC
//PROC OLD_PAUSE_TEXT_QUEUE(BOOL bpause, BOOL bKillTextNow = TRUE)
//
// IF bpause
// bPauseTextQueue = TRUE
// ELSE
// bPauseTextQueue = FALSE
// ENDIF
//
// IF bKillTextNow
// CLEAR_HELP(TRUE)
// CLEAR_PRINTS()
// KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
// ENDIF
//
//ENDPROC
//PURPOSE: Clears the lable queue
//PROC OLD_CLEAR_TEXT_QUEUE(BOOL bClearPrints = TRUE, BOOL bKillConversationNow = TRUE,BOOL bResetTriggeredList = TRUE)
// INT i = 0
// IF iNumberInStringQueue > 0
// FOR i = 0 to (iNumberInStringQueue-1)
// CLEAR_TEXT_OLD_TEXT_QUEUEITEM(i)
// ENDFOR
// iNumberInStringQueue = 0
// ENDIF
// //Clear_the_help_queue
// IF bClearPrints
// CLEAR_HELP(TRUE)
// CLEAR_PRINTS()
// IF bKillConversationNow
// KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
// ELSE
// KILL_ANY_CONVERSATION()
// ENDIF
// ENDIF
// IF bResetTriggeredList
// FOR i = 0 To (iNumberofStringsTriggered -1)
// iNumberofStringsTriggered = 0
// ENDFOR
// ENDIF
//ENDPROC
//PURPOSE: Queues Help at a location
//FUNC BOOL ADD_TEXT_TO_QUEUE(STRING sStringToQueue, SPEECH_TEXT_TYPE SpeechTextType, INT iTextDelayPassed = 0,BOOL bClearQueue = FALSE,
// INT iDurationPassed = DEFAULT_GOD_TEXT_TIME , enumConversationPriority eConvPriority = CONV_PRIORITY_MEDIUM,
// BOOL bDsiplayWithTextOnScreen = FALSE,
// //stuff fo the att location things
// FLOAT fLoactionX = 0.0,FLOAT fLoactionY = 0.0,FLOAT fLoactionZ = 0.0, ENTITY_INDEX eiPassed = NULL,
// eARROW_DIRECTION eArrow = HELP_TEXT_SOUTH , BOOL bIs3D = TRUE,HELP_MESSAGE_STYLE StylePassed = HELP_MESSAGE_STYLE_NORMAL )
//
// IF bClearQueue = TRUE
// OLD_CLEAR_TEXT_QUEUE()
// ENDIF
//
// IF iNumberInStringQueue < MAX_QUEUED_TEXT
// IF NOT IS_STRING_QUEUED(sStringToQueue)
// IF IS_STRING_NULL(sQUEUED_TEXT[iNumberInStringQueue].sSpeechString)
// sQUEUED_TEXT[iNumberInStringQueue].sSpeechString = sStringToQueue
// sQUEUED_TEXT[iNumberInStringQueue].bDsiplayWithTextOnScreen = bDsiplayWithTextOnScreen
// sQUEUED_TEXT[iNumberInStringQueue].iTextDelay = iTextDelayPassed
// sQUEUED_TEXT[iNumberInStringQueue].iDuration = iDurationPassed
// sQUEUED_TEXT[iNumberInStringQueue].eType = SpeechTextType
// sQUEUED_TEXT[iNumberInStringQueue].ePriority = eConvPriority
// sQUEUED_TEXT[iNumberInStringQueue].vSpeechLocation = <<fLoactionX,fLoactionY, fLoactionZ>>
// sQUEUED_TEXT[iNumberInStringQueue].ei = eiPassed
// sQUEUED_TEXT[iNumberInStringQueue].eDirection = eArrow
// sQUEUED_TEXT[iNumberInStringQueue].b3D = bIs3D
// sQUEUED_TEXT[iNumberInStringQueue].hlpStyle = StylePassed
// PRINTSTRING("Number in the Queue ++")//PRINTNL()
// iNumberInStringQueue++
// RETURN (TRUE)
// ENDIF
// ENDIF
// ELSE
// PRINTSTRING("-------------------------")//PRINTNL()
// PRINTSTRING("-- TOO MANY IN QUEUE --")//PRINTNL()
// PRINTSTRING("-------------------------")//PRINTNL()
// ENDIF
//
// RETURN FALSE
//
//ENDFUNC
////PURPOSE: Queues God text
//PROC OLD_TEXT_QUEUE_GOD_TEXT(STRING sStringToQueue, INT iTextDelayPassed = 0,INT iDurationPassed = DEFAULT_GOD_TEXT_TIME,BOOL bClearQueue = FALSE)
// ADD_TEXT_TO_QUEUE(sStringToQueue,TYPE_GOD, iTextDelayPassed, bClearQueue, iDurationPassed)
//ENDPROC
////PURPOSE: Queues Help
//PROC OLD_TEXT_QUEUE_HELP(STRING sStringToQueue, INT iTextDelayPassed = 0,BOOL bDsiplayWithTextOnScreen = FALSE,BOOL bClearQueue = FALSE,INT iDurationPassed = DEFAULT_GOD_TEXT_TIME)
// ADD_TEXT_TO_QUEUE(sStringToQueue,TYPE_HELP, iTextDelayPassed, bClearQueue, iDurationPassed, CONV_PRIORITY_MEDIUM,bDsiplayWithTextOnScreen)
//ENDPROC
//PROC OLD_TEXT_QUEUE_HELP_AT_LOCATION(STRING sStringToQueue, VECTOR vLocation, ENTITY_INDEX eiPassed = NULL, HELP_MESSAGE_STYLE StylePassed = HELP_MESSAGE_STYLE_NORMAL,
//eARROW_DIRECTION eArrow = HELP_TEXT_SOUTH,BOOL bIs3D = TRUE, INT iTextDelayPassed = 0,INT iDurationPassed = DEFAULT_GOD_TEXT_TIME,BOOL bClearQueue = FALSE, BOOL bDsiplayWithTextOnScreen = FALSE)
//
// ADD_TEXT_TO_QUEUE(sStringToQueue,TYPE_HELP_LOCATION, iTextDelayPassed ,bClearQueue, iDurationPassed,CONV_PRIORITY_MEDIUM,bDsiplayWithTextOnScreen,
// vLocation.X, vLocation.Y, vLocation.Z, eiPassed, eArrow,bIs3D, StylePassed)
//ENDPROC
////PURPOSE: Queues Speech
//PROC OLD_TEXT_QUEUESPEECH(STRING sStringToQueue, enumConversationPriority eConvPriority = CONV_PRIORITY_MEDIUM, INT iTextDelayPassed = 0,BOOL bClearQueue = FALSE)
// ADD_TEXT_TO_QUEUE(sStringToQueue,TYPE_SPEECH, iTextDelayPassed, bClearQueue, DEFAULT_GOD_TEXT_TIME, eConvPriority)
//ENDPROC
//
//
//// +--------------------------¦ Control the Speech Queue ¦----------------------------+
////PURPOSE:COntrols the speech queue
//PROC CONTROL_SPEECH_QUEUE()
//
// //this big turd controls the speech queue
// IF NOT bPauseTextQueue
// IF iNumberInStringQueue > 0
// IF IS_IT_SAFE_TO_PLAY_DIALOG(sQUEUED_TEXT[0].bDsiplayWithTextOnScreen)
// IF NOT IS_STRING_NULL(sQUEUED_TEXT[0].sSpeechString)
// //Timer only works if this function displayed the text before
// IF NOT bSpeechTimer
// iTextDelayTimer = GET_GAME_TIMER() + sQUEUED_TEXT[0].iTextDelay
// PRINTSTRING("Get Delay Timer")//PRINTNL()
// bSpeechTimer = TRUE
// ENDIF
// //If the text has not been triggered, or if it is meant to be displayed more than once
// IF GET_GAME_TIMER() > iTextDelayTimer
// IF sQUEUED_TEXT[0].eType = TYPE_GOD
// PRINT_ADV(sQUEUED_TEXT[0].sSpeechString, sQUEUED_TEXT[0].iDuration)
// ELIF sQUEUED_TEXT[0].eType = TYPE_HELP
// PRINT_HELP_ADV(sQUEUED_TEXT[0].sSpeechString, sQUEUED_TEXT[0].iDuration)
// ELIF sQUEUED_TEXT[0].eType = TYPE_SPEECH
// CREATE_CONVERSATION_ADV(sQUEUED_TEXT[0].sSpeechString, sQUEUED_TEXT[0].ePriority)
// ELIF sQUEUED_TEXT[0].eType = TYPE_HELP_LOCATION
// PRINT_HELP_ADV_POS(sQUEUED_TEXT[0].sSpeechString, sQUEUED_TEXT[0].iDuration, sQUEUED_TEXT[0].hlpStyle , sQUEUED_TEXT[0].vSpeechLocation,
// sQUEUED_TEXT[0].ei, sQUEUED_TEXT[0].b3D,sQUEUED_TEXT[0].eDirection)
// ENDIF
// bSpeechTimer = FALSE
// //remove the lable from the que
// MOVE_TEXT_OLD_TEXT_QUEUEDOWN_ONE(0)
// iNumberInStringQueue--
// ENDIF
// ENDIF
// ENDIF
// ENDIF
// ENDIF
// //Update Help Text
// OLD_HELP_TEXT_UPDATE()
//ENDPROC
//COMMON PROCS*******************************************************************************************
CONST_INT MAX_MODELS 20
INT iNumberModelsLoaded
MODEL_NAMES ModelLoaded[MAX_MODELS]
//PURPOSE: adds a single model request to the array of models held in memory
PROC ADD_MODEL_REQUEST_TO_ARRAY(MODEL_NAMES ModelName)
INT i
BOOL bmodelrequested
REQUEST_MODEL(ModelName)
IF iNumberModelsLoaded > 0
FOR i = 0 TO (iNumberModelsLoaded -1)
IF ModelLoaded[i] = ModelName
bmodelrequested = TRUE
PRINTSTRING("model already requested")
ENDIF
ENDFOR
IF NOT bmodelrequested
ModelLoaded[iNumberModelsLoaded] = ModelName
iNumberModelsLoaded++
PRINTSTRING("number of models requested : ")
PRINTINT(iNumberModelsLoaded)
//PRINTNL()
ENDIF
ELIF iNumberModelsLoaded = 0
ModelLoaded[0] = ModelName
PRINTSTRING("first model requested")
//PRINTNL()
iNumberModelsLoaded++
ENDIF
ENDPROC
// +--------------------- Remove item from Array? ----------------------+
//PURPOSE: Removes a single model from the Array
PROC REMOVE_MODEL_FROM_ARRAY(MODEL_NAMES ModelName)
INT i
INT iModelArrayNumber =-1
//find where the model is in the array, if it's there then remove it
IF iNumberModelsLoaded > 0
FOR i = 0 TO (iNumberModelsLoaded -1)
IF ModelLoaded[i] = ModelName
iModelArrayNumber = i
SET_MODEL_AS_NO_LONGER_NEEDED(ModelLoaded[i])
ModelLoaded[i] = DUMMY_MODEL_FOR_SCRIPT
//PRINTNL()PRINTSTRING("model cleaned up = ")PRINTINT(i)//PRINTNL()
ENDIF
ENDFOR
ENDIF
//move the array down one if needed.
IF iModelArrayNumber >= 0
AND iNumberModelsLoaded > 1
//PRINTNL()PRINTSTRING("MOVE_MODEL_ARRAY_DOWN_ONE")//PRINTNL()
FOR i = iModelArrayNumber To (iNumberModelsLoaded -1)
ModelLoaded[i] = ModelLoaded[i+1]
IF i = (iNumberModelsLoaded - 1)
ModelLoaded[i] = DUMMY_MODEL_FOR_SCRIPT
iNumberModelsLoaded--
ENDIF
ENDFOR
ENDIF
ENDPROC
//PURPOSE: checks to see if all the requested models in the array are in memory
FUNC BOOL ARE_REQUESTED_MODELS_LOADED()
INT i
IF iNumberModelsLoaded > 0
FOR i = 0 TO (iNumberModelsLoaded -1)
IF NOT HAS_MODEL_LOADED(ModelLoaded[i])
#IF IS_DEBUG_BUILD
PRINTSTRING("model loading: ")
PRINTSTRING(GET_MODEL_NAME_FOR_DEBUG(ModelLoaded[i]))
//PRINTNL()
#ENDIF
WAIT(0)
RETURN FALSE
ENDIF
ENDFOR
ENDIF
//PRINTSTRING("models loaded")
////PRINTNL()
RETURN TRUE
ENDFUNC
//PURPOSE: removes all models from memory
PROC CLEANUP_LOADED_MODEL_ARRAY()
INT i
IF iNumberModelsLoaded > 0
FOR i = 0 TO (iNumberModelsLoaded -1)
IF ModelLoaded[i] <> DUMMY_MODEL_FOR_SCRIPT
SET_MODEL_AS_NO_LONGER_NEEDED(ModelLoaded[i])
ModelLoaded[i] = DUMMY_MODEL_FOR_SCRIPT
ENDIF
ENDFOR
ENDIF
iNumberModelsLoaded = 0
//PRINTSTRING("models cleanedup")
//PRINTNL()
ENDPROC
CONST_INT MAX_RECS 10
INT iNumberCarRecsLoaded
INT CarRecLoaded[MAX_RECS]
//PURPOSE: adds a single model request to the array of models held in memory
PROC ADD_CARREC_REQUEST_TO_ARRAY(INT iPassed,STRING carrecdir)
INT i
BOOL bCarRecRequested = FALSE
REQUEST_VEHICLE_RECORDING(iPassed, carrecdir)
IF iNumberCarRecsLoaded > 0
IF iNumberCarRecsLoaded < (MAX_RECS -1)
FOR i = 0 TO (iNumberCarRecsLoaded -1)
IF CarRecLoaded[i] = iPassed
bCarRecRequested = TRUE
PRINTSTRING("carrec already requested")//PRINTNL()
ELIF CarRecLoaded[i] <> iPassed
//bCarRecRequested = FALSE
PRINTSTRING("new carrec requested")//PRINTNL()
ENDIF
ENDFOR
IF NOT bCarRecRequested
CarRecLoaded[iNumberCarRecsLoaded] = iPassed
iNumberCarRecsLoaded++
PRINTSTRING("number of carrecs requested : ")PRINTINT(iNumberCarRecsLoaded)//PRINTNL()
ENDIF
ENDIF
ELIF iNumberCarRecsLoaded = 0
CarRecLoaded[0] = iPassed
PRINTSTRING("first carrec requested")//PRINTNL()
iNumberCarRecsLoaded++
ENDIF
ENDPROC
//PURPOSE: Removes a single Car Rec from the Array
PROC REMOVE_CARREC_FROM_ARRAY(INT iPassed,STRING carrecdir)
INT i
INT iCarRecArrayNumber =-1
//find where the Car rec is in the array, if it's there then remove it
IF iNumberCarRecsLoaded > 0
AND iNumberCarRecsLoaded < (MAX_RECS -1)
FOR i = 0 TO (iNumberCarRecsLoaded -1)
IF CarRecLoaded[i] = iPassed
iCarRecArrayNumber = i
IF HAS_VEHICLE_RECORDING_BEEN_LOADED(CarRecLoaded[i], carrecdir)
REMOVE_VEHICLE_RECORDING(CarRecLoaded[i])
//PRINTNL()PRINTSTRING("Car rec cleaned up = ")PRINTINT(i)//PRINTNL()
ENDIF
ENDIF
ENDFOR
ENDIF
//move the array down one if needed.
IF iCarRecArrayNumber >= 0
AND iNumberCarRecsLoaded > 1
//PRINTNL()PRINTSTRING("MOVE_CARREC_ARRAY_DOWN_ONE")//PRINTNL()
FOR i = iCarRecArrayNumber To (iNumberCarRecsLoaded -1)
CarRecLoaded[i] = CarRecLoaded[i+1]
IF i = (iNumberCarRecsLoaded - 1)
CarRecLoaded[i] = 0
iNumberCarRecsLoaded--
ENDIF
ENDFOR
ENDIF
ENDPROC
//PURPOSE: checks to see if all the requested car-recs in the array are in memory
FUNC BOOL ARE_REQUESTED_CARRECS_LOADED(STRING carrecdir)
INT i
IF iNumberCarRecsLoaded > 0
FOR i = 0 TO (iNumberCarRecsLoaded -1)
IF NOT IS_STRING_NULL(carrecdir)
IF NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(CarRecLoaded[i], carrecdir)
PRINTSTRING("Car Rec loading = ")PRINTINT(CarRecLoaded[i])//PRINTNL()
RETURN FALSE
ENDIF
ENDIF
ENDFOR
ENDIF
//PRINTSTRING("Everything loaded")//PRINTNL()
RETURN TRUE
ENDFUNC
//PURPOSE: Cleans up the loaded car recs
PROC CLEANUP_LOADED_CARREC_ARRAY(STRING carrecdir)
INT i
IF iNumberCarRecsLoaded > 0
FOR i = 0 TO (iNumberCarRecsLoaded -1)
IF NOT IS_STRING_NULL(carrecdir)
REMOVE_VEHICLE_RECORDING(CarRecLoaded[i],carrecdir)
//PRINTNL()PRINTSTRING("Car rec cleaned up = ")PRINTINT(i)//PRINTNL()
CarRecLoaded[i] = 0
ENDIF
ENDFOR
ENDIF
//PRINTNL()PRINTSTRING("CLEANUP_LOADED_CARREC_ARRAY done")//PRINTNL()
iNumberCarRecsLoaded = 0
ENDPROC
//Clean up all request arrays
PROC CLEANUP_ALL_REQUEST_ARRAYS(STRING carrecdir)
CLEANUP_LOADED_MODEL_ARRAY()
CLEANUP_LOADED_CARREC_ARRAY(carrecdir)
ENDPROC
// ------------------------------------------------------------------
// PURPOSE: managed a timed fade out
PROC CONTROL_FADE_IN(INT iFadeTime)
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(iFadeTime)
WHILE IS_SCREEN_FADING_IN()
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
// PURPOSE: managed a timed fade in
PROC CONTROL_FADE_OUT(INT iFadeTime)
IF IS_SCREEN_FADED_IN()
DO_SCREEN_FADE_OUT(iFadeTime)
WHILE IS_SCREEN_FADING_OUT()
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
// PURPOSE: disables emergency sevices
proc disable_dispatch_services()
enable_dispatch_service(dt_fire_department, false)
enable_dispatch_service(dt_police_automobile, false)
enable_dispatch_service(dt_police_helicopter, false)
enable_dispatch_service(dt_ambulance_department, false)
endproc
// PURPOSE: enable emergency sevices
proc enable_dispatch_services()
enable_dispatch_service(dt_fire_department, true)
enable_dispatch_service(dt_police_automobile, true)
enable_dispatch_service(dt_police_helicopter, true)
enable_dispatch_service(dt_ambulance_department, true)
endproc
FUNC BOOL IS_STRING_EQUAL_TO_STRING(STRING sString1,STRING sString2)
INT iString1
INT iString2
iString1 = GET_HASH_KEY(sString1)
iString2 = GET_HASH_KEY(sString2)
IF iString1 = iString2
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDFUNC
//PURPOSE: prints god text if it is not the same as the last text printed.
PROC PRINT_GOD_TEXT(STRING sGodText)
PRINT_NOW(sGodText,DEFAULT_GOD_TEXT_TIME,1)
ENDPROC
FUNC FLOAT DISTANCE_BETWEEN_COORDS(VECTOR v1, VECTOR v2, BOOL in_2d = FALSE, BOOL use_square_root = TRUE)
IF in_2d
v1.z = 0.0
v2.z = 0.0
ENDIF
IF use_square_root
RETURN VDIST(v1, v2)
ELSE
RETURN VDIST2(v1, v2)
ENDIF
ENDFUNC
//PURPOSE: Returns a unit vector
FUNC VECTOR GET_UNIT_VECTOR(VECTOR v_start,VECTOR v_end, INT iMag = 1)
VECTOR v_unit
INT i
v_unit = v_end - v_start / VMAG(v_end - v_start)
FOR i = 0 To iMag
v_unit.x += v_unit.x
v_unit.y += v_unit.y
v_unit.z += v_unit.z
ENDFOR
RETURN v_unit
ENDFUNC
FUNC FLOAT GET_SCALAR_VELOCITY(VECTOR v_vel, BOOL b_use_square_root = TRUE)
FLOAT f_vel = (v_vel.x * v_vel.x) + (v_vel.y * v_vel.y) + (v_vel.z * v_vel.z)
IF b_use_square_root
RETURN SQRT(f_vel)
ELSE
RETURN f_vel
ENDIF
ENDFUNC
// PURPOSE:
/// Converges a value towards a given destination, by adding/removing a given amount.
PROC CONVERGE_VALUE(FLOAT &val, FLOAT desired_val, FLOAT amount_to_converge, BOOL adjust_for_framerate = FALSE)
IF val != desired_val
FLOAT converge_amount_this_frame = amount_to_converge
IF adjust_for_framerate
converge_amount_this_frame = 0.0 +@ amount_to_converge
ENDIF
IF val - desired_val > converge_amount_this_frame
val -= converge_amount_this_frame
ELIF val - desired_val < -converge_amount_this_frame
val += converge_amount_this_frame
ELSE
val = desired_val
ENDIF
ENDIF
ENDPROC
//PURPOSE: moves the player and their car to a new location
PROC WARP_PLAYER(VECTOR Location, FLOAT Heading,BOOL keepveh = TRUE)
IF keepveh
SET_PED_COORDS_KEEP_VEHICLE(PLAYER_PED_ID(),Location)
ELSE
SET_ENTITY_COORDS(PLAYER_PED_ID(),Location)
ENDIF
SET_ENTITY_HEADING(PLAYER_PED_ID(), Heading)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0)
//FREEZE_ENTITY_POSITION(PLAYER_PED_ID(),FALSE)
IF IS_SCREEN_FADED_OUT()
LOAD_SCENE(Location)
ENDIF
ENDPROC
BLIP_INDEX dest_blip
BLIP_INDEX veh_blip
BLIP_INDEX ped_blip
ENUM ROUTE_OPTIONS
RO_OVERRIDE_OFF = 0,
RO_OVERRIDE_ON,
RO_USE_DEFAULT
ENDENUM
// PURPOSE: controls the display of objective blips (vehcile, ped or loc)
PROC MANAGE_OBJECTIVE_BLIP_DISPLAY(PED_INDEX target_ped, VEHICLE_INDEX target_veh, VECTOR target_coords, BOOL b_enemy = FALSE, ROUTE_OPTIONS ro_create_route = RO_USE_DEFAULT)
BOOL bDrawRoute
IF target_veh <> NULL // adds vehicle blip and removes others
IF DOES_BLIP_EXIST(dest_blip)
REMOVE_BLIP(dest_blip)
ENDIF
IF DOES_BLIP_EXIST(ped_blip)
REMOVE_BLIP(ped_blip)
ENDIF
IF IS_VEHICLE_DRIVEABLE(target_veh)
IF NOT DOES_BLIP_EXIST(veh_blip)
veh_blip = CREATE_BLIP_FOR_VEHICLE(target_veh, b_enemy)
IF ro_create_route = RO_OVERRIDE_ON
SET_BLIP_ROUTE(veh_blip,TRUE)
ENDIF
//PRINTSTRING("veh obj blip")
//PRINTNL()
ENDIF
ENDIF
ELIF target_ped <> NULL //adds ped blip and removes others
IF NOT IS_PED_INJURED(target_ped)
IF DOES_BLIP_EXIST(veh_blip)
REMOVE_BLIP(veh_blip)
ENDIF
IF DOES_BLIP_EXIST(dest_blip)
REMOVE_BLIP(dest_blip)
ENDIF
IF NOT DOES_BLIP_EXIST(ped_blip)
IF IS_PED_IN_ANY_VEHICLE(target_ped)
ped_blip = CREATE_BLIP_FOR_PED(target_ped, b_enemy)
ELSE
ped_blip = CREATE_BLIP_FOR_PED(target_ped, b_enemy)
ENDIF
IF ro_create_route = RO_OVERRIDE_ON
SET_BLIP_ROUTE(ped_blip,TRUE)
ENDIF
//PRINTSTRING("ped obj blip")
//PRINTNL()
ELSE
IF IS_PED_IN_ANY_VEHICLE(target_ped)
SET_BLIP_SCALE(ped_blip,1.0)
ELSE
SET_BLIP_SCALE(ped_blip,BLIP_SIZE_PED)
ENDIF
ENDIF
ENDIF
ELSE
IF DOES_BLIP_EXIST(veh_blip)
REMOVE_BLIP(veh_blip)
ENDIF
IF DOES_BLIP_EXIST(ped_blip)
REMOVE_BLIP(ped_blip)
ENDIF
IF NOT DOES_BLIP_EXIST(dest_blip) //adds location blip and removes others
IF ro_create_route <> RO_OVERRIDE_OFF bDrawRoute = TRUE ELSE bDrawRoute = FALSE ENDIF
dest_blip = CREATE_BLIP_FOR_COORD(target_coords, bDrawRoute)
// PRINTSTRING("dest obj blip")
//PRINTNL()
ENDIF
ENDIF
ENDPROC
//PURPOSE: removes all mission blips
PROC CLEAN_OBJECTIVE_BLIP_DISPLAY()
IF DOES_BLIP_EXIST(veh_blip)
REMOVE_BLIP(veh_blip)
ENDIF
IF DOES_BLIP_EXIST(dest_blip)
REMOVE_BLIP(dest_blip)
ENDIF
IF DOES_BLIP_EXIST(ped_blip)
REMOVE_BLIP(ped_blip)
ENDIF
//PRINTSTRING("clean obj blip")
////PRINTNL()
ENDPROC
FUNC BOOL MANAGE_MY_TIMER(INT&start_time, INT time)
INT current_time
current_time = GET_GAME_TIMER()
IF ((current_time - start_time) > time)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC DO_SAFE_FADE_OUT()
IF NOT IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_OUT(500)
WHILE NOT IS_SCREEN_FADED_OUT()
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
proc end_cutscene(bool clear_tasks = true, float interp_heading = 0.0, float interp_pitch = 0.0, bool enable_emergency_services = true)
//SET_SCRIPTS_SAFE_FOR_CUTSCENE(false)
clear_prints()
clear_help()
kill_face_to_face_conversation()
display_hud(true)
display_radar(true)
set_widescreen_borders(false, 500)
if is_player_playing(player_id())
render_script_cams(false, false)
set_gameplay_cam_relative_heading(interp_heading)
set_gameplay_cam_relative_pitch(interp_pitch)
if clear_tasks
IF NOT IS_PED_INJURED(player_ped_id())
clear_ped_tasks(player_ped_id())
ENDIF
endif
set_player_control(player_id(), true)
hide_ped_weapon_for_scripted_cutscene(player_ped_id(), false)
endif
if enable_emergency_services
enable_dispatch_services()
else
disable_dispatch_services()
endif
do_screen_fade_in(500)
endproc
PROC END_CUTSCENE_WITHOUT_FADE(BOOL clear_tasks = true, BOOL interpolate_behind_player = false, FLOAT interp_heading = 0.0, FLOAT interp_pitch = 0.0, INT interp_to_game_time = 3000, BOOL enable_emergency_services = true)
//SET_SCRIPTS_SAFE_FOR_CUTSCENE(false)
CLEAR_PRINTS()
CLEAR_HELP()
KILL_FACE_TO_FACE_CONVERSATION()
DISPLAY_HUD(TRUE)
DISPLAY_RADAR(TRUE)
SET_WIDESCREEN_BORDERS(FALSE, 500)
IF IS_PLAYER_PLAYING(PLAYER_ID())
DESTROY_ALL_CAMS()
IF interpolate_behind_player
RENDER_SCRIPT_CAMS(false, true, interp_to_game_time)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(interp_heading)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(interp_pitch)
ELSE
RENDER_SCRIPT_CAMS(false, false)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(interp_heading)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(interp_pitch)
ENDIF
IF clear_tasks
CLEAR_PED_TASKS(PLAYER_PED_ID())
ENDIF
SET_PLAYER_CONTROL(PLAYER_ID(), true)
HIDE_PED_WEAPON_FOR_SCRIPTED_CUTSCENE(PLAYER_PED_ID(), false)
endif
if enable_emergency_services
enable_dispatch_services()
else
disable_dispatch_services()
endif
endproc
INT iStuckNow
BOOl bFlipTimerSet
VECTOR vFlipVec
//PURPOSE:checks to see if the vehicle is stuck or undrivable
FUNC BOOL MISSION_VEHICLE_FAIL_CHECKS(VEHICLE_INDEX VEHICLE)
IF DOES_ENTITY_EXIST(VEHICLE)
IF IS_VEHICLE_DRIVEABLE(VEHICLE)
IF IS_VEHICLE_MODEL(VEHICLE,BODHI2)
IF bFlipTimerSet = FALSE
vFlipVec = NORMALISE_VECTOR(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(VEHICLE, <<0,0,1>>) - GET_ENTITY_COORDS(VEHICLE))
IF ABSF(GET_ANGLE_BETWEEN_2D_VECTORS(vFlipVec.x, vFlipVec.z, 0, 1)) > 80
OR ABSF(GET_ANGLE_BETWEEN_2D_VECTORS(vFlipVec.y, vFlipVec.z, 0, 1)) > 80
OR IS_ENTITY_UPSIDEDOWN(VEHICLE)
PRINTSTRING("!!!!!!!!!!!!!!!!!!!STUCK")PRINTNL()
iStuckNow = GET_GAME_TIMER()
ENDIF
ELSE
vFlipVec = NORMALISE_VECTOR(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(VEHICLE, <<0,0,1>>) - GET_ENTITY_COORDS(VEHICLE))
IF ABSF(GET_ANGLE_BETWEEN_2D_VECTORS(vFlipVec.x, vFlipVec.z, 0, 1)) > 80
OR ABSF(GET_ANGLE_BETWEEN_2D_VECTORS(vFlipVec.y, vFlipVec.z, 0, 1)) > 80
OR IS_ENTITY_UPSIDEDOWN(VEHICLE)
IF MANAGE_MY_TIMER(iStuckNow,1000)
PRINTSTRING("!!!!!!!!!!!!!!!!!!!FUCKED")PRINTNL()
RETURN TRUE
ENDIF
ELSE
PRINTSTRING("!!!!!!!!!!!!!!!!!!!UNSTUCK")PRINTNL()
bFlipTimerSet = FALSE
ENDIF
ENDIF
ENDIF
IF IS_VEHICLE_STUCK_TIMER_UP(VEHICLE, VEH_STUCK_ON_ROOF, ROOF_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(VEHICLE, VEH_STUCK_JAMMED, JAMMED_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(VEHICLE, VEH_STUCK_HUNG_UP, HUNG_UP_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(VEHICLE, VEH_STUCK_ON_SIDE, SIDE_TIME)
RETURN TRUE
ENDIF
ELSE
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
//
//PROC REASSIGN_PLAYER_CHAR_DIALOGUE_SPEAKERS()
// IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL])
// IF sConversationPeds.PedInfo[1].Index != sSelectorPeds.pedID[SELECTOR_PED_MICHAEL]
// ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, sSelectorPeds.pedID[SELECTOR_PED_MICHAEL], "MICHAEL")
// ENDIF
// ENDIF
//
// IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN])
// IF sConversationPeds.PedInfo[3].Index != sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN]
// ADD_PED_FOR_DIALOGUE(sConversationPeds, 3, sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN], "FRANKLIN")
// ENDIF
// ENDIF
//
// IF NOT IS_PED_INJURED(sSelectorPeds.pedID[SELECTOR_PED_TREVOR])
// IF sConversationPeds.PedInfo[2].Index != sSelectorPeds.pedID[SELECTOR_PED_TREVOR]
// ADD_PED_FOR_DIALOGUE(sConversationPeds, 2, sSelectorPeds.pedID[SELECTOR_PED_TREVOR], "TREVOR")
// ENDIF
// ENDIF
//
// IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
// IF sConversationPeds.PedInfo[1].Index != PLAYER_PED_ID()
// ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, PLAYER_PED_ID(), "MICHAEL")
// ENDIF
// ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
// IF sConversationPeds.PedInfo[1].Index != PLAYER_PED_ID()
// ADD_PED_FOR_DIALOGUE(sConversationPeds, 1, PLAYER_PED_ID(), "FRANKLIN")
// ENDIF
// ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
// IF sConversationPeds.PedInfo[2].Index != PLAYER_PED_ID()
// ADD_PED_FOR_DIALOGUE(sConversationPeds, 2, PLAYER_PED_ID(), "TREVOR")
// ENDIF
// ENDIF
//ENDPROC
SELECTOR_CAM_STRUCT sCamDetails
SELECTOR_PED_STRUCT sSelectorPeds
FUNC BOOL SETUP_HOTSWAP_CAM(SELECTOR_SLOTS_ENUM targetCharacter)
FLOAT distance_between_peds
INT max_distance_limit = 130
INT minimum_distance_limit = 8
INT max_interp_limit = 5000
INT min_interp_limit = 1700
INT interp_time
IF NOT sCamDetails.bSplineCreated
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[targetCharacter])
distance_between_peds = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(sSelectorPeds.pedID[targetCharacter]))
IF distance_between_peds > 8.0
interp_time = ROUND((((distance_between_peds - minimum_distance_limit) / (max_distance_limit - minimum_distance_limit)) * (max_interp_limit - min_interp_limit)) + min_interp_limit)
ELSE
interp_time = 1700
ENDIF
IF NOT DOES_CAM_EXIST(sCamDetails.camID)
sCamDetails.camID = CREATE_CAM("DEFAULT_SPLINE_CAMERA", FALSE)
ENDIF
ADD_CAM_SPLINE_NODE(sCamDetails.camID, GET_GAMEPLAY_CAM_COORD(), GET_GAMEPLAY_CAM_ROT(), 0)
ADD_CAM_SPLINE_NODE(sCamDetails.camID, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sSelectorPeds.pedID[targetCharacter], <<0.263986, -3.0, 1.75>>), GET_ENTITY_ROTATION(sSelectorPeds.pedID[targetCharacter]), interp_time)
ADD_CAM_SPLINE_NODE(sCamDetails.camID, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sSelectorPeds.pedID[targetCharacter], <<0.263986, -2.75, 0.8>>), GET_ENTITY_ROTATION(sSelectorPeds.pedID[targetCharacter]), 250)
sCamDetails.bSplineCreated = TRUE
sCamDetails.camType = SELECTOR_CAM_STRAIGHT_INTERP
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC SETUP_NON_PLAYER_AFTER_HOTSWAP(PED_INDEX non_player,BOOL bdefendarea, BOOL bClearTask = TRUE)
IF NOT IS_PED_INJURED(non_player)
SET_PED_CAN_BE_TARGETTED(non_player, false)
SET_PED_SUFFERS_CRITICAL_HITS(non_player, false)
SET_PED_DIES_WHEN_INJURED(non_player, true)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(non_player, true)
SET_ENTITY_HEALTH(non_player,2000)
SET_PED_SUFFERS_CRITICAL_HITS(non_player,FALSE)
IF bClearTask
IF NOT IS_PED_INJURED(non_player)
CLEAR_PED_TASKS(non_player)
ENDIF
ENDIF
SET_ENTITY_INVINCIBLE(non_player,TRUE)
IF bdefendarea
SET_PED_SPHERE_DEFENSIVE_AREA(non_player, GET_ENTITY_COORDS(non_player), 10)
TASK_COMBAT_HATED_TARGETS_AROUND_PED(non_player,100)
ENDIF
ENDIF
ENDPROC
PROC MANAGE_INTERIOR_VIEWPOINT()
INT iInterior
iInterior = GET_ROOM_KEY_FOR_GAME_VIEWPORT()
SET_ROOM_FOR_GAME_VIEWPORT_BY_KEY(iInterior)
ENDPROC
INT iSwapProg
//PURPOSE: constantly run the hotswap selector/spline cam, and return true when selected the target ped
FUNC BOOL DO_MISSION_HOTSWAP_TO_PED(SELECTOR_SLOTS_ENUM targetCharacter, BOOL bforced = FALSE, BOOL bcloseswapcam = FALSE, BOOL bcustomCam = FALSE)
//INT iInterior
SWITCH iSwapProg
CASE 0 //displays the hint for the player select
SET_SELECTOR_PED_HINT(sSelectorPeds, targetCharacter)
IF targetCharacter = SELECTOR_PED_FRANKLIN
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_FRANKLIN,FALSE)
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_MICHAEL,TRUE)
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_TREVOR,TRUE)
PRINTSTRING("SELECTOR_PED_FRANKLIN")
//PRINTNL()
ELIF targetCharacter = SELECTOR_PED_MICHAEL
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_MICHAEL,FALSE)
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_FRANKLIN,TRUE)
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_TREVOR,TRUE)
PRINTSTRING("SELECTOR_PED_MICHAEL")
//PRINTNL()
ELIF targetCharacter = SELECTOR_PED_TREVOR
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_TREVOR,FALSE)
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_FRANKLIN,TRUE)
SET_SELECTOR_PED_BLOCKED(sSelectorPeds,SELECTOR_PED_MICHAEL,TRUE)
PRINTSTRING("SELECTOR_PED_TREVOR")
//PRINTNL()
ENDIF
IF bforced
sSelectorPeds.eNewSelectorPed = targetCharacter
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
sCamDetails.bPedSwitched =FALSE
ENDIF
CLEAR_PRINTS()
CLEAR_HELP()
iSwapProg++
BREAK
CASE 1 // detects the player making a character selection
IF bforced
IF bcloseswapcam
IF bCustomCam
IF SETUP_HOTSWAP_CAM(targetCharacter)
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
iSwapProg++
ENDIF
ELSE
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
iSwapProg++
ENDIF
ELSE
iSwapProg++
ENDIF
ELSE
IF UPDATE_SELECTOR_HUD(sSelectorPeds, FALSE) //Returns TRUE when the player has made a selection
IF sSelectorPeds.eNewSelectorPed = targetCharacter
IF bcloseswapcam
IF bcustomCam
IF SETUP_HOTSWAP_CAM(targetCharacter)
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
iSwapProg++
ENDIF
ELSE
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
iSwapProg++
ENDIF
ELSE
sCamDetails.pedTo = sSelectorPeds.pedID[targetCharacter]
iSwapProg++
ENDIF
ENDIF
ENDIF
ENDIF
BREAK
CASE 2 // runs the spline camera for the hotswap
MANAGE_INTERIOR_VIEWPOINT()
IF RUN_CAM_SPLINE_FROM_PLAYER_TO_PED(sCamDetails,0,0,SELECTOR_CAM_LONG_SPLINE)
IF sCamDetails.bOKToSwitchPed
IF NOT sCamDetails.bPedSwitched
IF TAKE_CONTROL_OF_SELECTOR_PED(sSelectorPeds)
sCamDetails.bPedSwitched = TRUE
ENDIF
ENDIF
ENDIF
ELSE
iSwapProg = 0
IF NOT IS_PED_INJURED(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed])
SET_PED_RELATIONSHIP_GROUP_HASH(sSelectorPeds.pedID[sSelectorPeds.ePreviousSelectorPed], RELGROUPHASH_PLAYER)
ENDIF
SET_PED_RELATIONSHIP_GROUP_HASH(PLAYER_PED_ID(), RELGROUPHASH_PLAYER)
SETUP_NON_PLAYER_AFTER_HOTSWAP(sSelectorPeds.pedID[SELECTOR_PED_MICHAEL],FALSE)
SETUP_NON_PLAYER_AFTER_HOTSWAP(sSelectorPeds.pedID[SELECTOR_PED_TREVOR],FALSE)
SETUP_NON_PLAYER_AFTER_HOTSWAP(sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN],FALSE)
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
enum enumPlacement
pos_none,
pos_barrels_1,
pos_barrels_2
ENDENUM
//RELATIONSHIP GROUP
REL_GROUP_HASH rel_group_buddies
REL_GROUP_HASH rel_group_enemies
CONST_INT MAX_BUDDY_PED 3
CONST_INT MAX_ENEMY_PED 55
CONST_INT MAX_DRIVER_PED 40
ENUM ENEMY_SITUATION_ENUM
ES_SIT_NONE,
ES_SIT_BULLET_NEAR,
ES_SIT_SHOT_HEARD,
ES_SIT_PLAYER_SEEN,
ES_SIT_RON_SEEN,
ES_SIT_REACT_TO_DAMAGE,
ES_REACT_TO_DISTURBANCE,
ES_GO_TO_COMBAT,
ES_SIT_DEAD_BODY
ENDENUM
STRUCT PED_STRUCT // contains details for all enemy mission peds
PED_INDEX ped
BLIP_INDEX blip
VECTOR loc
FLOAT head
WEAPON_TYPE wpn
MODEL_NAMES model
VECTOR vCov
BOOL bDoesCovExist
BOOL bTriggerTask
COVERPOINT_INDEX Cov
INT bikerReactionEvent
INT actionFlag
VECTOR vdestpos
OBJECT_INDEX obj
FLOAT desfloat
enumPlacement placement
ENEMY_SITUATION_ENUM esEnum
AI_BLIP_STRUCT EnemyBlipData
BOOL bRetask
INT iAlertTimer
BOOL bPathBlocked
BOOL bCalledForHelp
BOOL bCharge
BOOL bGoAggressive
BOOL bChangeTarget
INT iDelayTimer
BOOL bForceBlipOff
ENDSTRUCT
PED_STRUCT enemy[MAX_ENEMY_PED]
PED_STRUCT driver[MAX_DRIVER_PED]
PED_STRUCT buddy[MAX_BUDDY_PED]
PROC ACTIVATE_ENEMY(INT iThisPed)
IF NOT IS_PED_INJURED(enemy[iThisPed].ped)
SET_ENTITY_VISIBLE(enemy[iThisPed].ped,TRUE)
SET_PED_CURRENT_WEAPON_VISIBLE(enemy[iThisPed].ped,TRUE,FALSE)
SET_ENTITY_CAN_BE_DAMAGED(enemy[iThisPed].ped,TRUE)
SET_ENTITY_HEALTH(enemy[iThisPed].ped,135)
SET_PED_ACCURACY(enemy[iThisPed].ped,80)
STOP_PED_WEAPON_FIRING_WHEN_DROPPED(enemy[iThisPed].ped)
//SET_PED_CONFIG_FLAG(enemy[iThisPed].ped, DisableBlindFiringInShotReactions, TRUE)
ENDIF
ENDPROC
//PURPOSE: creates and sets up the specified enemies
PROC CREATE_ENEMIES(INT first, INT last, BOOL bblip,BOOL bRequestCollision = FALSE, BOOl bGuard = FALSE, BOOL bStartActive = TRUE, BOOL bBlockAI = TRUE)
INT i
FOR i = first TO last
REQUEST_MODEL(enemy[i].model)
IF HAS_MODEL_LOADED(enemy[i].model)
IF NOT DOES_ENTITY_EXIST(enemy[i].ped)
enemy[i].ped = CREATE_PED(PEDTYPE_MISSION, enemy[i].model, enemy[i].loc,enemy[i].head,TRUE)
IF bblip
enemy[i].blip = CREATE_BLIP_FOR_PED(enemy[i].ped,TRUE)
SET_BLIP_SCALE(enemy[i].blip, 0.5)
ENDIF
SET_PED_TARGET_LOSS_RESPONSE(enemy[i].ped,TLR_NEVER_LOSE_TARGET)
SET_PED_DIES_WHEN_INJURED(enemy[i].ped,TRUE)
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(enemy[i].ped,TRUE)
REMOVE_COVER_POINT(enemy[i].cov)
SET_ENTITY_HEALTH(enemy[i].ped ,135)
SET_PED_DIES_WHEN_INJURED(enemy[i].ped ,TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(enemy[i].ped ,rel_group_enemies)
GIVE_WEAPON_TO_PED(enemy[i].ped , enemy[i].wpn , 999, TRUE)
SET_CURRENT_PED_WEAPON(enemy[i].ped,enemy[i].wpn,TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(enemy[i].ped,bBlockAI)
SET_PED_AS_ENEMY(enemy[i].ped , TRUE)
SET_ENTITY_AS_MISSION_ENTITY(enemy[i].ped)
SET_PED_COMBAT_MOVEMENT(enemy[i].ped, CM_DEFENSIVE)
SET_PED_COMBAT_RANGE(enemy[i].ped, CR_MEDIUM)
SET_PED_COMBAT_ABILITY(enemy[i].ped, CAL_AVERAGE)
SET_PED_ACCURACY(enemy[i].ped,10)
SET_PED_COMBAT_ATTRIBUTES(enemy[i].ped,CA_ALWAYS_FIGHT,TRUE)
SET_PED_COMBAT_ATTRIBUTES(enemy[i].ped,CA_USE_ENEMY_ACCURACY_SCALING,TRUE)
SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(enemy[i].ped,TRUE)
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(enemy[i].ped,TRUE)
IF bRequestCollision = TRUE
REQUEST_COLLISION_AT_COORD(enemy[i].loc)
ENDIF
IF bGuard
//SET_PED_COMBAT_ATTRIBUTES(enemy[i].ped, CA_IS_A_GUARD, TRUE)
//SET_PED_CONFIG_FLAG(enemy[i].ped, PCF_AlwaysRespondToCriesForHelp, TRUE)
ENDIF
//SET_PED_COMBAT_ATTRIBUTES(enemy[iCount].ped, CA_IS_A_GUARD, TRUE)
//TASK_GUARD_CURRENT_POSITION(enemy[iCount].ped, 2, 15, TRUE)
IF bStartActive = FALSE
IF NOT IS_PED_INJURED(enemy[i].ped)
SET_ENTITY_VISIBLE(enemy[i].ped,FALSE)
SET_ENTITY_CAN_BE_DAMAGED(enemy[i].ped,FALSE)
SET_PED_CURRENT_WEAPON_VISIBLE(enemy[i].ped,FALSE,FALSE)
ENDIF
ENDIF
TEXT_LABEL_23 nameLabel = "Enemy "
nameLabel += i
SET_PED_NAME_DEBUG(enemy[i].ped ,nameLabel)
PRINTSTRING("enemy spawned : ")PRINTINT(i) //PRINTNL()
ELSE
PRINTSTRING("enemy already exists : ")PRINTINT(i)//PRINTNL()
ENDIF
ENDIF
ENDFOR
ENDPROC
//PURPOSE: creates and sets up the specified enemies
PROC CREATE_ENEMY_AT_COORD(INT enemyIndex, VECTOR vLoc, FLOAT fHead, BOOL bblip, BOOL bBlockAI = TRUE)
REMOVE_COVER_POINT(enemy[enemyIndex].cov)
enemy[enemyIndex].ped = CREATE_PED(PEDTYPE_MISSION, enemy[enemyIndex].model, vLoc, fHead,TRUE)
IF bblip
enemy[enemyIndex].blip = CREATE_BLIP_FOR_PED(enemy[enemyIndex].ped,TRUE)
SET_BLIP_SCALE(enemy[enemyIndex].blip, 0.5)
ENDIF
STOP_PED_WEAPON_FIRING_WHEN_DROPPED(enemy[enemyIndex].ped)
SET_PED_DIES_WHEN_INJURED(enemy[enemyIndex].ped,TRUE)
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(enemy[enemyIndex].ped,TRUE)
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(enemy[enemyIndex].ped,TRUE)
SET_PED_MONEY(enemy[enemyIndex].ped,0)
SET_ENTITY_HEALTH(enemy[enemyIndex].ped ,110)
SET_PED_DIES_WHEN_INJURED(enemy[enemyIndex].ped ,TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(enemy[enemyIndex].ped ,rel_group_enemies)
GIVE_WEAPON_TO_PED(enemy[enemyIndex].ped , enemy[enemyIndex].wpn , 999, TRUE)
SET_CURRENT_PED_WEAPON(enemy[enemyIndex].ped,enemy[enemyIndex].wpn,TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(enemy[enemyIndex].ped,bBlockAI)
SET_PED_AS_ENEMY(enemy[enemyIndex].ped , TRUE)
SET_ENTITY_AS_MISSION_ENTITY(enemy[enemyIndex].ped)
SET_PED_COMBAT_MOVEMENT(enemy[enemyIndex].ped, CM_DEFENSIVE)
SET_PED_COMBAT_RANGE(enemy[enemyIndex].ped, CR_MEDIUM)
SET_PED_COMBAT_ABILITY(enemy[enemyIndex].ped, CAL_AVERAGE)
SET_PED_COMBAT_ATTRIBUTES(enemy[enemyIndex].ped,CA_USE_ENEMY_ACCURACY_SCALING,TRUE)
SET_PED_ACCURACY(enemy[enemyIndex].ped,10)
SET_PED_TARGET_LOSS_RESPONSE(enemy[enemyIndex].ped,TLR_NEVER_LOSE_TARGET)
//SET_PED_COMBAT_ATTRIBUTES(enemy[iCount].ped, CA_IS_A_GUARD, TRUE)
//TASK_GUARD_CURRENT_POSITION(enemy[iCount].ped, 2, 15, TRUE)
TEXT_LABEL_23 nameLabel = "Enemy "
nameLabel += enemyIndex
SET_PED_NAME_DEBUG(enemy[enemyIndex].ped ,nameLabel)
PRINTSTRING("enemy spawned : ")
PRINTINT(enemyIndex)
//PRINTNL()
ENDPROC
//PURPOSE: creates and sets up the specified enemies
PROC CREATE_ENEMY_IN_VEHICLE(INT enemyIndex, VEHICLE_INDEX Enemyveh, BOOL bblip)
REMOVE_COVER_POINT(enemy[enemyIndex].cov)
IF IS_VEHICLE_DRIVEABLE(Enemyveh)
IF IS_VEHICLE_SEAT_FREE(Enemyveh,VS_DRIVER)
enemy[enemyIndex].ped = CREATE_PED_INSIDE_VEHICLE(Enemyveh, PEDTYPE_MISSION, enemy[enemyIndex].model,VS_DRIVER)
ENDIF
ENDIF
IF bblip
enemy[enemyIndex].blip = CREATE_BLIP_FOR_PED(enemy[enemyIndex].ped,TRUE)
SET_BLIP_SCALE(enemy[enemyIndex].blip, 0.5)
ENDIF
STOP_PED_WEAPON_FIRING_WHEN_DROPPED(enemy[enemyIndex].ped)
SET_PED_TARGET_LOSS_RESPONSE(enemy[enemyIndex].ped,TLR_NEVER_LOSE_TARGET)
SET_PED_ALLOW_HURT_COMBAT_FOR_ALL_MISSION_PEDS(FALSE)
SET_PED_DIES_WHEN_INJURED(enemy[enemyIndex].ped,TRUE)
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(enemy[enemyIndex].ped,TRUE)
SET_PED_MONEY(enemy[enemyIndex].ped,0)
SET_ENTITY_HEALTH(enemy[enemyIndex].ped ,125)
SET_PED_DIES_WHEN_INJURED(enemy[enemyIndex].ped ,TRUE)
SET_PED_RELATIONSHIP_GROUP_HASH(enemy[enemyIndex].ped ,rel_group_enemies)
GIVE_WEAPON_TO_PED(enemy[enemyIndex].ped , enemy[enemyIndex].wpn , 999, TRUE)
SET_CURRENT_PED_WEAPON(enemy[enemyIndex].ped,enemy[enemyIndex].wpn,TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(enemy[enemyIndex].ped,TRUE)
SET_PED_AS_ENEMY(enemy[enemyIndex].ped , TRUE)
SET_ENTITY_AS_MISSION_ENTITY(enemy[enemyIndex].ped)
SET_PED_COMBAT_MOVEMENT(enemy[enemyIndex].ped, CM_DEFENSIVE)
SET_PED_COMBAT_RANGE(enemy[enemyIndex].ped, CR_MEDIUM)
SET_PED_COMBAT_ABILITY(enemy[enemyIndex].ped, CAL_POOR)
SET_PED_ACCURACY(enemy[enemyIndex].ped,5)
SET_PED_COMBAT_ATTRIBUTES(enemy[enemyIndex].ped,CA_USE_ENEMY_ACCURACY_SCALING,TRUE)
//SET_PED_COMBAT_ATTRIBUTES(enemy[iCount].ped, CA_IS_A_GUARD, TRUE)
//TASK_GUARD_CURRENT_POSITION(enemy[iCount].ped, 2, 15, TRUE)
TEXT_LABEL_23 nameLabel = "Enemy "
nameLabel += enemyIndex
SET_PED_NAME_DEBUG(enemy[enemyIndex].ped ,nameLabel)
PRINTSTRING("enemy spawned : ")
PRINTINT(enemyIndex)
//PRINTNL()
ENDPROC
//PURPOS: Sets the gameplay camera'heading relative to the world coordinate system (not relative to the players local heading)
PROC SET_GAMEPLAY_CAM_WORLD_HEADING(FLOAT fHeading = 0.0)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(fHeading - GET_ENTITY_HEADING(PLAYER_PED_ID()))
ENDPROC
//PURPOSE: Creates a custom cover point associated with a ped
PROC CREATE_ENEMY_COVER_POINT(INT enemyIndex, VECTOR vCovCoord, FLOAT fCovDir, COVERPOINT_USAGE usage, COVERPOINT_HEIGHT height, COVERPOINT_ARC arc)
IF enemy[enemyIndex].bDoesCovExist
REMOVE_COVER_POINT(enemy[enemyIndex].cov)
ENDIF
IF NOT DOES_SCRIPTED_COVER_POINT_EXIST_AT_COORDS(vCovCoord)
enemy[enemyIndex].cov = ADD_COVER_POINT(vCovCoord, fCovDir, usage, height, arc)
ITEMSET_INDEX coverSet = CREATE_ITEMSET(TRUE)
ADD_TO_ITEMSET(enemy[enemyIndex].cov, coverSet)
IF NOT IS_PED_INJURED(enemy[enemyIndex].ped)
SET_PED_MONEY(enemy[enemyIndex].ped,0)
SET_PED_PREFERRED_COVER_SET(enemy[enemyIndex].ped, coverSet)
DESTROY_ITEMSET(coverSet)
enemy[enemyIndex].bDoesCovExist = TRUE
ELSE
#IF IS_DEBUG_BUILD
PRINTSTRING("TRIED TO ADD COVER POINT BUT PED IS INJURED")
#ENDIF
ENDIF
ELSE
#IF IS_DEBUG_BUILD
PRINTSTRING("COVERPOINT ALREADY EXISTS HERE")
#ENDIF
ENDIF
ENDPROC
//PURPOSE: Tasks a ped into a custom cover point created as needed
PROC TASK_PUT_ENEMY_INTO_CUSTOM_COVER(INT enemyIndex, VECTOR vCoverPos, FLOAT fCovDir, INT Time, COVERPOINT_USAGE usage, COVERPOINT_HEIGHT height, COVERPOINT_ARC arc, BOOL CanPeekAndAim = FALSE, FLOAT BlendInDuration = 0.0, bool ForceInitialFacingDirection = FALSE, bool bForceFaceLeft = FALSE, BOOL bSequence = TRUE)
IF NOT DOES_SCRIPTED_COVER_POINT_EXIST_AT_COORDS(vCoverPos)
CREATE_ENEMY_COVER_POINT(enemyIndex, vCoverPos, fCovDir, usage, height, arc)
IF bSequence
TASK_SEEK_COVER_TO_COVER_POINT(NULL, enemy[enemyIndex].cov, GET_ENTITY_COORDS(PLAYER_PED_ID()),Time,canPeekAndAim)
ELSE
TASK_PUT_PED_DIRECTLY_INTO_COVER(enemy[enemyIndex].ped, vCoverPos, Time, CanpeekAndAim, BlendInDuration, ForceInitialFacingDirection, bForceFaceLeft)
ENDIF
ELSE
IF bSequence
SET_PED_SPHERE_DEFENSIVE_AREA(enemy[enemyIndex].ped, vCoverPos,1)
TASK_SEEK_COVER_FROM_PED(NULL,PLAYER_PED_ID(),Time,CanPeekAndAim)
ELSE
TASK_PUT_PED_DIRECTLY_INTO_COVER(enemy[enemyIndex].ped, vCoverPos, Time, CanpeekAndAim, BlendInDuration, ForceInitialFacingDirection, bForceFaceLeft)
ENDIF
ENDIF
ENDPROC
//
//PROC CREATE_CUSTOM_COVER_POINT_FOR_CREW_MEMBER(INT iCrew, VECTOR vCoverPos, FLOAT fCov)
//
//ENDPROC
//PURPOSE: Creates a custom cover point associated with a ped
PROC CREATE_BUDDY_COVER_POINT(INT buddyIndex, VECTOR vCovCoord, FLOAT fCovDir, COVERPOINT_USAGE usage, COVERPOINT_HEIGHT height, COVERPOINT_ARC arc)
IF buddy[buddyIndex].bDoesCovExist
REMOVE_COVER_POINT(buddy[buddyIndex].cov)
ENDIF
IF NOT IS_PED_INJURED(buddy[buddyIndex].ped)
IF NOT DOES_SCRIPTED_COVER_POINT_EXIST_AT_COORDS(vCovCoord)
buddy[buddyIndex].cov = ADD_COVER_POINT(vCovCoord, fCovDir, usage, height, arc)
ITEMSET_INDEX coverSet = CREATE_ITEMSET(TRUE)
ADD_TO_ITEMSET(buddy[buddyIndex].cov, coverSet)
SET_PED_PREFERRED_COVER_SET(buddy[buddyIndex].ped, coverSet)
DESTROY_ITEMSET(coverSet)
ELSE
buddy[buddyIndex].bDoesCovExist = TRUE
ENDIF
ENDIF
ENDPROC
//PURPOSE: Tasks a ped into a custom cover point created as needed
PROC TASK_PUT_BUDDY_INTO_CUSTOM_COVER(INT buddyIndex, VECTOR vCoverPos,VECTOR vCovFromThis, FLOAT fCovDir, INT Time, COVERPOINT_USAGE usage, COVERPOINT_HEIGHT height, COVERPOINT_ARC arc, BOOL CanPeekAndAim = FALSE, FLOAT BlendInDuration = 0.0, bool ForceInitialFacingDirection = FALSE, bool bForceFaceLeft = FALSE, BOOL bSequence = TRUE)
CREATE_BUDDY_COVER_POINT(buddyIndex, vCoverPos, fCovDir, usage, height, arc)
IF bSequence
TASK_SEEK_COVER_TO_COVER_POINT(NULL, buddy[buddyIndex].cov, vCovFromThis,Time,canPeekAndAim)
//TASK_PUT_PED_DIRECTLY_INTO_COVER(NULL, vCoverPos, Time, CanpeekAndAim, BlendInDuration, ForceInitialFacingDirection, bForceFaceLeft)
ELSE
TASK_PUT_PED_DIRECTLY_INTO_COVER(buddy[buddyIndex].ped, vCoverPos, Time, CanpeekAndAim, BlendInDuration, ForceInitialFacingDirection, bForceFaceLeft)
ENDIF
ENDPROC
//PURPOSE: Creates a custom cover point associated with a ped
PROC CREATE_DRIVER_COVER_POINT(INT driverIndex, VECTOR vCovCoord, FLOAT fCovDir, COVERPOINT_USAGE usage, COVERPOINT_HEIGHT height, COVERPOINT_ARC arc)
IF driver[driverIndex].bDoesCovExist
REMOVE_COVER_POINT(driver[driverIndex].cov)
ENDIF
IF NOT IS_PED_INJURED(driver[driverIndex].ped)
IF NOT DOES_SCRIPTED_COVER_POINT_EXIST_AT_COORDS(vCovCoord)
driver[driverIndex].cov = ADD_COVER_POINT(vCovCoord, fCovDir, usage, height, arc)
ITEMSET_INDEX coverSet = CREATE_ITEMSET(TRUE)
ADD_TO_ITEMSET(driver[driverIndex].cov, coverSet)
SET_PED_PREFERRED_COVER_SET(driver[driverIndex].ped, coverSet)
DESTROY_ITEMSET(coverSet)
driver[driverIndex].bDoesCovExist = TRUE
ENDIF
ENDIF
ENDPROC
//PURPOSE: Tasks a ped into a custom cover point created as needed
PROC TASK_PUT_DRIVER_INTO_CUSTOM_COVER(INT driverIndex, VECTOR vCoverPos, FLOAT fCovDir, INT Time, COVERPOINT_USAGE usage, COVERPOINT_HEIGHT height, COVERPOINT_ARC arc, BOOL CanPeekAndAim = FALSE, FLOAT BlendInDuration = 0.0, bool ForceInitialFacingDirection = FALSE, bool bForceFaceLeft = FALSE, BOOL bSequence = TRUE)
CREATE_DRIVER_COVER_POINT(driverIndex, vCoverPos, fCovDir, usage, height, arc)
IF bSequence
TASK_SEEK_COVER_TO_COVER_POINT(NULL, driver[driverIndex].cov, GET_ENTITY_COORDS(PLAYER_PED_ID()),Time,canPeekAndAim)
//TASK_PUT_PED_DIRECTLY_INTO_COVER(NULL, vCoverPos, Time, CanpeekAndAim, BlendInDuration, ForceInitialFacingDirection, bForceFaceLeft)
ELSE
TASK_PUT_PED_DIRECTLY_INTO_COVER(driver[driverIndex].ped, vCoverPos, Time, CanpeekAndAim, BlendInDuration, ForceInitialFacingDirection, bForceFaceLeft)
ENDIF
ENDPROC
//
//PROC CREATE_CUSTOM_COVER_POINT_FOR_CREW_MEMBER(INT iCrew, VECTOR vCoverPos, FLOAT fCov)
//
//ENDPROC
//PURPOSE: tasks a ped to stay in a spot and shoot at a target ped
PROC TASK_COMBAT_PED_AND_ALWAYS_STAY_IN_PLACE(PED_INDEX target, VECTOR vCoord, FLOAT fMoveBlendRatio, BOOL bDuck = FALSE,BOOL bSequence = TRUE)
IF bSequence
TASK_FOLLOW_NAV_MESH_TO_COORD(null, vCoord, fMoveBlendRatio)
IF bDuck
TASK_DUCK(null, 300)
TASK_SET_SPHERE_DEFENSIVE_AREA(null, vCoord, 1.0)
TASK_TOGGLE_DUCK(null, TOGGLE_DUCK_ON)
TASK_SHOOT_AT_ENTITY(null, target, -1, FIRING_TYPE_RANDOM_BURSTS)
ELSE
TASK_SET_SPHERE_DEFENSIVE_AREA(null, vCoord, 1.0)
TASK_COMBAT_PED(null, target)
ENDIF
ENDIF
ENDPROC
CONST_INT MAX_MISSION_VEH 35
STRUCT VEH_STRUCT // contains details for all mission vehicles
VEHICLE_INDEX veh
BLIP_INDEX blip
VECTOR loc
FLOAT head
MODEL_NAMES model
INT iRecordingNumber
INT iThisProgress
INT iThisTimer
INT iDamage
INT iDamageTimer
INT iAttackPattern
INT iAttackPatternTimer
VECTOR vThisLocation
FLOAT fThisHeading
INT iGetToNewPositionTimer
ENDSTRUCT
VEH_STRUCT mission_veh[MAX_MISSION_VEH]
//PURPOSE: Makes a mission vehicle
PROC CREATE_ENEMY_VEHICLE(INT vehindex,MODEL_NAMES vehmod,VECTOR vVehloc,FLOAT vehhead, MODEL_NAMES drivermod,BOOL bdriver=FALSE, INT firstpedindex = 0,INT numberpassengers=0,BOOL bInvul = FALSE,INT iColour = -1,WEAPON_TYPE wpn = WEAPONTYPE_CARBINERIFLE )
INT i
mission_veh[vehindex].veh=CREATE_VEHICLE(vehmod,vVehloc,vehhead)
IF vehindex != 2
//SET_VEHICLE_DOORS_LOCKED(mission_veh[vehindex].veh,VEHICLELOCK_LOCKOUT_PLAYER_ONLY)
IF iColour != - 1
SET_VEHICLE_COLOUR_COMBINATION(mission_veh[vehindex].veh,iColour)
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
TEXT_LABEL_23 nameLabel = "VEHICLE "
nameLabel += vehindex
SET_VEHICLE_NAME_DEBUG(mission_veh[vehindex].veh ,nameLabel)
#ENDIF
IF bdriver
IF IS_VEHICLE_SEAT_FREE(mission_veh[vehindex].veh,VS_DRIVER)
driver[firstpedindex].ped = CREATE_PED_INSIDE_VEHICLE(mission_veh[vehindex].veh,PEDTYPE_MISSION,drivermod)
ENDIF
GIVE_WEAPON_TO_PED(driver[firstpedindex].ped, wpn, 999, TRUE)
GIVE_WEAPON_TO_PED(driver[firstpedindex].ped, WEAPONTYPE_PISTOL, INFINITE_AMMO, FALSE)
SET_PED_RELATIONSHIP_GROUP_HASH(driver[firstpedindex].ped ,rel_group_enemies)
SET_PED_AS_ENEMY(driver[firstpedindex].ped , TRUE)
SET_ENTITY_AS_MISSION_ENTITY(driver[firstpedindex].ped)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(driver[firstpedindex].ped,TRUE)
SET_PED_MONEY(driver[firstpedindex].ped,0)
SET_PED_ACCURACY(driver[firstpedindex].ped,3)
SET_VEHICLE_DOORS_LOCKED(mission_veh[vehindex].veh,VEHICLELOCK_UNLOCKED)
SET_PED_ALLOW_HURT_COMBAT_FOR_ALL_MISSION_PEDS(FALSE)
SET_PED_DIES_WHEN_INJURED(driver[firstpedindex].ped,TRUE)
IF driver[firstpedindex].ped != NULL
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(driver[firstpedindex].ped,TRUE)
ENDIF
#IF IS_DEBUG_BUILD
nameLabel = "Driver "
nameLabel += firstpedindex
SET_PED_NAME_DEBUG(driver[firstpedindex].ped ,nameLabel)
#ENDIF
ENDIF
IF numberpassengers > 0
IF numberpassengers > GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(mission_veh[vehindex].veh)
numberpassengers = GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(mission_veh[vehindex].veh)
ENDIF
FOR i = 1 TO numberpassengers
PRINTINT(i)
//PRINTNL()
IF IS_VEHICLE_SEAT_FREE(mission_veh[vehindex].veh,INT_TO_ENUM(VEHICLE_SEAT,(i-1)))
driver[firstpedindex+i].ped=CREATE_PED_INSIDE_VEHICLE(mission_veh[vehindex].veh,PEDTYPE_MISSION,drivermod,INT_TO_ENUM(VEHICLE_SEAT,(i-1)))
ENDIF
SET_PED_MONEY(driver[firstpedindex+1].ped,0)
GIVE_WEAPON_TO_PED(driver[firstpedindex+i].ped,WEAPONTYPE_CARBINERIFLE,200,TRUE)
SET_PED_COMBAT_ABILITY(driver[firstpedindex+i].ped, CAL_POOR)
SET_PED_COMBAT_ATTRIBUTES(driver[firstpedindex+i].ped, CA_AGGRESSIVE,TRUE)
SET_PED_ACCURACY(driver[firstpedindex+i].ped,5)
SET_PED_COMBAT_MOVEMENT(driver[firstpedindex+i].ped,CM_WILLADVANCE)
SET_PED_COMBAT_RANGE(driver[firstpedindex+i].ped,CR_FAR)
SET_PED_RELATIONSHIP_GROUP_HASH(driver[firstpedindex+i].ped,rel_group_enemies)
SET_PED_AS_ENEMY(driver[firstpedindex+i].ped , TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(driver[firstpedindex+i].ped,TRUE)
SET_ENTITY_PROOFS( mission_veh[vehindex].veh, FALSE,FALSE,FALSE,bInvul,bInvul)
SET_PED_ALLOW_HURT_COMBAT_FOR_ALL_MISSION_PEDS(FALSE)
SET_PED_DIES_WHEN_INJURED(driver[firstpedindex+i].ped,TRUE)
INFORM_MISSION_STATS_OF_HEADSHOT_WATCH_ENTITY(driver[firstpedindex+i].ped,TRUE)
#IF IS_DEBUG_BUILD
nameLabel = "Driver "
nameLabel += (firstpedindex+i)
SET_PED_NAME_DEBUG(driver[firstpedindex+i].ped ,nameLabel)
#ENDIF
ENDFOR
ENDIF
ENDPROC
SEQUENCE_INDEX TASK_SEQUENCE
FUNC BOOL MOVE_AND_ATTACK(VECTOR vtrigger,INT ifirstenemy,INT ilastenemy,INT idelay = 1,INT iroll = 0,BOOL baim = FALSE)
INT i
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(),vtrigger,<<4,4,4>>,FALSE,TRUE)
FOR i = ifirstenemy TO ilastenemy
IF NOT IS_PED_INJURED(enemy[i].ped)
//SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(enemy[irepeater].ped,FALSE)
OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
//TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,enemy[iCount].vCov,PLAYER_PED_ID(),PEDMOVE_RUN,TRUE)
TASK_STAND_STILL(NULL,idelay)
IF NOT baim
TASK_GO_STRAIGHT_TO_COORD(NULL,enemy[i].vCov,PEDMOVE_RUN)
ELSE
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,enemy[i].vCov,PLAYER_PED_ID(),PEDMOVE_WALK,TRUE,0.5,4,FALSE)
ENDIF
IF iroll = 1
TASK_PLAY_ANIM(NULL,"ev_dives","PLYR_ROLL_LEFT")
ELIF iroll = 2
TASK_PLAY_ANIM(NULL,"ev_dives","PLYR_ROLL_RIGHT")
ENDIF
TASK_COMBAT_HATED_TARGETS_AROUND_PED(NULL,200.0)
CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_PERFORM_SEQUENCE(enemy[i].ped,TASK_SEQUENCE)
CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
SET_PED_COMBAT_MOVEMENT(enemy[i].ped,CM_DEFENSIVE)
SET_PED_SPHERE_DEFENSIVE_AREA(enemy[i].ped, enemy[i].vCov, 2.0)
IF NOT DOES_BLIP_EXIST(enemy[i].blip)
enemy[i].blip = CREATE_BLIP_FOR_PED(enemy[i].ped,TRUE)
ENDIF
ENDIF
ENDFOR
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
//PURPOSE: returns true if the number of specified enemies drop below the threshold.
FUNC BOOL IS_NUMBER_ENEMIES_ALIVE_BELOW(INT first, INT last,INT ienemythreshold)
INT ienemycount = 0
INT i
FOR i = first TO last
IF DOES_ENTITY_EXIST(enemy[i].ped)
IF NOT IS_PED_INJURED(enemy[i].ped)
ienemycount++
ENDIF
ENDIF
ENDFOR
IF ienemycount > ienemythreshold
RETURN FALSE
ELSE
RETURN TRUE
ENDIF
ENDFUNC
PROC EXIT_VEHICLE_TO_FIGHT_ADVANCED(VEHICLE_INDEX playbackveh,INT iDriver,VECTOR vCover,FLOAT fdir,INT iTime, COVERPOINT_USAGE usage,COVERPOINT_HEIGHT height, COVERPOINT_ARC arc)
IF IS_VEHICLE_DRIVEABLE(playbackveh)
IF NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(playbackveh))
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(playbackveh)
IF NOT IS_PED_INJURED(driver[iDriver].ped)
//IF GET_SCRIPT_TASK_STATUS(driver[iDriver].ped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
IF NOT driver[iDriver].bTriggerTask
//OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
//TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL,TRUE)
//TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,vCover ,PLAYER_PED_ID(),PEDMOVE_RUN,TRUE,3,5)
//TASK_PUT_DRIVER_INTO_CUSTOM_COVER(iDriver,vCover,fdir,iTime, usage, height,arc,TRUE)
//TASK_SET_SPHERE_DEFENSIVE_AREA(NULL,vCover,2)
//TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL,TRUE)
SET_PED_COMBAT_ATTRIBUTES(driver[iDriver].ped,CA_USE_VEHICLE,FALSE)
TASK_COMBAT_PED(driver[iDriver].ped,PLAYER_PED_ID())
SET_PED_SPHERE_DEFENSIVE_AREA(driver[iDriver].ped,GET_ENTITY_COORDS(playbackveh),3.0)
driver[iDriver].bTriggerTask = TRUE
//CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
//TASK_PERFORM_SEQUENCE(driver[iDriver].ped,TASK_SEQUENCE)
//CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
ENDIF
IF driver[iDriver].actionFlag = 99
SET_PED_COMBAT_ATTRIBUTES(driver[iDriver].ped,CA_USE_VEHICLE,FALSE)
OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL,TRUE)
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,vCover ,PLAYER_PED_ID(),PEDMOVE_RUN,TRUE,3,5)
TASK_PUT_DRIVER_INTO_CUSTOM_COVER(iDriver,vCover,fdir,iTime, usage, height,arc,TRUE)
TASK_SET_SPHERE_DEFENSIVE_AREA(NULL,vCover,2)
TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL,TRUE)
CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_PERFORM_SEQUENCE(driver[iDriver].ped,TASK_SEQUENCE)
CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
driver[iDriver].actionFlag = 0
ENDIF
ENDIF
ENDIF
ELSE
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(playbackveh)
STOP_PLAYBACK_RECORDED_VEHICLE(playbackveh)
IF NOT IS_PED_INJURED(driver[iDriver].ped)
SET_PED_COMBAT_ATTRIBUTES(driver[iDriver].ped,CA_USE_VEHICLE,FALSE)
IF GET_SCRIPT_TASK_STATUS(driver[iDriver].ped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,GET_ENTITY_COORDS(PLAYER_PED_ID()) ,PLAYER_PED_ID(),PEDMOVE_WALK,TRUE,3,5)
TASK_COMBAT_PED(NULL,PLAYER_PED_ID())
CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_PERFORM_SEQUENCE(driver[iDriver].ped,TASK_SEQUENCE)
CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC EXIT_VEHICLE_TO_FIGHT(VEHICLE_INDEX playbackveh, FLOAT defX = 0.0, FLOAT defY = 0.0, FLOAT defZ = 0.0)
INT i
IF IS_VEHICLE_DRIVEABLE(playbackveh)
IF NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(playbackveh))
IF GET_PED_IN_VEHICLE_SEAT(playbackveh) != PLAYER_PED_ID()
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(playbackveh)
FOR i = -1 TO GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(playbackveh) - 1
PED_INDEX tempdriverped = GET_PED_IN_VEHICLE_SEAT(playbackveh,INT_TO_ENUM(VEHICLE_SEAT,i))
//PRINTLN(i)
IF NOT IS_PED_INJURED(tempdriverped)
SET_PED_COMBAT_ATTRIBUTES(tempdriverped,CA_USE_VEHICLE,FALSE)
IF NOT IS_VECTOR_ZERO(<<defX,defY,defZ>>)
TASK_SET_SPHERE_DEFENSIVE_AREA(tempdriverped,<<defX,defY,defZ>>,2)
ENDIF
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(tempdriverped,FALSE)
IF GET_SCRIPT_TASK_STATUS(tempdriverped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
// IF IS_PED_IN_ANY_VEHICLE(tempdriverped)
// TASK_LEAVE_ANY_VEHICLE(NULL,GET_RANDOM_INT_IN_RANGE(0,200),ECF_DONT_CLOSE_DOOR)
// ENDIF
TASK_COMBAT_PED(NULL,PLAYER_PED_ID())
//TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,GET_ENTITY_COORDS(PLAYER_PED_ID()) ,PLAYER_PED_ID(),PEDMOVE_WALK,TRUE,3,5)
CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_PERFORM_SEQUENCE(tempdriverped,TASK_SEQUENCE)
CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
ENDIF
ENDIF
ENDFOR
ENDIF
ENDIF
ELSE
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(playbackveh)
STOP_PLAYBACK_RECORDED_VEHICLE(playbackveh)
SET_ENTITY_PROOFS(playbackveh,FALSE,FALSE,FALSE,FALSE,FALSE)
FOR i = -1 TO GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(playbackveh) - 1
PED_INDEX tempdriverped = GET_PED_IN_VEHICLE_SEAT(playbackveh,INT_TO_ENUM(VEHICLE_SEAT,i))
//PRINTLN(i)
IF NOT IS_PED_INJURED(tempdriverped)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(tempdriverped,FALSE)
SET_PED_COMBAT_ATTRIBUTES(tempdriverped,CA_USE_VEHICLE,FALSE)
IF GET_SCRIPT_TASK_STATUS(tempdriverped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
// IF IS_PED_IN_ANY_VEHICLE(tempdriverped)
// TASK_LEAVE_ANY_VEHICLE(NULL,GET_RANDOM_INT_IN_RANGE(0,200),ECF_DONT_CLOSE_DOOR )
// ENDIF
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,GET_ENTITY_COORDS(PLAYER_PED_ID()) ,PLAYER_PED_ID(),PEDMOVE_WALK,TRUE,3,5)
TASK_COMBAT_PED(NULL,PLAYER_PED_ID())
CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_PERFORM_SEQUENCE(tempdriverped,TASK_SEQUENCE)
CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
ENDIF
ENDIF
ENDFOR
ENDIF
ENDIF
ENDIF
ENDPROC
PROC EXIT_HELI_TO_FIGHT(VEHICLE_INDEX playbackveh,VECTOR vIsInArea , VECTOR vIsInAreaSize)
INT i
IF IS_VEHICLE_DRIVEABLE(playbackveh)
IF NOT IS_PED_INJURED(GET_PED_IN_VEHICLE_SEAT(playbackveh))
IF NOT IS_VECTOR_ZERO(vIsInArea)
IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(playbackveh) OR (NOT ARE_VECTORS_EQUAL(<<0,0,0>>, vIsInArea) AND IS_ENTITY_AT_COORD(playbackveh,vIsInArea,vIsInAreaSize))
FOR i = -1 TO GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(playbackveh) - 1
PED_INDEX tempdriverped = GET_PED_IN_VEHICLE_SEAT(playbackveh,INT_TO_ENUM(VEHICLE_SEAT,i))
//PRINTLN(i)
IF NOT IS_PED_INJURED(tempdriverped)
SET_PED_COMBAT_ATTRIBUTES(tempdriverped,CA_USE_VEHICLE,FALSE)
IF GET_SCRIPT_TASK_STATUS(tempdriverped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
// IF IS_PED_IN_ANY_VEHICLE(tempdriverped)
// TASK_LEAVE_ANY_VEHICLE(NULL,GET_RANDOM_INT_IN_RANGE(0,200),ECF_DONT_CLOSE_DOOR)
// ENDIF
IF NOT IS_PED_IN_ANY_HELI(tempdriverped)
TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL,FALSE)
TASK_SET_SPHERE_DEFENSIVE_AREA(NULL,GET_ENTITY_COORDS(playbackveh),20)
TASK_COMBAT_PED(NULL,PLAYER_PED_ID())
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,GET_ENTITY_COORDS(PLAYER_PED_ID()) ,PLAYER_PED_ID(),PEDMOVE_WALK,TRUE,3,5)
ELSE
TASK_RAPPEL_FROM_HELI(NULL,30)
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,GET_ENTITY_COORDS(PLAYER_PED_ID()) ,PLAYER_PED_ID(),PEDMOVE_WALK,TRUE,3,5)
ENDIF
CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_PERFORM_SEQUENCE(tempdriverped,TASK_SEQUENCE)
CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
ENDIF
ENDIF
ENDFOR
ENDIF
ENDIF
ELSE
IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(playbackveh)
MODEL_NAMES Thismodel
Thismodel = GET_ENTITY_MODEL(playbackveh)
IF NOT IS_THIS_MODEL_A_HELI(Thismodel)
STOP_PLAYBACK_RECORDED_VEHICLE(playbackveh)
SET_ENTITY_PROOFS(playbackveh,FALSE,FALSE,FALSE,FALSE,FALSE)
FOR i = -1 TO GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(playbackveh) - 1
PED_INDEX tempdriverped = GET_PED_IN_VEHICLE_SEAT(playbackveh,INT_TO_ENUM(VEHICLE_SEAT,i))
//PRINTLN(i)
IF NOT IS_PED_INJURED(tempdriverped)
SET_PED_COMBAT_ATTRIBUTES(tempdriverped,CA_USE_VEHICLE,FALSE)
IF GET_SCRIPT_TASK_STATUS(tempdriverped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
OPEN_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(NULL,FALSE)
TASK_SET_SPHERE_DEFENSIVE_AREA(NULL,GET_ENTITY_COORDS(playbackveh),20)
TASK_COMBAT_PED(NULL,PLAYER_PED_ID())
// IF IS_PED_IN_ANY_VEHICLE(tempdriverped)
// TASK_LEAVE_ANY_VEHICLE(NULL,GET_RANDOM_INT_IN_RANGE(0,200),ECF_DONT_CLOSE_DOOR )
// ENDIF
TASK_GO_TO_COORD_WHILE_AIMING_AT_ENTITY(NULL,GET_ENTITY_COORDS(PLAYER_PED_ID()) ,PLAYER_PED_ID(),PEDMOVE_WALK,TRUE,3,5)
CLOSE_SEQUENCE_TASK(TASK_SEQUENCE)
TASK_PERFORM_SEQUENCE(tempdriverped,TASK_SEQUENCE)
CLEAR_SEQUENCE_TASK(TASK_SEQUENCE)
ENDIF
ENDIF
ENDFOR
ELSE
IF IS_VEHICLE_DRIVEABLE(playbackveh)
EXPLODE_VEHICLE(playbackveh)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL IS_VEHICLE_ROUGHLY_FACING_THIS_DIRECTION(VEHICLE_INDEX veh, FLOAT idealHeading, FLOAT acceptableRange = 30.0)
FLOAT upperLimit, lowerLimit
upperLimit = idealHeading + (acceptableRange/2)
IF upperLimit > 360
upperLimit -= 360.0
ENDIF
lowerLimit = idealHeading - (acceptableRange/2)
IF lowerLimit < 0
lowerLimit += 360.0
ENDIF
IF IS_VEHICLE_DRIVEABLE(veh)
IF upperLimit > lowerLimit
IF GET_ENTITY_HEADING(veh) < upperLimit
AND GET_ENTITY_HEADING(veh) > lowerLimit
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ELSE
IF GET_ENTITY_HEADING(veh) < upperLimit
OR GET_ENTITY_HEADING(veh) > lowerLimit
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
// ======================================================================
// Synchronised Scene
// ======================================================================
FUNC BOOL IS_PED_ROUGHLY_FACING_THIS_DIRECTION(PED_INDEX ped, FLOAT idealHeading, FLOAT acceptableRange = 30.0)
FLOAT upperLimit, lowerLimit
upperLimit = idealHeading + (acceptableRange/2)
IF upperLimit > 360
upperLimit -= 360.0
ENDIF
lowerLimit = idealHeading - (acceptableRange/2)
IF lowerLimit < 0
lowerLimit += 360.0
ENDIF
IF NOT IS_PED_INJURED(ped)
IF upperLimit > lowerLimit
IF GET_ENTITY_HEADING(ped) < upperLimit
AND GET_ENTITY_HEADING(ped) > lowerLimit
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ELSE
IF GET_ENTITY_HEADING(ped) < upperLimit
OR GET_ENTITY_HEADING(ped) > lowerLimit
RETURN TRUE
ELSE
RETURN FALSE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC GET_PED_READY_FOR_ANIM(PED_INDEX ped, VECTOR vDesired, FLOAT fDesired, SEQUENCE_INDEX seq, FLOAT fMoveBlend = 1.0, BOOL bUseNavMesh = TRUE, BOOL bWarp = FALSE, INT iDelay = 0, INT bDefaultTime =DEFAULT_TIME_BEFORE_WARP, STRING sAlt = NULL, STRING sAltDict = NULL, BOOL bDucking = FALSE )
IF NOT IS_PED_INJURED(ped)
IF GET_SCRIPT_TASK_STATUS(ped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
IF NOT IS_STRING_NULL_OR_EMPTY(sAlt)
REQUEST_ANIM_DICT(sAltDict)
IF HAS_ANIM_DICT_LOADED(sAltDict)
SET_PED_ALTERNATE_WALK_ANIM(NULL,sAltDict,sAlt,8,FALSE)
ENDIF
ENDIF
IF bWarp
SET_ENTITY_COORDS(ped,vDesired)
SET_ENTITY_HEADING(ped,fDesired)
ELSE
//CLEAR_PED_TASKS(ped)
OPEN_SEQUENCE_TASK(seq)
IF iDelay != 0
TASK_PAUSE(NULL,iDelay)
ENDIF
IF bDucking
//TASK_TOGGLE_DUCK(NULL,TOGGLE_DUCK_ON)
ENDIF
IF bUseNavMesh
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL,vDesired,fMoveBlend,bDefaultTime,0.4, ENAV_DEFAULT | ENAV_STOP_EXACTLY, fDesired)
//TASK_PED_SLIDE_TO_COORD_HDG_RATE(NULL,vDesired,fDesired,1,1)
ELSE
TASK_GO_STRAIGHT_TO_COORD(NULL,vDesired,fMoveBlend,bDefaultTime,fDesired)
//TASK_PED_SLIDE_TO_COORD_HDG_RATE(NULL,vDesired,fDesired,1,1)
ENDIF
CLOSE_SEQUENCE_TASK(seq)
TASK_PERFORM_SEQUENCE(ped,seq)
CLEAR_SEQUENCE_TASK(seq)
ENDIF
ENDIF
ENDIF
ENDPROC
///
PROC TASK_READY_FOR_ANIM(PED_INDEX ped, VECTOR vDesired, FLOAT fDesired, FLOAT fMoveBlend = 1.0, BOOL bUseNavMesh = TRUE, INT iDelay = 0, INT bDefaultTime =DEFAULT_TIME_BEFORE_WARP, BOOL bDucking = FALSE )
IF NOT IS_PED_INJURED(ped)
IF iDelay != 0
TASK_PAUSE(NULL,iDelay)
ENDIF
IF bDucking
TASK_TOGGLE_DUCK(NULL,TOGGLE_DUCK_ON)
ENDIF
IF bUseNavMesh
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL,vDesired,fMoveBlend,bDefaultTime,0.4, ENAV_DEFAULT | ENAV_STOP_EXACTLY, fDesired)
PRINTSTRING("TASK_READY_FOR_ANIM")//PRINTNL()
ELSE
TASK_GO_STRAIGHT_TO_COORD(NULL,vDesired,fMoveBlend,bDefaultTime,fDesired)
ENDIF
ENDIF
ENDPROC
FUNC BOOL IS_PED_READY_FOR_ANIM(PED_INDEX ped, VECTOR vDesired,FLOAT fDesired,VECTOR vTolerance, FLOAT fTolerance = 360.0 ,BOOL bEnteredLoopedAnim = FALSE)
IF NOT IS_PED_INJURED(ped)
IF bEnteredLoopedAnim = FALSE
IF GET_SCRIPT_TASK_STATUS(ped,SCRIPT_TASK_PERFORM_SEQUENCE)<> PERFORMING_TASK
IF IS_ENTITY_AT_COORD(ped,vDesired,vTolerance)
AND IS_PED_ROUGHLY_FACING_THIS_DIRECTION(ped,fDesired,fTolerance)
PRINTSTRING("This Ped is in position: ")
RETURN TRUE
ENDIF
ENDIF
ELSE
IF GET_SCRIPT_TASK_STATUS(ped,SCRIPT_TASK_PLAY_ANIM)<> PERFORMING_TASK
IF IS_ENTITY_AT_COORD(ped,vDesired,vTolerance)
AND IS_PED_ROUGHLY_FACING_THIS_DIRECTION(ped,fDesired,fTolerance)
PRINTSTRING("This Ped is in position: ")
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
///////////// DEBUG STUFF ***************************************************************************************************
#IF IS_DEBUG_BUILD
VECTOR POINT_AT_COORDS =<<0.0, 0.0, 0.0>>
VECTOR vCAMERA
VECTOR vCAMERA_ROTATION
VECTOR vPOINT_AT_COORDS
VECTOR vPOINT_AT_COORDS_OFFSET
VECTOR vOBJECT
VECTOR vOBJECT_ROTATION
VECTOR vATTACH_OFFSET
CONST_INT MAX_OBJECTS 10
INT iCameraOffsetProc
INT iIndex[6]
FLOAT fCAMERAfov = 45.0
STRUCT OBJECT_STRUCT // contains details for the bombs
OBJECT_INDEX obj
VECTOR Pos
VECTOR Rot
MODEL_NAMES model
ENDSTRUCT
OBJECT_STRUCT object[MAX_OBJECTS]
//cam proc
TEXT_WIDGET_ID widgetID
VEHICLE_INDEX tempVehicle[2]
PED_INDEX tempPED[2]
OBJECT_INDEX tempObj[2]
CAMERA_INDEX CAM
MODEL_NAMES eModel
BOOL bPointAt
BOOL bAttach
BOOL bAttachVeh[2]
BOOL bAttachPed[2]
BOOL bAttachObj[2]
BOOL bActive
BOOL bAtCoord
BOOL bUpdatePos
BOOL bMakeObject
BOOL bSetAsCameraPos
PROC CAMERA_OFFSET_PROC()
SWITCH iCameraOffsetProc
CASE 0
START_WIDGET_GROUP("CAMERA_OFFSET_PROC")
// Widgets for the Main Mission Controlers
ADD_WIDGET_STRING("Main Controlers")
ADD_WIDGET_BOOL("bActive",bActive)
ADD_WIDGET_FLOAT_SLIDER("fCAMERAfov", fCAMERAfov, 1.0, 130.0, 1.0)
ADD_WIDGET_STRING("CAMERA VECTOR")
ADD_WIDGET_FLOAT_SLIDER("vCAMERA.x", vCAMERA.x, -9999.99, 9999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vCAMERA.y", vCAMERA.y, -9999.99, 9999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vCAMERA.z", vCAMERA.z, -9999.99, 9999.99, 0.01)
ADD_WIDGET_STRING("CAMERA ROTATION")
ADD_WIDGET_FLOAT_SLIDER("vCAMERA_ROTATION.x", vCAMERA_ROTATION.x, -999.99, 999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vCAMERA_ROTATION.y", vCAMERA_ROTATION.y, -999.99, 999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vCAMERA_ROTATION.z", vCAMERA_ROTATION.z, -999.99, 999.99, 0.01)
ADD_WIDGET_STRING("Attach to object")
ADD_WIDGET_BOOL("bAttach",bAttach)
ADD_WIDGET_BOOL("Attach To car",bAttachVeh[0])
ADD_WIDGET_INT_SLIDER("mission_veh index", iIndex[0], 0, MAX_MISSION_VEH-1, 1)
ADD_WIDGET_BOOL("Attach To Ped",bAttachPed[0])
ADD_WIDGET_INT_SLIDER("enemy index", iIndex[1], 0, MAX_ENEMY_PED-1, 1)
ADD_WIDGET_BOOL("Attach to Object",bAttachObj[0])
ADD_WIDGET_INT_SLIDER("Object index", iIndex[2], 0, MAX_ENEMY_PED-1, 1)
ADD_WIDGET_STRING("Point at Controlers")
ADD_WIDGET_BOOL("bPointAt",bPointAt)
ADD_WIDGET_BOOL("Point at car",bAttachVeh[1])
ADD_WIDGET_INT_SLIDER("mission_veh index", iIndex[3], 0, MAX_MISSION_VEH-1, 1)
ADD_WIDGET_BOOL("Point at Ped",bAttachPed[1])
ADD_WIDGET_INT_SLIDER("enemy index", iIndex[4], 0, MAX_ENEMY_PED-1, 1)
ADD_WIDGET_BOOL("Point at object",bAttachObj[1])
ADD_WIDGET_INT_SLIDER("Object index", iIndex[5], 0, MAX_ENEMY_PED-1, 1)
ADD_WIDGET_STRING("Point at Controlers")
ADD_WIDGET_BOOL("bAtCoord",bAtCoord)
ADD_WIDGET_FLOAT_SLIDER("vPOINT_AT_COORDS.x", vPOINT_AT_COORDS.x, -9999.99, 9999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vPOINT_AT_COORDS.y", vPOINT_AT_COORDS.y, -9999.99, 9999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vPOINT_AT_COORDS.z", vPOINT_AT_COORDS.z, -9999.99, 9999.99, 0.01)
ADD_WIDGET_STRING("Point at OBJECT offset Controlers")
ADD_WIDGET_FLOAT_SLIDER("vPOINT_AT_COORDS.x", vPOINT_AT_COORDS_OFFSET.x, -999.99, 999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vPOINT_AT_COORDS.y", vPOINT_AT_COORDS_OFFSET.y, -999.99, 999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vPOINT_AT_COORDS.z", vPOINT_AT_COORDS_OFFSET.z, -999.99, 999.99, 0.01)
if POINT_AT_COORDS.x = 0.0
ENDIF
STOP_WIDGET_GROUP()
iCameraOffsetProc++
BREAK
CASE 1
tempVehicle[0] = mission_veh[iIndex[0]].veh
tempPED[0] = enemy[iIndex[1]].ped
tempVehicle[1] = mission_veh[iIndex[3]].veh
tempPED[1] = enemy[iIndex[4]].ped
IF bActive = TRUE
IF NOT DOES_CAM_EXIST(CAM)
CAM = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA",FALSE)
ENDIF
IF NOT IS_CAM_ACTIVE(CAM)
SET_CAM_ACTIVE(CAM, TRUE)
ENDIF
RENDER_SCRIPT_CAMS(TRUE,FALSE)
ELSE
IF DOES_CAM_EXIST(CAM)
SET_CAM_ACTIVE(CAM, TRUE)
DESTROY_CAM(CAM)
RENDER_SCRIPT_CAMS(FALSE,FALSE)
ENDIF
ENDIF
IF DOES_CAM_EXIST(CAM)
IF bAttach = TRUE
IF NOT DOES_CAM_EXIST(CAM)
CAM = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA",FALSE)
ENDIF
IF NOT IS_CAM_ACTIVE(CAM)
SET_CAM_ACTIVE(CAM, TRUE)
ENDIF
IF IS_VEHICLE_DRIVEABLE(tempVehicle[0])AND bAttachVeh[0]
ATTACH_CAM_TO_ENTITY(CAM, tempVehicle[0],vCAMERA, TRUE)
ELIF NOT IS_PED_INJURED(tempPED[0])AND bAttachPed[0]
ATTACH_CAM_TO_ENTITY(CAM, tempPED[0],vCAMERA, TRUE)
ELIF DOES_ENTITY_EXIST(tempObj[0])AND bAttachObj[0]
ATTACH_CAM_TO_ENTITY(CAM, tempObj[0],vCAMERA, TRUE)
ENDIF
SET_CAM_FOV(CAM, fCAMERAfov)
SET_CAM_ROT(CAM,vCAMERA_ROTATION)
ENDIF
IF bPointAt
IF NOT bAtCoord
IF NOT DOES_CAM_EXIST(CAM)
CAM = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA",FALSE)
ENDIF
IF NOT IS_CAM_ACTIVE(CAM)
SET_CAM_ACTIVE(CAM, TRUE)
ENDIF
IF IS_VEHICLE_DRIVEABLE(tempVehicle[1])AND bAttachVeh[1]
POINT_CAM_AT_ENTITY(CAM, tempVehicle[1],vPOINT_AT_COORDS_OFFSET, TRUE)
ELIF NOT IS_PED_INJURED(tempPED[1]) AND bAttachPed[1]
POINT_CAM_AT_ENTITY(CAM, tempPED[1],vPOINT_AT_COORDS_OFFSET, TRUE)
ELIF DOES_ENTITY_EXIST(tempObj[1]) AND bAttachObj[1]
POINT_CAM_AT_ENTITY(CAM, tempObj[1],vPOINT_AT_COORDS_OFFSET, TRUE)
ENDIF
SET_CAM_FOV(CAM, fCAMERAfov)
SET_CAM_ROT(CAM,vCAMERA_ROTATION)
ELSE
POINT_CAM_AT_COORD(CAM, vPOINT_AT_COORDS )
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC MAKE_AND_POS_OBJECT_PROC()
SWITCH iCameraOffsetProc
CASE 0
START_WIDGET_GROUP("MAKE_AND_POS_OBJECT_PROC")
// Widgets for the Main Mission Controlers
ADD_WIDGET_STRING("Main Controlers")
ADD_WIDGET_BOOL("bActive",bActive)
ADD_WIDGET_STRING("make object")
widgetID = ADD_TEXT_WIDGET("Modle Name")
ADD_WIDGET_BOOL("bMakeObject",bMakeObject)
ADD_WIDGET_INT_SLIDER("Object index", iIndex[0], 0, MAX_OBJECTS-1, 1)
ADD_WIDGET_BOOL("bUpdatePos",bUpdatePos)
ADD_WIDGET_BOOL("bSetAsCameraPos",bSetAsCameraPos)
ADD_WIDGET_STRING("vOBJECT VECTOR")
ADD_WIDGET_FLOAT_SLIDER("vOBJECT.x", vOBJECT.x, -9999.99, 9999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vOBJECT.y", vOBJECT.y, -9999.99, 9999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vOBJECT.z", vOBJECT.z, -9999.99, 9999.99, 0.01)
ADD_WIDGET_STRING("vOBJECT ROTATION")
ADD_WIDGET_FLOAT_SLIDER("vOBJECT_ROTATION.x", vOBJECT_ROTATION.x, -180.00, 180.00, 0.1)
ADD_WIDGET_FLOAT_SLIDER("vOBJECT_ROTATION.y", vOBJECT_ROTATION.y, -180.00, 180.00, 0.1)
ADD_WIDGET_FLOAT_SLIDER("vOBJECT_ROTATION.z", vOBJECT_ROTATION.z, -180.00, 180.00, 0.1)
ADD_WIDGET_STRING("Attach to object")
ADD_WIDGET_BOOL("bAttach",bAttach)
ADD_WIDGET_BOOL("Attach To car",bAttachVeh[0])
ADD_WIDGET_INT_SLIDER("mission_veh index", iIndex[1], 0, MAX_MISSION_VEH-1, 1)
ADD_WIDGET_BOOL("Attach To Ped",bAttachPed[0])
ADD_WIDGET_INT_SLIDER("enemy index", iIndex[2], 0, MAX_ENEMY_PED-1, 1)
ADD_WIDGET_BOOL("Attach to Object",bAttachObj[0])
ADD_WIDGET_INT_SLIDER("Object index", iIndex[3], 0, MAX_OBJECTS-1, 1)
ADD_WIDGET_STRING("vATTACH OFFSET")
ADD_WIDGET_FLOAT_SLIDER("vATTACH_OFFSET.x", vATTACH_OFFSET.x, -999.99, 999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vATTACH_OFFSET.y", vATTACH_OFFSET.y, -999.99, 999.99, 0.01)
ADD_WIDGET_FLOAT_SLIDER("vATTACH_OFFSET.z", vATTACH_OFFSET.z, -999.99, 999.99, 0.01)
STOP_WIDGET_GROUP()
iCameraOffsetProc++
BREAK
CASE 1
tempVehicle[0] = mission_veh[iIndex[1]].veh
tempPED[0] = enemy[iIndex[2]].ped
tempObj[0] = object[iIndex[3]].obj
IF bActive = TRUE
eModel = INT_TO_ENUM(MODEL_NAMES, GET_HASH_KEY(GET_CONTENTS_OF_TEXT_WIDGET(widgetID)))
IF IS_MODEL_IN_CDIMAGE(eModel)
IF NOT HAS_MODEL_LOADED(eModel)
REQUEST_MODEL(eModel)
WHILE NOT HAS_MODEL_LOADED(eModel)
WAIT(0)
ENDWHILE
ENDIF
ENDIF
ELSE
IF HAS_MODEL_LOADED(eModel)
SET_MODEL_AS_NO_LONGER_NEEDED(eModel)
ENDIF
ENDIF
IF bSetAsCameraPos
IF DOES_CAM_EXIST(GET_DEBUG_CAM())
vOBJECT = GET_CAM_COORD( GET_DEBUG_CAM())
bSetAsCameraPos= FALSE
ENDIF
ENDIF
IF bMakeObject
IF NOT DOES_ENTITY_EXIST(object[iIndex[0]].obj)
object[iIndex[0]].obj = CREATE_OBJECT(eModel,vOBJECT)
bMakeObject = FALSE
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(object[iIndex[0]].obj)
bUpdatePos = TRUE
SET_ENTITY_COORDS_NO_OFFSET(object[iIndex[0]].obj , vOBJECT )
SET_ENTITY_ROTATION(object[iIndex[0]].obj , vOBJECT_ROTATION )
ENDIF
IF DOES_ENTITY_EXIST(object[iIndex[0]].obj)
IF bAttach
IF bAttachVeh[0]
IF IS_VEHICLE_DRIVEABLE(tempVehicle[0])
IF NOT IS_ENTITY_ATTACHED(object[iIndex[0]].obj)
ATTACH_ENTITY_TO_ENTITY(object[iIndex[0]].obj,tempVehicle[0], 0,vATTACH_OFFSET, vOBJECT_ROTATION )
ELSE
DETACH_ENTITY(object[iIndex[0]].obj, FALSE)
ATTACH_ENTITY_TO_ENTITY(object[iIndex[0]].obj,tempVehicle[0], 0,vATTACH_OFFSET, vOBJECT_ROTATION )
ENDIF
ENDIF
ELIF bAttachPed[0]
IF NOT IS_PED_INJURED(tempPED[0])
IF NOT IS_ENTITY_ATTACHED(object[iIndex[0]].obj)
ATTACH_ENTITY_TO_ENTITY(object[iIndex[0]].obj,tempPED[0], BONETAG_ROOT,vATTACH_OFFSET, vOBJECT_ROTATION )
ELSE
DETACH_ENTITY(object[iIndex[0]].obj, FALSE)
ATTACH_ENTITY_TO_ENTITY(object[iIndex[0]].obj,tempPED[0], BONETAG_ROOT,vATTACH_OFFSET, vOBJECT_ROTATION )
ENDIF
ENDIF
ELIF bAttachObj[0]
IF DOES_ENTITY_EXIST(tempObj[0])
IF NOT IS_ENTITY_ATTACHED(object[iIndex[0]].obj)
ATTACH_ENTITY_TO_ENTITY(object[iIndex[0]].obj,tempObj[0], 0,vATTACH_OFFSET, vOBJECT_ROTATION )
ELSE
DETACH_ENTITY(object[iIndex[0]].obj, FALSE)
ATTACH_ENTITY_TO_ENTITY(object[iIndex[0]].obj,tempObj[0], 0,vATTACH_OFFSET, vOBJECT_ROTATION )
ENDIF
ENDIF
ENDIF
ELSE
IF IS_ENTITY_ATTACHED(object[iIndex[0]].obj)
DETACH_ENTITY(object[iIndex[0]].obj, FALSE)
ENDIF
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
#ENDIF
// obtain the offset to attach the particular rope to the chopper
FUNC VECTOR GET_ROPE_OFFSET_FROM_CHOPPER(INT iRope)
SWITCH iRope
CASE 0
RETURN <<-CHOPPER_ROPE_OFFSET_X, CHOPPER_ROPE_OFFSET_Y, CHOPPER_ROPE_OFFSET_Z>>
BREAK
CASE 1
RETURN <<CHOPPER_ROPE_OFFSET_X, CHOPPER_ROPE_OFFSET_Y, CHOPPER_ROPE_OFFSET_Z>>
BREAK
CASE 2
RETURN <<-CHOPPER_ROPE_OFFSET_X, -CHOPPER_ROPE_OFFSET_Y, CHOPPER_ROPE_OFFSET_Z>>
BREAK
CASE 3
RETURN <<CHOPPER_ROPE_OFFSET_X, -CHOPPER_ROPE_OFFSET_Y, CHOPPER_ROPE_OFFSET_Z>>
BREAK
ENDSWITCH
SCRIPT_ASSERT("Passed in a bad rope to GET_ROPE_OFFSET_FROM_CHOPPER. Use 0-3.")
RETURN <<0,0,0>>
ENDFUNC
// obtain the offset to attach the rope to the container
FUNC VECTOR GET_ROPE_OFFSET_FROM_CONTAINER(INT iRope)
SWITCH iRope
CASE 0
RETURN <<-CONTAINER_ROPE_OFFSET_X, CONTAINER_ROPE_OFFSET_YALT, CONTAINER_ROPE_OFFSET_Z>>
BREAK
CASE 1
RETURN <<CONTAINER_ROPE_OFFSET_X, CONTAINER_ROPE_OFFSET_YALT, CONTAINER_ROPE_OFFSET_Z>>
BREAK
CASE 2
RETURN <<-CONTAINER_ROPE_OFFSET_X, -CONTAINER_ROPE_OFFSET_Y, CONTAINER_ROPE_OFFSET_Z>>
BREAK
CASE 3
RETURN <<CONTAINER_ROPE_OFFSET_X, -CONTAINER_ROPE_OFFSET_Y, CONTAINER_ROPE_OFFSET_Z>>
BREAK
ENDSWITCH
SCRIPT_ASSERT("Passed in a bad rope to GET_ROPE_OFFSET_FROM_CONTAINER. Use 0-3.")
RETURN <<0,0,0>>
ENDFUNC
// delete ropes
PROC DELETE_BIOTECH_ROPES(ROPE_INDEX &ropes[], BOOL &bRopesCreated, BOOL &bRopesAttached)
IF bRopesCreated
INT i
REPEAT 4 i
DELETE_ROPE(ropes[i])
ENDREPEAT
ENDIF
bRopesCreated = FALSE
bRopesAttached = FALSE
ENDPROC
// create ropes
PROC CREATE_DOCKS_ROPES(VEHICLE_INDEX &chopperVehicle, ROPE_INDEX &ropes[], BOOL &bRopesCreated, BOOL bTaut = FALSE)
IF NOT bRopesCreated
INT i
VECTOR vCreatePos
IF IS_VEHICLE_DRIVEABLE(chopperVehicle)
REPEAT 4 i
vCreatePos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(chopperVehicle, GET_ROPE_OFFSET_FROM_CHOPPER(i))
PHYSICS_ROPE_TYPE ropeType
IF bTaut
ropeType = PHYSICS_ROPE_THIN
ELSE
ropeType = PHYSICS_ROPE_DEFAULT
ENDIF
ropes[i] = ADD_ROPE(vCreatePos, <<0,0,0>>, THIS_ROPE_LENGTH, ropeType)
ENDREPEAT
bRopesCreated = TRUE
ENDIF
ENDIF
ENDPROC
// get a heading normalised between 0 and 360
FUNC FLOAT NORMALISE_HEADING(FLOAT fHeading)
FLOAT fReturn = fHeading
IF fReturn < 0
fReturn += 360
ELIF fReturn > 360
fReturn -= 360
ENDIF
RETURN fReturn
ENDFUNC
// attach chopper to container with rope
PROC ATTACH_CHOPPER_TO_ENTITY_WITH_ROPE(VEHICLE_INDEX &chopperVehicle, VEHICLE_INDEX &containerObject, ROPE_INDEX &ropes[], BOOL &bRopesCreated, BOOL &bRopesAttached, BOOL bPin = FALSE, BOOL bTaut = FALSE)
IF NOT bRopesCreated
CREATE_DOCKS_ROPES(chopperVehicle, ropes, bRopesCreated, bTaut)
ENDIF
IF bRopesCreated
IF NOT bRopesAttached
INT i
VECTOR vChopperAttachPos
VECTOR vContainerAttachPos
IF IS_VEHICLE_DRIVEABLE(chopperVehicle)
AND IS_VEHICLE_DRIVEABLE(containerObject)
IF DOES_ENTITY_HAVE_PHYSICS(containerObject)
OR bPin
DETACH_ENTITY(containerObject)
REPEAT 4 i
vChopperAttachPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(chopperVehicle, GET_ROPE_OFFSET_FROM_CHOPPER(i))
vContainerAttachPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(containerObject, GET_ROPE_OFFSET_FROM_CONTAINER(i))
IF bPin
//DETACH_ROPE_FROM_ENTITY(ropes[i], containerObject)
PIN_ROPE_VERTEX(ropes[i], 0, vChopperAttachPos)
PIN_ROPE_VERTEX(ropes[i], GET_ROPE_VERTEX_COUNT(ropes[i])-1, vContainerAttachPos)
ELSE
UNPIN_ROPE_VERTEX(ropes[i], 0)
UNPIN_ROPE_VERTEX(ropes[i], GET_ROPE_VERTEX_COUNT(ropes[i])-1)
ATTACH_ENTITIES_TO_ROPE(ropes[i], containerObject, chopperVehicle, vContainerAttachPos, vChopperAttachPos, THIS_ROPE_LENGTH, 0, 0)
ENDIF
ENDREPEAT
IF NOT bPin
//SET_OBJECT_PHYSICS_PARAMS(containerObject, 1600, 1.0, <<0.02, 0.02, 0.003>>, <<0.02, 0.4, 0.4>>)
//APPLY_FORCE_TO_ENTITY(containerObject, APPLY_TYPE_EXTERNAL_IMPULSE, <<0,0,0.1>>, <<0,0,0>>, 0, FALSE, TRUE, TRUE)
SET_ENTITY_DYNAMIC(containerObject, true)
ENDIF
bRopesAttached = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
// maintain rope pin attachment while container on ground
PROC MAINTAIN_ROPE_PIN_ATTACHMENT(VEHICLE_INDEX &chopperVehicle, ROPE_INDEX &ropes[])
INT i
VECTOR vChopperAttachPos
IF IS_VEHICLE_DRIVEABLE(chopperVehicle)
REPEAT 4 i
vChopperAttachPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(chopperVehicle, GET_ROPE_OFFSET_FROM_CHOPPER(i))
PIN_ROPE_VERTEX(ropes[i], 0, vChopperAttachPos)
ENDREPEAT
ENDIF
ENDPROC
// maintain rope pin attachment to container while attached to a vehicle
PROC MAINTAIN_ROPE_PIN_ATTACHMENT_TO_VEHICLE(VEHICLE_INDEX &pinVehicle, ROPE_INDEX &ropes[], VECTOR vContainerOffsetFromVehicle)
INT i
VECTOR vContainerAttachPos
IF IS_VEHICLE_DRIVEABLE(pinVehicle)
REPEAT 4 i
vContainerAttachPos = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(pinVehicle, GET_ROPE_OFFSET_FROM_CONTAINER(i) + vContainerOffsetFromVehicle)
PIN_ROPE_VERTEX(ropes[i], GET_ROPE_VERTEX_COUNT(ropes[i])-1, vContainerAttachPos)
ENDREPEAT
ENDIF
ENDPROC
// unpin rope ends
PROC UNPIN_ROPE_ENDS(ROPE_INDEX &ropes[], BOOL bUnpinFirst, BOOL bUnpinLast)
INT i
REPEAT 4 i
IF bUnpinFirst
UNPIN_ROPE_VERTEX(ropes[i], 0)
ENDIF
IF bUnpinLast
UNPIN_ROPE_VERTEX(ropes[i], GET_ROPE_VERTEX_COUNT(ropes[i])-1)
ENDIF
ENDREPEAT
ENDPROC