Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_AIDangerReaction_DoorMovement.c
Go to the documentation of this file.
3 {
4  static const float AGENT_DEFAULT_RADIUS = 0.3;
5  static const float AGENT_DEFAULT_HEIGHT = 1.8;
6  static const float REACTION_DIST_SQ = 100.0;
7 #ifdef WORKBENCH
8  ref Shape s1,s2,s3,s4;
9 #endif
10 
11  override bool PerformReaction(notnull SCR_AIUtilityComponent utility, notnull SCR_AIThreatSystem threatSystem, AIDangerEvent dangerEvent)
12  {
13  IEntity door = dangerEvent.GetObject();
14  if (!door)
15  return false;
16  vector agentPos = utility.GetOrigin();
17  vector doorPos = door.GetOrigin();
18 
19  //Initial filter for hearing distance (TODO: optimization spatial grid)
20  float distSq = vector.DistanceSq(agentPos, doorPos);
21  if (distSq >= REACTION_DIST_SQ)
22  return false;
23 
24  vector min, max;
25  float distToDoorY = doorPos[1] - agentPos[1];
26  //If agent is below door more than agent height, skip
27  if (distToDoorY > AGENT_DEFAULT_HEIGHT)
28  return false;
29 
30  door.GetBounds(min, max);
31  vector doorExtent = max - min;
32  //If agent above door more than door height, skip
33  if (-distToDoorY > doorExtent[1])
34  return false;
35 
36  float distToDoorXZ = vector.DistanceXZ(doorPos, agentPos) - AGENT_DEFAULT_RADIUS;
37  doorExtent[1] = 0.0;
38  float doorLength = doorExtent.Length();
39  //If the agent isn't in XZ range, skip
40  if (distToDoorXZ > doorLength)
41  return false;
42 
43  //Ensure the necessary entities and components are valid
44  SCR_ChimeraAIAgent agent = SCR_ChimeraAIAgent.Cast(utility.GetOwner());
45  if (!agent)
46  return false;
47 
48  //Turn around if the instigator of door is an enemy,
49  IEntity actionStarter = dangerEvent.GetVictim();
50  if (agent.IsEnemy(actionStarter))
51  {
52  utility.AddAction(new SCR_AIMoveIndividuallyBehavior(utility, null, agentPos, SCR_AIActionBase.PRIORITY_BEHAVIOR_MOVE_INDIVIDUALLY, 0, null, AGENT_DEFAULT_RADIUS));
53  utility.m_LookAction.LookAt(actionStarter.GetOrigin(), utility.m_LookAction.PRIO_DANGER_EVENT);
54  return true;
55  }
56 
57  ChimeraCharacter character = ChimeraCharacter.Cast(agent.GetControlledEntity());
58  if (character && character.IsInVehicle())
59  return false;
60 
61  DoorComponent doorComponent = DoorComponent.Cast(door.FindComponent(DoorComponent));
62  if (!doorComponent)
63  return false;
64 
65  vector doorNormal = door.VectorToParent(vector.Forward);
66  bool flipLogic = doorComponent.GetAngleRange() < 0.0; // door that open -90 have the normals in oposite direction
67  if (flipLogic)
68  doorNormal = -1.0 * doorNormal;
69  if (doorComponent.IsOpening())
70  doorNormal = -1.0 * doorNormal;
71 
72  vector agentDirection = agentPos - doorComponent.GetDoorPivotPointWS();
73  agentDirection.Normalize();
74 
75  vector rightHand = vector.Up * doorNormal; // vector pointing in direction of door revolvment perpend. to doorNormal
76  if (flipLogic)
77  rightHand = -1.0 * rightHand;
78  if (doorComponent.IsClosing())
79  rightHand = -1.0 * rightHand;
80 
81  IEntity doorFrame = door.GetParent();
82  if (!doorFrame)
83  doorFrame = door;
84 
85  vector doorFrameUp = doorFrame.VectorToParent(vector.Up);
86  vector fleeingDir;
87 
88 #ifdef WORKBENCH
89  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_AI_SHOW_DEBUG_SHAPES))
90  {
91  s1 = Shape.CreateArrow(doorPos, doorPos + agentDirection, 0.1, COLOR_RED, ShapeFlags.NOZBUFFER);
92  s2 = Shape.CreateArrow(doorPos, doorPos + doorNormal, 0.1, COLOR_BLUE, ShapeFlags.NOZBUFFER);
93  s3 = Shape.CreateArrow(doorPos, doorPos + rightHand, 0.1, COLOR_GREEN, ShapeFlags.NOZBUFFER);
94  }
95 #endif
96  float dotP1 = vector.Dot(doorNormal, agentDirection);
97  float dotP2 = vector.Dot(rightHand, agentDirection);
98  float distanceToMove;
99  bool isDoorOpeningUpwards = !float.AlmostEqual(vector.Dot(doorNormal, doorFrameUp),0); // bar gates have rotation planes paralel with up vector of "door frame"
100 
101  if (isDoorOpeningUpwards)
102  {
103  if (!doorComponent.IsClosing()) // ignoring opening gate
104  return false;
105  else
106  {
107  distToDoorXZ = vector.DistanceXZ(doorFrame.GetOrigin(), agentPos) - AGENT_DEFAULT_RADIUS;
108  doorLength = 2.0; // bit hacky but simple
109  if (dotP2 < 0)
110  fleeingDir = -1.0 * rightHand;
111  else
112  fleeingDir = rightHand;
113  distanceToMove = Math.Clamp((doorLength - distToDoorXZ) * 2.0, doorLength, 2.0 * doorLength);
114  }
115  }
116  else
117  {
118  if (dotP1 < 0) // standing in the other halfplane, than the one where the door is revolving
119  return false;
120  else if (dotP2 > 0) // standing in the halfplane of revolving door but not in the quadrant
121  return false;
122  if (doorComponent.IsClosing())
123  fleeingDir = -1.0 * rightHand;
124  else
125  fleeingDir = doorNormal;
126  distanceToMove = Math.Clamp((doorLength - distToDoorXZ) * 2.0, 2.0 * AGENT_DEFAULT_RADIUS, doorLength);
127  }
128 
129 #ifdef WORKBENCH
130  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_AI_SHOW_DEBUG_SHAPES))
131  s4 = Shape.CreateArrow(agentPos, agentPos + fleeingDir * distanceToMove, 0.5, COLOR_YELLOW, ShapeFlags.NOZBUFFER);
132 #endif
133  vector movePos = agentPos + fleeingDir * distanceToMove;
134 
135  //Step away and free door space
136  utility.AddAction(new SCR_AIMoveIndividuallyBehavior(utility, null, movePos, SCR_AIActionBase.PRIORITY_BEHAVIOR_MOVE_INDIVIDUALLY, 0, null, AGENT_DEFAULT_RADIUS));
137  return true;
138  }
139 };
SCR_AIActionBase
Definition: SCR_AIAction.c:1
SCR_AIDangerReaction
Definition: SCR_AIDangerReaction.c:4
SCR_ChimeraAIAgent
Definition: SCR_ChimeraAIAgent.c:5
SCR_AIMoveIndividuallyBehavior
Definition: SCR_AIMoveBehavior.c:30
DoorComponent
Definition: DoorComponent.c:12
SCR_AIDangerReaction_DoorMovement
Definition: SCR_AIDangerReaction_DoorMovement.c:2
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
SCR_AIThreatSystem
Definition: SCR_AIThreatSystem.c:17
BaseContainerProps
SCR_AIGoalReaction_Follow BaseContainerProps
Handles insects that are supposed to be spawned around selected prefabs defined in prefab names array...
Definition: SCR_AIGoalReaction.c:468