Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_DestructionBaseHandler.c
Go to the documentation of this file.
1 #define ENABLE_BASE_DESTRUCTION
2 //------------------------------------------------------------------------------------------------
8 {
9  [Attribute("", UIWidgets.ResourceNamePicker, desc: "Model to swap to on destruction", params: "xob et")]
10  protected ResourceName m_sWreckModel;
11  [Attribute("1", UIWidgets.Slider, desc: "Delay for the wreck model switch upon destruction (ms)", params: "1 10000 1")]
12  protected int m_iWreckDelay;
13  [Attribute("100", UIWidgets.Slider, desc: "Default mass of the wreck physics, to be set if the part did not have physics before destruction", params: "0 10000 1")]
14  protected float m_fDefaultWreckMass;
15 
16  [Attribute("0", UIWidgets.CheckBox, "If true the part will detach from parent after hitzone is destroyed")]
17  protected bool m_bDetachAfterDestroyed;
18  [Attribute("1", UIWidgets.CheckBox, "If true the part will be hidden after it is destroyed, unless wreck model is provided")]
19  protected bool m_bAllowHideWreck;
20  [Attribute("1", UIWidgets.CheckBox, "If true and not detached the part will be deleted after parent entity is destroyed")]
21  protected bool m_bDeleteAfterParentDestroyed;
22  [Attribute("0", UIWidgets.CheckBox, "If true the physics will be disabled after hitzone is destroyed")]
23  protected bool m_bDisablePhysicsAfterDestroyed;
24 #ifdef ENABLE_BASE_DESTRUCTION
25 
26  protected IEntity m_pOwner; // TODO: Remove once we can get the owner dynamically
27  protected bool m_bIsDestructionDelayed;
28 
29  //------------------------------------------------------------------------------------------------
31  void StartDestruction(bool immediate = false)
32  {
33  if (immediate)
34  {
35  if (m_bIsDestructionDelayed)
36  GetGame().GetCallqueue().Remove(StartDestruction);
37 
38  // Delegation is only allowed through destruction manager, ensuring the event will always be triggered inside frame
39  // This includes deletion, physics deactivation, deletion
40  SCR_MPDestructionManager destructionManager = SCR_MPDestructionManager.GetInstance();
41  if (destructionManager)
42  destructionManager.DestroyInFrame(this);
43  else
44  Debug.DPrint("SCR_MPDestructionManager is missing, cannot perform DestroyInFrame");
45 
46  return;
47  }
48 
49  if (!m_bIsDestructionDelayed)
50  {
51  m_bIsDestructionDelayed = true;
52 
53  // The delay allows for particle effects to envelop vehicle before it is transformed to wreck.
54  // CallLater is used as a simple measure to delay that operation
55  GetGame().GetCallqueue().CallLater(StartDestruction, m_iWreckDelay, param1: true);
56  }
57  }
58 
59  //------------------------------------------------------------------------------------------------
61  void OnRepair()
62  {
63  if (!m_pOwner || m_pOwner.IsDeleted())
64  return;
65 
66  ResourceName object = SCR_Global.GetPrefabAttributeResource(m_pOwner, "MeshObject", "Object");
67  SetModel(object);
68 
69  // Some objects have no valid destruction physics
70  if (!m_bDisablePhysicsAfterDestroyed)
71  return;
72 
73  m_pOwner.SetFlags(EntityFlags.TRACEABLE, false);
74 
75  Physics physics = m_pOwner.GetPhysics();
76  if (!physics)
77  return;
78 
79  // Set proper physics simulation state for slotted entities, use just collision physics.
80  if (m_pOwner.GetParent())
81  physics.ChangeSimulationState(SimulationState.COLLISION);
82  else
83  physics.ChangeSimulationState(SimulationState.SIMULATION);
84  }
85 
86  //------------------------------------------------------------------------------------------------
89  void HandleDestruction()
90  {
91  m_bIsDestructionDelayed = false;
92 
93  if (!m_pOwner || m_pOwner.IsDeleted())
94  return;
95 
96  IEntity parent = m_pOwner.GetParent();
97  if (parent && parent.IsDeleted())
98  return;
99 
100  // Destroy all children slotted entities
101  array<EntitySlotInfo> slotInfos = {};
102  EntitySlotInfo.GetSlotInfos(m_pOwner, slotInfos);
103  foreach (EntitySlotInfo slotInfo : slotInfos)
104  {
105  if (!slotInfo)
106  continue;
107 
108  IEntity slotEntity = slotInfo.GetAttachedEntity();
109  if (!slotEntity)
110  continue;
111 
112  if (slotEntity.IsDeleted())
113  continue;
114 
115  HitZoneContainerComponent hitZoneContainer = HitZoneContainerComponent.Cast(slotEntity.FindComponent(HitZoneContainerComponent));
116  if (!hitZoneContainer)
117  continue;
118 
119  HitZone hitZone = hitZoneContainer.GetDefaultHitZone();
120  if (hitZone)
121  {
122  if (hitZone.GetDamageState() == EDamageState.DESTROYED)
123  {
124  SCR_DestructibleHitzone destructibleHitZone = SCR_DestructibleHitzone.Cast(hitZone);
125  if (destructibleHitZone)
126  destructibleHitZone.StartDestruction(true);
127  }
128  else
129  {
130  hitZone.SetHealth(0);
131  }
132  }
133  }
134 
135  // Check parent only if the part is not set to be deleted anyway
136  if (m_bDeleteAfterParentDestroyed && parent)
137  {
138  HitZoneContainerComponent parentContainer = HitZoneContainerComponent.Cast(parent.FindComponent(HitZoneContainerComponent));
139  if (parentContainer && parentContainer.GetDefaultHitZone() && parentContainer.GetDefaultHitZone().GetDamageState() == EDamageState.DESTROYED)
140  {
141  DeleteSelf();
142  return;
143  }
144  }
145 
146  if (m_bAllowHideWreck || !m_sWreckModel.IsEmpty())
147  SetModel(m_sWreckModel, m_bAllowHideWreck);
148 
149  if (m_bDetachAfterDestroyed)
150  DetachFromParent(true);
151 
152  // Some objects have no valid destruction physics
153  if (!m_bDisablePhysicsAfterDestroyed)
154  return;
155 
156  m_pOwner.ClearFlags(EntityFlags.TRACEABLE, false);
157 
158  Physics physics = m_pOwner.GetPhysics();
159  if (physics)
160  physics.ChangeSimulationState(SimulationState.NONE);
161  }
162 
163  //------------------------------------------------------------------------------------------------
166  private void DetachFromParent(bool updateHierarchy)
167  {
168  if (!m_pOwner || m_pOwner.IsDeleted())
169  return;
170 
171  IEntity parent = m_pOwner.GetParent();
172  if (!parent || parent.IsDeleted())
173  return;
174 
175  Physics physics = m_pOwner.GetPhysics();
176  if (!physics)
177  return;
178 
179  vector velocity = physics.GetVelocity();
180  vector angularVelocity = physics.GetAngularVelocity();
181 
182  EntitySlotInfo slotInfo = EntitySlotInfo.GetSlotInfo(m_pOwner);
183  if (slotInfo)
184  slotInfo.DetachEntity(updateHierarchy);
185 
186  if (physics.IsDynamic() && !m_pOwner.GetParent())
187  {
188  physics.SetVelocity(velocity);
189  physics.SetAngularVelocity(angularVelocity);
190  }
191  }
192 
193  //------------------------------------------------------------------------------------------------
195  void DeleteSelf()
196  {
197  if (!m_pOwner || m_pOwner.IsDeleted())
198  return;
199 
200  if (m_pOwner.GetParent())
201  DetachFromParent(false);
202 
203  m_pOwner.SetObject(null, string.Empty);
204  RplComponent.DeleteRplEntity(m_pOwner, true);
205  }
206 
207  //------------------------------------------------------------------------------------------------
212  protected void SetModel(ResourceName modelName, bool allowEmpty = false)
213  {
214  if (!m_pOwner || m_pOwner.IsDeleted())
215  return;
216 
217  Vehicle vehicle = Vehicle.Cast(m_pOwner);
218  if (vehicle)
219  {
220  vehicle.SetWreckModel(modelName);
222  if (effectComp)
223  effectComp.Deactivate(vehicle);
224  }
225  else
226  {
227  Resource resource = Resource.Load(modelName);
228  VObject model;
229  if (resource && resource.IsValid())
230  model = resource.GetResource().ToVObject();
231 
232  if (model || allowEmpty)
233  m_pOwner.SetObject(model, string.Empty);
234  }
235 
236  m_pOwner.Update();
237 
238  // If there is no model, ignore the rest
239  Physics physics = m_pOwner.GetPhysics();
240  if (!physics)
241  return;
242 
243  // If the object has dynamic physics, pass the state
244  float mass = physics.GetMass();
245  if (mass == 0)
246  mass = m_fDefaultWreckMass;
247 
248  if (physics.UpdateGeometries())
249  {
250  physics.SetActive(ActiveState.ACTIVE);
251  physics.EnableGravity(true);
252  m_pOwner.SetFlags(EntityFlags.TRACEABLE);
253  }
254  else
255  {
256  physics.ChangeSimulationState(SimulationState.NONE);
257  m_pOwner.ClearFlags(EntityFlags.TRACEABLE);
258  }
259  }
260 
261  //------------------------------------------------------------------------------------------------
262  void Init(IEntity owner, HitZone hitZone)
263  {
264  m_pOwner = owner;
265  }
266 #endif
267 }
HitZone
Definition: HitZone.c:12
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_DestructibleHitzone
Definition: SCR_DestructibleHitzone.c:3
EDamageState
EDamageState
Definition: EDamageState.c:12
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
EntitySlotInfo
Adds ability to attach an object to a slot.
Definition: EntitySlotInfo.c:8
HitZoneContainerComponent
Definition: HitZoneContainerComponent.c:12
Attribute
typedef Attribute
Post-process effect of scripted camera.
SCR_MPDestructionManager
Definition: SCR_MPDestructionManager.c:103
SCR_DestructionBaseHandler
Definition: SCR_DestructionBaseHandler.c:7
SCR_Global
Definition: Functions.c:6
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
SCR_BaseEffectManagerComponent
Definition: SCR_BaseEffectManagerComponent.c:11
BaseContainerProps
SCR_AIGoalReaction_Follow BaseContainerProps
Handles insects that are supposed to be spawned around selected prefabs defined in prefab names array...
Definition: SCR_AIGoalReaction.c:468