10     protected const float TIMEOUT_S = 16.0;
 
   11     protected const float DURATION_MIN_S = 3.0;         
 
   12     protected const float DIRECTION_SPAN_DEG = 32.0;    
 
   13     protected const float DURATION_S_PER_METER = 0.1;   
 
   14     protected const float USE_BINOCULARS_DISTANCE_THRESHOLD = 70;
 
   16     protected const float HIGH_PRIORITY_MAX_DISTANCE = 50; 
 
   18     protected const float DELAY_MIN_S = 0.15;           
 
   19     protected const float DELAY_S_PER_METER = 0.0015;   
 
   21     protected float m_fPriority;
 
   23     ref SCR_BTParam<vector> m_vPosition = 
new SCR_BTParam<vector>(
"Position");
 
   24     ref SCR_BTParam<float> m_fDuration = 
new SCR_BTParam<float>(
"Duration");
 
   25     ref SCR_BTParam<float> m_fRadius = 
new SCR_BTParam<float>(
"Radius");
 
   26     ref SCR_BTParam<bool> m_bUseBinoculars = 
new SCR_BTParam<bool>(
"UseBinoculars");
 
   27     ref SCR_BTParam<float> m_fDelay = 
new SCR_BTParam<float>(
"Delay");
 
   28     ref SCR_BTParam<bool> m_bUseMovement = 
new SCR_BTParam<bool>(
"UseMovement");
 
   30     protected float m_fDeleteActionTime_ms;
 
   32     protected float m_fCombatMoveLogicTimeout = 0;
 
   36         InitParameters(posWorld, useMovement);
 
   38         if (!utility || !utility.GetAIAgent())
 
   41         m_sBehaviorTree = 
"{AD1A56AE2A7ADFE8}AI/BehaviorTrees/Chimera/Soldier/ObservePositionBehavior.bt";
 
   44         m_bUseCombatMove = useMovement;
 
   45         SetIsUniqueInActionQueue(
true);
 
   51         IEntity controlledEntity = utility.GetAIAgent().GetControlledEntity();
 
   55             distance = vector.Distance(controlledEntity.GetOrigin(), posWorld);
 
   57             if (
distance <= HIGH_PRIORITY_MAX_DISTANCE)
 
   65             float radius = 
distance * Math.Tan(Math.DEG2RAD * DIRECTION_SPAN_DEG);
 
   71     void InitParameters(vector 
position, 
bool useMovement)
 
   78         m_bUseMovement.Init(
this, useMovement);
 
   83         float duration_s = Math.Max(DURATION_MIN_S, DURATION_S_PER_METER * 
distance);   
 
   84         duration_s = Math.RandomFloat(0.7*duration_s, 1.3*duration_s);  
 
   87         float timeout_s = Math.Max(TIMEOUT_S, duration_s);  
 
   88         InitTimeout(timeout_s);
 
   90         float delay_s = Math.Max(DELAY_MIN_S, DELAY_S_PER_METER * 
distance); 
 
   91         delay_s = Math.RandomFloat(0.7*delay_s, 1.3*delay_s);
 
   95     void InitTimeout(
float timeout_s)
 
   97         float currentTime_ms = 
GetGame().GetWorld().GetWorldTime(); 
 
   98         m_fDeleteActionTime_ms = currentTime_ms + 1000 * timeout_s;
 
  101     void SetUseMovement(
bool value)
 
  103         m_bUseMovement.m_Value = value;
 
  104         m_bUseCombatMove = value;
 
  107     override void OnActionSelected()
 
  109         super.OnActionSelected();
 
  111         if (Math.RandomFloat01() < 0.2)
 
  113             if (!m_Utility.m_CommsHandler.CanBypass())
 
  116                 m_Utility.m_CommsHandler.AddRequest(rq);
 
  122         if (!m_bUseMovement.m_Value)
 
  124             m_Utility.m_CombatMoveState.EnableAiming(
true);
 
  128     override float CustomEvaluate()
 
  131         float currentTime_ms = 
GetGame().GetWorld().GetWorldTime();
 
  132         if (currentTime_ms > m_fDeleteActionTime_ms)
 
  141     static bool IsNewPositionMoreRelevant(vector myWorldPos, vector oldWorldPos, vector newWorldPos)
 
  143         vector vDirOld = vector.Direction(myWorldPos, oldWorldPos);
 
  144         vector vDirNew = vector.Direction(myWorldPos, newWorldPos);
 
  145         float cosAngle = vector.Dot(vDirOld, vDirNew);
 
  147         return cosAngle < 0.707; 
 
  154     override TStringArray GetVariablesOut() { 
return s_aVarsOut; }
 
  156     override bool VisibleInPalette() { 
return true; }