855 lines
25 KiB
XML
Executable File
855 lines
25 KiB
XML
Executable File
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
USING "commands_camera.sch"
|
|
USING "commands_pad.sch"
|
|
USING "commands_script.sch"
|
|
USING "commands_vehicle.sch"
|
|
USING "commands_path.sch"
|
|
USING "flow_public_core_override.sch"
|
|
USING "commands_ped.sch"
|
|
USING "commands_task.sch"
|
|
USING "selector_public.sch"
|
|
using "dialogue_public.sch"
|
|
USING "commands_audio.sch"
|
|
USING "drunk_public.sch"
|
|
USING "beam_effect.sch"
|
|
USING "CompletionPercentage_public.sch"
|
|
USING "commands_graphics.sch"
|
|
USING "script_blips.sch"
|
|
USING "script_ped.sch"
|
|
USING "usefulcommands.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
WIDGET_GROUP_ID thisWidget
|
|
#ENDIF
|
|
|
|
struct structInvPointd
|
|
bool bActive
|
|
int searches
|
|
int searchTime
|
|
vector vCoord
|
|
ENDSTRUCT
|
|
|
|
int iUpdateNode
|
|
|
|
// ================================ debug ===============================
|
|
|
|
|
|
// ================================ vectors ======================
|
|
vector player_alert_location,player_last_alert_location
|
|
vector nearectSafePoint
|
|
|
|
// ============================= player seen state
|
|
ENUM ENUM_PLAYER_SEEN_STATE
|
|
NOT_SEEN,
|
|
ENGAGED,
|
|
CHANGE_TO_LOST,
|
|
LOST
|
|
ENDENUM
|
|
|
|
ENUM_PLAYER_SEEN_STATE player_seen_state
|
|
|
|
// ============================= dialogue =========================
|
|
structPedsForConversation SWADIO
|
|
string audioBank
|
|
TEXT_LABEL_23 nextDialogue
|
|
int nextDialoguePed = -1
|
|
TEXT_LABEL_23 dia_spotted
|
|
TEXT_LABEL_23 dia_fleeing
|
|
TEXT_LABEL_23 dia_lost
|
|
TEXT_LABEL_23 dia_hunting
|
|
TEXT_LABEL_23 dia_panic
|
|
|
|
// ============================== comments =======================
|
|
enum enumComments
|
|
COMMENT_NONE,
|
|
COMMENT_SPOTTED,
|
|
COMMENT_JUSTGONE,
|
|
COMMENT_NOT_HERE,
|
|
COMMENT_HUNTING,
|
|
COMMENT_SPOTTED_BY_PASSIVE_PED
|
|
ENDENUM
|
|
|
|
enumComments commentStoredForDialogue
|
|
int pedStoredForDialogue
|
|
|
|
|
|
// =============================== rel groups ===================
|
|
REL_GROUP_HASH AIGroup
|
|
|
|
// ================================= BIKERS =========================
|
|
|
|
|
|
enum enumSweepActions
|
|
NO_ACTION,
|
|
EXPLORING,
|
|
JUST_RESPOND_TO_PLAYER_APPROACH,
|
|
GIVE_PASSIVE_REACTION_TO_PLAYER,
|
|
PERFORMING_PASSIVE_RESPONSE_TO_PLAYER,
|
|
ENGAGING,
|
|
GETTING_TO_ALERT_LOC,
|
|
RESPOND_TO_ALERT,
|
|
LOST_TARGET
|
|
ENDENUM
|
|
|
|
enum enumType
|
|
AGGRESIVE_SEARCHER,
|
|
PASSIVE_ONLY_ALERTS
|
|
endenum
|
|
|
|
struct structSearcherPed
|
|
PED_INDEX iD
|
|
int targetNode=-1
|
|
enumSweepActions action = NO_ACTION
|
|
bool seesPlayer
|
|
enumType type
|
|
ENDSTRUCT
|
|
|
|
structSearcherPed searcherPed[max_sweep_peds]
|
|
int addedPedCount
|
|
|
|
struct structInvPoint
|
|
bool bActive
|
|
vector vCoord
|
|
int searches, searchTime
|
|
ENDSTRUCT
|
|
|
|
structInvPoint InvPoint[max_invPoints]
|
|
|
|
// bools
|
|
#IF IS_DEBUG_BUILD
|
|
bool bSave,bDraw
|
|
int selectedPoint = -1
|
|
#ENDIF
|
|
|
|
bool bInit
|
|
bool bSweepBegun
|
|
bool bPauseDialogue
|
|
bool bAudioSetup
|
|
|
|
//ints
|
|
int nextSweepPed
|
|
int added_points //count how many points added
|
|
int return_ped_control_to_mission_Script
|
|
int last_ped_to_be_taken_by_mission_script
|
|
|
|
#if IS_DEBUG_BUILD
|
|
proc debugSweep(WIDGET_GROUP_ID parentWidget)
|
|
int i
|
|
|
|
|
|
if not DOES_WIDGET_GROUP_EXIST(thisWidget)
|
|
if DOES_WIDGET_GROUP_EXIST(parentWidget)
|
|
SET_CURRENT_WIDGET_GROUP(parentWidget)
|
|
thisWidget = START_WIDGET_GROUP("Temptest")
|
|
ADD_WIDGET_BOOL("Save",bSave)
|
|
ADD_WIDGET_BOOL("Draw Stuff",bDraw)
|
|
START_WIDGET_GROUP("Seach Nodes")
|
|
for i = 0 to max_invPoints-1
|
|
ADD_WIDGET_INT_READ_ONLY("time",InvPoint[i].searchTime)
|
|
ENDFOR
|
|
STOP_WIDGET_GROUP()
|
|
STOP_WIDGET_GROUP()
|
|
CLEAR_CURRENT_WIDGET_GROUP(parentWidget)
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
if bDraw = true
|
|
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(true)
|
|
if not IS_PED_INJURED(PLAYER_PED_ID())
|
|
for i = 0 to max_sweep_peds-1
|
|
IF NOT IS_PED_INJURED(searcherPed[i].iD)
|
|
SET_TEXT_SCALE(0.3,0.3)
|
|
switch searcherPed[i].action
|
|
case NO_ACTION
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1+(to_float(i) * 0.05),"STRING","NO_ACTION")
|
|
break
|
|
case EXPLORING
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1+(to_float(i) * 0.05),"STRING","EXPLORING")
|
|
break
|
|
case ENGAGING
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1+(to_float(i) * 0.05),"STRING","ENGAGING")
|
|
break
|
|
case GETTING_TO_ALERT_LOC
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1+(to_float(i) * 0.05),"STRING","GETTING_TO_ALERT_LOC")
|
|
break
|
|
case RESPOND_TO_ALERT
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1+(to_float(i) * 0.05),"STRING","RESPOND_TO_ALERT")
|
|
break
|
|
case LOST_TARGET
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1+(to_float(i) * 0.05),"STRING","LOST_TARGET")
|
|
BREAk
|
|
case JUST_RESPOND_TO_PLAYER_APPROACH
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1+(to_float(i) * 0.05),"STRING","JUST_RESPOND_TO_PLAYER_APPROACH")
|
|
BREAk
|
|
ENDSWITCH
|
|
|
|
if not IS_PED_INJURED(PLAYER_PED_ID())
|
|
if searcherPed[i].seesPlayer = true
|
|
SET_TEXT_SCALE(0.3,0.3)
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.9,0.1+(to_float(i) * 0.05),"STRING","SEE")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDFOR
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
#ENDIF
|
|
|
|
PROC INIT_SEARCH_VARS()
|
|
IF not bInit
|
|
bInit=true
|
|
addedPedCount = 0
|
|
|
|
ADD_RELATIONSHIP_GROUP("bikers",AIGroup)
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE,AIGroup,RELGROUPHASH_PLAYER)
|
|
commentStoredForDialogue = COMMENT_NONE
|
|
|
|
/*
|
|
for i = 0 to max_sweep_peds-1
|
|
if i = -1
|
|
searcherPed[i].iD = CREATE_PED(PEDTYPE_MISSION,G_M_Y_LOST_01,<< 66.9024, 3611.3176, 38.9110 >>+(<<1.5*to_float(i),0,0>>),43)
|
|
GIVE_WEAPON_TO_PED(searcherPed[i].iD,WEAPONTYPE_PISTOL50,87,true)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(searcherPed[i].iD,AIGroup)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(searcherPed[i].iD,true)
|
|
searcherPed[i].blip = CREATE_BLIP_FOR_ENTITY(searcherPed[i].iD,true)
|
|
ENDIF
|
|
ENDFOR
|
|
*/
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
proc SET_INV_POINT_DATA(vector vCoord)
|
|
if added_points < max_invPoints
|
|
InvPoint[added_points].bActive = TRUE
|
|
InvPoint[added_points].vCoord = vCoord
|
|
added_points++
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
proc Edit_investigate_points()
|
|
if bDraw
|
|
VECTOR vMouse
|
|
//check if this mouse positino is near an existing node
|
|
|
|
IF IS_MOUSE_BUTTON_JUST_PRESSED(MB_LEFT_BTN)
|
|
|
|
vMouse = GET_SCRIPT_MOUSE_POINTER_IN_WORLD_COORDS()
|
|
int i
|
|
selectedPoint=-1
|
|
for i = 0 to max_invPoints-1
|
|
IF InvPoint[i].bActive
|
|
if GET_DISTANCE_BETWEEN_COORDS(InvPoint[i].vCoord,vMouse) < 2.0
|
|
selectedPoint = i
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
if selectedPoint=-1
|
|
for i = 0 to max_invPoints-1
|
|
IF NOT InvPoint[i].bActive
|
|
InvPoint[i].bActive = true
|
|
selectedPoint = i
|
|
i = max_invPoints
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_MOUSE_BUTTON_PRESSED(MB_LEFT_BTN) or IS_MOUSE_BUTTON_JUST_PRESSED(MB_LEFT_BTN)
|
|
if selectedPoint != -1
|
|
vMouse = GET_SCRIPT_MOUSE_POINTER_IN_WORLD_COORDS()
|
|
InvPoint[selectedPoint].vCoord = vMouse
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
proc draw_investigate_points()
|
|
if bdraw = true
|
|
int i
|
|
int r,g,b
|
|
for i = 0 to max_invPoints-1
|
|
IF InvPoint[i].bActive
|
|
|
|
if InvPoint[i].searches = 0
|
|
r=0 g=0 b=255
|
|
ELIF InvPoint[i].searches = 1
|
|
r=255 g=255 b=0
|
|
ELSE
|
|
r=255 g=0 b=0
|
|
ENDIF
|
|
if i = selectedPoint
|
|
DRAW_DEBUG_BOX(InvPoint[i].vCoord - <<0.5,0.5,0.5>>,InvPoint[i].vCoord + <<0.5,0.5,0.5>>,255,0,0)
|
|
ELSE
|
|
DRAW_DEBUG_BOX(InvPoint[i].vCoord - <<0.5,0.5,0.5>>,InvPoint[i].vCoord + <<0.5,0.5,0.5>>,r,g,b)
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
proc save_investigate_points()
|
|
if bSave
|
|
int i
|
|
println("")
|
|
for i = 0 to max_invPoints-1
|
|
IF InvPoint[i].bActive
|
|
println("SET_INV_POINT_DATA(",InvPoint[i].vCoord,")")
|
|
ENDIF
|
|
ENDFOR
|
|
bSave = FALSE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
proc control_investigate_points()
|
|
Edit_investigate_points()
|
|
draw_investigate_points()
|
|
save_investigate_points()
|
|
ENDPROC
|
|
|
|
#ENDIF
|
|
|
|
proc goToNextNode(int pedID)
|
|
if not IS_PED_INJURED(searcherPed[pedID].iD)
|
|
float nodeWeight, heading, dist
|
|
float distanceFactor, clusterFactor, busyFactor
|
|
int i,angleSegment
|
|
int iClusterAtAngle[8] //45 degree search segments - how many peds are in each search seg
|
|
//find cluster of searches in various directions
|
|
for i = 0 to max_sweep_peds-1
|
|
if pedID != i
|
|
if not IS_PED_INJURED(searcherPed[i].iD)
|
|
heading = GET_HEADING_FROM_COORDS(GET_ENTITY_COORDS(searcherPed[pedID].iD),GET_ENTITY_COORDS(searcherPed[i].iD),true)
|
|
angleSegment = floor(heading/45.0)
|
|
iClusterAtAngle[angleSegment]++
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
float bestNodeWeight = 0.0
|
|
int chosenNode = -1
|
|
for i = 0 to max_invPoints-1
|
|
if InvPoint[i].searches < 2
|
|
heading = GET_HEADING_FROM_COORDS(GET_ENTITY_COORDS(searcherPed[pedID].iD),InvPoint[i].vCoord,true)
|
|
dist = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(searcherPed[pedID].iD),InvPoint[i].vCoord,FALSE)
|
|
angleSegment = floor(heading/45.0)
|
|
clusterFactor = (1.0 - (0.2 * to_float(iClusterAtAngle[angleSegment])))
|
|
distanceFactor = (1.0 - (dist/40.0))
|
|
if distanceFactor < 0.0 distanceFactor = 0.0 ENDIF
|
|
if InvPoint[i].searches = 0
|
|
busyFactor = 1.0
|
|
ELIF InvPoint[i].searches = 1
|
|
busyFactor = 0.2
|
|
ELSE
|
|
busyFactor = 0.0
|
|
ENDIF
|
|
|
|
nodeWeight = 1.0 * clusterFactor * distanceFactor * busyFactor
|
|
if nodeWeight > bestNodeWeight
|
|
chosenNode = i
|
|
bestNodeWeight = nodeWeight
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
|
|
IF chosenNode = -1
|
|
chosennode = GET_RANDOM_INT_IN_RANGE(0,max_invPoints)
|
|
ENDIF
|
|
if chosenNode != -1
|
|
//println("CHOSE NODE ",chosenNode," with ",InvPoint[chosenNode].searches," searches")
|
|
IF NOT IS_PED_INJURED(searcherPed[pedID].iD)
|
|
searcherPed[pedID].targetNode = chosenNode
|
|
InvPoint[chosenNode].searches++
|
|
|
|
InvPoint[chosenNode].searchTime = GET_GAME_TIMER() + 50000
|
|
bSweepBegun = true
|
|
|
|
//choose method to get to next coord
|
|
SEQUENCE_INDEX aSeq
|
|
OPEN_SEQUENCE_TASK(aSeq)
|
|
if GET_RANDOM_INT_IN_RANGE(0,5) < 3
|
|
SET_PED_STEALTH_MOVEMENT(searcherPed[pedID].iD,FALSE)
|
|
ELSE
|
|
SET_PED_STEALTH_MOVEMENT(searcherPed[pedID].iD,TRUE)
|
|
ENDIF
|
|
|
|
switch GET_RANDOM_INT_IN_RANGE(0,2)
|
|
case 0
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(null,InvPoint[chosenNode].vCoord,InvPoint[chosenNode].vCoord+<<0,0,1.0>>,PEDMOVE_RUN,FALSE,1.5,3.0)
|
|
BREAK
|
|
case 1
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(null,InvPoint[chosenNode].vCoord,InvPoint[chosenNode].vCoord+<<0,0,1.0>>,PEDMOVE_WALK,FALSE,2.5,3.0)
|
|
BREAK
|
|
case 2
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(null,InvPoint[chosenNode].vCoord,PEDMOVE_RUN)
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
CLOSE_SEQUENCE_TASK(aSeq)
|
|
TASK_PERFORM_SEQUENCE(searcherPed[pedID].iD,aSeq)
|
|
CLEAR_SEQUENCE_TASK(aseq)
|
|
//println(pedID,": Go to Coord B:")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
proc checkPedReachedTarget(int pedID)
|
|
if GET_SCRIPT_TASK_STATUS(searcherPed[pedID].iD,script_task_any) != PERFORMING_TASK and searcherPed[pedID].targetNode >= -1
|
|
searcherPed[pedID].targetNode = -1
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
func enumComments SWEEP_DIALOGUE_ALERT(ped_index &pedSpeaking)
|
|
enumComments returnComment = commentStoredForDialogue
|
|
commentStoredForDialogue = COMMENT_NONE
|
|
|
|
IF pedStoredForDialogue >= 0
|
|
pedSpeaking = searcherPed[pedStoredForDialogue].iD
|
|
endif
|
|
|
|
RETURN returnComment
|
|
ENDFUNC
|
|
|
|
func bool IS_PED_BEING_RETURNED_TO_MISSION_SCRIPT(ped_index &returnPed)
|
|
IF return_ped_control_to_mission_Script != -1
|
|
last_ped_to_be_taken_by_mission_script = return_ped_control_to_mission_Script
|
|
return_ped_control_to_mission_Script = -1
|
|
returnPed = searcherPed[return_ped_control_to_mission_Script].iD
|
|
return TRUE
|
|
ELSE
|
|
last_ped_to_be_taken_by_mission_script = -1
|
|
ENDIF
|
|
return FALSE
|
|
endfunc
|
|
|
|
proc SET_NEXT_DIALOGUE(string convLabel,int bikerCommenting,bool interruptNow = FALSE)
|
|
//println("set next dialogue")
|
|
if bAudioSetup
|
|
if interruptNow
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE()
|
|
ENDIF
|
|
nextDialogue = convLabel
|
|
|
|
if bikerCommenting = -1 bikerCommenting = -2 ENDIF
|
|
if nextDialoguePed != -1
|
|
REMOVE_PED_FOR_DIALOGUE(SWADIO,1)
|
|
ENDIF
|
|
nextDialoguePed = bikerCommenting
|
|
//if nextDialoguePed = -2
|
|
//ELSE
|
|
ADD_PED_FOR_DIALOGUE(SWADIO, 1, null,"BIKER1")// searcherPed[nextDialoguePed].iD, "BIKER1")
|
|
ENDIF
|
|
//ENDIF
|
|
ENDPROC
|
|
|
|
|
|
proc CONTROL_DIALOGUE()
|
|
if bAudioSetup
|
|
if not IS_STRING_NULL_OR_EMPTY(nextDialogue)
|
|
//println("create a conv")
|
|
IF bPauseDialogue = FALSE
|
|
if CREATE_CONVERSATION(SWADIO,audioBank,nextDialogue,CONV_PRIORITY_VERY_HIGH)
|
|
nextDialogue = ""
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
proc makeBikerComment(enumComments comment, int bikerCommenting)
|
|
switch comment
|
|
case COMMENT_SPOTTED
|
|
commentStoredForDialogue = COMMENT_SPOTTED
|
|
pedStoredForDialogue = bikerCommenting
|
|
SET_NEXT_DIALOGUE(dia_spotted,bikerCommenting,true)
|
|
BREAK
|
|
CASE COMMENT_NOT_HERE
|
|
commentStoredForDialogue = COMMENT_NOT_HERE
|
|
pedStoredForDialogue = bikerCommenting
|
|
SET_NEXT_DIALOGUE(dia_lost,bikerCommenting,true)
|
|
break
|
|
CASE COMMENT_JUSTGONE
|
|
commentStoredForDialogue = COMMENT_JUSTGONE
|
|
pedStoredForDialogue = bikerCommenting
|
|
SET_NEXT_DIALOGUE(dia_fleeing,bikerCommenting,true)
|
|
break
|
|
CASE COMMENT_HUNTING
|
|
commentStoredForDialogue = COMMENT_HUNTING
|
|
pedStoredForDialogue = bikerCommenting
|
|
SET_NEXT_DIALOGUE(dia_hunting,bikerCommenting,true)
|
|
break
|
|
CASE COMMENT_SPOTTED_BY_PASSIVE_PED
|
|
commentStoredForDialogue = COMMENT_SPOTTED_BY_PASSIVE_PED
|
|
pedStoredForDialogue = bikerCommenting
|
|
SET_NEXT_DIALOGUE(dia_panic,bikerCommenting,true)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
proc engage_player_now(int bikerCommenting)
|
|
int i
|
|
IF searcherPed[i].type = AGGRESIVE_SEARCHER
|
|
makeBikerComment(COMMENT_SPOTTED,bikerCommenting)
|
|
ELSE
|
|
makeBikerComment(COMMENT_SPOTTED_BY_PASSIVE_PED,bikerCommenting)
|
|
ENDIF
|
|
PLAYER_SEEN_STATE = ENGAGED
|
|
if not IS_PED_INJURED(PLAYER_PED_ID())
|
|
player_alert_location = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
ELSE
|
|
if not IS_PED_INJURED(PLAYER_PED_ID())
|
|
GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
ENDIF
|
|
ENDIF
|
|
for i = 0 to max_sweep_peds-1
|
|
IF searcherPed[i].type = AGGRESIVE_SEARCHER
|
|
if i != bikerCommenting
|
|
searcherPed[i].action = GETTING_TO_ALERT_LOC
|
|
ELSE
|
|
searcherPed[i].action = ENGAGING
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
ENDPROC
|
|
|
|
proc checkPlayerSpotted()
|
|
int i
|
|
if not IS_PED_INJURED(PLAYER_PED_ID())
|
|
for i = nextSweepPed to nextSweepPed
|
|
if nextSweepPed < max_sweep_peds
|
|
if not IS_PED_INJURED(searcherPed[i].iD)
|
|
bool bSeeCheck
|
|
if HAS_ENTITY_CLEAR_LOS_TO_ENTITY(searcherPed[i].iD,PLAYER_PED_ID()) //CAN_PED_SEE_HATED_PED(searcherPed[i].iD,PLAYER_PED_ID())
|
|
if GET_DISTANCE_BETWEEN_ENTITIES(searcherPed[i].iD,PLAYER_PED_ID()) < 40.0
|
|
bSeeCheck=TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
if HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(searcherPed[i].iD,PLAYER_PED_ID())
|
|
bSeeCheck=TRUE
|
|
ENDIF
|
|
|
|
if bSeeCheck
|
|
searcherPed[i].seesPlayer = TRUE
|
|
|
|
player_alert_location = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
|
|
IF searcherPed[i].type = AGGRESIVE_SEARCHER
|
|
IF searcherPed[i].action != ENGAGING
|
|
CLEAR_PED_TASKS(searcherPed[i].iD)
|
|
searcherPed[i].targetNode = -2
|
|
searcherPed[i].action = ENGAGING
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF searcherPed[i].type = PASSIVE_ONLY_ALERTS
|
|
IF searcherPed[i].action != GIVE_PASSIVE_REACTION_TO_PLAYER
|
|
AND searcherPed[i].action != PERFORMING_PASSIVE_RESPONSE_TO_PLAYER
|
|
searcherPed[i].action = GIVE_PASSIVE_REACTION_TO_PLAYER
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF PLAYER_SEEN_STATE != ENGAGED
|
|
engage_player_now(i)
|
|
ENDIF
|
|
|
|
ELSE
|
|
searcherPed[i].seesPlayer = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
nextSweepPed++
|
|
ENDIF
|
|
if nextSweepPed >= max_sweep_peds
|
|
nextSweepPed = 0
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
proc revise_engaged_state()
|
|
|
|
int i
|
|
|
|
SWITCH PLAYER_SEEN_STATE
|
|
case ENGAGED
|
|
if not ARE_VECTORS_EQUAL(player_alert_location,player_last_alert_location)
|
|
player_last_alert_location = player_alert_location
|
|
//println("player moved from ",player_last_alert_location," to ",player_alert_location," 25m set to 0")
|
|
for i = 0 to max_invPoints-1
|
|
if GET_DISTANCE_BETWEEN_COORDS(InvPoint[i].vCoord,player_alert_location) < 25.0
|
|
InvPoint[i].searches = 0
|
|
ELSE
|
|
InvPoint[i].searches = 2
|
|
//println("Node ",i," changed to 15000 sec")
|
|
InvPoint[i].searchTime=GET_GAME_TIMER() + 15000
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
BREAK
|
|
case CHANGE_TO_LOST
|
|
makeBikerComment(COMMENT_NOT_HERE,-1)
|
|
float fDist
|
|
for i = 0 to max_invPoints-1
|
|
fdist = GET_DISTANCE_BETWEEN_COORDS(InvPoint[i].vCoord,player_alert_location)
|
|
if fdist < 30.0
|
|
InvPoint[i].searches = 0
|
|
ELIF fdist < 60.0
|
|
InvPoint[i].searches = 1
|
|
InvPoint[i].searchTime=GET_GAME_TIMER() + floor((fdist - 30.0) / 2.0)
|
|
ELSE
|
|
InvPoint[i].searches = 2
|
|
InvPoint[i].searchTime=GET_GAME_TIMER() + 20000
|
|
ENDIF
|
|
ENDFOR
|
|
PLAYER_SEEN_STATE = LOSt
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
proc player_not_at_last_location(int iCommentPed)
|
|
if PLAYER_SEEN_STATE = ENGAGED
|
|
makeBikerComment(COMMENT_NOT_HERE,iCommentPed)
|
|
PLAYER_SEEN_STATE = CHANGE_TO_LOST
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
func bool GET_GOTO_COORD(vector targetVec, vector &returnVec)
|
|
returnVec = targetVec+<<GET_RANDOM_FLOAT_IN_RANGE(-20.0,20.0),GET_RANDOM_FLOAT_IN_RANGE(-20.0,20.0),0.0>>
|
|
if not IS_VECTOR_ZERO(returnVec)
|
|
return true
|
|
ENDIF
|
|
return FALSE
|
|
ENDFUNC
|
|
|
|
|
|
|
|
proc control_search()
|
|
int i
|
|
|
|
checkPlayerSpotted()
|
|
revise_engaged_state()
|
|
|
|
if not IS_PED_INJURED(PLAYER_PED_ID())
|
|
for i = 0 to max_sweep_peds-1
|
|
if not IS_PED_INJURED(searcherPed[i].iD)
|
|
switch searcherPed[i].action
|
|
case NO_ACTION
|
|
if GET_PED_RELATIONSHIP_GROUP_HASH(searcherPed[i].iD) = int_to_enum(REL_GROUP_HASH,0)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(searcherPed[i].iD,AIGroup)
|
|
ENDIF
|
|
IF searcherPed[i].type = AGGRESIVE_SEARCHER
|
|
searcherPed[i].action = EXPLORING
|
|
searcherPed[i].targetNode = -1
|
|
ELSE
|
|
searcherPed[i].action = JUST_RESPOND_TO_PLAYER_APPROACH
|
|
ENDIF
|
|
BREAK
|
|
CASE EXPLORING
|
|
if not IS_PED_IN_ANY_VEHICLE(searcherPed[i].iD)
|
|
if searcherPed[i].targetNode = -1
|
|
goToNextNode(i)
|
|
ELSE
|
|
checkPedReachedTarget(i)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
BREAK
|
|
CASE GIVE_PASSIVE_REACTION_TO_PLAYER
|
|
searcherPed[i].action = PERFORMING_PASSIVE_RESPONSE_TO_PLAYER
|
|
//ped puts hands up. repeats task on completion below if player is still in sight.
|
|
TASK_HANDS_UP(searcherPed[i].iD,5000)
|
|
BREAK
|
|
|
|
CASE PERFORMING_PASSIVE_RESPONSE_TO_PLAYER
|
|
IF searcherPed[i].seesPlayer = FALSE
|
|
If last_ped_to_be_taken_by_mission_script = i
|
|
searcherPed[i].action = JUST_RESPOND_TO_PLAYER_APPROACH
|
|
ELSE
|
|
return_ped_control_to_mission_Script = i
|
|
ENDIF
|
|
ELSE
|
|
IF GET_SCRIPT_TASK_STATUS(searcherPed[i].iD,script_task_hands_up) = FINISHED_TASK
|
|
TASK_HANDS_UP(searcherPed[i].iD,5000)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE GETTING_TO_ALERT_LOC
|
|
|
|
if GET_GOTO_COORD(player_alert_location,nearectSafePoint)
|
|
|
|
//println(i,": Go to Coord A:",nearectSafePoint)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(searcherPed[i].iD,nearectSafePoint,nearectSafePoint+<<0,0,1.0>>,PEDMOVE_RUN,FALSE,15.0,15.0)
|
|
searcherPed[i].action = LOST_TARGET
|
|
ENDIF
|
|
break
|
|
|
|
case ENGAGING
|
|
if searcherPed[i].seesPlayer = FALSE
|
|
if GET_SCRIPT_TASK_STATUS(searcherPed[i].iD,script_task_combat) = PERFORMING_TASK
|
|
CLEAR_PED_TASKS(searcherPed[i].iD)
|
|
ENDIF
|
|
searcherPed[i].action = LOST_TARGET
|
|
ELSE
|
|
if GET_SCRIPT_TASK_STATUS(searcherPed[i].iD,script_task_combat) != PERFORMING_TASK
|
|
if not IS_PED_INJURED(PLAYER_PED_ID())
|
|
TASK_COMBAT_PED(searcherPed[i].iD,PLAYER_PED_ID())
|
|
//println(i,": combat A")
|
|
SET_PED_SPHERE_DEFENSIVE_AREA(searcherPed[i].iD,player_alert_location+<<GET_RANDOM_FLOAT_IN_RANGE(-20.0,20.0),GET_RANDOM_FLOAT_IN_RANGE(-20.0,20.0),0.0>>,6.0)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
case LOST_TARGET
|
|
if PLAYER_SEEN_STATE = LOST
|
|
searcherPed[i].action = EXPLORING
|
|
searcherPed[i].targetNode = -1
|
|
REMOVE_PED_DEFENSIVE_AREA(searcherPed[i].iD)
|
|
ENDIF
|
|
//is ped within range of last seen location
|
|
if searcherPed[i].seesPlayer = FALSE
|
|
if GET_SCRIPT_TASK_STATUS(searcherPed[i].iD,script_task_any) != PERFORMING_TASK
|
|
if GET_DISTANCE_BETWEEN_COORDS(player_alert_location,GET_ENTITY_COORDS(searcherPed[i].iD)) < 25.0
|
|
//lost target responses...
|
|
if GET_DISTANCE_BETWEEN_COORDS(player_alert_location,GET_ENTITY_COORDS(searcherPed[i].iD)) < 2.5
|
|
player_not_at_last_location(i)
|
|
ELSE
|
|
int iRand
|
|
iRand = GET_RANDOM_INT_IN_RANGE(0,4)
|
|
switch iRand
|
|
case 0 //aim at coord
|
|
TASK_AIM_GUN_AT_COORD(searcherPed[i].iD,player_alert_location+<<0,0,1.0>>,4000)
|
|
//println(i,": GAim gun at coord:")
|
|
BREAK
|
|
case 1
|
|
//move to last coord
|
|
|
|
if GET_GOTO_COORD(player_alert_location,nearectSafePoint)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(searcherPed[i].iD,nearectSafePoint,nearectSafePoint+<<0,0,1.0>>,PEDMOVE_RUN,FALSE,1.0,1.0)
|
|
ENDIF
|
|
//println(i,": go to coord D:")
|
|
|
|
BREAK
|
|
|
|
case 2
|
|
//seek cover
|
|
TASK_SEEK_COVER_FROM_POS(searcherPed[i].iD,player_alert_location,10000,true)
|
|
//println(i,": seek cover:")
|
|
BREAK
|
|
case 3
|
|
//go to a nearby node
|
|
goToNextNode(i)
|
|
break
|
|
ENDSWITCH
|
|
ENDIF
|
|
ELSE
|
|
vector vTarget
|
|
vTarget = player_alert_location+<<GET_RANDOM_FLOAT_IN_RANGE(-20.0,20.0),GET_RANDOM_FLOAT_IN_RANGE(-20.0,20.0),0.0>>
|
|
if GET_GOTO_COORD(vTarget,nearectSafePoint)
|
|
TASK_GO_TO_COORD_WHILE_AIMING_AT_COORD(searcherPed[i].iD,nearectSafePoint,nearectSafePoint+<<0,0,0.6>>,PEDMOVE_RUN,FALSE,9.0,9.0)
|
|
ENDIF
|
|
//println(i,": Go to coord E:")
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
if get_Game_timer() > InvPoint[iUpdateNode].searchTime
|
|
InvPoint[iUpdateNode].searches = 0
|
|
ENDIF
|
|
iUpdateNode++
|
|
if iUpdateNode >= max_invPoints
|
|
iUpdateNode = 0
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
func bool has_sweep_begun()
|
|
if bSweepBegun
|
|
return TRUE
|
|
ENDIF
|
|
return FALSE
|
|
ENDFUNC
|
|
|
|
proc resetSweepData()
|
|
int i
|
|
player_alert_location = <<0,0,0>>
|
|
player_last_alert_location = <<0,0,0>>
|
|
nearectSafePoint = <<0,0,0>>
|
|
player_seen_state = NOT_SEEN
|
|
nextDialogue = ""
|
|
nextDialoguePed = -1
|
|
addedPedCount = 0
|
|
|
|
for i = 0 to max_sweep_peds-1
|
|
searcherPed[i].targetNode=-1
|
|
searcherPed[i].action=NO_ACTION
|
|
searcherPed[i].seesPlayer = FALSE
|
|
ENDFOR
|
|
|
|
for i = 0 to max_invPoints-1
|
|
InvPoint[i].searches=0
|
|
InvPoint[i].searchTime=0
|
|
ENDFOR
|
|
bSweepBegun = FALSE
|
|
ENDPROC
|
|
|
|
|
|
|
|
proc init_sweep_dialogue(STRING sAudioBank,STRING dial_spotted,STRING dial_fleeing,STRING dial_lost,STRING dial_hunting)
|
|
bAudioSetup = true
|
|
audioBank = sAudioBank
|
|
dia_spotted = dial_spotted
|
|
dia_fleeing = dial_fleeing
|
|
dia_lost = dial_lost
|
|
dia_hunting = dial_hunting
|
|
ENDPROC
|
|
|
|
proc pause_sweep_dialogue(bool pauseSweepDialogue=TRUE)
|
|
bPauseDialogue = pauseSweepDialogue
|
|
ENDPROC
|
|
|
|
//PARAM NOTES: type= AGGRESIVE_SEARCHER OR PASSIVE_ONLY_ALERTS
|
|
proc add_sweeper_ped(PED_INDEX pedID,enumType type=AGGRESIVE_SEARCHER)
|
|
// CPRINTLN(DEBUG_TREVOR3,"Ped added to search")
|
|
if addedPedCount < max_sweep_peds
|
|
searcherPed[addedPedCount].iD = pedID
|
|
// CPRINTLN(DEBUG_TREVOR3,"Ped added: ",native_to_int(pedID)," and ",native_to_int(searcherPed[addedPedCount].iD))
|
|
searcherPed[addedPedCount].action = NO_ACTION
|
|
searcherPed[addedPedCount].type = type
|
|
//SET_PED_RELATIONSHIP_GROUP_HASH(searcherPed[addedPedCount].iD,AIGroup)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(searcherPed[addedPedCount].iD,true)
|
|
addedPedCount++
|
|
ELSE
|
|
SCRIPT_ASSERT("Too many peds added to sweep. Increase max_sweep_peds?")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC control_AI_sweep(#IF IS_DEBUG_BUILD WIDGET_GROUP_ID parentWidget #endif)
|
|
#IF IS_DEBUG_BUILD
|
|
debugSweep(parentWidget)
|
|
control_investigate_points()
|
|
#ENDIF
|
|
INIT_SEARCH_VARS()
|
|
control_search()
|
|
CONTROL_DIALOGUE()
|
|
ENDPROC
|
|
/*
|
|
#IF IS_FINAL_BUILD
|
|
SCRIPT
|
|
ENDSCRIPT
|
|
#ENDIF
|
|
*/
|