Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_FuelSupportStationComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/SupportStation", description: "")]
3 {
4  [Attribute(desc: "Sound effect played when fuel is updated. Broadcast to players. Leave empty if no sfx", category: "Fuel Support Station")]
5  protected string m_sOnUpdateSoundEffectEventName;
6 
7  protected ref SCR_AudioSourceConfiguration m_OnUpdateAudioSourceConfiguration;
8 
9  //------------------------------------------------------------------------------------------------
13  SCR_AudioSourceConfiguration GetOnUpdateAudioConfig()
14  {
15  //~ Create Audio source if it does not yet exist
17  {
18  if (SCR_StringHelper.IsEmptyOrWhiteSpace(m_sOnUseSoundEffectFile) || SCR_StringHelper.IsEmptyOrWhiteSpace(m_sOnUpdateSoundEffectEventName))
19  return null;
20 
21  m_OnUpdateAudioSourceConfiguration = new SCR_AudioSourceConfiguration();
24 
25  if (!CanMoveWithPhysics())
27  else
29  }
30 
32  }
33 }
34 
35 class SCR_FuelSupportStationComponent : SCR_BaseSupportStationComponent
36 {
37  [Attribute(defvalue: EFuelFlowCapacityOut.FUEL_CARGO.ToString(), uiwidget: UIWidgets.SearchComboBox, desc: "Maximum Flow Capacity (per minute). Is only used if entity does not have a Fuelmanager with Nodes as scripted fuel nodes have the max flow assigned", enums: ParamEnumArray.FromEnum( EFuelFlowCapacityOut ), category: "Fuel Support Station Only")]
38  protected EFuelFlowCapacityOut m_BackupMaxFlowCapacity;
39 
40  [Attribute(ESupportStationReasonInvalid.NO_FUEL_TO_GIVE.ToString(), desc: "The reason to display when the fuelManager has no fuel to give. For fuel canister this is diffrent then for example a tanker", uiwidget: UIWidgets.SearchComboBox, enums: ParamEnumArray.FromEnum(ESupportStationReasonInvalid), category: "Fuel Support Station Only")]
42 
44 
45  //------------------------------------------------------------------------------------------------
46  protected override void DelayedInit(IEntity owner)
47  {
48  if (!owner)
49  return;
50 
51  super.DelayedInit(owner);
52 
54  }
55 
56  //------------------------------------------------------------------------------------------------
57  override bool IsValid(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action, vector actionPosition, out ESupportStationReasonInvalid reasonInvalid, out int supplyCost)
58  {
59  if (!super.IsValid(actionOwner, actionUser, action, actionPosition, reasonInvalid, supplyCost))
60  return false;
61 
62  //~ Has no fuel to provide so not valid
64  {
65  reasonInvalid = m_EmptyInvalidReason;
66  return false;
67  }
68 
69  return true;
70  }
71 
72  //------------------------------------------------------------------------------------------------
74  {
75  return ESupportStationType.FUEL;
76  }
77 
78  //------------------------------------------------------------------------------------------------
79  //~ When fuel is removed and how much and from which node (Server only)
80  protected void OnFuelAddedToVehicleServer(float fuelAmount, SCR_FuelNode nodeUsedForRefuel)
81  {
82  //~ No node was used as provider
83  if (!nodeUsedForRefuel)
84  return;
85 
86  //~ Update fuel node amount
87  nodeUsedForRefuel.SetFuel(Math.Clamp(nodeUsedForRefuel.GetFuel() - fuelAmount, 0, nodeUsedForRefuel.GetMaxFuel()));
88  }
89 
90  //------------------------------------------------------------------------------------------------
91  //~ Get the max flow and potentially the node used for refueling
92  protected void GetFuelNodeInfo(out float maxFlowCapacity, out SCR_FuelNode nodeUsedForRefuel, float actionDuration)
93  {
94  maxFlowCapacity = 0;
95  nodeUsedForRefuel = null;
96 
97  //~ No fuel manager so use backup and always allow for fuel to be used
99  {
100  maxFlowCapacity = (m_BackupMaxFlowCapacity / 60) * actionDuration;
101  return;
102  }
103 
104  array<BaseFuelNode> nodes = {};
105  m_SupportStationFuelManager.GetFuelNodesList(nodes);
106 
107  SCR_FuelNode scrNode;
108 
109  //~ Loop through all nodes and grab the first provider that has fuel
110  foreach(BaseFuelNode node: nodes)
111  {
112  //~ Requires SCR_FuelNode
113  scrNode = SCR_FuelNode.Cast(node);
114  if (!scrNode)
115  continue;
116 
117  //~ Can provide and has fuel
118  if (scrNode.CanProvideFuel() && scrNode.GetFuel() > 0)
119  {
120  nodeUsedForRefuel = scrNode;
121 
122  maxFlowCapacity = (scrNode.GetMaxFlowCapacityOut() / 60) * actionDuration;
123 
124  //~ Fuel tank is almost empty so use current amount as max flow
125  if (scrNode.GetFuel() < maxFlowCapacity)
126  maxFlowCapacity = scrNode.GetFuel();
127 
128  return;
129  }
130  }
131  }
132 
133  //------------------------------------------------------------------------------------------------
134  //~ Fuel does not execute super.OnExecutedServer as it has an on partly done
135  override void OnExecutedServer(notnull IEntity actionOwner, notnull IEntity actionUser, notnull SCR_BaseUseSupportStationAction action)
136  {
137  if (!actionOwner)
138  return;
139 
140  //~ Get refuel action
142  if (!refuelAction)
143  {
144  Debug.Error2("SCR_FuelSupportStationComponent", "Was initiated by an user action that does not inherit from 'SCR_RefuelAtSupportStationAction'");
145  return;
146  }
147 
148  array<int> fuelTankIDs = {};
149  refuelAction.GetFuelTankIDs(fuelTankIDs);
150 
151  //~ Target needs fuel manager and can be refueled
152  SCR_FuelManagerComponent targetFuelManager = SCR_FuelManagerComponent.Cast(actionOwner.FindComponent(SCR_FuelManagerComponent));
153  if (!targetFuelManager || !targetFuelManager.CanBeRefueledScripted(fuelTankIDs))
154  return;
155 
156  //~ Get action duration per second
157  float actionDuration = 1;
158  if (action)
159  {
160  actionDuration = action.GetActionDuration();
161 
162  if (actionDuration < 0)
163  actionDuration *= -1;
164  }
165 
166  float maxFlowCapacityOut;
167  SCR_FuelNode nodeUsedForRefuel;
168  GetFuelNodeInfo(maxFlowCapacityOut, nodeUsedForRefuel, actionDuration);
169 
170  //~ Safty should never be called as HasFuelToProvide should catch this
171  if (maxFlowCapacityOut <= 0)
172  return;
173 
174  array<BaseFuelNode> nodes = {};
175  targetFuelManager.GetFuelNodesList(nodes);
176 
177  float fuelToAdded = maxFlowCapacityOut;
178  float preChangeFuel;
179 
180  SCR_FuelNode scrNode;
181 
182  bool maxFlowCapacityReached = false;
183  float maxFlowNode = 1;
184 
185  //Refuel one node at the time
186  for (int i = 0, count = nodes.Count(); i < count; i++)
187  {
188  //~ Node already max fuel or null so ignore
189  if (!nodes[i] || nodes[i].GetFuel() >= nodes[i].GetMaxFuel())
190  continue;
191 
192  scrNode = SCR_FuelNode.Cast(nodes[i]);
193 
194  //~ Check if action allows the node to be filled
195  if (refuelAction && !refuelAction.CheckIfFuelNodeIsValid(scrNode))
196  continue;
197 
198  //~ Fuel before change
199  preChangeFuel = nodes[i].GetFuel();
200 
201  if (scrNode)
202  {
203  //~ Node cannot receive fuel
204  if (!scrNode.CanReceiveFuel())
205  continue;
206 
207  maxFlowNode = (scrNode.GetMaxFlowCapacityIn() / 60) * actionDuration;
208 
209  //~ Check if the max flow capacity is reached (With multiplier)
210  maxFlowCapacityReached = fuelToAdded > maxFlowNode;
211 
212  //~ Make sure node receives only what max flow capacity allows (with multiplier)
213  scrNode.SetFuel(Math.Clamp(scrNode.GetFuel() + Math.Clamp(fuelToAdded, 0, maxFlowNode), 0, scrNode.GetMaxFuel()));
214  }
215  //~ Simply add to node as there is no max flow capacity
216  else
217  {
218  nodes[i].SetFuel(Math.Clamp(nodes[i].GetFuel() + fuelToAdded, 0, nodes[i].GetMaxFuel()));
219  }
220 
221  fuelToAdded -= nodes[i].GetFuel() - preChangeFuel;
222 
223  if (maxFlowCapacityReached)
224  break;
225 
226  if (fuelToAdded <= 0)
227  {
228  fuelToAdded = 0;
229  break;
230  }
231  }
232 
233  //~ Sends over amount of fuel that was added to vehicle. In case supplies or fuel needs to be removed
234  OnFuelAddedToVehicleServer(maxFlowCapacityOut - fuelToAdded, nodeUsedForRefuel);
235 
236  //~ Fuel uses own function to broadcast to include current percentage so super.OnExecutedServer() is never called
237  float fuelTankFillPercentage = targetFuelManager.GetTotalFuel() / targetFuelManager.GetTotalMaxFuel();
238  bool currentTankFull = true;
239 
240  //~ Check if current tank is full
241  foreach (BaseFuelNode node : nodes)
242  {
243  if (!refuelAction.CheckIfFuelNodeIsValid(SCR_FuelNode.Cast(node)))
244  continue;
245 
246  //~ Current tank not yet full
247  if (node.GetFuel() < node.GetMaxFuel())
248  {
249  currentTankFull = false;
250  break;
251  }
252  }
253 
254  RplId ownerId;
255  RplId userId;
256  int playerId;
257 
258  //~ Get broadcast ids
259  FindEntityIds(actionOwner, actionUser, ownerId, userId, playerId);
260 
261  //~ On fuel executed
262  OnExecuteFuel(actionOwner, actionUser, playerId, fuelTankFillPercentage, currentTankFull, action);
263  Rpc(OnExecuteFuelBroadcast, ownerId, userId, playerId, fuelTankFillPercentage, currentTankFull, action.GetActionID());
264  }
265 
266  //------------------------------------------------------------------------------------------------
267  //~ called by Server to convert ReplicationIDs to entity and player
268  [RplRpc(RplChannel.Reliable, RplRcver.Broadcast)]
269  protected void OnExecuteFuelBroadcast(RplId ownerId, RplId userId, int userPlayerId, float fuelTankFillPercentage, bool currentTankFull, int actionId)
270  {
271  IEntity actionOwner, actionUser;
272  GetEntitiesFromID(ownerId, userId, actionOwner, actionUser);
273 
275  if (actionOwner)
276  {
277  ActionsManagerComponent actionManager = ActionsManagerComponent.Cast(actionOwner.FindComponent(ActionsManagerComponent));
278  if (actionManager)
279  action = SCR_BaseUseSupportStationAction.Cast(actionManager.FindAction(actionId));
280 
281  OnExecuteFuel(actionOwner, actionUser, userPlayerId, fuelTankFillPercentage, currentTankFull, action);
282  }
283  }
284 
285  //------------------------------------------------------------------------------------------------
286  //~ Called by fuel only on server and client
287  protected void OnExecuteFuel(IEntity actionOwner, IEntity actionUser, int playerId, float fuelPercentage, bool currentTankFull, SCR_BaseUseSupportStationAction action)
288  {
289  //~ On succesfully executed
290  OnSuccessfullyExecuted(actionOwner, actionUser, action);
291 
292  //~ Refuel not done
293  if (fuelPercentage < 1 && !currentTankFull)
294  {
295  PlayRefuelUpdateSound(actionOwner, action);
296  }
297  //~ Refuel of current tank is done
298  else if (fuelPercentage < 1 && currentTankFull)
299  {
300  //~ Refuel done sfx
301  PlaySoundEffect(GetOnUseAudioConfig(), actionOwner, action);
302  }
303  //~ Refuel is fully done
304  else
305  {
306  //~ Refuel done sfx
307  PlaySoundEffect(GetOnUseAudioConfig(), actionOwner, action);
308 
309  //~ Play full done voice event (if any)
310  PlayCharacterVoiceEvent(actionUser);
311  }
312 
313  //~ Do not send notification
315  return;
316 
317  //~ Editable entity not found
318  SCR_EditableEntityComponent userEditableEntity = SCR_EditableEntityComponent.Cast(actionUser.FindComponent(SCR_EditableEntityComponent));
319  if (!userEditableEntity)
320  return;
321 
322  RplId userRplId = Replication.FindId(userEditableEntity);
323 
324  //~ Check if player is in vehicle that is being refueled
325  array<int> playersInVehicle = {};
326  GetPlayerIdsInVehicle(actionOwner, playersInVehicle);
327 
328  //~ In vehicle so send notification that another player is refueling the vehicle you are in
329  if (playersInVehicle.Contains(SCR_PlayerController.GetLocalPlayerId()))
330  {
331  if (fuelPercentage < 1 && !currentTankFull)
332  SCR_NotificationsComponent.SendLocal(ENotification.SUPPORTSTATION_REFUELED_BY_OTHER_UPDATE, userRplId, fuelPercentage * 1000);
333  else if (fuelPercentage < 1 && currentTankFull)
334  SCR_NotificationsComponent.SendLocal(ENotification.SUPPORTSTATION_REFUELED_BY_OTHER_TANK_FULL, userRplId, fuelPercentage * 1000);
335  else
336  SCR_NotificationsComponent.SendLocal(ENotification.SUPPORTSTATION_REFUELED_BY_OTHER_DONE, userRplId);
337  }
338  }
339 
340  //------------------------------------------------------------------------------------------------
341  protected override void OnExecute(IEntity actionOwner, IEntity actionUser, int playerId, SCR_BaseUseSupportStationAction action)
342  {
343  //~ Clear on execute so it does not call on complete
344  }
345 
346 
347  //------------------------------------------------------------------------------------------------
348  protected void PlayRefuelUpdateSound(IEntity actionOwner, SCR_BaseUseSupportStationAction action)
349  {
350  ResourceName soundFile;
351  string soundEventName;
352 
354  if (!classData)
355  return;
356 
357  //~ Play sound
358  PlaySoundEffect(classData.GetOnUpdateAudioConfig(), actionOwner, action);
359  }
360 }
SCR_BaseSupportStationComponentClass
Definition: SCR_BaseSupportStationComponent.c:2
m_sOnUseSoundEffectFile
protected ResourceName m_sOnUseSoundEffectFile
Definition: SCR_BaseSupportStationComponent.c:12
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
GetSupportStationType
override ESupportStationType GetSupportStationType()
Definition: SCR_FuelSupportStationComponent.c:73
SCR_PlayerController
Definition: SCR_PlayerController.c:31
SCR_Enum
Definition: SCR_Enum.c:1
FindEntityIds
protected void FindEntityIds(IEntity owner, IEntity user, out RplId ownerId, out RplId userId, out int playerId)
Definition: SCR_BaseSupportStationComponent.c:148
m_sOnUpdateSoundEffectEventName
protected string m_sOnUpdateSoundEffectEventName
Definition: SCR_FuelSupportStationComponent.c:3
BaseFuelNode
Definition: BaseFuelNode.c:12
EAudioSourceConfigurationFlag
EAudioSourceConfigurationFlag
Definition: SCR_AudioSourceConfiguration.c:1
GetEntitiesFromID
protected void GetEntitiesFromID(RplId ownerId, RplId userId, out IEntity owner, out IEntity user)
Definition: SCR_BaseSupportStationComponent.c:171
OnExecuteFuel
protected void OnExecuteFuel(IEntity actionOwner, IEntity actionUser, int playerId, float fuelPercentage, bool currentTankFull, SCR_BaseUseSupportStationAction action)
Definition: SCR_FuelSupportStationComponent.c:287
SCR_StringHelper
Definition: SCR_StringHelper.c:1
OnSuccessfullyExecuted
protected void OnSuccessfullyExecuted(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action)
Definition: SCR_BaseSupportStationComponent.c:214
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
RplRpc
SCR_AchievementsHandlerClass ScriptComponentClass RplRpc(RplChannel.Reliable, RplRcver.Owner)] void UnlockOnClient(AchievementId achievement)
Definition: SCR_AchievementsHandler.c:11
Attribute
SCR_FuelSupportStationComponentClass SCR_BaseSupportStationComponentClass Attribute(defvalue:EFuelFlowCapacityOut.FUEL_CARGO.ToString(), uiwidget:UIWidgets.SearchComboBox, desc:"Maximum Flow Capacity (per minute). Is only used if entity does not have a Fuelmanager with Nodes as scripted fuel nodes have the max flow assigned", enums:ParamEnumArray.FromEnum(EFuelFlowCapacityOut), category:"Fuel Support Station Only")] protected EFuelFlowCapacityOut m_BackupMaxFlowCapacity
PlaySoundEffect
protected void PlaySoundEffect(SCR_AudioSourceConfiguration audioConfig, notnull IEntity soundOwner, SCR_BaseUseSupportStationAction action)
Definition: SCR_BaseSupportStationComponent.c:222
PlayCharacterVoiceEvent
protected void PlayCharacterVoiceEvent(IEntity character)
Definition: SCR_BaseSupportStationComponent.c:269
ENotification
ENotification
Definition: ENotification.c:4
ESupportStationReasonInvalid
ESupportStationReasonInvalid
Definition: ESupportStationReasonInvalid.c:3
m_SupportStationFuelManager
protected SCR_FuelManagerComponent m_SupportStationFuelManager
Definition: SCR_FuelSupportStationComponent.c:43
GetSendNotificationOnUse
bool GetSendNotificationOnUse()
Definition: SCR_BaseSupportStationComponent.c:28
m_OnUpdateAudioSourceConfiguration
protected ref SCR_AudioSourceConfiguration m_OnUpdateAudioSourceConfiguration
Definition: SCR_FuelSupportStationComponent.c:5
ESupportStationType
ESupportStationType
Definition: ESupportStationType.c:2
OnExecutedServer
override void OnExecutedServer(notnull IEntity actionOwner, notnull IEntity actionUser, notnull SCR_BaseUseSupportStationAction action)
Definition: SCR_FuelSupportStationComponent.c:135
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
SCR_EditableEntityComponent
Definition: SCR_EditableEntityComponent.c:13
SCR_FuelManagerComponent
void SCR_FuelManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_FuelManagerComponent.c:475
OnFuelAddedToVehicleServer
protected void OnFuelAddedToVehicleServer(float fuelAmount, SCR_FuelNode nodeUsedForRefuel)
Definition: SCR_FuelSupportStationComponent.c:80
GetFuelNodeInfo
protected void GetFuelNodeInfo(out float maxFlowCapacity, out SCR_FuelNode nodeUsedForRefuel, float actionDuration)
Definition: SCR_FuelSupportStationComponent.c:92
GetPlayerIdsInVehicle
protected void GetPlayerIdsInVehicle(IEntity vehicle, out notnull array< int > playerIds)
Definition: SCR_BaseSupportStationComponent.c:743
OnExecuteFuelBroadcast
protected void OnExecuteFuelBroadcast(RplId ownerId, RplId userId, int userPlayerId, float fuelTankFillPercentage, bool currentTankFull, int actionId)
Definition: SCR_FuelSupportStationComponent.c:269
PlayRefuelUpdateSound
protected void PlayRefuelUpdateSound(IEntity actionOwner, SCR_BaseUseSupportStationAction action)
Definition: SCR_FuelSupportStationComponent.c:348
IsValid
override bool IsValid(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action, vector actionPosition, out ESupportStationReasonInvalid reasonInvalid, out int supplyCost)
Definition: SCR_FuelSupportStationComponent.c:57
DelayedInit
protected override void DelayedInit(IEntity owner)
Definition: SCR_FuelSupportStationComponent.c:46
SCR_BaseUseSupportStationAction
Definition: SCR_BaseUseSupportStationAction.c:1
CanMoveWithPhysics
bool CanMoveWithPhysics()
Definition: SCR_BaseSupportStationComponent.c:36
GetOnUseAudioConfig
SCR_AudioSourceConfiguration GetOnUseAudioConfig()
Definition: SCR_BaseSupportStationComponent.c:54
OnExecute
protected override void OnExecute(IEntity actionOwner, IEntity actionUser, int playerId, SCR_BaseUseSupportStationAction action)
Definition: SCR_FuelSupportStationComponent.c:341
SCR_FuelSupportStationComponentClass
Definition: SCR_FuelSupportStationComponent.c:2
m_EmptyInvalidReason
protected ESupportStationReasonInvalid m_EmptyInvalidReason
Definition: SCR_FuelSupportStationComponent.c:41
SCR_RefuelAtSupportStationAction
Definition: SCR_RefuelAtSupportStationAction.c:1
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180