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

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
*/