1 #define ENABLE_BASE_DESTRUCTION
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;
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
26 protected IEntity m_pOwner;
27 protected bool m_bIsDestructionDelayed;
31 void StartDestruction(
bool immediate =
false)
35 if (m_bIsDestructionDelayed)
36 GetGame().GetCallqueue().Remove(StartDestruction);
41 if (destructionManager)
42 destructionManager.DestroyInFrame(
this);
44 Debug.DPrint(
"SCR_MPDestructionManager is missing, cannot perform DestroyInFrame");
49 if (!m_bIsDestructionDelayed)
51 m_bIsDestructionDelayed =
true;
55 GetGame().GetCallqueue().CallLater(StartDestruction, m_iWreckDelay, param1:
true);
63 if (!m_pOwner || m_pOwner.IsDeleted())
66 ResourceName
object =
SCR_Global.GetPrefabAttributeResource(m_pOwner,
"MeshObject",
"Object");
70 if (!m_bDisablePhysicsAfterDestroyed)
73 m_pOwner.SetFlags(EntityFlags.TRACEABLE,
false);
75 Physics physics = m_pOwner.GetPhysics();
80 if (m_pOwner.GetParent())
81 physics.ChangeSimulationState(SimulationState.COLLISION);
83 physics.ChangeSimulationState(SimulationState.SIMULATION);
89 void HandleDestruction()
91 m_bIsDestructionDelayed =
false;
93 if (!m_pOwner || m_pOwner.IsDeleted())
96 IEntity parent = m_pOwner.GetParent();
97 if (parent && parent.IsDeleted())
101 array<EntitySlotInfo> slotInfos = {};
108 IEntity slotEntity = slotInfo.GetAttachedEntity();
112 if (slotEntity.IsDeleted())
116 if (!hitZoneContainer)
119 HitZone hitZone = hitZoneContainer.GetDefaultHitZone();
125 if (destructibleHitZone)
126 destructibleHitZone.StartDestruction(
true);
130 hitZone.SetHealth(0);
136 if (m_bDeleteAfterParentDestroyed && parent)
139 if (parentContainer && parentContainer.GetDefaultHitZone() && parentContainer.GetDefaultHitZone().GetDamageState() ==
EDamageState.DESTROYED)
146 if (m_bAllowHideWreck || !m_sWreckModel.IsEmpty())
147 SetModel(m_sWreckModel, m_bAllowHideWreck);
149 if (m_bDetachAfterDestroyed)
150 DetachFromParent(
true);
153 if (!m_bDisablePhysicsAfterDestroyed)
156 m_pOwner.ClearFlags(EntityFlags.TRACEABLE,
false);
158 Physics physics = m_pOwner.GetPhysics();
160 physics.ChangeSimulationState(SimulationState.NONE);
166 private void DetachFromParent(
bool updateHierarchy)
168 if (!m_pOwner || m_pOwner.IsDeleted())
171 IEntity parent = m_pOwner.GetParent();
172 if (!parent || parent.IsDeleted())
175 Physics physics = m_pOwner.GetPhysics();
179 vector velocity = physics.GetVelocity();
180 vector angularVelocity = physics.GetAngularVelocity();
184 slotInfo.DetachEntity(updateHierarchy);
186 if (physics.IsDynamic() && !m_pOwner.GetParent())
188 physics.SetVelocity(velocity);
189 physics.SetAngularVelocity(angularVelocity);
197 if (!m_pOwner || m_pOwner.IsDeleted())
200 if (m_pOwner.GetParent())
201 DetachFromParent(
false);
203 m_pOwner.SetObject(
null,
string.Empty);
204 RplComponent.DeleteRplEntity(m_pOwner,
true);
212 protected void SetModel(ResourceName modelName,
bool allowEmpty =
false)
214 if (!m_pOwner || m_pOwner.IsDeleted())
217 Vehicle vehicle = Vehicle.Cast(m_pOwner);
220 vehicle.SetWreckModel(modelName);
223 effectComp.Deactivate(vehicle);
227 Resource resource = Resource.Load(modelName);
229 if (resource && resource.IsValid())
230 model = resource.GetResource().ToVObject();
232 if (model || allowEmpty)
233 m_pOwner.SetObject(model,
string.Empty);
239 Physics physics = m_pOwner.GetPhysics();
244 float mass = physics.GetMass();
246 mass = m_fDefaultWreckMass;
248 if (physics.UpdateGeometries())
250 physics.SetActive(ActiveState.ACTIVE);
251 physics.EnableGravity(
true);
252 m_pOwner.SetFlags(EntityFlags.TRACEABLE);
256 physics.ChangeSimulationState(SimulationState.NONE);
257 m_pOwner.ClearFlags(EntityFlags.TRACEABLE);
262 void Init(IEntity owner,
HitZone hitZone)