//************************************************************************************ // +---------------------------------------------------------------------------------+ // +--------------------------¦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 = <> // 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(<>) TASK_SET_SPHERE_DEFENSIVE_AREA(tempdriverped,<>,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 <> BREAK CASE 2 RETURN <<-CHOPPER_ROPE_OFFSET_X, -CHOPPER_ROPE_OFFSET_Y, CHOPPER_ROPE_OFFSET_Z>> BREAK CASE 3 RETURN <> 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 <> BREAK CASE 2 RETURN <<-CONTAINER_ROPE_OFFSET_X, -CONTAINER_ROPE_OFFSET_Y, CONTAINER_ROPE_OFFSET_Z>> BREAK CASE 3 RETURN <> 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