Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_BaseSupportStationComponent.c
Go to the documentation of this file.
1[ComponentEditorProps(category: "GameScripted/SupportStation", description: "")]
3{
4 [Attribute("0", desc: "If false then the object has no physics to move itself. If true it means the entity is a vehicle (or part of a vehicle) and it can be moved via physics which means it checks the rigid body if it has a velocity and does not allow to be used if it has", category: "General Settings")]
5 protected bool m_bIsVehicle;
6
7 [Attribute("1", desc: "If true it will send out a notification if the user uses it. The Inherented class does need to support notifications for it to be send", category: "Specific Settings")]
9
10 [Attribute("0", desc: "If true it allows the support station to get the 'FactionAffiliationComponent' from parent. This is only done when no 'FactionAffiliationComponent' is found on self and main use case is for vehicle compartments. Only used if 'FactionUsageCheck' is set", category: "Faction Settings")]
12
13 [Attribute("{9DD9C6279F4489B4}Sounds/Editor/SupportStations/SupportStations_Vehicles.acp", desc: "File that contains the sound effect", params: "acp", category: "On use Audio")]
15
16 [Attribute(desc: "Sound effect played when executing is done. Broadcast to players. Leave empty if no sfx", category: "On use Audio")]
18
19 [Attribute(desc: "Sound played from from user on successfully action. (Some support station might play action on action owner instead of user). Leave empty to not play any voice effects", category: "On use Audio")]
22 [Attribute("40", desc: "Priority of voice played on use", params: "0 inf 1", category: "On use Audio")]
24
25 protected ref SCR_AudioSourceConfiguration m_OnUseAudioSourceConfiguration;
27 //------------------------------------------------------------------------------------------------
35 //------------------------------------------------------------------------------------------------
39 {
40 return m_bIsVehicle;
41 }
42
43 //------------------------------------------------------------------------------------------------
51
52 //------------------------------------------------------------------------------------------------
56 SCR_AudioSourceConfiguration GetOnUseAudioConfig()
57 {
58 //~ Create Audio source if it does not yet exist
61
63 }
64
65 //------------------------------------------------------------------------------------------------
69 SCR_AudioSourceConfiguration CreateOnUseAudioConfig(ResourceName soundFile, string soundEvent)
70 {
72 return null;
73
74 SCR_AudioSourceConfiguration soundConfig = new SCR_AudioSourceConfiguration();
75 soundConfig.m_sSoundProject = soundFile;
76 soundConfig.m_sSoundEventName = soundEvent;
77
78 if (!CanMoveWithPhysics())
79 soundConfig.m_eFlags = SCR_Enum.SetFlag(soundConfig.m_eFlags, EAudioSourceConfigurationFlag.Static);
80 else
81 soundConfig.m_eFlags = SCR_Enum.RemoveFlag(soundConfig.m_eFlags, EAudioSourceConfigurationFlag.Static);
82
83 return soundConfig;
84 }
85
86 //------------------------------------------------------------------------------------------------
90 void GetCharacterVoiceSoundEventVariables(out string characterVoiceEventOnUse, out int characterVoicePriority)
91 {
92 characterVoiceEventOnUse = m_sCharacterVoiceEventOnUse;
93 characterVoicePriority = m_iCharacterVoicePriority;
94 }
95}
96
97class SCR_BaseSupportStationComponent : ScriptComponent
98{
99 [Attribute("0", desc: "Priority dictates the array order when trying to get the first availible support station. Higher priority means it is closer to the start of the array. Think of grabbing a composition refuel station before a vehicle refuel station.", uiwidget: UIWidgets.SearchComboBox, enums: ParamEnumArray.FromEnum(ESupportStationPriority), category: "General Settings")]
100 protected ESupportStationPriority m_eSupportStationPriority;
101
102 [Attribute("7", desc: "In meters, Range in which the entity which the player interacts is needs to be. If -1 it will not add itself to the Support Station Manager and can only be used by the action manager that is also a component of the entity this component is part of, note that the action manager will also never check if any are around it only the component on the entity.", category: "General Settings")]
103 protected float m_fRange;
104
105 [Attribute("0", desc: "If using range and this is set to true it will use the bounding box of the entity on which the support station action is to check if in range. Otherwise will use the Action position.", category: "General Settings")]
107
108 [Attribute("1", desc: "Enable/disable the supply Station.", category: "General Settings")]
109 protected bool m_bIsEnabled;
110
111 [Attribute("0", desc: "When executing the action and isUsingSupplies this is the base supply cost of the action regardless of any additional supply costs. 0 to have no upfront cost (note inherented classes might still have their own supply cost calculation)", params: "0 inf 1", category: "Supplies")]
113
114 [Attribute("0", desc: "If Supply station has range it can ignore itself. If you set this false it will also grab itself when looking for stations in range. Think of a fuel tank able to refuel itself. If this is true it cannot if this is false it can. Not that compartments on vehicles are seen as seperate. So a fuel provider cannot refuel itself but it can still refuel the truck for driving", category: "Specific Settings")]
115 protected bool m_bIgnoreSelf;
116
117 [Attribute(desc: "Offset of the center of the support station. Note the Area Mesh zone will only visualise this correctly on runtime not in workbench", uiwidget: UIWidgets.Coords, params: "inf inf 0 purpose=coords space=entity", category: "Specific Settings")]
118 protected vector m_vOffset;
119
120 [Attribute(desc: "Set faction of user that can use Support Station, will be ignored if non are selected. Requires a 'FactionAffiliationComponent' on the Support Station or (or 'AllowGetFactionFromParent' is true on vehicle compartments). It will always allow interaction if user does not have 'FactionAffiliationComponent'. Default faction is the faction associated with the Initial Support Station faction. Flags are checked in order. DISALLOW ON null is only checked when Default faction check is not set.", uiwidget: UIWidgets.Flags, enums: ParamEnumArray.FromEnum(ESupportStationFactionUsage), category: "Faction Settings")]
122
123 [Attribute(desc: "Action name when executing the action. Note that if this is left empty then the default ActionManager action name is used", category: "General Settings")]
125
126 protected SCR_ResourceConsumer m_ResourceConsumer;
128
129 //~ Will send bool over if enabled or not
131
132 //Refs
135 protected FactionAffiliationComponent m_FactionAffiliationComponent;
136 protected SCR_ServicePointComponent m_ServicePointComponent;
137 //~ if the handler exists than supplies are synced with server
139
140 //======================================== EXECUTE ========================================\\
141 //------------------------------------------------------------------------------------------------
147 void OnExecutedServer(notnull IEntity actionOwner, notnull IEntity actionUser, notnull SCR_BaseUseSupportStationAction action)
148 {
149 RplId ownerId;
150 RplId userId;
151 int playerId;
152
153 FindEntityIds(actionOwner, actionUser, ownerId, userId, playerId);
154
155 OnExecute(actionOwner, actionUser, playerId, action);
156 Rpc(OnExecuteBroadcast, ownerId, userId, playerId, action.GetActionID());
157 }
158
159 //------------------------------------------------------------------------------------------------
160 //~ Get ids for replication
161 protected void FindEntityIds(IEntity owner, IEntity user, out RplId ownerId, out RplId userId, out int playerId)
162 {
163 if (owner)
164 {
165 ownerId = Replication.FindItemId(owner.FindComponent(RplComponent));
166
167 if (ownerId == Replication.INVALID_ID)
168 {
169 IEntity parent = owner.GetParent();
170 if (parent)
171 ownerId = Replication.FindItemId(parent.FindComponent(RplComponent));
172 }
173 }
174
175 if (user)
176 userId = Replication.FindItemId(user.FindComponent(RplComponent));
177
178 PlayerManager playerManager = GetGame().GetPlayerManager();
179 if (playerManager)
180 playerId = playerManager.GetPlayerIdFromControlledEntity(user);
181 }
182
183 //------------------------------------------------------------------------------------------------
184 protected void GetEntitiesFromID(RplId ownerId, RplId userId, out IEntity owner, out IEntity user)
185 {
186 RplComponent rpl = RplComponent.Cast(Replication.FindItem(ownerId));
187 if (rpl)
188 owner = rpl.GetEntity();
189
190 rpl = RplComponent.Cast(Replication.FindItem(userId));
191 if (rpl)
192 user = rpl.GetEntity();
193 }
194
195 //------------------------------------------------------------------------------------------------
196 //~ called by Server to convert ReplicationIDs to entities
197 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
198 protected void OnExecuteBroadcast(RplId ownerId, RplId userId, int userPlayerId, int actionId)
199 {
200 IEntity actionOwner, actionUser;
201 GetEntitiesFromID(ownerId, userId, actionOwner, actionUser);
202
203 //~ Get action
205 if (actionOwner)
206 {
208
209 if (actionManager)
210 action = SCR_BaseUseSupportStationAction.Cast(actionManager.FindAction(actionId));
211 }
212
213 OnExecute(actionOwner, actionUser, userPlayerId, action);
214 }
215
216 //------------------------------------------------------------------------------------------------
219 protected void OnExecute(IEntity actionOwner, IEntity actionUser, int playerId, SCR_BaseUseSupportStationAction action)
220 {
221 //~ On succesfully executed
222 OnSuccessfullyExecuted(actionOwner, actionUser, action);
223 }
224
225 //------------------------------------------------------------------------------------------------
226 //~ Support station was successfully executed. Called on server and client but only by inherited versions
227 protected void OnSuccessfullyExecuted(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action)
228 {
230 }
231
232 //======================================== AUDIO ========================================\\
233 //------------------------------------------------------------------------------------------------
234 //~ Play SoundEffect
235 protected void PlaySoundEffect(SCR_AudioSourceConfiguration audioConfig, notnull IEntity soundOwner, SCR_BaseUseSupportStationAction action)
236 {
237 //~ No audio given so ignore function. It might be that no event name or file name are assigned
238 if (!audioConfig || !soundOwner)
239 return;
240
241 //~ Get sound component
242 SoundComponent soundComponent = SoundComponent.Cast(soundOwner.FindComponent(SoundComponent));
243
244 //~ Has sound component. Play sound with that offset
245 if (soundComponent)
246 {
247 //~ Check if sound can be played. If true simply play the sound and return
248 if (soundComponent.GetEventIndex(audioConfig.m_sSoundEventName) > 0)
249 {
250 if (action)
251 {
252 vector mat[4] = {vector.Right, vector.Up, vector.Forward, action.GetWorldPositionAction()};
253 soundComponent.SetTransformation(mat); // this is necessary as otherwise sound system may use some old position, which might be far enough, that the sound is going to fail audibility test
254 soundComponent.SoundEventOffset(audioConfig.m_sSoundEventName, action.GetLocalPositionAction());
255 }
256 else
257 {
258 soundComponent.SoundEventOffset(audioConfig.m_sSoundEventName, audioConfig.m_vOffset);
259 }
260
261 return;
262 }
263 //~ Sound was not played
264 else
265 {
266 Print(string.Format("'SCR_BaseSupportStationComponent': Trying to play sound for '%1' but sound either sound event '%2' or more likely sound file '%3' is not included on the SoundComponent! SCR_SoundManagerModule is used instead but that means position of sound is not updated if entity moves while sound is playing.", soundOwner, audioConfig.m_sSoundEventName, audioConfig.m_sSoundProject), LogLevel.WARNING);
267 }
268 }
269
270 //~ No sound manager
271 SCR_SoundManagerModule soundManager = SCR_SoundManagerModule.GetInstance(soundOwner.GetWorld());
272 if (!soundManager)
273 return;
274
275 SCR_AudioSource audioSource;
276
277 if (action)
278 {
279 audioSource = soundManager.CreateAudioSource(soundOwner, audioConfig, action.GetWorldPositionAction());
280 }
281 else
282 {
283 audioSource = soundManager.CreateAudioSource(soundOwner, audioConfig);
284 }
285
286 //~ Play sound
287 if (!audioSource)
288 return;
289
290 soundManager.PlayAudioSource(audioSource);
291 }
292
293 //------------------------------------------------------------------------------------------------
294 //~ Place voice event for given character if any events are assigned is assigned
295 protected void PlayCharacterVoiceEvent(IEntity character)
296 {
297 if (!character)
298 return;
299
300 //~ Grab Communication sound component of character
302 if (!communicationSoundComponent)
303 return;
304
305 //~ Grab class data
307 if (!classData)
308 return;
309
310 string characterVoiceEventOnUse;
311 int characterVoicePriority;
312
313 //~ Get character voice variables
314 classData.GetCharacterVoiceSoundEventVariables(characterVoiceEventOnUse, characterVoicePriority);
315
316 //~ Check if voice has been assigned
317 if (!SCR_StringHelper.IsEmptyOrWhiteSpace(characterVoiceEventOnUse))
318 communicationSoundComponent.SoundEventPriority(characterVoiceEventOnUse, characterVoicePriority, true);
319 }
320
321 //======================================== IS VALID ========================================\\
322 //------------------------------------------------------------------------------------------------
332 bool IsValid(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action, vector actionPosition, out ESupportStationReasonInvalid reasonInvalid, out int supplyAmount)
333 {
334 //~ Check if enabled
335 if (!IsEnabled())
336 {
337 //~ Check if uses range and if it should ignore self and is self. In that case simply show not in range
338 if (UsesRange() && IgnoreSelf() && actionOwner == GetOwner())
339 reasonInvalid = ESupportStationReasonInvalid.NOT_IN_RANGE;
340 //~ Inform players if for example trying to repair a vehicle. If the support station is on the Action owner itself than the action will simply not show
341 else
342 reasonInvalid = ESupportStationReasonInvalid.DISABLED;
343
344 return false;
345 }
346
347 //~ If has service point and is not online show not in range
348 if (m_ServicePointComponent && m_ServicePointComponent.GetServiceState() != SCR_EServicePointStatus.ONLINE)
349 {
350 //~ Todo: Add various ESupportStationReasonInvalid for status such as BROKEN
351 reasonInvalid = ESupportStationReasonInvalid.NOT_IN_RANGE;
352 return false;
353 }
354
355 //~ Check if it should ignore itself. If so check if the action owner is itself
356 if (IgnoreSelf() && actionOwner == GetOwner())
357 {
358 reasonInvalid = ESupportStationReasonInvalid.NOT_IN_RANGE;
359 return false;
360 }
361
362 //~ If uses range check if the station is in range
363 if (UsesRange() && !IsInRange(actionOwner, actionPosition))
364 {
365 reasonInvalid = ESupportStationReasonInvalid.NOT_IN_RANGE;
366 return false;
367 }
368
369 //~ Check if Station is destroyed
370 if (m_eCurrentDamageState == EDamageState.DESTROYED)
371 {
372 reasonInvalid = ESupportStationReasonInvalid.DESTROYED_STATION;
373 return false;
374 }
375
376 //~ Check if station is a valid faction
377 if (!IsUserValidFaction(actionUser))
378 {
379 reasonInvalid = ESupportStationReasonInvalid.INVALID_FACTION;
380 return false;
381 }
382
383 //~ Check if it uses supplies
384 if (AreSuppliesEnabled())
385 {
386 //~ Set amount of supplies used on action
387 supplyAmount = GetSupplyAmountAction(actionOwner, actionUser, action);
388
389 //~ Action costs supplies
390 if (!HasSupplyGainInsteadOfCost(action))
391 {
392 //~ Check if there are enough supplies
393 if (!HasEnoughSupplies(actionOwner, actionUser, supplyAmount))
394 {
395 reasonInvalid = ESupportStationReasonInvalid.NO_SUPPLIES;
396 return false;
397 }
398 }
399 //~ Action generates supplies
400 else
401 {
402 if (!HasSpaceForSuppliesGeneration(actionOwner, actionUser, supplyAmount))
403 {
404 reasonInvalid = ESupportStationReasonInvalid.NO_SUPPLY_STORAGE_SPACE;
405 return false;
406 }
407 }
408 }
409 //~ No supplies used so set cost -1 so system knows not to display supply amount
410 else
411 {
412 supplyAmount = -1;
413 }
414
415 //~ Check if the support station is moving
416 if (IsMoving())
417 {
418 reasonInvalid = ESupportStationReasonInvalid.IS_MOVING;
419 return false;
420 }
421
422 return true;
423 }
424
425 //======================================== GETTERS / SETTERS ========================================\\
426 //---------------------------------------- Type ----------------------------------------\\
427 //------------------------------------------------------------------------------------------------
431 {
432 //~ OVERWRITE IN INHERIT CLASS
433 return ESupportStationType.NONE;
434 }
435
436 //---------------------------------------- Priority ----------------------------------------\\
437 //------------------------------------------------------------------------------------------------
441 {
442 return m_eSupportStationPriority;
443 }
444
445
446 //---------------------------------------- Enabled ----------------------------------------\\
447 //------------------------------------------------------------------------------------------------
450 void SetEnabled(bool enable)
451 {
452 if (m_bIsEnabled == enable)
453 return;
454
455 SetEnabledBroadcast(enable);
456 Rpc(SetEnabledBroadcast, enable);
457 }
458
459 //------------------------------------------------------------------------------------------------
460 [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
461 protected void SetEnabledBroadcast(bool enable)
462 {
463 if (m_bIsEnabled == enable)
464 return;
465
466 m_bIsEnabled = enable;
467
468 //~ Create and invoke onEnabledChanged
471
473
474 //~ Todo: Needs new mapmarker function and the map marker should have an inherented function that listens to the support station not the otherway around
475 //~ Set map marker active or not if any
476// SCR_CampaignServiceMapDescriptorComponent mapMarker = SCR_CampaignServiceMapDescriptorComponent.Cast(GetOwner().FindComponent(SCR_CampaignServiceMapDescriptorComponent));
477// if (mapMarker)
478// mapMarker.SetServiceMarkerActive(enable);
479 }
480
481 //------------------------------------------------------------------------------------------------
485 {
486 return m_bIsEnabled;
487 }
488
489 //------------------------------------------------------------------------------------------------
500
501 //------------------------------------------------------------------------------------------------
506 {
507 return false;
508 }
509
510 //---------------------------------------- IsMoving ----------------------------------------\\
511 //------------------------------------------------------------------------------------------------
512 protected bool IsMoving()
513 {
514 //~ If has physics assigned check if it is moving. Otherwise return false
515 if (!m_PhysicsVehicle)
516 return false;
517
518 Physics physics = m_PhysicsVehicle.GetPhysics();
519 if (!physics)
520 return false;
521
522 return physics.GetVelocity() != vector.Zero || physics.GetAngularVelocity() != vector.Zero;
523 }
524
525 //---------------------------------------- Faction Check ----------------------------------------\\
526 //------------------------------------------------------------------------------------------------
527 protected bool IsUserValidFaction(IEntity user)
528 {
529 //~ No Flags set so Ignore
530 if (m_eFactionUsageCheck == 0 || !user)
531 return true;
532
533 //~ Support station does not have a faction affiliation component so it is always valid
535 return true;
536
537 //~ Check if user has Faction affiliation. If no then user is considered neutral and always true
538 FactionAffiliationComponent userFactionAffiliation = FactionAffiliationComponent.Cast(user.FindComponent(FactionAffiliationComponent));
539 if (!userFactionAffiliation)
540 return true;
541
542 //~ Check if user has Faction. If no then user is considered neutral and always true
543 Faction userFaction = userFactionAffiliation.GetAffiliatedFaction();
544 if (!userFaction)
545 return true;
546
547 Faction supportStationFaction;
548
549 //~ Checks current faction
550 if (SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.SAME_CURRENT_FACTION) || SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.FRIENDLY_CURRENT_FACTION))
551 {
552 //~ Only check if has current faction
553 supportStationFaction = m_FactionAffiliationComponent.GetAffiliatedFaction();
554 if (supportStationFaction)
555 {
556 //~ If faction is the same
557 if (SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.SAME_CURRENT_FACTION) && supportStationFaction.GetFactionKey() == userFaction.GetFactionKey())
558 return true;
559
560 //~ If faction is friendly
561 if (SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.FRIENDLY_CURRENT_FACTION) && supportStationFaction.IsFactionFriendly(userFaction))
562 return true;
563
564 //~ Current faction exists but is not the same (or if friendly is checked and is not friendly)
565 return false;
566 }
567 }
568
569 //~ Checks default faction
570 if (SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.SAME_DEFAULT_FACTION) || SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.FRIENDLY_DEFAULT_FACTION))
571 {
572 //~ No default faction so return true
573 supportStationFaction = m_FactionAffiliationComponent.GetDefaultAffiliatedFaction();
574 if (!supportStationFaction)
575 return true;
576
577 //~ If default faction is the same
578 if (SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.SAME_DEFAULT_FACTION) && supportStationFaction.GetFactionKey() == userFaction.GetFactionKey())
579 return true;
580
581 //~ If default faction is friendly
582 if (SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.FRIENDLY_DEFAULT_FACTION) && supportStationFaction.IsFactionFriendly(userFaction))
583 return true;
584
585 //~ Default faction exists but is not the same (or if friendly is checked and is not friendly)
586 return false;
587 }
588
589 //~ Has no current faction and did not check Default faction. So check if it is allowed to be used neutral
590 return !SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.DISALLOW_USE_ON_CURRENT_FACTION_NULL);
591 }
592
593 //---------------------------------------- Faction Check ----------------------------------------\\
594 //------------------------------------------------------------------------------------------------
598 {
600 return null;
601
602 SCR_Faction faction = SCR_Faction.Cast(m_FactionAffiliationComponent.GetAffiliatedFaction());
603 if (faction)
604 return faction;
605
606 //~ If allow get default do that if no faction was found
607 if (!SCR_Enum.HasFlag(m_eFactionUsageCheck, ESupportStationFactionUsage.DISALLOW_USE_ON_CURRENT_FACTION_NULL))
608 faction = SCR_Faction.Cast(m_FactionAffiliationComponent.GetDefaultAffiliatedFaction());
609
610 return faction;
611 }
612
613 //======================================== SUPPLIES ========================================\\
614 //------------------------------------------------------------------------------------------------
618 protected int GetSupplyAmountAction(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action)
619 {
621 }
622
623 //------------------------------------------------------------------------------------------------
627 {
629 return int.MAX;
630
631 //~ Make sure to create or poke the consumer handler so server sends updates for clients
632 if (Replication.IsClient())
633 {
636 else
638 }
639 //~ Simply update if server
640 else
641 {
642 GetGame().GetResourceGrid().UpdateInteractor(m_ResourceConsumer);
643 }
644
645 return m_ResourceConsumer.GetAggregatedResourceValue();
646 }
647
648 //------------------------------------------------------------------------------------------------
649 //~ Check if enough supplies to execute the action
650 protected bool HasEnoughSupplies(IEntity actionOwner, IEntity actionUser, int supplyAmountToCheck)
651 {
652 if (supplyAmountToCheck <= 0 || !m_ResourceConsumer || !AreSuppliesEnabled())
653 return true;
654
655 //~ Make sure to create or poke the consumer handler so server sends updates for clients
656 if (Replication.IsClient())
657 {
660 else
662 }
663 //~ Simply update if server
664 else
665 {
666 GetGame().GetResourceGrid().UpdateInteractor(m_ResourceConsumer);
667 }
668
669 //~ Check availability
670 return m_ResourceConsumer.GetAggregatedResourceValue() >= supplyAmountToCheck;
671 }
672
673 //------------------------------------------------------------------------------------------------
677 protected bool OnConsumeSuppliesServer(int amount)
678 {
679 if (amount <= 0 || !m_ResourceConsumer || !AreSuppliesEnabled())
680 return true;
681
682 //~ Check if consumption was successful
683 SCR_ResourceConsumtionResponse response = m_ResourceConsumer.RequestConsumtion(amount);
684
685 return response.GetReason() == EResourceReason.SUFFICIENT;
686 }
687
688 //------------------------------------------------------------------------------------------------
689 //~ Check if there is enough storage for supplies to execute the action
690 protected bool HasSpaceForSuppliesGeneration(IEntity actionOwner, IEntity actionUser, int supplyAmountToCheck)
691 {
692 //~ TODO: For now it isn't easy for client to request for generators if there is both storage available as well as able to create an orphan supply.
693 //~ This means we will always return this true but it will require the resourcecomponent to always generate orphans as well
694 return true;
695
696 /*if (supplyAmountToCheck <= 0 || !m_ResourceGenerator || !AreSuppliesEnabled())
697 return true;
698
699 //~ Make sure to create or poke the consumer handler so server sends updates for clients
700 if (Replication.IsClient())
701 {
702 if (m_ResourceSubscriptionHandleGenerator)
703 m_ResourceSubscriptionHandleGenerator.Poke();
704 else
705 m_ResourceSubscriptionHandleGenerator = GetGame().GetResourceSystemSubscriptionManager().RequestSubscriptionListenerHandleGraceful(m_ResourceGenerator, Replication.FindItemId(SCR_ResourcePlayerControllerInventoryComponent.Cast(GetGame().GetPlayerController().FindComponent(SCR_ResourcePlayerControllerInventoryComponent))));
706 }
707 //~ Simply update if server
708 else
709 {
710 GetGame().GetResourceGrid().UpdateInteractor(m_ResourceGenerator);
711 }
712
713 SCR_ResourceGenerationResponse response = m_ResourceGenerator.RequestAvailability(supplyAmountToCheck);
714 //~ Check availability
715 return response.GetReason() == EResourceReason.SUFFICIENT;*/
716 }
717
718 //------------------------------------------------------------------------------------------------
722 protected bool OnGenerateSuppliesServer(int amount)
723 {
724 if (amount <= 0 || !m_ResourceGenerator || !AreSuppliesEnabled())
725 return true;
726
727 //~ Check if generation was successful
728 SCR_ResourceGenerationResponse response = m_ResourceGenerator.RequestGeneration(amount);
729
730 return response.GetReason() == EResourceReason.SUFFICIENT;
731 }
732
733 //------------------------------------------------------------------------------------------------
737 {
738 SCR_ResourceComponent resourceComponent = GetResourceComponent();
739
740 return resourceComponent && resourceComponent.IsResourceTypeEnabled();
741 }
742
743 //------------------------------------------------------------------------------------------------
745 SCR_ResourceConsumer GetResourceConsumer()
746 {
747 return m_ResourceConsumer;
748 }
749
750 //------------------------------------------------------------------------------------------------
756
757 //------------------------------------------------------------------------------------------------
758 protected SCR_ResourceComponent GetResourceComponent()
759 {
760 IEntity owner = GetOwner();
761 if (!owner)
762 return null;
763
764 return SCR_ResourceComponent.FindResourceComponent(owner);
765 }
766
767 //---------------------------------------- Range ----------------------------------------\\
768 //------------------------------------------------------------------------------------------------
771 float GetRange()
772 {
773 return m_fRange;
774 }
775
776 //------------------------------------------------------------------------------------------------
780 bool IsInRange(notnull IEntity actionOwner, vector actionPosition)
781 {
782 vector mins, maxs;
783 actionOwner.GetBounds(mins, maxs);
784
785 //~ Does not use bounding box or no bounding box found
786 if (!m_bUseRangeBoundingBox || (mins == vector.Zero && maxs == vector.Zero))
787 {
788 //~ Check if action is in range
789 if (vector.DistanceSq(actionPosition, GetPosition()) > Math.Pow(GetRange(), 2))
790 return false;
791 else
792 return true;
793 }
794
795 return Math3D.IntersectionSphereAABB(GetPosition() - actionOwner.GetOrigin(), GetRange(), mins, maxs);
796 }
797
798 //------------------------------------------------------------------------------------------------
803 {
804 return m_fRange > 0;
805 }
806
807 //---------------------------------------- Position ----------------------------------------\\
808 //------------------------------------------------------------------------------------------------
812 {
813 return GetOwner().CoordToParent(GetOffset());
814 }
815
816 //---------------------------------------- Position Offset ----------------------------------------\\
817 //------------------------------------------------------------------------------------------------
820 {
821 return m_vOffset;
822 }
823
824
825 //---------------------------------------- Other ----------------------------------------\\
826 //------------------------------------------------------------------------------------------------
830 {
831 return m_bIgnoreSelf;
832 }
833
834 //------------------------------------------------------------------------------------------------
840
841 //---------------------------------------- Notification ----------------------------------------\\
842 protected bool GetSendNotificationOnUse()
843 {
844 SCR_BaseSupportStationComponentClass classData = SCR_BaseSupportStationComponentClass.Cast(GetComponentData(GetOwner()));
845 return classData && classData.GetSendNotificationOnUse();
846 }
847
848 //---------------------------------------- Sound ----------------------------------------\\
849
850 //------------------------------------------------------------------------------------------------
851 protected SCR_AudioSourceConfiguration GetOnUseAudioConfig()
852 {
853 SCR_BaseSupportStationComponentClass classData = SCR_BaseSupportStationComponentClass.Cast(GetComponentData(GetOwner()));
854 if (!classData)
855 return null;
856
857 return classData.GetOnUseAudioConfig();
858 }
859
860 //------------------------------------------------------------------------------------------------
861 protected SCR_AudioSourceConfiguration CreateOnUseAudioConfig(ResourceName soundFile, string soundEvent)
862 {
863 SCR_BaseSupportStationComponentClass classData = SCR_BaseSupportStationComponentClass.Cast(GetComponentData(GetOwner()));
864 if (!classData)
865 return null;
866
867 return classData.CreateOnUseAudioConfig(soundFile, soundEvent);
868 }
869
870 //======================================== PLAYERS IN VEHICLE ========================================\\
871
872 //------------------------------------------------------------------------------------------------
873 //~ Get an array of all player Ids within vehicle
874 protected void GetPlayerIdsInVehicle(IEntity vehicle, out notnull array<int> playerIds)
875 {
876 playerIds.Clear();
877
878 if (!vehicle)
879 return;
880
881 SCR_BaseCompartmentManagerComponent compartmentManager = SCR_BaseCompartmentManagerComponent.Cast(vehicle.FindComponent(SCR_BaseCompartmentManagerComponent));
882 if (!compartmentManager)
883 {
884 IEntity parent = vehicle.GetParent();
885 if (parent)
886 compartmentManager = SCR_BaseCompartmentManagerComponent.Cast(parent.FindComponent(SCR_BaseCompartmentManagerComponent));
887
888 if (!compartmentManager)
889 return;
890 }
891
892 PlayerManager playerManager = GetGame().GetPlayerManager();
893 if (!playerManager)
894 return;
895
896 array<IEntity> occupants = {};
897 compartmentManager.GetOccupants(occupants);
898 CompartmentAccessComponent compartmentAccess;
899
900 int playerID;
901
902 foreach (IEntity occupant : occupants)
903 {
904 playerID = playerManager.GetPlayerIdFromControlledEntity(occupant);
905
906 if (playerID > 0)
907 playerIds.Insert(playerID);
908 }
909 }
910
911 //======================================== DAMAGE ========================================\\
912
913 //------------------------------------------------------------------------------------------------
919 bool OverrideDamageState(EDamageState damageState, bool checkIfHasDamageSystem)
920 {
921 //~ Already the same state
922 if (damageState == m_eCurrentDamageState)
923 return false;
924
925 //~ Check if there is a damage system and ignore this call if there is
926 if (checkIfHasDamageSystem)
927 {
928 //~ Check has damage manager
929 SCR_DamageManagerComponent damageManager = SCR_DamageManagerComponent.Cast(GetOwner().FindComponent(SCR_DamageManagerComponent));
930 if (damageManager)
931 return false;
932
934 if (hitZoneContainer)
935 {
936 SCR_HitZone defaultHitZone = SCR_HitZone.Cast(hitZoneContainer.GetDefaultHitZone());
937 if (defaultHitZone)
938 return false;
939 }
940 }
941
942 OnDamageStateChanged(damageState);
943 return true;
944 }
945
946 //---------------------------------------- On HitZone damage state changed ----------------------------------------\\
947 //------------------------------------------------------------------------------------------------
949 protected void OnHitZoneDamageStateChanged(SCR_HitZone defaultHitZone)
950 {
951 OnDamageStateChanged(defaultHitZone.GetDamageState());
952 }
953
954 //---------------------------------------- On damage state changed ----------------------------------------\\
955 //------------------------------------------------------------------------------------------------
957 protected void OnDamageStateChanged(EDamageState damageState)
958 {
959 //~ Same state so ignore
960 if (damageState == m_eCurrentDamageState)
961 return;
962
963 //~ If using range make sure to add self or remove self from manager
964 if (UsesRange())
965 {
966 //~ Is destroyed so remove self from support stations
967 if (damageState == EDamageState.DESTROYED)
968 {
970 if (!supportStationManager)
971 return;
972
973 supportStationManager.RemoveSupportStation(this);
974 }
975 //~ No longer destroyed so add itself back to the manager
976 else if (m_eCurrentDamageState == EDamageState.DESTROYED)
977 {
979 if (!supportStationManager)
980 return;
981
982 supportStationManager.AddSupportStation(this);
983 }
984 }
985
986 //~ Update damage state
987 m_eCurrentDamageState = damageState;
988 }
989
990 //---------------------------------------- Subscribe/Unsubscribe On damage state changed ----------------------------------------\\
991 //------------------------------------------------------------------------------------------------
993 protected void AddRemoveOnDamageStateChanged(IEntity owner, bool subscribe)
994 {
995 SCR_DamageManagerComponent damageManager = SCR_DamageManagerComponent.Cast(owner.FindComponent(SCR_DamageManagerComponent));
996 if (damageManager)
997 {
998 //~ Subscribe to on damage state changed
999 if (subscribe)
1000 {
1001 //~ Also set current state
1002 m_eCurrentDamageState = damageManager.GetState();
1003 damageManager.GetOnDamageStateChanged().Insert(OnDamageStateChanged);
1004 }
1005 //~ Unsubscribe to on damage state changed
1006 else
1007 {
1008 damageManager.GetOnDamageStateChanged().Remove(OnDamageStateChanged);
1009 }
1010
1011 }
1012
1014 if (hitZoneContainer)
1015 {
1016 SCR_HitZone defaultHitZone = SCR_HitZone.Cast(hitZoneContainer.GetDefaultHitZone());
1017
1018 if (defaultHitZone)
1019 {
1020 //~ Subscribe to on damage state changed
1021 if (subscribe)
1022 {
1023 //~ Also set current state
1024 m_eCurrentDamageState = defaultHitZone.GetDamageState();
1026 }
1027 //~ Unsubscribe to on damage state changed
1028 else
1029 {
1031 }
1032 }
1033 }
1034 }
1035
1036 //======================================== RPL ========================================\\
1037
1038 //------------------------------------------------------------------------------------------------
1039 override bool RplSave(ScriptBitWriter writer)
1040 {
1041 writer.WriteBool(m_bIsEnabled);
1042
1043 return true;
1044 }
1045
1046 //------------------------------------------------------------------------------------------------
1047 override bool RplLoad(ScriptBitReader reader)
1048 {
1049 int enabled;
1050
1051 reader.ReadBool(enabled);
1052
1053 SetEnabledBroadcast(enabled);
1054
1055 return true;
1056 }
1057
1058 //======================================== INIT ========================================\\
1059
1060 //------------------------------------------------------------------------------------------------
1061 protected bool InitValidSetup()
1062 {
1064 {
1065 Print("'" + GetOwner().GetName() + "' No Support Station type assigned in the inherented class. Overwrite the 'GetSupportStationType()' function and do not use the base class!", LogLevel.ERROR);
1066 return false;
1067 }
1068
1069 return true;
1070 }
1071
1072 //------------------------------------------------------------------------------------------------
1073 //~ Temp solution until replication fixed
1075 {
1076 SCR_ResourceComponent resourceComponent = SCR_ResourceComponent.FindResourceComponent(GetOwner());
1077 if (resourceComponent)
1078 {
1079 m_ResourceConsumer = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1080 m_ResourceGenerator = resourceComponent.GetGenerator(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1081 }
1082
1083 }
1084
1085 //------------------------------------------------------------------------------------------------
1086 override void EOnInit(IEntity owner)
1087 {
1088 //~ Call init later to make sure vehicle slot has a parent
1089 GetGame().GetCallqueue().CallLater(DelayedInit, param1: owner);
1090 }
1091
1092 //------------------------------------------------------------------------------------------------
1093 protected void DelayedInit(IEntity owner)
1094 {
1095 if (!InitValidSetup() || !owner)
1096 return;
1097
1098 SCR_ResourceComponent resourceComponent = GetResourceComponent();
1099 if (resourceComponent)
1100 {
1101 m_ResourceConsumer = resourceComponent.GetConsumer(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1102 m_ResourceGenerator = resourceComponent.GetGenerator(EResourceGeneratorID.DEFAULT, EResourceType.SUPPLIES);
1103
1105 Print("'SCR_BaseSupportStationComponent' 'EOnInit': '" + GetOwner() + "' Support Station is set to use supplies as it has a Resource Component but it has no consumer nor generator set up", LogLevel.ERROR);
1106 //~ Temp solution until replication fixed
1107 else
1108 resourceComponent.TEMP_GetOnInteractorReplicated().Insert(TEMP_OnInteractorReplicated);
1109 }
1110
1111 //~ Subscribe to on damage state changed
1112 AddRemoveOnDamageStateChanged(owner, true);
1113
1115
1116 //~ Not static so get Physics component
1117 if (classData && classData.CanMoveWithPhysics())
1118 {
1119 Vehicle vehicle = Vehicle.Cast(owner);
1120 if (!vehicle)
1121 vehicle = Vehicle.Cast(owner.GetParent());
1122
1123 if (vehicle)
1124 m_PhysicsVehicle = vehicle;
1125 }
1126
1127 //~ If faction is checked on use set faction affiliation ref
1128 m_FactionAffiliationComponent = FactionAffiliationComponent.Cast(owner.FindComponent(FactionAffiliationComponent));
1129
1130 //~ Could not find Faction affiliation component
1132 {
1133 //~ Get Faction affiliation from parent
1134 if (classData && classData.AllowGetFactionFromParent())
1135 {
1136 IEntity parent = owner.GetParent();
1137 if (parent)
1138 m_FactionAffiliationComponent = FactionAffiliationComponent.Cast(parent.FindComponent(FactionAffiliationComponent));
1139 }
1140
1141 //~ Support Station (nor parent if checked) has Faction affiliation component and it needs to be there for the IsValid check
1143 Print(string.Format("'SCR_BaseSupportStationComponent' of type '%1' has Faction usage check set to not ignore but is missing a 'FactionAffiliationComponent'", typename.EnumToString(ESupportStationType, GetSupportStationType())), LogLevel.ERROR);
1144 }
1145
1146 //~ Uses range so add self to the manager if not destroyed
1147 if (UsesRange())
1148 {
1149 //~ Has damage manager and is destroyed so do not add self to manager
1150 if (m_eCurrentDamageState == EDamageState.DESTROYED)
1151 return;
1152
1154 if (!supportStationManager)
1155 {
1156 //~ Entity exists in the world when loaded instead of later spawned
1157 if (owner.IsLoaded())
1158 Print("'SCR_BaseSupportStationComponent' Support station on entity that exists in world when loaded has range but no 'SCR_SupportStationManagerComponent' availible on GameMode. So it won't work!", LogLevel.WARNING);
1159 //~ Show VME for any new support stations added
1160 else
1161 Debug.Error2("SCR_BaseSupportStationComponent", "Support station exists with range but no 'SCR_SupportStationManagerComponent' availible on GameMode!");
1162
1163 return;
1164 }
1165
1166 //~ Add self to manager
1167 supportStationManager.AddSupportStation(this);
1168 }
1169
1170 //~ Get service point to see if it is online
1171 m_ServicePointComponent = SCR_ServicePointComponent.Cast(owner.FindComponent(SCR_ServicePointComponent));
1172 }
1173
1174 //------------------------------------------------------------------------------------------------
1175 override void OnPostInit(IEntity owner)
1176 {
1177 if (SCR_Global.IsEditMode())
1178 return;
1179
1180 SetEventMask(owner, EntityEvent.INIT);
1181 }
1182
1183 //======================================== DESTROY ========================================\\
1184
1185 //------------------------------------------------------------------------------------------------
1186 override void OnDelete(IEntity owner)
1187 {
1189 return;
1190
1191 //~ Unsubscribe to onDamage state changed
1192 AddRemoveOnDamageStateChanged(owner, false);
1193
1194 //~ Does not use range so do not remove self to supportStationManager
1195 if (!UsesRange())
1196 return;
1197
1198 if (m_eCurrentDamageState == EDamageState.DESTROYED)
1199 return;
1200
1202 if (!supportStationManager)
1203 return;
1204
1205 supportStationManager.RemoveSupportStation(this);
1206
1208 {
1209 SCR_ResourceComponent resourceComponent = SCR_ResourceComponent.FindResourceComponent(owner);
1210 if (!resourceComponent && owner.GetParent())
1211 resourceComponent = SCR_ResourceComponent.FindResourceComponent(owner.GetParent());
1212
1213 if (resourceComponent)
1214 resourceComponent.TEMP_GetOnInteractorReplicated().Remove(TEMP_OnInteractorReplicated);
1215 }
1216 }
1217
1218 //------------------------------------------------------------------------------------------------
1223 static SCR_BaseSupportStationComponent FindSupportStation(notnull IEntity entity, SCR_ESupportStationResupplyType type = SCR_ESupportStationResupplyType.NONE, SCR_EComponentFinderQueryFlags queryFlags = SCR_EComponentFinderQueryFlags.ENTITY | SCR_EComponentFinderQueryFlags.SLOTS)
1224 {
1225 SCR_BaseSupportStationComponent foundSupportStation;
1226 array<Managed> supportStations = {};
1227
1228 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.ENTITY))
1229 {
1230 entity.FindComponents(SCR_BaseSupportStationComponent, supportStations);
1231
1232 //~ Get correct support station
1233 foreach (Managed supportStation : supportStations)
1234 {
1235 foundSupportStation = SCR_BaseSupportStationComponent.Cast(supportStation);
1236 if (!foundSupportStation)
1237 continue;
1238
1239 if (type == SCR_ESupportStationResupplyType.NONE || foundSupportStation.GetSupportStationType() == type)
1240 return foundSupportStation;
1241 }
1242 }
1243
1244 //~ If vehicle loop through slotted entities
1245 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.SLOTS))
1246 {
1247 SlotManagerComponent slotManager = SlotManagerComponent.Cast(entity.FindComponent(SlotManagerComponent));
1248 if (slotManager)
1249 {
1250 array<EntitySlotInfo> slotInfos = {};
1251 slotManager.GetSlotInfos(slotInfos);
1252 IEntity slotEntity;
1253
1254 foreach (EntitySlotInfo slotInfo : slotInfos)
1255 {
1256 slotEntity = slotInfo.GetAttachedEntity();
1257 if (!slotEntity)
1258 continue;
1259
1260 slotEntity.FindComponents(SCR_BaseSupportStationComponent, supportStations);
1261
1262 foreach (Managed supportStation : supportStations)
1263 {
1264 foundSupportStation = SCR_BaseSupportStationComponent.Cast(supportStation);
1265 if (!foundSupportStation)
1266 continue;
1267
1268 if (type == SCR_ESupportStationResupplyType.NONE || foundSupportStation.GetSupportStationType() == type)
1269 return foundSupportStation;
1270 }
1271 }
1272 }
1273 }
1274
1275 //~ Find support station in children
1276 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.CHILDREN))
1277 {
1278 IEntity child = entity.GetChildren();
1279
1280 while (child)
1281 {
1282 child.FindComponents(SCR_BaseSupportStationComponent, supportStations);
1283
1284 //~ Get correct support station
1285 foreach (Managed supportStation : supportStations)
1286 {
1287 foundSupportStation = SCR_BaseSupportStationComponent.Cast(supportStation);
1288 if (!foundSupportStation)
1289 continue;
1290
1291 if (type == SCR_ESupportStationResupplyType.NONE || foundSupportStation.GetSupportStationType() == type)
1292 return foundSupportStation;
1293 }
1294
1295 child = child.GetSibling();
1296 }
1297 }
1298
1299 IEntity parent;
1300
1301 //~ Find in parent
1302 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.PARENT))
1303 {
1304 parent = entity.GetParent();
1305
1306 if (parent)
1307 {
1308 parent.FindComponents(SCR_BaseSupportStationComponent, supportStations);
1309
1310 //~ Get correct support station
1311 foreach (Managed supportStation : supportStations)
1312 {
1313 foundSupportStation = SCR_BaseSupportStationComponent.Cast(supportStation);
1314 if (!foundSupportStation)
1315 continue;
1316
1317 if (type == SCR_ESupportStationResupplyType.NONE || foundSupportStation.GetSupportStationType() == type)
1318 return foundSupportStation;
1319 }
1320 }
1321 }
1322
1323 //~ Find in vehicle slots of parent
1324 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.PARENT_SLOTS))
1325 {
1326 if (!parent)
1327 parent = entity.GetParent();
1328
1329 if (parent)
1330 foundSupportStation = SCR_BaseSupportStationComponent.FindSupportStation(parent, type, SCR_EComponentFinderQueryFlags.SLOTS);
1331
1332 if (foundSupportStation)
1333 return foundSupportStation;
1334 }
1335
1336 IEntity rootParent;
1337
1338 //~ Find in root parent
1339 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.ROOT_PARENT))
1340 {
1341 rootParent = entity.GetRootParent();
1342
1343 if (rootParent)
1344 {
1345 rootParent.FindComponents(SCR_BaseSupportStationComponent, supportStations);
1346
1347 //~ Get correct support station
1348 foreach (Managed supportStation : supportStations)
1349 {
1350 foundSupportStation = SCR_BaseSupportStationComponent.Cast(supportStation);
1351 if (!foundSupportStation)
1352 continue;
1353
1354 if (type == SCR_ESupportStationResupplyType.NONE || foundSupportStation.GetSupportStationType() == type)
1355 return foundSupportStation;
1356 }
1357 }
1358 }
1359
1360 //~ Find in vehicle slots of root parent
1361 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.PARENT_SLOTS))
1362 {
1363 if (!rootParent)
1364 rootParent = entity.GetRootParent();
1365
1366 if (rootParent)
1367 foundSupportStation = SCR_BaseSupportStationComponent.FindSupportStation(rootParent, type, SCR_EComponentFinderQueryFlags.SLOTS);
1368
1369 if (foundSupportStation)
1370 return foundSupportStation;
1371 }
1372
1373 //~ Find in siblings
1374 if (SCR_Enum.HasFlag(queryFlags, SCR_EComponentFinderQueryFlags.SIBLINGS))
1375 {
1376 if (!parent)
1377 parent = entity.GetParent();
1378
1379 if (parent)
1380 {
1381 //~ Get siblings from parent
1382 IEntity child = parent.GetChildren();
1383
1384 while (child)
1385 {
1386 //~ Ignore self
1387 if (child == entity)
1388 {
1389 child = child.GetSibling();
1390 continue;
1391 }
1392
1393 child.FindComponents(SCR_BaseSupportStationComponent, supportStations);
1394
1395 //~ Get correct support station
1396 foreach (Managed supportStation : supportStations)
1397 {
1398 foundSupportStation = SCR_BaseSupportStationComponent.Cast(supportStation);
1399 if (!foundSupportStation)
1400 continue;
1401
1402 if (type == SCR_ESupportStationResupplyType.NONE || foundSupportStation.GetSupportStationType() == type)
1403 return foundSupportStation;
1404 }
1405
1406 child = child.GetSibling();
1407 }
1408 }
1409 }
1410
1411 //~ Not found
1412 return null;
1413 }
1414}
1415
ESupportStationPriority
ESupportStationType
ArmaReforgerScripted GetGame()
Definition game.c:1398
bool IsMoving()
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
void SCR_AudioSource(SCR_AudioSourceConfiguration audioSourceConfiguration, vector mat[4])
override int GetSupplyAmountAction(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action)
override void OnExecute(IEntity actionOwner, IEntity actionUser, int playerId, SCR_BaseUseSupportStationAction action)
override void OnExecutedServer(notnull IEntity actionOwner, notnull IEntity actionUser, notnull SCR_BaseUseSupportStationAction action)
override void DelayedInit(IEntity owner)
override bool InitValidSetup()
void TEMP_OnInteractorReplicated()
LocalizedString GetOverrideUserActionName()
bool HasSupplyGainInsteadOfCost(SCR_BaseUseSupportStationAction action)
void GetPlayerIdsInVehicle(IEntity vehicle, out notnull array< int > playerIds)
void PlayCharacterVoiceEvent(IEntity character)
void OnHitZoneDamageStateChanged(SCR_HitZone defaultHitZone)
Called when default hitZone damage state changed. Not called if entity has a damage manager.
FactionAffiliationComponent m_FactionAffiliationComponent
ESupportStationPriority GetSupportStationPriority()
bool HasEnoughSupplies(IEntity actionOwner, IEntity actionUser, int supplyAmountToCheck)
ref ScriptInvoker Event_OnEnabledChanged
SCR_ResourceGenerator GetResourceGenerator()
@ SAME_CURRENT_FACTION
The user with the same faction as the current faction can interact with the support station.
@ FRIENDLY_DEFAULT_FACTION
he user with a faction that is a friendly faction to the default faction of the support station can i...
@ DISALLOW_USE_ON_CURRENT_FACTION_NULL
If set it disallows the support station to be used if the faction of the Support station is not set....
@ FRIENDLY_CURRENT_FACTION
The user with a faction that is a friendly faction as the current faction can interact with the suppo...
@ SAME_DEFAULT_FACTION
The user with the same faction as the default faction of the support station can interact with the su...
LocalizedString m_sOverrideUserActionName
ESupportStationFactionUsage m_eFactionUsageCheck
ESupportStationType GetSupportStationType()
bool HasSpaceForSuppliesGeneration(IEntity actionOwner, IEntity actionUser, int supplyAmountToCheck)
bool OnConsumeSuppliesServer(int amount)
bool OnGenerateSuppliesServer(int amount)
SCR_ResourceSystemSubscriptionHandleBase m_ResourceSubscriptionHandler
SCR_AudioSourceConfiguration CreateOnUseAudioConfig(ResourceName soundFile, string soundEvent)
void OnExecuteBroadcast(RplId ownerId, RplId userId, int userPlayerId, int actionId)
void AddRemoveOnDamageStateChanged(IEntity owner, bool subscribe)
Grabs either damage manager or HitZoneContainer to subscribe to OnDamageStateChanged.
bool OverrideDamageState(EDamageState damageState, bool checkIfHasDamageSystem)
bool IsUserValidFaction(IEntity user)
void FindEntityIds(IEntity owner, IEntity user, out RplId ownerId, out RplId userId, out int playerId)
void GetEntitiesFromID(RplId ownerId, RplId userId, out IEntity owner, out IEntity user)
int GetMaxAvailableSupplies()
ScriptInvoker GetOnEnabledChanged()
SCR_ServicePointComponent m_ServicePointComponent
void OnSuccessfullyExecuted(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action)
void PlaySoundEffect(SCR_AudioSourceConfiguration audioConfig, notnull IEntity soundOwner, SCR_BaseUseSupportStationAction action)
bool IsInRange(notnull IEntity actionOwner, vector actionPosition)
SCR_AudioSourceConfiguration GetOnUseAudioConfig()
EDamageState m_eCurrentDamageState
void SetEnabledBroadcast(bool enable)
SCR_ResourceComponent GetResourceComponent()
Caches and returns the resource component.
SCR_ResourceConsumer GetResourceConsumer()
SCR_CampaignFaction GetFaction()
override void DelayedInit()
SCR_CharacterSoundComponentClass GetComponentData()
EDamageType type
SCR_EComponentFinderQueryFlags
Used for component finding to know where it can search to get the given component.
override void OnDamageStateChanged(EDamageState newState, EDamageState previousDamageState, bool isJIP)
vector m_vOffset
void SCR_ResourceConsumtionResponse(float availableResource=0, float resourceMultiplier=0, float range=0, EResourceReason reasonCode=EResourceReason.UNAVAILABLE)
EResourceGeneratorID
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
SCR_ResourceConsumer m_ResourceConsumer
SCR_ResourceGenerator m_ResourceGenerator
enum EVehicleType IEntity
Definition Debug.c:13
proto external int SetEventMask(notnull IEntity owner, int mask)
proto external GenericComponent FindComponent(typename typeName)
void Rpc(func method, void p0=NULL, void p1=NULL, void p2=NULL, void p3=NULL, void p4=NULL, void p5=NULL, void p6=NULL, void p7=NULL)
proto external Managed FindComponent(typename typeName)
proto external IEntity GetChildren()
proto external int FindComponents(typename typeName, notnull array< Managed > outComponents)
proto external bool IsLoaded()
proto external IEntity GetParent()
proto external vector CoordToParent(vector coord)
proto external IEntity GetSibling()
proto external IEntity GetRootParent()
Definition Math.c:13
Main replication API.
Definition Replication.c:14
Replication item identifier.
Definition RplId.c:14
ref SCR_AudioSourceConfiguration m_OnUseAudioSourceConfiguration
SCR_AudioSourceConfiguration CreateOnUseAudioConfig(ResourceName soundFile, string soundEvent)
void GetCharacterVoiceSoundEventVariables(out string characterVoiceEventOnUse, out int characterVoicePriority)
static bool IsEditMode()
Definition Functions.c:1566
ScriptInvoker GetOnDamageStateChanged(bool createNew=true)
Definition SCR_HitZone.c:32
static bool IsEmptyOrWhiteSpace(string input)
void RemoveSupportStation(SCR_BaseSupportStationComponent supportStation)
void AddSupportStation(SCR_BaseSupportStationComponent supportStation)
static void OnSupportStationExecutedSuccessfully(notnull SCR_BaseSupportStationComponent supportStation, ESupportStationType supportStationType, IEntity actionUser, IEntity actionOwner, SCR_BaseUseSupportStationAction action)
static SCR_SupportStationManagerComponent GetInstance()
proto external GenericEntity GetOwner()
Get owner entity.
void EOnInit(IEntity owner)
bool RplLoad(ScriptBitReader reader)
bool RplSave(ScriptBitWriter writer)
proto external void SetTransformation(vector transf[])
proto external int GetEventIndex(string name)
enum EPhysicsLayerPresets Vehicle
Definition gameLib.c:24
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
void SetEnabled(bool enabled)
EntityEvent
Various entity events.
Definition EntityEvent.c:14
int IsEnabled()
Returns true if the light is enabled.
proto external PlayerController GetPlayerController()
EDamageState
void RplRpc(RplChannel channel, RplRcver rcver, RplCondition condition=RplCondition.None, string customConditionName="")
Definition EnNetwork.c:95
RplRcver
Definition RplRcver.c:59
RplChannel
Communication channel. Reliable is guaranteed to be delivered. Unreliable not.
Definition RplChannel.c:14
Tuple param1
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134