Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_FragmentEntity.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
3 {
4 };
5 
6 //------------------------------------------------------------------------------------------------
8 class SCR_FragmentEntity : BaseBuilding
9 {
10  #ifdef ENABLE_DESTRUCTION
11  protected SCR_DestructionFractalComponent m_DestructibleParent = null;
12  protected int m_iIndex = -1;
13  protected float m_fHealth = 10;
14 
15  //------------------------------------------------------------------------------------------------
17  bool GetIsAnchor()
18  {
19  return m_DestructibleParent.GetCurrentFractalVariant().GetFragmentIndexIsAnchor(m_iIndex);
20  }
21 
22  //------------------------------------------------------------------------------------------------
24  int GetIndex()
25  {
26  return m_iIndex;
27  }
28 
29  //------------------------------------------------------------------------------------------------
31  float GetHealth()
32  {
33  return m_fHealth;
34  }
35 
36  //------------------------------------------------------------------------------------------------
38  bool GetDestroyed()
39  {
40  return GetHealth() <= 0;
41  }
42 
43  //------------------------------------------------------------------------------------------------
45  SCR_DestructionFractalComponent GetDestructibleParent()
46  {
47  return m_DestructibleParent;
48  }
49 
50  //------------------------------------------------------------------------------------------------
52  void Initialize(SCR_DestructionFractalComponent destructibleParent, int index, float health, ResourceName assetPath)
53  {
54  m_DestructibleParent = destructibleParent;
55  m_iIndex = index;
56  m_fHealth = health;
57 
58  // Load the model, set physics and add this as child to parent
59  Resource resource = Resource.Load(assetPath);
60  VObject asset = resource.GetResource().ToVObject();
61  SetObject(asset, "");
62  m_DestructibleParent.GetOwner().AddChild(this, -1);
63  Update();
64  Physics phys = Physics.CreateStatic(this, -1);
65  if (phys)
66  SCR_PhysicsHelper.RemapInteractionLayer(phys, EPhysicsLayerDefs.Dynamic, EPhysicsLayerDefs.Static);
67  }
68 
69  //------------------------------------------------------------------------------------------------
71  override void EOnContact(IEntity owner, IEntity other, Contact contact)
72  {
73  if (GetDestroyed())
74  return;
75 
76  if (!m_DestructibleParent)
77  return;
78 
79  if (RplSession.Mode() == RplMode.Client) // Ignore impacts on clients
80  return;
81 
82  if (other && other.IsInherited(SCR_DebrisSmallEntity)) // Ignore impacts from debris
83  return;
84 
85  //if (other && other.IsInherited(ChimeraCharacter)) // Ignore character impacts
86  // return;
87 
88  // Get the physics of the dynamic object (if owner is static, then we use the other object instead)
89  Physics physics = owner.GetPhysics();
90  if ((!physics || !physics.IsDynamic()) && other && other.GetPhysics())
91  physics = other.GetPhysics();
92 
93  // In case neither had physics (this can only happen if contact is not called from physics step)
94  if (!physics)
95  return;
96 
97  // Now get the relative force, which is the impulse divided by the mass of the dynamic object
98  float relativeForce = 0;
99  if (physics.IsDynamic())
100  relativeForce = contact.Impulse / physics.GetMass();
101 
102  if (relativeForce < m_DestructibleParent.m_fRelativeContactForceThresholdMinimum) // Below minimum threshold, ignore
103  return;
104 
105  float damage = relativeForce * m_DestructibleParent.m_fForceToDamageScale;
106 
107  IEntity otherParent = null;
108  if (other)
109  otherParent = other.GetParent();
110 
111  vector outMat[3];
112  vector relativeVelocityBefore = contact.VelocityBefore2 - contact.VelocityBefore1;
113 
114  outMat[0] = contact.Position; // Hit position
115  outMat[1] = relativeVelocityBefore.Normalized(); // Hit direction
116  outMat[2] = contact.Normal; // Hit normal
117 
118  // Send damage to damage handling
119  OnDamage(damage, EDamageType.KINETIC, other, outMat, other, otherParent, string.Empty, contact.GetRelativeNormalVelocityAfter() - contact.GetRelativeNormalVelocityBefore());
120 
121  // Not destroyed yet, ignore
122  if (!GetDestroyed())
123  return;
124 
125  physics = owner.GetPhysics();
126  if (!physics)
127  return;
128 
129  // Set collision layer to none to avoid further contacts
130  physics.SetInteractionLayer(EPhysicsLayerDefs.VehicleCast);
131 
132  // Static physics, so add previous velocity to impactor as it otherwise "bounces"
133  if (!physics.IsDynamic())
134  {
135  auto otherPhysics = other.GetPhysics();
136  if (otherPhysics && otherPhysics.IsDynamic())
137  {
138  vector relativeVelocityAfter = contact.VelocityAfter2 - contact.VelocityAfter1;
139  otherPhysics.SetVelocity((relativeVelocityAfter - relativeVelocityBefore) * -1 + otherPhysics.GetVelocity());
140  }
141  }
142  }
143 
144  //------------------------------------------------------------------------------------------------
146  override void EOnFrame(IEntity owner, float timeSlice)
147  {
148  delete this;
149  }
150 
151  //------------------------------------------------------------------------------------------------
153  override void OnDamage(float damage, EDamageType type, IEntity pHitEntity, inout vector outMat[3], IEntity damageSource, notnull Instigator instigator, int colliderID, float speed)
154  {
155  if (!m_DestructibleParent)
156  return;
157 
158  if (damage < m_DestructibleParent.m_fDamageThresholdMinimum) // Below minimum threshold, ignore
159  return;
160 
161  if (RplSession.Mode() == RplMode.Client)
162  return;
163 
164  // Maximum damage threshold, destroy entirely
165  if (damage >= m_DestructibleParent.m_fDamageThresholdMaximum)
166  {
167  m_DestructibleParent.OnDamage(damage, type, pHitEntity, outMat, damageSource, damageSourceParent, colliderID, speed);
168  return;
169  }
170 
171  // Reduce health
172  m_fHealth -= damage;
173  if (m_fHealth < 0)
174  m_fHealth = 0;
175 
176  if (m_fHealth > 0) // Health above 0, ignore
177  return;
178 
179  // Reached 0 health, destroy
180  m_DestructibleParent.OnFragmentDestroyed(this, type, damage, outMat[0], outMat[1]);
181  QueueDestroy(type, damage, outMat[0], outMat[1]);
182  }
183 
184  //------------------------------------------------------------------------------------------------
185  void QueueDestroy(EDamageType damageType, float damage, vector hitPosition, vector hitDirection, bool doParticleFX = true)
186  {
187  if (doParticleFX)
188  SCR_DestructionCommon.PlayParticleEffect_FractionDestruction(this, m_DestructibleParent.m_ParticleDestroyFragment, damageType, hitPosition, hitDirection);
189 
190  SCR_FragmentDebris debrisSettings = m_DestructibleParent.m_DebrisDestroyFragment;
191  if (debrisSettings)
192  debrisSettings.Spawn(this, m_DestructibleParent.GetOwner().GetPhysics(), damage, hitDirection);
193 
194  m_DestructibleParent.GetOwner().RemoveChild(this);
195  SetEventMask(EntityEvent.FRAME); // We will delete on the next frame
196  }
197 
198  //------------------------------------------------------------------------------------------------
199  void SCR_FragmentEntity(IEntitySource src, IEntity parent)
200  {
201  SetEventMask(EntityEvent.CONTACT);
202  }
203  #endif
204 };
m_fHealth
protected float m_fHealth
Definition: SCR_FuelNode.c:60
OnDamage
override protected void OnDamage(notnull BaseDamageContext damageContext)
Definition: SCR_ArmorDamageManagerComponent.c:11
QueueDestroy
void QueueDestroy()
Called when the object should be destroyed and various effects or other things need to be performed (...
Definition: SCR_DestructionBaseComponent.c:260
EOnFrame
override void EOnFrame(IEntity owner, float timeSlice)
Definition: SCR_PlayerProfileManagerComponent.c:199
EOnContact
override void EOnContact(IEntity owner, IEntity other, Contact contact)
Definition: SCR_ParticleContactComponent.c:89
SCR_FragmentEntity
An entity used to represent fragments of destructible objects such as glass shards or wood splinters.
Definition: SCR_FragmentEntity.c:8
SCR_DestructionFractalComponent
Fractal destruction component. For objects that should shatter/splinter etc.
Definition: SCR_DestructionFractalComponent.c:34
Instigator
Definition: Instigator.c:6
GetHealth
float GetHealth()
Definition: SCR_FuelNode.c:196
SCR_FragmentEntityClass
Definition: SCR_FragmentEntity.c:2
Update
override void Update(float timeSlice)
Definition: SCR_CampaignBuildingGadgetToolComponent.c:28
BaseBuildingClass
Definition: BaseBuilding.c:12
Initialize
void Initialize()
Definition: SCR_CampaignMilitaryBaseComponent.c:181
SCR_DebrisSmallEntity
Definition: DebrisSmallEntity.c:14
SCR_PhysicsHelper
Definition: SCR_PhysicsHelper.c:6
m_iIndex
private int m_iIndex
Definition: SCR_StressTestGroupActivation.c:11
index
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
Definition: SCR_DestructionSynchronizationComponent.c:17
GetDestroyed
bool GetDestroyed()
Definition: SCR_DestructionBaseComponent.c:142
type
EDamageType type
Definition: SCR_DestructibleTreeV2.c:32
EDamageType
EDamageType
Definition: EDamageType.c:12
SCR_FragmentDebris
Definition: SCR_DestructionFractalComponent.c:1160
SCR_DestructionCommon
Class containing common functions between destructible classes.
Definition: SCR_DestructionCommon.c:7