Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_BaseCompartmentManagerComponent.c
Go to the documentation of this file.
2{
3 [Attribute("0", desc: "Will block supply actions if one or more compartments are occupied as well as blocking player get in actions if there are supplies. This is a hotfix until proper solution as it simply disables some player actions on the surface rather than with proper logic and does not effect AI")]
5
6 //------------------------------------------------------------------------------------------------
11}
12
13class SCR_BaseCompartmentManagerComponent : BaseCompartmentManagerComponent
14{
15 //Compartment slots associated with crew
16 static const ref array<ECompartmentType> CREW_COMPARTMENT_TYPES = {ECompartmentType.PILOT, ECompartmentType.TURRET};
17
18 //Compartment slots associated with passengers
19 static const ref array<ECompartmentType> PASSENGER_COMPARTMENT_TYPES = {ECompartmentType.CARGO};
20
21 //~ Default Occupant spawning
22 protected ref array<BaseCompartmentSlot> m_aCompartmentsToSpawnDefaultOccupant;
23 protected ref array<IEntity> m_aSpawnedDefaultOccupants;
24 protected AIGroup m_SpawnedOccupantsAIGroup;
26 protected ref ScriptInvoker Event_OnDoneSpawningDefaultOccupants; //~ Send over SCR_BaseCompartmentManagerComponent, array of spawned characters (IEntity) as well as bool WasCanceled
27 protected ref array<ref array<ECompartmentType>> m_aDefaultOccupantsCompartmentTypesToSpawn = {}; //~ Keeps track of the default occupants types that need to be spawned. The types grouped together will be spawned in the same group
28
29 //------------------------------------------------------------------------------------------------
33 {
35 if (!data)
36 return false;
37
38 return data.ShouldBlockSuppliesIfOccupied();
39 }
40
41 //------------------------------------------------------------------------------------------------
45 void GetCompartmentsOfType(inout array<BaseCompartmentSlot> outCompartments, ECompartmentType compartmentType)
46 {
47 array<BaseCompartmentSlot> compartments = {}; GetCompartments(compartments);
48 foreach (BaseCompartmentSlot compartment: compartments)
49 {
50 if (compartment && compartment.GetType() == compartmentType)
51 outCompartments.Insert(compartment);
52 }
53 }
54
55 //------------------------------------------------------------------------------------------------
58 void GetCompartmentsOfTypes(inout array<BaseCompartmentSlot> outCompartments, notnull array<ECompartmentType> compartmentTypes)
59 {
60 outCompartments.Clear();
61 array<BaseCompartmentSlot> compartments = {};
62 GetCompartments(compartments);
63
64 foreach (BaseCompartmentSlot compartment: compartments)
65 {
66 if (compartment && compartmentTypes.Contains(compartment.GetType()))
67 outCompartments.Insert(compartment);
68 }
69 }
70
71 //------------------------------------------------------------------------------------------------
76 void GetFreeCompartmentsOfType(inout array<BaseCompartmentSlot> outCompartments, ECompartmentType compartmentType, bool checkHasValidOccupantPrefab = false)
77 {
78 array<BaseCompartmentSlot> compartments = {}; GetCompartments(compartments);
79 foreach (BaseCompartmentSlot compartment: compartments)
80 {
81 if (compartment && compartment.GetType() == compartmentType && !compartment.IsOccupied() && compartment.IsCompartmentAccessible() && (!checkHasValidOccupantPrefab || (checkHasValidOccupantPrefab && !compartment.GetDefaultOccupantPrefab().IsEmpty())))
82 outCompartments.Insert(compartment);
83 }
84 }
85
86 //------------------------------------------------------------------------------------------------
91 BaseCompartmentSlot GetFirstFreeCompartmentOfType(ECompartmentType compartmentType, bool checkHasValidOccupantPrefab = false)
92 {
93 array<BaseCompartmentSlot> compartments = {}; GetCompartments(compartments);
94 foreach (BaseCompartmentSlot compartment: compartments)
95 {
96 if (compartment && compartment.GetType() == compartmentType && !compartment.IsOccupied() && compartment.IsCompartmentAccessible() && (!checkHasValidOccupantPrefab || (checkHasValidOccupantPrefab && !compartment.GetDefaultOccupantPrefab().IsEmpty())))
97 return compartment;
98 }
99
100 return null;
101 }
102
103 //------------------------------------------------------------------------------------------------
108 BaseCompartmentSlot GetFirstFreeCompartmentOfType(typename compartmentClass, bool checkHasValidOccupantPrefab = false)
109 {
110 array<BaseCompartmentSlot> compartments = {};
111 GetCompartments(compartments);
112
113 foreach (BaseCompartmentSlot compartment: compartments)
114 {
115 if (compartment.Type() != compartmentClass)
116 continue;
117
118 if (!compartment.IsOccupied() && compartment.IsCompartmentAccessible() && (!checkHasValidOccupantPrefab || !compartment.GetDefaultOccupantPrefab().IsEmpty()))
119 return compartment;
120 }
121
122 return null;
123 }
124
125 //------------------------------------------------------------------------------------------------
129 bool HasFreeCompartmentOfTypes(notnull array<ECompartmentType> compartmentTypes)
130 {
131 array<BaseCompartmentSlot> compartments = {};
132
133 foreach (ECompartmentType type: compartmentTypes)
134 {
135 compartments.Clear();
136 GetCompartmentsOfType(compartments, type);
137
138 foreach (BaseCompartmentSlot compartment: compartments)
139 {
140 if (!compartment.IsOccupied() && compartment.IsCompartmentAccessible())
141 return true;
142 }
143 }
144
145 return false;
146 }
147
148 //------------------------------------------------------------------------------------------------
151 {
152 array<IEntity> occupants = {};
153 GetOccupants(occupants);
154
155 return occupants.Count();
156 }
157
158 //------------------------------------------------------------------------------------------------
161 void GetOccupants(inout array<IEntity> occupants)
162 {
163 array<BaseCompartmentSlot> compartments = {}; GetCompartments(compartments);
164 IEntity occupant;
165 foreach (BaseCompartmentSlot compartment: compartments)
166 {
167 occupant = compartment.GetOccupant();
168 if (occupant)
169 occupants.Insert(occupant);
170 }
171 }
172
173 //------------------------------------------------------------------------------------------------
177 void GetOccupantsOfType(inout array<IEntity> occupants, ECompartmentType compartmentType)
178 {
179 array<BaseCompartmentSlot> compartments = {}; GetCompartmentsOfType(compartments, compartmentType);
180 IEntity occupant;
181 foreach (BaseCompartmentSlot compartment: compartments)
182 {
183 occupant = compartment.GetOccupant();
184 if (occupant)
185 occupants.Insert(occupant);
186 }
187 }
188
189 //------------------------------------------------------------------------------------------------
196 void DamageOccupants(float damage, EDamageType damageType, notnull Instigator instigator, bool damageWhileGetIn = false, bool damageWhileGetOut = false)
197 {
198 if (damage == 0)
199 return;
200
201 array<BaseCompartmentSlot> compartments = {};
202 GetCompartments(compartments);
203
204 foreach (BaseCompartmentSlot compartment: compartments)
205 {
206 if (compartment)
207 {
208 compartment.DamageOccupant(damage, damageType, instigator, damageWhileGetIn, damageWhileGetOut);
209 if (damageType == EDamageType.COLLISION)
210 compartment.ScreenShakeOccupant(damage);
211 }
212 }
213 }
214
215 //------------------------------------------------------------------------------------------------
221 void KillOccupants(notnull Instigator instigator, bool eject = false, bool gettingIn = false, bool gettingOut = false)
222 {
223 array<BaseCompartmentSlot> compartments = {};
224 GetCompartments(compartments);
225
226 foreach (BaseCompartmentSlot compartment : compartments)
227 {
228 if (compartment)
229 compartment.KillOccupant(instigator, eject, gettingIn, gettingOut);
230 }
231 }
232
233 //------------------------------------------------------------------------------------------------
240 bool EjectRandomOccupants(float ejectionChance = -1, bool ejectUnconscious = false, out bool allEjectedImmediately = true, bool ejectOnTheSpot = false)
241 {
242 array<BaseCompartmentSlot> compartments = {};
243 GetCompartments(compartments);
244
245 bool characterEjected;
246 bool ejectedImmediately;
247 allEjectedImmediately = true;
248 foreach (BaseCompartmentSlot compartment : compartments)
249 {
250 // if ejectionChance is <0, eject if random > compartmentChance
251 float random = Math.RandomFloat01();
252 if (ejectionChance < 0)
253 {
254 if (random > compartment.GetRandomEjectionChance())
255 continue;
256 }// if ejectionChance is 0>&&<1, eject if random > ejectionChance
257 else if (ejectionChance > 0 && ejectionChance < 1)
258 {
259 if (random > ejectionChance)
260 continue;
261 }
262 // else if (ejectionChance == 1) force eject
263 if (compartment)
264 {
265 characterEjected = compartment.EjectOccupant(ejectionChance == 1, ejectUnconscious, ejectedImmediately, ejectOnTheSpot) || characterEjected;
266 allEjectedImmediately = allEjectedImmediately && ejectedImmediately;
267 }
268 }
269
270 return characterEjected;
271 }
272
273 //------------------------------------------------------------------------------------------------
276 void SetCompartmentsAccessibleForAI(bool accessible)
277 {
278 array<BaseCompartmentSlot> compartments = {};
279 GetCompartments(compartments);
280
281 foreach (BaseCompartmentSlot compartment: compartments)
282 compartment.SetCompartmentAccessible(accessible);
283 }
284
285 //------------------------------------------------------------------------------------------------
296
297 //------------------------------------------------------------------------------------------------
301 void SetAllCompartmentsAccessibleOfTypes(notnull array<ECompartmentType> compartmentTypes, bool setAccessible)
302 {
303 array<BaseCompartmentSlot> compartments = {};
304 GetCompartmentsOfTypes(compartments, compartmentTypes);
305
306 foreach(BaseCompartmentSlot compartment: compartments)
307 {
308 compartment.SetCompartmentAccessible(setAccessible);
309 }
310 }
311
312 //--------------------------------------------------- Check can occupy with characters ---------------------------------------------------\\
313
314 //------------------------------------------------------------------------------------------------
325 bool CanOccupy(array<ECompartmentType> compartmentTypes, bool checkHasDefaultOccupantsData = true, FactionKey friendlyFaction = string.Empty, bool checkOccupyingFaction = true, bool checkForFreeCompartments = true)
326 {
328 return false;
329
330 //~ Check if default character data is defined
331 if (checkHasDefaultOccupantsData && !HasDefaultOccupantsDataForTypes(compartmentTypes))
332 return false;
333
334 //~ Check if all occupants in vehicle are friendly. If not return false
335 if (checkOccupyingFaction && !IsOccupiedByFriendlies(friendlyFaction, true))
336 return false;
337
338 //~ Check if there is at least one free compartment. If not return false
339 if (checkForFreeCompartments && !HasFreeCompartmentOfTypes(compartmentTypes))
340 return false;
341
342 return true;
343 }
344
345 //--------------------------------------------------- Spawn default occupants ---------------------------------------------------\\
346
347 //------------------------------------------------------------------------------------------------
354 bool SpawnDefaultOccupants(notnull array<ECompartmentType> compartmentTypes)
355 {
356 //~ No compartment types given to spawn
357 if (compartmentTypes.IsEmpty())
358 {
360 Event_OnDoneSpawningDefaultOccupants.Invoke(this, null, true);
361
362 return false;
363 }
364
365 //~ Check if is already spawning
366 for(int i = 0; i < m_aDefaultOccupantsCompartmentTypesToSpawn.Count(); i++)
367 {
369 {
371 i--;
372 continue;
373 }
374
375 foreach(ECompartmentType type: compartmentTypes)
376 {
377 //~ Is already spawning the same type
379 {
380 Print(string.Format("'SCR_BaseCompartmentManagerComponent' is already spawning default occupants of type %1!", typename.EnumToString(ECompartmentType, type)), LogLevel.WARNING);
381 return false;
382 }
383 }
384 }
385
386 //~ Add to spawn list
387 m_aDefaultOccupantsCompartmentTypesToSpawn.Insert(compartmentTypes);
388
389 //~ Directly spawn in vehicle as not currently spawning anything
391 {
392 return InitiateSpawnDefaultOccupants(compartmentTypes);
393 }
394 //~ Already spawning so wait until done
395 else
396 {
398 foreach (ECompartmentType compartmentType: compartmentTypes)
399 {
401 }
402
403 //~ Nothing to spawn in so cancel
405 return false;
406 }
407
408 return true;
409 }
410
411 //~ Actually initia
412 protected bool InitiateSpawnDefaultOccupants(notnull array<ECompartmentType> compartmentTypes)
413 {
416
417 foreach (ECompartmentType compartmentType: compartmentTypes)
418 {
420 }
421
422 //~ Nothing to spawn in so cancel
424 {
426 return false;
427 }
428
431
432 GetGame().GetCallqueue().CallLater(SpawnDefaultOccupantEachFrame, 0, true);
433 return true;
434 }
435
436 //~ Spawns a character each frame to take the load of the server
438 {
439 BaseCompartmentSlot compartmentToFill = null;
440
441 for(int i = 0; i < m_aCompartmentsToSpawnDefaultOccupant.Count(); i++)
442 {
443 //~ Invalid compartment so remove it from the list
445 {
447 i--;
448 continue;
449 }
450
451 compartmentToFill = m_aCompartmentsToSpawnDefaultOccupant[i];
453 break;
454 }
455
456 //~ No compartments found
457 if (!compartmentToFill)
458 {
460 return;
461 }
462
463 IEntity spawnedCharacter = compartmentToFill.SpawnDefaultCharacterInCompartment(m_SpawnedOccupantsAIGroup);
464 if (!spawnedCharacter)
465 return;
466
467
468 m_aSpawnedDefaultOccupants.Insert(spawnedCharacter);
469
472 }
473
474 //------------------------------------------------------------------------------------------------
481
482 //------------------------------------------------------------------------------------------------
488
489 //~ Called when finished spawning. Note that it will spawn more passengers if it has a queue
490 protected void FinishedSpawningDefaultOccupants(bool wasCanceled)
491 {
493 SCR_CompartmentAccessComponent compartmentAccess;
494
497
500 GetGame().GetCallqueue().Remove(SpawnDefaultOccupantEachFrame);
501
502 //~ Clear queue
503 if (wasCanceled)
504 {
506 }
507 //~ next in queue
508 else
509 {
510 //~ Delete the one just spawned
512 //~ Spawn the entities that where waiting to be spawned
515 }
516 }
517
518 //--------------------------------------------------- Vehicle occupied by friendly ---------------------------------------------------\\
519
520 //------------------------------------------------------------------------------------------------
526 bool IsOccupiedByFriendlies(FactionKey vehicleFactionKey, bool allFriendly, bool trueIfEmpty = true)
527 {
528 //~ No given string so cannot check
529 if (vehicleFactionKey.IsEmpty())
530 return false;
531
532 array<BaseCompartmentSlot> compartments = {};
533 GetCompartments(compartments);
534
535 if (compartments.IsEmpty())
536 return false;
537
538 //~ No faction manager so return false
539 SCR_FactionManager factionManager = SCR_FactionManager.Cast(GetGame().GetFactionManager());
540 if (!factionManager)
541 return false;
542
543 IEntity occupant;
544 FactionAffiliationComponent factionAffiliationComponent;
545 Faction occupantFaction;
546 Faction vehicleFaction = factionManager.GetFactionByKey(vehicleFactionKey);
547 bool friendlyFound = false;
548 bool occupantFound = false;
549
550 //~ Go over each compartment and see if it is occupied and if the enetity is an enemy or neutral to the given faction
551 foreach (BaseCompartmentSlot compartment: compartments)
552 {
553 occupant = compartment.GetOccupant();
554
555 if (!occupant)
556 continue;
557
558 occupantFound = true;
559
560 factionAffiliationComponent = FactionAffiliationComponent.Cast(occupant.FindComponent(FactionAffiliationComponent));
561 if (!factionAffiliationComponent)
562 continue;
563
564 occupantFaction = factionAffiliationComponent.GetAffiliatedFaction();
565
566 //~ Same faction so is friendly
567 if (occupantFaction.GetFactionKey() == vehicleFactionKey)
568 return true;
569
570 //~ Occupent is friendly
571 if (vehicleFaction.IsFactionFriendly(occupantFaction))
572 {
573 if (allFriendly)
574 friendlyFound = true;
575 else
576 return true;
577 }
578 //~ Occupent is not friendly!
579 else
580 {
581 return false;
582 }
583 }
584
585 //~ No occupants found
586 if (!occupantFound)
587 return trueIfEmpty;
588
589 //~ Multiple occupants found check if all must be friendly
590 if (allFriendly)
591 return friendlyFound;
592
593 return false;
594 }
595
596 //------------------------------------------------------------------------------------------------
599 {
600 //~ If vehicle check if it is occupied
601 array<IEntity> occupants = {};
602 GetOccupants(occupants);
603
604 //~ Entity is occupied by characters
605 if (!occupants.IsEmpty())
606 return true;
607
608 array<BaseCompartmentSlot> compartments = {};
609 GetCompartments(compartments);
610
611 foreach (BaseCompartmentSlot compartment : compartments)
612 {
613 if (!compartment)
614 continue;
615
616 //~ Vehicle currently has a locked compartment so is in use
617 if (compartment.IsGetInLocked())
618 return true;
619 }
620
621 return false;
622 }
623
624 //--------------------------------------------------- Has default occupent data set of type ---------------------------------------------------\\
625
626 //------------------------------------------------------------------------------------------------
630 bool HasDefaultOccupantsDataForTypes(array<ECompartmentType> compartmentTypes)
631 {
632 array<BaseCompartmentSlot> compartments = new array<BaseCompartmentSlot>;
633 SCR_DefaultOccupantData defaultOccupantData;
634
635 foreach (ECompartmentType compartmentType: compartmentTypes)
636 {
637 compartments.Clear();
638 GetCompartmentsOfType(compartments, compartmentType);
639
640 foreach (BaseCompartmentSlot compartment: compartments)
641 {
642 defaultOccupantData = compartment.GetDefaultOccupantData();
643
644 if (defaultOccupantData && defaultOccupantData.IsValid())
645 return true;
646 }
647 }
648 return false;
649 }
650
651 //------------------------------------------------------------------------------------------------
652 // destructor
654 {
655 //~ Component destroyed before it could finish spawning all characters
658 }
659}
bool IsCompartmentAccessible()
ECompartmentType
ArmaReforgerScripted GetGame()
Definition game.c:1398
ref array< BaseCompartmentSlot > m_aCompartmentsToSpawnDefaultOccupant
BaseCompartmentSlot GetFirstFreeCompartmentOfType(ECompartmentType compartmentType, bool checkHasValidOccupantPrefab=false)
bool InitiateSpawnDefaultOccupants(notnull array< ECompartmentType > compartmentTypes)
ref ScriptInvoker Event_OnDoneSpawningDefaultOccupants
void DamageOccupants(float damage, EDamageType damageType, notnull Instigator instigator, bool damageWhileGetIn=false, bool damageWhileGetOut=false)
bool CanOccupy(array< ECompartmentType > compartmentTypes, bool checkHasDefaultOccupantsData=true, FactionKey friendlyFaction=string.Empty, bool checkOccupyingFaction=true, bool checkForFreeCompartments=true)
void GetOccupantsOfType(inout array< IEntity > occupants, ECompartmentType compartmentType)
ref array< ref array< ECompartmentType > > m_aDefaultOccupantsCompartmentTypesToSpawn
void ~SCR_BaseCompartmentManagerComponent()
void CancelSpawningCharacters()
Cancel spawning if in progress.
bool SpawnDefaultOccupants(notnull array< ECompartmentType > compartmentTypes)
bool IsOccupiedByFriendlies(FactionKey vehicleFactionKey, bool allFriendly, bool trueIfEmpty=true)
void SpawnDefaultOccupantEachFrame()
SCR_BaseCompartmentManagerComponentClass CREW_COMPARTMENT_TYPES
bool AnyCompartmentsOccupiedOrLocked()
bool HasDefaultOccupantsDataForTypes(array< ECompartmentType > compartmentTypes)
void GetFreeCompartmentsOfType(inout array< BaseCompartmentSlot > outCompartments, ECompartmentType compartmentType, bool checkHasValidOccupantPrefab=false)
void GetCompartmentsOfTypes(inout array< BaseCompartmentSlot > outCompartments, notnull array< ECompartmentType > compartmentTypes)
void KillOccupants(notnull Instigator instigator, bool eject=false, bool gettingIn=false, bool gettingOut=false)
bool EjectRandomOccupants(float ejectionChance=-1, bool ejectUnconscious=false, out bool allEjectedImmediately=true, bool ejectOnTheSpot=false)
void GetOccupants(inout array< IEntity > occupants)
void SetAllCompartmentsAccessibleOfTypes(notnull array< ECompartmentType > compartmentTypes, bool setAccessible)
ref array< IEntity > m_aSpawnedDefaultOccupants
void FinishedSpawningDefaultOccupants(bool wasCanceled)
AIGroup m_SpawnedOccupantsAIGroup
ScriptInvoker GetOnDoneSpawningDefaultOccupants()
void GetCompartmentsOfType(inout array< BaseCompartmentSlot > outCompartments, ECompartmentType compartmentType)
void SetCompartmentsAccessibleForAI(bool accessible)
bool HasFreeCompartmentOfTypes(notnull array< ECompartmentType > compartmentTypes)
SCR_CharacterSoundComponentClass GetComponentData()
EDamageType type
Get all prefabs that have the spawner data
bool IsOccupied()
Returns true, if slot is occupied.
void SCR_FactionManager(IEntitySource src, IEntity parent)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
IEntity SpawnDefaultCharacterInCompartment(inout AIGroup group, ResourceName groupPrefab="{000CD338713F2B5A}Prefabs/AI/Groups/Group_Base.et")
proto external Managed FindComponent(typename typeName)
Definition Math.c:13
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
SCR_FieldOfViewSettings Attribute
EDamageType
Definition EDamageType.c:13
proto bool Contains(T value)
proto native bool IsEmpty()
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134