Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_FuelSupportStationComponent.c
Go to the documentation of this file.
1[ComponentEditorProps(category: "GameScripted/SupportStation", description: "")]
4 [Attribute(desc: "Sound effect played when fuel is updated. Broadcast to players. Leave empty if no sfx", category: "Fuel Support Station")]
6
7 protected ref SCR_AudioSourceConfiguration m_OnUpdateAudioSourceConfiguration;
8
9 //------------------------------------------------------------------------------------------------
33}
34
35class 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 supplyAmount)
58 {
59 if (!super.IsValid(actionOwner, actionUser, action, actionPosition, reasonInvalid, supplyAmount))
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 //------------------------------------------------------------------------------------------------
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 {
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 or no user
314 if (!GetSendNotificationOnUse() || !actionUser)
315 return;
316
317 //~ Editable entity not found
319 if (!userEditableEntity)
320 return;
321
322 RplId userRplId = Replication.FindItemId(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 //------------------------------------------------------------------------------------------------
349 {
351 if (!classData)
352 return;
353
354 //~ Play sound
355 PlaySoundEffect(classData.GetOnUpdateAudioConfig(), actionOwner, action);
356 }
357}
ENotification
ESupportStationType
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
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)
bool GetSendNotificationOnUse()
void GetPlayerIdsInVehicle(IEntity vehicle, out notnull array< int > playerIds)
void PlayCharacterVoiceEvent(IEntity character)
ESupportStationType GetSupportStationType()
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)
void OnSuccessfullyExecuted(IEntity actionOwner, IEntity actionUser, SCR_BaseUseSupportStationAction action)
void PlaySoundEffect(SCR_AudioSourceConfiguration audioConfig, notnull IEntity soundOwner, SCR_BaseUseSupportStationAction action)
SCR_AudioSourceConfiguration GetOnUseAudioConfig()
override void DelayedInit()
SCR_CharacterSoundComponentClass GetComponentData()
void SCR_FuelManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
SCR_FuelManagerComponent m_SupportStationFuelManager
ESupportStationReasonInvalid m_EmptyInvalidReason
void OnExecuteFuelBroadcast(RplId ownerId, RplId userId, int userPlayerId, float fuelTankFillPercentage, bool currentTankFull, int actionId)
void OnFuelAddedToVehicleServer(float fuelAmount, SCR_FuelNode nodeUsedForRefuel)
void OnExecuteFuel(IEntity actionOwner, IEntity actionUser, int playerId, float fuelPercentage, bool currentTankFull, SCR_BaseUseSupportStationAction action)
void GetFuelNodeInfo(out float maxFlowCapacity, out SCR_FuelNode nodeUsedForRefuel, float actionDuration)
void PlayRefuelUpdateSound(IEntity actionOwner, SCR_BaseUseSupportStationAction action)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition Debug.c:13
proto external Managed FindComponent(typename typeName)
Definition Math.c:13
Main replication API.
Definition Replication.c:14
Replication item identifier.
Definition RplId.c:14
SCR_AudioSourceConfiguration GetOnUpdateAudioConfig()
ref SCR_AudioSourceConfiguration m_OnUpdateAudioSourceConfiguration
static int GetLocalPlayerId()
Returns either a valid ID of local player or 0.
static bool IsEmptyOrWhiteSpace(string input)
IEntity GetOwner()
Owner entity of the fuel tank.
SCR_FieldOfViewSettings Attribute
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