Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_DeployMultiPartInventoryItemAction.c
Go to the documentation of this file.
2{
3 [Attribute(defvalue: "0", desc: "Id of a variant that this action is meant to deploy.", params: "0 inf")]
4 protected int m_iVariantId;
5
6 [Attribute(desc: "If game should check if ground on the deploy position is not tilted too much for given deployable variant")]
7 protected bool m_bCheckTilt;
8
9 [Attribute(desc: "If game should check if this place has enough space to fit this entity")]
11
12 [Attribute(desc: "If game should check if storage of this is entity is empty, and in case that it is not, then prevent the player from using this action.")]
13 protected bool m_bCheckStorage;
14
15 [Attribute(desc: "If game should check if this place doesnt have a roof above it")]
16 protected bool m_bPreventIfIndoors;
17
18 [Attribute(desc: "If game should try to render the visualisation of the replacment prefab")]
19 protected bool m_bShowVisualisation;
20
21 [Attribute(defvalue: "0", desc: "Dictates if more than one user at a time can use this action")]
23
24 [Attribute(defvalue: "0", desc: "Should the effect of this action be considered as dismantled")]
25 protected bool m_bReportAsDismantling;
26
27 [Attribute(EGadgetType.NONE.ToString(), uiwidget: UIWidgets.ComboBox, desc: "What gadget player has to equip in order to be able to use this action", enumType: EGadgetType)]
28 protected EGadgetType m_eRequiredGadget;
29
31 protected BaseInventoryStorageComponent m_Storage;
34 protected bool m_bIsSelected;
35 protected bool m_bLastCanPerformResult = true;
38
39 protected const LocalizedString CANNOT_PERFORM_REASON_TOO_STEEP = "#AR-UserAction_Assemble_TooSteep";
40 protected const LocalizedString CANNOT_PERFORM_REASON_NOT_EMPTY = "#AR-UserAction_Assemble_NotEmpty";
41 protected const LocalizedString CANNOT_PERFORM_REASON_NOT_HERE = "#AR-UserAction_Assemble_CannotPlaceHere";
42 protected const LocalizedString CANNOT_PERFORM_REASON_ALREADY_IN_USE = "#AR-UserAction_Blocked_InUseByOther";
43
45 protected const int VALIDATION_DELAY = 500;
46
47 //------------------------------------------------------------------------------------------------
48 override void Init(IEntity pOwnerEntity, GenericComponent pManagerComponent)
49 {
50 super.Init(pOwnerEntity, pManagerComponent);
51
52 m_Storage = BaseInventoryStorageComponent.Cast(pOwnerEntity.FindComponent(BaseInventoryStorageComponent));
53 }
54
55 //------------------------------------------------------------------------------------------------
56 override bool CanBeShownScript(IEntity user)
57 {
58 IEntity owner = GetOwner();
59 if (!owner || owner.GetParent())
60 return false;
61
62 if (CompartmentAccessComponent.GetVehicleIn(user))
63 return false;
64
65 if (m_eRequiredGadget != EGadgetType.NONE)
66 {
68 if (!m_GadgetManager)
69 return false;
70
71 SCR_GadgetComponent gadgetComp = m_GadgetManager.GetHeldGadgetComponent();
72 if (!gadgetComp || gadgetComp.GetType() != m_eRequiredGadget)
73 return false;
74
75 if (m_eRequiredGadget == EGadgetType.BUILDING_TOOL)
76 {
77 SCR_CampaignBuildingGadgetToolComponent etoolComp = SCR_CampaignBuildingGadgetToolComponent.Cast(gadgetComp);
78 if (etoolComp && etoolComp.GetIsPlacementModeEnabled())
79 return false;
80 }
81 }
82
83 Vehicle veh = Vehicle.Cast(owner);
84 if (veh)
85 {
86 if (veh.IsOccupied())
87 return false;
88 }
89 else
90 {
91 SCR_BaseCompartmentManagerComponent compartmentManager = SCR_BaseCompartmentManagerComponent.Cast(owner.FindComponent(SCR_BaseCompartmentManagerComponent));
92 if (compartmentManager && compartmentManager.GetOccupantCount() > 0)
93 return false;
94 }
95
96 return super.CanBeShownScript(user);
97 }
98
99 //------------------------------------------------------------------------------------------------
100 override bool CanBePerformedScript(IEntity user)
101 {
102 IEntity owner = GetOwner();
103 if (!owner)
104 return false;
105
106 ChimeraCharacter character = ChimeraCharacter.Cast(user);
107 if (!character)
108 return false;
109
110 CharacterControllerComponent controller = character.GetCharacterController();
111 if (!controller)
112 return false;
113
114 if (m_eRequiredGadget != EGadgetType.NONE && m_GadgetManager)
115 {
116 if (!m_bActionStarted && !controller.CanUseItem())
117 {
118 SetCannotPerformReason(string.Empty);
119 return false;
120 }
121
122 if (controller.IsChangingStance())
123 {
124 SetCannotPerformReason(string.Empty);
125 return false;
126 }
127
128 if (m_eSavedStance >= 0 && m_eSavedStance != controller.GetStance())
129 { // without this if you time it just right, you would be able to break changing stance, and also cancel item animation playback
130 SetCannotPerformReason(string.Empty);
131 return false;
132 }
133
134 SCR_GadgetComponent gadgetComp = m_GadgetManager.GetHeldGadgetComponent();
135 if (!gadgetComp || gadgetComp.GetMode() != EGadgetMode.IN_HAND)
136 { // IN_HAND is set only when gadget is actually equipped, while CanUseItem will return true even when we play gadget equipping animation, and thus we can't actually play item animation :/
137 SetCannotPerformReason(string.Empty);
138 return false;
139 }
140 }
141
142 if (!m_bIsSelected)
144
146 {
148 return false;
149 }
150
151 SCR_MultiPartDeployableItemComponent multiPartComp = SCR_MultiPartDeployableItemComponent.Cast(m_DeployableItemComp);
152 if (!multiPartComp)
153 return false;
154
155 if (multiPartComp.GetCurrentlyCachedVariantId() != m_iVariantId)
156 multiPartComp.FetchVariantData(m_iVariantId);
157
158 vector angle;
159 vector transform[4];
160 if (multiPartComp.IsUsingPartPositionAndRotation())
161 {
162 owner.GetTransform(transform);
163 }
164 else
165 {
166 TraceParam param = new TraceParam();
167 array<IEntity> excludeArray = {owner, user};
168 param.ExcludeArray = excludeArray;
169 param.LayerMask = EPhysicsLayerPresets.Projectile;
170
171 vector position = owner.GetOrigin() + owner.VectorToParent(multiPartComp.GetAdditionaPlacementOffset()) + vector.Up * 0.1;
172 SCR_TerrainHelper.GetTerrainBasis(position, transform, owner.GetWorld(), false, param);
173
174 CharacterHeadAimingComponent headAiming = controller.GetHeadAimingComponent();
175 if (!headAiming)
176 return false;
177
178 vector charMat[4];
179 character.GetWorldTransform(charMat);
180 angle = headAiming.GetLookAngles();
181 angle = angle.AnglesToVector(); //Converts spherical coordinates to unit length vector
182 angle = angle.Multiply3(charMat); //Translate from local space to world space
183 angle = angle.VectorToAngles(); //Convert back to angles
184
185 if (!multiPartComp.IsSurfaceValid(param.TraceEnt, transform[3], param.TraceNorm, param.NodeIndex, param.ColliderIndex, param.SurfaceProps, param.TraceMaterial, param.ColliderName))
186 {
188 return false;
189 }
190 }
191
193 {
194 if (m_bIsSelected)
195 multiPartComp.VisualizeReplacementEntity(transform, angle);
196 else
197 multiPartComp.SetPreviewState(SCR_EPreviewState.NONE);
198 }
199
200 WorldTimestamp currentTimestamp = owner.GetWorld().GetTimestamp();
201 if (m_NextCheckTimestamp && currentTimestamp.Less(m_NextCheckTimestamp))
203
204 m_NextCheckTimestamp = currentTimestamp.PlusMilliseconds(VALIDATION_DELAY);
206
208 {
209 array<IEntity> outItems = {};
210 m_Storage.GetAll(outItems);
211 if (!outItems.IsEmpty())
212 {
214 return false;
215 }
216 }
217
218 if (m_bCheckTilt && !multiPartComp.CheckSurfaceTilt(transform[1]))
219 {
221 return false;
222 }
223
224 string failReason;
225 if (!multiPartComp.FindRequiredElements(failReason))
226 {
227 SetCannotPerformReason(failReason);
228 return false;
229 }
230
231 if (m_bCheckForAvailableSpace && !multiPartComp.CheckAvailableSpace(transform, angle, failReason))
232 {
233 SetCannotPerformReason(failReason);
234 return false;
235 }
236
237 if (m_bPreventIfIndoors && multiPartComp.CheckIfPositionIsIndoors(transform))
238 {
240 return false;
241 }
242
244 multiPartComp.SetPreviewState(SCR_EPreviewState.PLACEABLE);
245
247
249 }
250
251 //------------------------------------------------------------------------------------------------
252 override void SetCannotPerformReason(string reason)
253 {
254 SCR_MultiPartDeployableItemComponent multiPartComp = SCR_MultiPartDeployableItemComponent.Cast(m_DeployableItemComp);
255 if (multiPartComp)
256 {
257 if (m_bIsSelected)
258 multiPartComp.SetPreviewState(SCR_EPreviewState.BLOCKED);
259 else
260 multiPartComp.SetPreviewState(SCR_EPreviewState.NONE);
261 }
262
263 super.SetCannotPerformReason(reason);
264 }
265
266 //------------------------------------------------------------------------------------------------
267 override void PerformAction(IEntity pOwnerEntity, IEntity pUserEntity)
268 {
269 ChimeraCharacter character = ChimeraCharacter.Cast(pUserEntity);
270 if (!character)
271 return;
272
273 bool isAi;
274 if (SCR_CharacterHelper.IsPlayerOrAIOwner(character, isAi))
275 StopAction(character);
276
277 GetGame().GetCallqueue().CallLater(ResetDeployingDelayed, 100, param1: pUserEntity); //reset bool later so there is enough time for user action to disappear
278 RplComponent rplComp = SCR_EntityHelper.GetEntityRplComponent(pOwnerEntity);
279 if (!rplComp || !rplComp.IsOwner())//ensure that only owner of the entity is doing the rest
280 return;
281
282 SCR_MultiPartDeployableItemComponent multiPartComp = SCR_MultiPartDeployableItemComponent.Cast(m_DeployableItemComp);
283 if (!multiPartComp)
284 return;
285
286 //Do this again so other clients have the same data set
287 multiPartComp.FetchVariantData(m_iVariantId);
288 string failReason;
289 if (!multiPartComp.FindRequiredElements(failReason))
290 return;
291
292 multiPartComp.Deploy(m_iVariantId, pUserEntity, m_vDesiredDirection, false, !m_bReportAsDismantling);
293 OnConfirmed(pUserEntity);
294 }
295
296 //------------------------------------------------------------------------------------------------
297 override void OnActionStart(IEntity pUserEntity)
298 {
300 return;
301
302 m_CurrentUser = ChimeraCharacter.Cast(pUserEntity);
303 if (!m_CurrentUser)
304 return;
305
306 super.OnActionStart(pUserEntity);
307
309 ToggleCompartmentAccess(pUserEntity);
310
311 ChimeraCharacter character = ChimeraCharacter.Cast(pUserEntity);
312 if (!character)
313 return;
314
315 CharacterControllerComponent controller = character.GetCharacterController();
316 if (!controller)
317 return;
318
319 CharacterHeadAimingComponent headAiming = controller.GetHeadAimingComponent();
320 if (!headAiming)
321 return;
322
323 vector charMat[4];
324 character.GetWorldTransform(charMat);
325 m_vDesiredDirection = headAiming.GetLookAngles();
326 m_vDesiredDirection = m_vDesiredDirection.AnglesToVector(); //Converts spherical coordinates to unit length vector
327 m_vDesiredDirection = m_vDesiredDirection.Multiply3(charMat); //Translate from local space to world space
328 m_vDesiredDirection = m_vDesiredDirection.VectorToAngles(); //Convert back to angles
329
330 if (!m_bActionStarted)
331 return;//this is set only for the player who is doing the action
332
333 if (m_eRequiredGadget == EGadgetType.NONE)
334 return;
335
336 m_eSavedStance = controller.GetStance();
338 if (!m_GadgetManager)
339 return;
340
341 IEntity gadgetEntity = m_GadgetManager.GetHeldGadget();
342 if (!gadgetEntity)
343 return;
344
345 CharacterAnimationComponent animationComponent = controller.GetAnimationComponent();
346 int itemActionId = animationComponent.BindCommand("CMD_Item_Action");
347
349 params.SetEntity(gadgetEntity);
350 params.SetAllowMovementDuringAction(false);
351 params.SetKeepInHandAfterSuccess(true);
352 params.SetCommandID(itemActionId);
353 params.SetCommandIntArg(1);
354
355 controller.TryUseItemOverrideParams(params);
356 }
357
358 //------------------------------------------------------------------------------------------------
361 protected void ToggleCompartmentAccess(IEntity blockingUser = null)
362 {
363 IEntity owner = GetOwner();
364 if (!owner)
365 return;
366
367 SCR_BaseCompartmentManagerComponent compartmentMgr = SCR_BaseCompartmentManagerComponent.Cast(owner.FindComponent(SCR_BaseCompartmentManagerComponent));
368 if (!compartmentMgr)
369 return;
370
371 array<BaseCompartmentSlot> outCompartments = {};
372 if (compartmentMgr.GetCompartments(outCompartments) < 1)
373 return;
374
375 foreach (BaseCompartmentSlot compartment : outCompartments)
376 {
377 compartment.SetReserved(blockingUser);
378 }
379 }
380
381 //------------------------------------------------------------------------------------------------
382 override void OnActionCanceled(IEntity pOwnerEntity, IEntity pUserEntity)
383 {
384 super.OnActionCanceled(pOwnerEntity, pUserEntity);
385
386 m_CurrentUser = null;
389
390 m_eSavedStance = -1;
392 if (m_eRequiredGadget == EGadgetType.NONE)
393 return;
394
395 ChimeraCharacter character = ChimeraCharacter.Cast(pUserEntity);
396 if (!character)
397 return;
398
399 StopAction(character);
400 }
401
402 //------------------------------------------------------------------------------------------------
403 override bool GetActionNameScript(out string outName)
404 {
405 UIInfo info = GetUIInfo();
406 if (!info)
407 return false;
408
409 outName = WidgetManager.Translate(info.GetName(), info.GetDescription());
410 return true;
411 }
412
413 //------------------------------------------------------------------------------------------------
416 void StopAction(notnull ChimeraCharacter character)
417 {
419 return;
420
421 CharacterControllerComponent charController = character.GetCharacterController();
422 if (!charController)
423 return;
424
425 CharacterAnimationComponent animationComponent = charController.GetAnimationComponent();
426 if (!animationComponent)
427 return;
428
429 CharacterCommandHandlerComponent cmdHandler = animationComponent.GetCommandHandler();
430 if (cmdHandler)
431 cmdHandler.FinishItemUse(true);
432 }
433
434 //------------------------------------------------------------------------------------------------
435 override void OnActionSelected()
436 {
437 m_bIsSelected = true;
438 }
439
440 //------------------------------------------------------------------------------------------------
441 override void OnActionDeselected()
442 {
446
447 m_bIsSelected = false;
448 SCR_MultiPartDeployableItemComponent multiPartComp = SCR_MultiPartDeployableItemComponent.Cast(m_DeployableItemComp);
449 if (!multiPartComp)
450 return;
451
453 multiPartComp.SetPreviewState(SCR_EPreviewState.NONE);
454
455 multiPartComp.ClearCache();
456 }
457
458 //------------------------------------------------------------------------------------------------
459 // destructor
467}
ArmaReforgerScripted GetGame()
Definition game.c:1398
vector position
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
proto external Managed FindComponent(typename typeName)
proto external vector GetOrigin()
proto external BaseWorld GetWorld()
proto external void GetTransform(out vector mat[])
proto external IEntity GetParent()
proto external vector VectorToParent(vector vec)
SCR_BaseDeployableInventoryItemComponent m_DeployableItemComp
override void Init(IEntity pOwnerEntity, GenericComponent pManagerComponent)
override void PerformAction(IEntity pOwnerEntity, IEntity pUserEntity)
override void OnActionCanceled(IEntity pOwnerEntity, IEntity pUserEntity)
const int VALIDATION_DELAY
delay in ms used to control how often costly parts are executed
static RplComponent GetEntityRplComponent(notnull IEntity entity)
static SCR_GadgetManagerComponent GetGadgetManager(IEntity entity)
static IEntity GetLocalControlledEntity()
static bool GetTerrainBasis(vector pos, out vector result[4], BaseWorld world=null, bool noUnderwater=false, TraceParam trace=null)
UIInfo - allows to define UI elements.
Definition UIInfo.c:14
enum EPhysicsLayerPresets Vehicle
Definition gameLib.c:24
EPhysicsLayerPresets
Enum is filled by C++ by data in project config PhysicsSettings.LayerPresets.
Definition gameLib.c:19
IEntity GetOwner()
Owner entity of the fuel tank.
ECharacterStance
SCR_FieldOfViewSettings Attribute
Tuple param1