Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
BaseCompartmentSlot.c
Go to the documentation of this file.
2{
3 [Attribute("0", desc: "Switching seats is allowed only between compartments with matching section")]
4 protected int m_iCompartmentSection;
5
6 [Attribute("0", desc: "Set whether compartment is water tight. People inside may drown if false")]
7 protected bool m_bIsWaterTight;
8
9 [Attribute(desc: "Contains Default Prefab of character to be spawned into compartment", params: "et")]
10 protected ref SCR_DefaultOccupantData m_DefaultOccupantData;
11
12 [Attribute(desc: "Contains parameters for executing screenshake upon crashing vehicle for passengers", params: "et")]
14
15 [Attribute("-89.9", desc: "Aim limit angle override (in degrees) when free-looking down", params: "-89.9 0.05 0.05")]
17
18 [Attribute("89.9", desc: "Aim limit angle override (in degrees) when free-looking up", params: "0.05 89.9 0.05")]
20
21 [Attribute("-160.0", desc: "Aim limit angle override (in degrees) when free-looking left", params: "-160.0 0.05 0.05")]
23
24 [Attribute("160.0", desc: "Aim limit angle override (in degrees) when free-looking right", params: "0.05 160.0 0.05")]
26
27 [Attribute("-1 1 1", desc: "First person camera local space offset scale from Neck1 bone")]
29
30 [Attribute("1.0", desc: "Extent to which body should account for turret traverse.\nThe higher, the more neck will rotate around turret pivot\nExamples: BTR-70 neck does not pivot, tripod and M151 turret pivots")]
32
33 [Attribute("0.5", desc: "Chance the occupant will get ejected upon EjectOccupant being called.\nOnly applies to compartments without roof or open doors unless forced")]
34 protected float m_fRandomEjectionChance;
36 static const vector SPAWN_IN_VEHICLE_OFFSET = Vector(0, 250, 0); //~ Offset added when characters are spawned to add to vehicle. To make sure they are close and streamed but not on the vehicle as this would kill them
37
38 protected bool m_bCompartmentAccessible = true;
39
40 //------------------------------------------------------------------------------------------------
41 override void DebugDrawPosition()
42 {
43 Color c = Color.FromInt(Color.WHITE);
45 c = Color.FromInt(Color.BLACK);
46 vector pos = GetPosition();
47 if (pos != vector.Zero)
48 Shape.CreateCylinder(c.PackToInt(), ShapeFlags.ONCE, GetPosition(), 0.05, 5);
49 }
50
51 //------------------------------------------------------------------------------------------------
56
57 //------------------------------------------------------------------------------------------------
59 {
61 }
63 //------------------------------------------------------------------------------------------------
66 {
68 }
70 //------------------------------------------------------------------------------------------------
73 {
74 return m_bIsWaterTight;
75 }
76
77 //------------------------------------------------------------------------------------------------
80 May differ from GetOwner() if the slot is placed in vehicle's child entity, e.g., truck's cargo frame.
81 \return Vehicle entity
82 */
84 {
85 IEntity owner = GetOwner();
86 IEntity vehicle;
87 while (owner)
88 {
90 vehicle = owner;
91
92 owner = owner.GetParent();
93 }
94 return vehicle;
95 }
96
97 //------------------------------------------------------------------------------------------------
101 \param[out] compartmentID Variable to be filled with ID of the compartment relative to the vehicle. May differ from GetCompartmentSlotID() which returns only ID within the entity the slot belong sto.
102 \return Vehicle entity
103 */
104 IEntity GetVehicle(out int compartmentID)
105 {
106 IEntity owner = GetOwner();
107 IEntity vehicle;
108 Managed component, componentCandidate;
109 while (owner)
110 {
111 componentCandidate = owner.FindComponent(BaseCompartmentManagerComponent);
112 if (componentCandidate)
113 {
114 vehicle = owner;
115 component = componentCandidate;
116 }
117
118 owner = owner.GetParent();
119 }
120 if (vehicle)
121 {
123 array<BaseCompartmentSlot> compartments = {};
124 manager.GetCompartments(compartments);
125 compartmentID = compartments.Find(this);
126 }
127 return vehicle;
128 }
129
130 //------------------------------------------------------------------------------------------------
132 Get if compartment is occupied
133 \return returns true if occupied else returns false
134 */
136 {
137 return GetOccupant() != null;
139
140 //------------------------------------------------------------------------------------------------
141 void DamageOccupant(float damage, EDamageType damageType, notnull Instigator instigator, bool damageWhileGetIn = true, bool damageWhileGetOut = true)
142 {
143 ChimeraCharacter character = ChimeraCharacter.Cast(GetOccupant());
144 if (!character)
145 return;
146
147 RplComponent rpl = character.GetRplComponent();
148 if (rpl && rpl.IsProxy())
149 return;
150
151 // Ignore characters that only began to get in the vehicle
152 CompartmentAccessComponent access = character.GetCompartmentAccessComponent();
153 if (!damageWhileGetIn && access && access.IsGettingIn())
154 return;
155
156 if (!damageWhileGetOut && access && access.IsGettingOut())
157 return;
158
159 SCR_DamageManagerComponent damageManager = character.GetDamageManager();
160 if (damageManager)
161 damageManager.DamageRandomHitZones(damage, damageType, instigator);
163
164 //------------------------------------------------------------------------------------------------
165 void ScreenShakeOccupant(float damage)
166 {
167 ChimeraCharacter character = ChimeraCharacter.Cast(GetOccupant());
168 if (!character)
169 return;
170
172 return;
173
174 SCR_DamageManagerComponent damageManager = character.GetDamageManager();
175 if (!damageManager)
176 return;
177
178 float inTime, sustainTime, outTime, maxScreenShakeHealthThreshold, linearMagnitude, angularMagnitude;
179 m_ScreenShakeData.GetScreenShakeData(inTime, sustainTime, outTime, maxScreenShakeHealthThreshold, linearMagnitude, angularMagnitude);
180
181 float maxScreenShake = damageManager.GetMaxHealth() * maxScreenShakeHealthThreshold;
182 if (maxScreenShake == 0)
183 return;
184
185 SCR_CameraShakeManagerComponent.AddCameraShake(Math.Lerp(0, linearMagnitude, damage / maxScreenShake), Math.Lerp(0, angularMagnitude, damage / maxScreenShake), inTime, sustainTime, outTime);
187
188 //------------------------------------------------------------------------------------------------
189 void KillOccupant(notnull Instigator instigator, bool eject = false, bool gettingIn = false, bool gettingOut = false)
190 {
191 ChimeraCharacter character = ChimeraCharacter.Cast(GetOccupant());
192 if (!character)
193 return;
194
195 SCR_DamageManagerComponent damageManager = character.GetDamageManager();
196 if (!damageManager)
197 return;
198
199 CharacterControllerComponent controller = character.GetCharacterController();
200 if (!controller)
201 return;
202
203 CompartmentAccessComponent access = character.GetCompartmentAccessComponent();
204 if (!gettingIn && access && access.IsGettingIn())
205 return;
206
207 if (!gettingOut && access && access.IsGettingOut())
208 return;
209
210 if (eject && access)
211 {
212 access.GetOutVehicle(EGetOutType.TELEPORT, -1, ECloseDoorAfterActions.INVALID, false);
213 // because person needs to be out of vehicle for sure
214 GetGame().GetCallqueue().CallLater(damageManager.Kill, 1, false, instigator);
215 }
216 else
217 {
218 damageManager.Kill(instigator);
219 }
220 }
221
222 //------------------------------------------------------------------------------------------------
226 //! \param[out] ejectedImmediately returns true if this client was capable of ejecting character that is in this compartment
227 //! \param[in] ejectOnTheSpot if character should be ejected in the position where he currently is
228 //! \return true if character was ejected
229 bool EjectOccupant(bool forceEject = false, bool ejectUnconsciously = false, out bool ejectedImmediately = false, bool ejectOnTheSpot = false)
230 {
231 ChimeraCharacter character = ChimeraCharacter.Cast(GetOccupant());
232 if (!character)
233 return false;
234
235 RplComponent rpl = character.GetRplComponent();
236 if (rpl && rpl.IsProxy())
237 return false;
238
239 // Ignore characters that only began to get in the vehicle
240 SCR_CompartmentAccessComponent access = SCR_CompartmentAccessComponent.Cast(character.GetCompartmentAccessComponent());
241 if (!access)
242 return false;
243
244 int nearestDoorInd;
245 if (!ejectOnTheSpot)
246 {
247 nearestDoorInd = PickDoorIndexForPoint(character.GetOrigin());
248 BaseCompartmentManagerComponent compartmentManager = GetManager();
249 if (compartmentManager)
250 ejectOnTheSpot = compartmentManager.IsDoorFake(nearestDoorInd);
251 }
252
253 if (ejectUnconsciously)
254 {
255 SCR_CharacterDamageManagerComponent damageMan = SCR_CharacterDamageManagerComponent.Cast(character.GetDamageManager());
256 if (damageMan)
257 damageMan.ForceUnconsciousness(damageMan.GetResilienceHitZone().GetDamageStateThreshold(ECharacterDamageState.STATE3));
258 }
259
260 if (forceEject || GetManager().IsDoorOpen(nearestDoorInd) || ShouldCharactersFallOutWhenFlipped())
261 {
262 if (!ejectOnTheSpot)
263 {
264 ejectedImmediately = access.GetOutVehicle(EGetOutType.TELEPORT, nearestDoorInd, ECloseDoorAfterActions.INVALID, false);
265 }
266 else
267 {
268 vector mat[4];
269 character.GetTransform(mat);
270 mat[3] = character.AimingPosition();//dont use root position as it may be f.e. under the vehicle floor
271
272 ejectedImmediately = access.GetOutVehicle_NoDoor(mat, ejectUnconsciously, false);
273 }
274
275 if (!ejectedImmediately)
276 access.AskOwnerToGetOutFromVehicle(EGetOutType.TELEPORT, nearestDoorInd, ECloseDoorAfterActions.INVALID, false, ejectOnTheSpot);
277
278 return true;
279 }
280
281 return false;
282 }
283
284 //------------------------------------------------------------------------------------------------
286 Get default occupent prefab data
287 \return Default occupant data
288 */
289 SCR_DefaultOccupantData GetDefaultOccupantData()
290 {
292 }
293
294 //------------------------------------------------------------------------------------------------
296 Get default occupent prefab ResourceName
297 \return Default occupant prefab
298 */
299 ResourceName GetDefaultOccupantPrefab(bool checkIfValid = true)
300 {
301 if (!m_DefaultOccupantData || (checkIfValid && !m_DefaultOccupantData.IsValid()))
302 return string.Empty;
303
305 }
306
307 //------------------------------------------------------------------------------------------------
312 \param groupPrefabGroup prefab, Generally want to keep it as default value as faction and usch is set automaticly
313 \return Returns spawned character
314 */
315 IEntity SpawnDefaultCharacterInCompartment(inout AIGroup group, ResourceName groupPrefab = "{000CD338713F2B5A}Prefabs/AI/Groups/Group_Base.et")
316 {
317 return SpawnCharacterInCompartment(GetDefaultOccupantPrefab(), group, groupPrefab);
318 }
319
320 //------------------------------------------------------------------------------------------------
325 \param createGroupForCharacter If a group should be created for the spawned character
326 \return Returns spawned character
327 */
328 IEntity SpawnCharacterInCompartment(ResourceName characterPrefab, inout AIGroup group, ResourceName groupPrefab = "{000CD338713F2B5A}Prefabs/AI/Groups/Group_Base.et")
329 {
330 if (characterPrefab.IsEmpty() || !IsCompartmentAccessible() || GetOccupant() != null)
331 return null;
332
333 //~ Spawn at vehicle position
335 GetOwner().GetTransform(params.Transform);
336
337 ChimeraWorld world = GetGame().GetWorld();
338
339 //~ Spawn characters above the vehicle to make sure physics do not interact with the character and they die on contact of the vehicle
340 params.Transform[3] + SPAWN_IN_VEHICLE_OFFSET;
341
342 IEntity spawnedCharacter = GetGame().SpawnEntityPrefab(Resource.Load(characterPrefab), null, params);
343 if (!spawnedCharacter)
344 {
345 Print(string.Format("'BaseCompartmentSlot' Failed to spawn character in compartment. Check if ResourceName is correct! Path: '%1'", characterPrefab), LogLevel.ERROR);
346 return null;
347 }
348
349 AIControlComponent agentControlComponent = AIControlComponent.Cast(spawnedCharacter.FindComponent(AIControlComponent));
350 if (!agentControlComponent)
351 {
352 Print("'BaseCompartmentSlot' Could not get AIControlComponent from spawned character, so entity is deleted!", LogLevel.ERROR);
353 delete spawnedCharacter;
354 return null;
355 }
356
357 agentControlComponent.ActivateAI();
358
359 CompartmentAccessComponent compartmentAccess = CompartmentAccessComponent.Cast(spawnedCharacter.FindComponent(CompartmentAccessComponent));
360 if (!compartmentAccess)
361 {
362 Print("'BaseCompartmentSlot' Could not get CompartmentAccessComponent from spawned character, so entity is deleted!", LogLevel.ERROR);
363 delete spawnedCharacter;
364 return null;
365 }
366
367 //~ Could not move in compartment so delete
368 if (!compartmentAccess.GetInVehicle(GetOwner(), this, true, -1, ECloseDoorAfterActions.INVALID, world.IsGameTimePaused()))
369 {
370 Print(string.Format("'BaseCompartmentSlot' Trying to spawn character in compartment but it could not be moved into it so character is deleted. Compartment type: %1", typename.EnumToString(ECompartmentType, GetType())), LogLevel.WARNING);
371 delete spawnedCharacter;
372 return null;
373 }
374
375 //~ Create new group
376 if (!group)
377 {
378 IEntity groupEntity = GetGame().SpawnEntityPrefab(Resource.Load(groupPrefab));
379 if (!groupEntity)
380 {
381 Print("'BaseCompartmentSlot' Could not create group for spawned character. Most likly incorrect group prefab given!", LogLevel.ERROR);
382 return spawnedCharacter;
383 }
384
385 group = AIGroup.Cast(groupEntity);
386 if (!group)
387 {
388 Print("'BaseCompartmentSlot' Could not create group for spawned character as spawned group prefab is missing AIGroup component!", LogLevel.ERROR);
389 delete groupEntity;
390 return spawnedCharacter;
391 }
392
393 //~ Set group's faction
394 SCR_AIGroup groupScripted = SCR_AIGroup.Cast(group);
395 if (groupScripted)
396 {
397 FactionAffiliationComponent factionComponent = FactionAffiliationComponent.Cast(spawnedCharacter.FindComponent(FactionAffiliationComponent));
398 if (factionComponent)
399 {
400 Faction faction = factionComponent.GetAffiliatedFaction();
401 if (faction)
402 groupScripted.InitFactionKey(faction.GetFactionKey());
403 }
404 }
405 }
406
407 //~ Add the entity to the group
408 group.AddAgent(agentControlComponent.GetControlAIAgent());
409
410 return spawnedCharacter;
412
413 //------------------------------------------------------------------------------------------------
418
419 //------------------------------------------------------------------------------------------------
424
425 //------------------------------------------------------------------------------------------------
430
431 //------------------------------------------------------------------------------------------------
436
437 //------------------------------------------------------------------------------------------------
442
443 //------------------------------------------------------------------------------------------------
448
449 //------------------------------------------------------------------------------------------------
451 {
453 }
454}
455
456[BaseContainerProps(), BaseContainerCustomTitleField("m_sDefaultOccupantPrefab")]
457class SCR_DefaultOccupantData
458{
459 [Attribute(desc: "Default Prefab of character to be spawned into compartment", params: "et")]
460 protected ResourceName m_sDefaultOccupantPrefab;
461
462 [Attribute("1", desc: "This entry will be considered empty and is ignored if flase")]
463 protected bool m_bEnabled;
464
466 {
467 return m_sDefaultOccupantPrefab;
468 }
469
470 bool IsValid()
471 {
472 return m_bEnabled && !m_sDefaultOccupantPrefab.IsEmpty();
473 }
474}
475
476[BaseContainerProps(configRoot: true)]
478{
479 //ScreenShake parameters
480 [Attribute(defvalue: "0.05", desc: "Screen shake effect fade in duration")]
481 protected float m_fInTime;
482
483 [Attribute(defvalue: "0.05", desc: "Screen shake effect peak intensity sustain duration")]
484 protected float m_fSustainTime;
485
486 [Attribute(defvalue: "0.01", desc: "Screen shake effect fade out duration")]
487 protected float m_fOutTime;
488
489 [Attribute(defvalue: "0.5", desc: "At this health (scaled) the maximum shake effect will occur")]
491
492 [Attribute(defvalue: "7", desc: "Magnitude of linear (positional change) shake")]
493 protected float m_fLinearMagnitude;
494
495 [Attribute(defvalue: "5", desc: "Magnitude of angular (rotational change) shake")]
496 protected float m_fAngularMagnitude;
497
498 void GetScreenShakeData(out float inTime, out float sustainTime, out float outTime, out float maxScreenShakeHealthThreshold, out float linearMagnitude, out float angularMagnitude)
499 {
500 inTime = m_fInTime;
501 sustainTime = m_fSustainTime;
502 outTime = m_fOutTime;
503 maxScreenShakeHealthThreshold = m_fMaxScreenShakeHealthThreshold;
504 linearMagnitude = m_fLinearMagnitude;
505 angularMagnitude = m_fAngularMagnitude;
506 }
507}
BaseCompartmentSlot ExtBaseCompartmentSlot BaseContainerCustomTitleField("m_sDefaultOccupantPrefab")
ResourceName GetDefaultOccupantPrefab(bool checkIfValid=true)
BaseCompartmentSlot ExtBaseCompartmentSlot BaseContainerProps()
ECompartmentType
ArmaReforgerScripted GetGame()
Definition game.c:1398
override EGadgetType GetType()
ECharacterDamageState
override SCR_EditorManagerEntity GetManager()
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
static const vector SPAWN_IN_VEHICLE_OFFSET
SCR_DefaultOccupantData GetDefaultOccupantData()
override void DebugDrawPosition()
ResourceName GetDefaultOccupantPrefab(bool checkIfValid=true)
ref SCR_BaseScreenShakeData m_ScreenShakeData
IEntity SpawnCharacterInCompartment(ResourceName characterPrefab, inout AIGroup group, ResourceName groupPrefab="{000CD338713F2B5A}Prefabs/AI/Groups/Group_Base.et")
IEntity SpawnDefaultCharacterInCompartment(inout AIGroup group, ResourceName groupPrefab="{000CD338713F2B5A}Prefabs/AI/Groups/Group_Base.et")
void KillOccupant(notnull Instigator instigator, bool eject=false, bool gettingIn=false, bool gettingOut=false)
float GetFreelookCameraNeckFollowTraverse()
IEntity GetVehicle(out int compartmentID)
void SetCompartmentAccessible(bool val)
void DamageOccupant(float damage, EDamageType damageType, notnull Instigator instigator, bool damageWhileGetIn=true, bool damageWhileGetOut=true)
bool EjectOccupant(bool forceEject=false, bool ejectUnconsciously=false, out bool ejectedImmediately=false, bool ejectOnTheSpot=false)
ref SCR_DefaultOccupantData m_DefaultOccupantData
vector GetFreelookCameraNeckOffsetScale()
int GetCompartmentSection()
Switching seats is allowed only between compartments with matching area.
void ScreenShakeOccupant(float damage)
Definition Color.c:13
proto external Managed FindComponent(typename typeName)
proto external void GetTransform(out vector mat[])
proto external IEntity GetParent()
Definition Math.c:13
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
bool InitFactionKey(string factionKey)
void GetScreenShakeData(out float inTime, out float sustainTime, out float outTime, out float maxScreenShakeHealthThreshold, out float linearMagnitude, out float angularMagnitude)
void AskOwnerToGetOutFromVehicle(EGetOutType type, int doorInfoIndex, ECloseDoorAfterActions closeDoor, bool performWhenPaused, bool ejectOnTheSpot=false)
static ResourceName GetRandomVariant(ResourceName prefab)
static IEntity GetLocalControlledEntity()
Instance of created debug visualizer.
Definition Shape.c:14
void EntitySpawnParams()
Definition gameLib.c:130
IEntity GetOwner()
Owner entity of the fuel tank.
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
ShapeFlags
Definition ShapeFlags.c:13
SCR_FieldOfViewSettings Attribute
EDamageType
Definition EDamageType.c:13
proto native vector Vector(float x, float y, float z)
ECloseDoorAfterActions
EGetOutType
Definition EGetOutType.c:13