Code:
Scriptname THEW:THEW_Scr_ActorEncounter extends Actor Conditional
Group ActorConfiguration
THEW:THEW_Scr_EncounterQuest:EncounterActorDescription Property ActorDescription Auto
{ This configuration will be overriden unless you set ActorIsPredefined to true. }
Int Property ActorBehaviour = 0 Auto Conditional
{ This var will be set by the actor script to control package states.
If an actors is linked to another with the keyword THEW_KW_Encounter_Leader, he will copy his state from this actor.
If an actor has linked refs with the keywords THEW_KW_Encounter_TargetEnd and THEW_KW_Encounter_TargetStart he will use his own state.
If an actors is linked to another with the keyword THEW_KW_Encounter_Leader and he is dead, he will flee to the linked end location.
-1: Flee to linked ref with keyword THEW_KW_Encounter_TargetEnd
0: Waiting for configuration
1: Travel to start location
2: Sandbox around start location
3: Travel to end location
4: Sandbox around end location
}
EndGroup
Group MandatoryData
Actor Property Player Auto Const Mandatory
Keyword Property THEW_KW_Encounter_Target_Start Auto Const Mandatory
Keyword Property THEW_KW_Encounter_Target_End Auto Const Mandatory
Keyword Property THEW_KW_Encounter_Target_Flee Auto Const Mandatory
ActorValue Property AvAggression Auto Const Mandatory
ActorValue Property AvConfidence Auto Const Mandatory
ActorValue Property AvAssistance Auto Const Mandatory
GlobalVariable Property GameHour Auto Const Mandatory
GlobalVariable Property GameDaysPassed Auto Const Mandatory
THEW:THEW_Scr_EncounterQuest Property EncounterQuest Auto Const Mandatory
EndGroup
; --- Private vars ----
int actorState = 0 ; Actor state. 0: Not initialized, 1: waiting for configuration, 2: configured, 3: relaxing around player, 4: travelling to the end destination, 5: disabled
float timerInterval = 20.0 ; Timer interval in seconds.
float sandboxEndTime = 0.0 ; This timer will be used to track the sandbox duration.
THEW:THEW_Scr_ActorEncounter myLeader ; The linked actor as encounter actor script.
; Initializes the actor on first load, unloads him on second.
Event OnLoad()
if actorState == 0
actorState = 1
StartTimer(timerInterval / 2)
EncounterQuest.LogMessage(self.GetBaseObject(), "OnLoad()", "Actor initialized.")
else
if playerIsInSight() == false
deleteActor()
endif
endif
EndEvent
Event OnDeath()
actorState = 666
SetLinkedRef(none)
CancelTimer()
EndEvent
Event OnCellDetach()
deleteActor()
EndEvent
Event OnTimer(int aiTimerID)
updateActor()
EndEvent
Function updateActor()
if actorState == 1 ; Try to initialize actor and send him to the first destination.
initActor()
StartTimer(timerInterval / 2)
elseif actorState == 2 ; Actor is on the way to the first destination.
if ActorDescription.ActorIsLeader || ActorDescription.GroupHasLeader == false
if GetDistance(GetLinkedRef(THEW_KW_Encounter_Target_Start)) < EncounterQuest.PackageChangeDistance
if ActorRelaxAllowed == true
sandboxEndTime = GameDaysPassed + GroupRelaxTime
ActorBehaviour = 2
EvaluatePackage()
actorState = 3
else
ActorBehaviour = 3
EvaluatePackage()
actorState = 4
endif
endif
else
updateFromMyLeader()
endif
StartTimer(timerInterval)
elseif actorState == 3 ; Actor has reached destination and will sandbox for a defined time.
if ActorDescription.ActorIsLeader || ActorDescription.GroupHasLeader == false
if sandboxEndTime > GameDaysPassed
ActorBehaviour = 3
EvaluatePackage()
actorState = 4
endif
else
updateFromMyLeader()
endif
StartTimer(timerInterval)
elseif actorState == 4 ; Actor is on the way to the end location and will relax there until the cell is deatached or the player goes away.
if ActorDescription.ActorIsLeader || ActorDescription.GroupHasLeader == false
if GetDistance(GetLinkedRef(THEW_KW_Encounter_Target_End)) < EncounterQuest.PackageChangeDistance
ActorBehaviour = 4
EvaluatePackage()
actorState = 5
endif
else
updateFromMyLeader()
StartTimer(timerInterval) ; Leaders do not need timer anymore.
endif
endif
logActorState()
EndFunction
Function initActor()
if ActorDescription.ActorConfigReady == true
SetValue(AvAggression, ActorDescription.ActorAggression)
SetValue(AvConfidence, ActorDescription.ActorConfidence)
SetValue(AvAssistance, ActorDescription.ActorAssistance)
if ActorDescription.ActorFaction
AddToFaction(ActorDescription.ActorFaction)
endif
ActorBehaviour = 1
EvaluatePackage()
actorState = 2
endif
EndFunction
Function deleteActor()
actorState = 666
SetLinkedRef(none)
CancelTimer()
DisableNoWait()
Delete()
EndFunction
Bool Function playerIsInSight()
if GetDistance(Player) > ActorDescription.PlayerOutOfSightDistance
return false
endif
return true
EndFunction
Bool Function playerIsNear()
if GetDistance(Player) < ActorDescription.PlayerNearDistance
return true
endif
return false
EndFunction
int[] Function getMyLeaderBehaviour()
int [] behaviour = new int[2]
behaviour[0] = actorState
behaviour[1] = 0
if myLeader
if (myLeader as Actor).IsDead()
behaviour[1] = -1
else
behaviour[1] = myLeader.ActorBehaviour
endif
elseif GetLinkedRef(THEW_KW_Encounter_Target_Start)
if GetLinkedRef(THEW_KW_Encounter_Target_Start) As THEW:THEW_Scr_ActorEncounter
myLeader = GetLinkedRef(THEW_KW_Encounter_Target_Start) As THEW:THEW_Scr_ActorEncounter
behaviour[1] = myLeader.ActorBehaviour
endif
endif
return behaviour
EndFunction
Function updateFromMyLeader()
int[] myBehaviour = getMyLeaderBehaviour()
if myBehaviour[0] != actorState
ActorBehaviour = myBehaviour[1]
EvaluatePackage()
actorState = myBehaviour[0]
endif
EndFunction
Function logActorState ()
string log = EncounterQuest.AddToLog("isLeader", ActorDescription.ActorIsLeader)
log += EncounterQuest.AddToLog("ActorState", actorState)
log += EncounterQuest.AddToLog("ActorBehaviour", ActorBehaviour)
EncounterQuest.LogMessage(self.GetBaseObject(), "Actor Info", log)
EndFunction