Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_RotorDamageManagerComponent.c
Go to the documentation of this file.
2 {
3 }
4 
5 class SCR_RotorDamageManagerComponent : SCR_DamageManagerComponent
6 {
7  protected VehicleHelicopterSimulation m_HelicopterSimulation;
9  protected SoundComponent m_SoundComponent;
10  protected SCR_RotorHitZone m_RotorHitZone;
11 
12  protected ParticleEffectEntity m_ParticleEffectEntity;
13  protected ref ParticleEffectEntitySpawnParams m_ParticleSpawnParams;
14  // Collider index for static rotor
15  protected int m_iShapeIndex1 = -1;
16 
17  protected const float MIN_ROTOR_DAMAGE = 15.0; //everything below 15.0 gets discarded when calling HandleDamage
18 
19  [Attribute(defvalue: "0.5")]
20  protected float m_fImpulseDamageMultiplier;
21 
22  [Attribute(defvalue: "1.0")]
23  protected float m_fRotorDamageMultiplier;
24 
25  [Attribute(defvalue: "1.0")]
27 
28  [Attribute(defvalue: "10.0")]
29  protected float m_fMinCharacterDamage;
30 
31  [Attribute(defvalue: "10000.0")]
32  protected float m_fMaxCharacterDamage;
33 
34  [Attribute("{4AAF69CCD1AEA70E}Particles/Vehicle/Helicopter/Rotor Collision Effects/Helicopter_Rotor_Collision_Main_Solid.ptc")]
35  protected ResourceName m_sDefaultParticlePath;
36 
37  [Attribute(defvalue: "2")]
38  protected int m_iEffectIndex;
39 
40  [Attribute(desc: "Blade collision sound event")]
41  protected string m_sImpactSoundEvent;
42 
43  //------------------------------------------------------------------------------------------------
44  protected void DamageRotors(float damage)
45  {
46  damage *= m_fRotorDamageMultiplier;
47  if (damage < MIN_ROTOR_DAMAGE)
48  damage = MIN_ROTOR_DAMAGE;
49 
50  m_RotorHitZone.HandleDamage(damage, EDamageType.COLLISION, null);
51  }
52 
53  //------------------------------------------------------------------------------------------------
54  protected void DamageOther(notnull IEntity other, float damage)
55  {
56  ChimeraCharacter character = ChimeraCharacter.Cast(other);
57  SCR_DamageManagerComponent characterDamageManager;
58  if (character)
59  characterDamageManager = character.GetDamageManager();
60 
61  if (!characterDamageManager || characterDamageManager.IsDestroyed())
62  return;
63 
65 
66  Physics otherPhysics = other.GetPhysics();
67  array<HitZone> characterHitZones = {};
68  characterDamageManager.GetAllHitZones(characterHitZones);
69 
70  foreach (HitZone characterHitZone : characterHitZones)
71  {
72  if (!characterHitZone.HasColliderNodes() || characterHitZone.GetDamageState() == EDamageState.DESTROYED)
73  continue;
74 
75  array<int> colliderIDs = {};
76  characterHitZone.GetColliderIDs(colliderIDs);
77 
78  foreach (int colliderID : colliderIDs)
79  {
80  if (m_RotorHitZone.HasCollision(otherPhysics.GetGeomWorldPosition(colliderID)))
81  {
82  characterHitZone.HandleDamage(damage, EDamageType.COLLISION, null);
83  break;
84  }
85  }
86  }
87  }
88 
89  //------------------------------------------------------------------------------------------------
90  protected void EmitRotorParticles(vector contactPos, GameMaterial contactMat)
91  {
92  //set particle emitter transform
93 
94  vector ownerTransform[4];
95  m_RootDamageManager.GetOwner().GetWorldTransform(ownerTransform);
96 
97  vector rotorTransformLocal[4];
98  m_HelicopterSimulation.RotorGetTransform(m_RotorHitZone.GetRotorIndex(), rotorTransformLocal);
99 
100  float rotorRadius = m_RotorHitZone.GetRotorRadius();
101  float rotorRadiusSq = rotorRadius * rotorRadius;
102 
103  vector rotorEdge = vector.Right * rotorRadius;
104  vector contactPositionLocal = contactPos.InvMultiply4(ownerTransform).InvMultiply4(rotorTransformLocal).Normalized() * rotorRadius;
105 
106  float distanceEdgeToContactSq = vector.DistanceSq(rotorEdge, contactPositionLocal);
107  float rotorContactAngle = Math.RAD2DEG * Math.Acos((2 * rotorRadiusSq - distanceEdgeToContactSq) / (2 * rotorRadiusSq));
108  if (contactPositionLocal[1] < 0) // if contact is below half-circle, add 180 degrees to complete 360 degree circle
109  rotorContactAngle = 360 - rotorContactAngle;
110 
111  vector rotationMatrix[3];
112  if (m_HelicopterSimulation.RotorGetSpinDirection(m_RotorHitZone.GetRotorIndex()) == SpinDirection.CLOCKWISE)
113  Math3D.AnglesToMatrix({180, 0, rotorContactAngle}, rotationMatrix);
114  else
115  Math3D.AnglesToMatrix({180, 0, rotorContactAngle + 180}, rotationMatrix);
116 
117  vector resultRotation[3];
118  Math3D.MatrixMultiply3(rotorTransformLocal, rotationMatrix, resultRotation);
119 
120  vector translatedTransform[4];
121  Math3D.MatrixMultiply3(ownerTransform, resultRotation, translatedTransform);
122  translatedTransform[3] = contactPos;
123 
124  //set particle emitter ptc
125  GameMaterial material = contactMat;
126  ParticleEffectInfo effectInfo = material.GetParticleEffectInfo();
127 
128  ResourceName resource = effectInfo.GetVehicleDustResource(m_iEffectIndex);
129  if (!resource || resource.IsEmpty())
130  resource = m_sDefaultParticlePath;
131 
132  //play effect
133  m_ParticleSpawnParams.Transform = translatedTransform;
134  m_ParticleEffectEntity = ParticleEffectEntity.SpawnParticleEffect(resource, m_ParticleSpawnParams);
135  }
136 
137  //------------------------------------------------------------------------------------------------
141  void PlayRotorImpactSound(vector contactPos, int contactShapeIndex1)
142  {
143  if (!m_SoundComponent)
144  return;
145 
146  if (m_sImpactSoundEvent.IsEmpty())
147  return;
148 
149  RotorState rotorState = m_HelicopterSimulation.RotorGetState(m_RotorHitZone.GetRotorIndex());
150  if (rotorState == RotorState.DESTROYED)
151  return;
152 
153  if (rotorState == RotorState.STATIC)
154  {
155  int shapeIndex1 = contactShapeIndex1;
156  if (m_iShapeIndex1 == shapeIndex1)
157  return;
158 
159  m_iShapeIndex1 = shapeIndex1;
160  }
161 
162  // Get sound position
163  vector mat[4];
164  Math3D.MatrixIdentity4(mat);
165  mat[3] = contactPos;
166 
167  m_SoundComponent.SoundEventTransform(m_sImpactSoundEvent, mat);
168  }
169 
170  //------------------------------------------------------------------------------------------------
171  override void OnDamageStateChanged(EDamageState state)
172  {
173  super.OnDamageStateChanged(state);
174 
176  if (state != EDamageState.DESTROYED)
177  SetEventMask(GetOwner(), EntityEvent.CONTACT);
178  else
179  ClearEventMask(GetOwner(), EntityEvent.CONTACT);
180  }
181 
182  //------------------------------------------------------------------------------------------------
183  protected bool TraceFilter(notnull IEntity e)
184  {
185  return e != GetOwner() && e != m_RootDamageManager.GetOwner(); // ignore if traced entity is rotor or hull
186  }
187 
188  //------------------------------------------------------------------------------------------------
190  [RplRpc(RplChannel.Unreliable, RplRcver.Broadcast)]
191  protected void RPC_OnContactBroadcast(vector contactPos, vector contactNormal, int contactShapeIndex1)
192  {
193  TraceParam trace = new TraceParam();
194  trace.Start = contactPos + contactNormal;
195  trace.End = contactPos - contactNormal;
196  trace.Flags = TraceFlags.WORLD | TraceFlags.ENTS;
197 
198  GetGame().GetWorld().TraceMove(trace, TraceFilter);
199 
200  GameMaterial contactMat = trace.SurfaceProps;
201 
202  EmitRotorParticles(contactPos, contactMat);
203  PlayRotorImpactSound(contactPos, contactShapeIndex1);
204  }
205 
206  //------------------------------------------------------------------------------------------------
207  override bool OnContact(IEntity owner, IEntity other, Contact contact)
208  {
209  if (!m_RotorHitZone)
210  return false;
211 
212  //compute damage
213 
214  vector rotorTransform[4];
215  m_RotorHitZone.GetPointInfo().GetTransform(rotorTransform);
216 
217  float rotorRPM = m_HelicopterSimulation.RotorGetRPM(m_RotorHitZone.GetRotorIndex()) * 0.1;
218  float rotorRadius = m_RotorHitZone.GetRotorRadius();
219  float rotorCenterToContact = vector.Distance(rotorTransform[3], contact.Position);
220  float rotorRPMMultiplier = Math.Clamp(rotorCenterToContact / rotorRadius, 0, 1);
221  int rotorBladeCount = m_RotorHitZone.GetBladeCount();
222 
223  if (rotorRadius <= 0)
224  rotorRadius = 1;
225  if (rotorBladeCount <= 0)
226  rotorBladeCount = 1;
227 
228  float damage = rotorRPM * rotorRPMMultiplier / m_RotorHitZone.GetBladeCount() + contact.Impulse * m_fImpulseDamageMultiplier;
229 
230  ChimeraCharacter character = ChimeraCharacter.Cast(other);
231  if (!character && m_RootDamageManager && contact.Impulse >= m_RootDamageManager.GetMinImpulse())
232  m_RootDamageManager.CollisionDamage(owner, other, contact);
233 
234  if (m_RotorHitZone.IsSpinning())
235  {
236  if (character)
237  DamageOther(other, damage);
238 
239  RPC_OnContactBroadcast(contact.Position, contact.Normal, contact.ShapeIndex1);
240  Rpc(RPC_OnContactBroadcast, contact.Position, contact.Normal, contact.ShapeIndex1);
241  }
242 
243  DamageRotors(damage);
244 
245  return super.OnContact(owner, other, contact);
246  }
247 
248  //------------------------------------------------------------------------------------------------
249  protected void GetComponentsDelayed()
250  {
251  IEntity root = GetOwner().GetRootParent();
252 
253  m_HelicopterSimulation = VehicleHelicopterSimulation.Cast(root.FindComponent(VehicleHelicopterSimulation));
255  m_SoundComponent = SoundComponent.Cast(root.FindComponent(SoundComponent));
256 
257  m_ParticleSpawnParams = new ParticleEffectEntitySpawnParams();
258  m_ParticleSpawnParams.TransformMode = ETransformMode.WORLD;
259  m_ParticleSpawnParams.UseFrameEvent = true;
260  }
261 
262  //------------------------------------------------------------------------------------------------
263  override void OnInit(IEntity owner)
264  {
265  super.OnInit(owner);
266 
267  // Do not do anything if the default hitzone is not rotor hitzone
268  m_RotorHitZone = SCR_RotorHitZone.Cast(GetDefaultHitZone());
269  if (!m_RotorHitZone)
270  return;
271 
272  GetGame().GetCallqueue().CallLater(GetComponentsDelayed); //get components after init
273 
274  RplComponent rplComp = RplComponent.Cast(GetOwner().FindComponent(RplComponent));
275  if (!rplComp || rplComp.IsProxy())
276  return;
277 
278  SetEventMask(GetOwner(), EntityEvent.CONTACT);
279  }
280 }
m_sDefaultParticlePath
protected ResourceName m_sDefaultParticlePath
Definition: SCR_RotorDamageManagerComponent.c:35
GetComponentsDelayed
protected void GetComponentsDelayed()
Definition: SCR_RotorDamageManagerComponent.c:249
m_fImpulseDamageMultiplier
protected float m_fImpulseDamageMultiplier
Definition: SCR_RotorDamageManagerComponent.c:20
m_sImpactSoundEvent
protected string m_sImpactSoundEvent
Definition: SCR_RotorDamageManagerComponent.c:41
m_HelicopterSimulation
SCR_RotorDamageManagerComponentClass m_HelicopterSimulation
OnContact
override bool OnContact(IEntity owner, IEntity other, Contact contact)
Definition: SCR_RotorDamageManagerComponent.c:207
m_RootDamageManager
protected SCR_VehicleDamageManagerComponent m_RootDamageManager
Definition: SCR_RotorDamageManagerComponent.c:8
HitZone
Definition: HitZone.c:12
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
m_fMaxCharacterDamage
protected float m_fMaxCharacterDamage
Definition: SCR_RotorDamageManagerComponent.c:32
SCR_VehicleDamageManagerComponent
void SCR_VehicleDamageManagerComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
Definition: SCR_VehicleDamageManagerComponent.c:1720
SCR_RotorDamageManagerComponentClass
Definition: SCR_RotorDamageManagerComponent.c:1
EDamageState
EDamageState
Definition: EDamageState.c:12
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
RplRpc
SCR_AchievementsHandlerClass ScriptComponentClass RplRpc(RplChannel.Reliable, RplRcver.Owner)] void UnlockOnClient(AchievementId achievement)
Definition: SCR_AchievementsHandler.c:11
DamageRotors
protected void DamageRotors(float damage)
Definition: SCR_RotorDamageManagerComponent.c:44
m_fMinCharacterDamage
protected float m_fMinCharacterDamage
Definition: SCR_RotorDamageManagerComponent.c:29
m_ParticleEffectEntity
protected ParticleEffectEntity m_ParticleEffectEntity
Definition: SCR_RotorDamageManagerComponent.c:12
Attribute
typedef Attribute
Post-process effect of scripted camera.
EmitRotorParticles
protected void EmitRotorParticles(vector contactPos, GameMaterial contactMat)
Definition: SCR_RotorDamageManagerComponent.c:90
MIN_ROTOR_DAMAGE
const protected float MIN_ROTOR_DAMAGE
Definition: SCR_RotorDamageManagerComponent.c:17
m_fCharacterDamageMultiplier
protected float m_fCharacterDamageMultiplier
Definition: SCR_RotorDamageManagerComponent.c:26
SCR_DamageManagerComponentClass
enum ECharacterHitZoneGroup SCR_DamageManagerComponentClass
RPC_OnContactBroadcast
protected void RPC_OnContactBroadcast(vector contactPos, vector contactNormal, int contactShapeIndex1)
Clients don't simulate physics so this rpc replicates collision information for particles,...
Definition: SCR_RotorDamageManagerComponent.c:191
m_RotorHitZone
protected SCR_RotorHitZone m_RotorHitZone
Definition: SCR_RotorDamageManagerComponent.c:10
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
DamageOther
protected void DamageOther(notnull IEntity other, float damage)
Definition: SCR_RotorDamageManagerComponent.c:54
m_iShapeIndex1
protected int m_iShapeIndex1
Definition: SCR_RotorDamageManagerComponent.c:15
m_SoundComponent
protected SoundComponent m_SoundComponent
Definition: SCR_RotorDamageManagerComponent.c:9
PlayRotorImpactSound
void PlayRotorImpactSound(vector contactPos, int contactShapeIndex1)
Definition: SCR_RotorDamageManagerComponent.c:141
m_fRotorDamageMultiplier
protected float m_fRotorDamageMultiplier
Definition: SCR_RotorDamageManagerComponent.c:23
m_ParticleSpawnParams
protected ref ParticleEffectEntitySpawnParams m_ParticleSpawnParams
Definition: SCR_RotorDamageManagerComponent.c:13
EDamageType
EDamageType
Definition: EDamageType.c:12
m_iEffectIndex
protected int m_iEffectIndex
Definition: SCR_RotorDamageManagerComponent.c:38
TraceFilter
protected bool TraceFilter(notnull IEntity e)
Definition: SCR_RotorDamageManagerComponent.c:183
ParticleEffectInfo
Definition: ParticleEffectInfo.c:12
RotorState
RotorState
Definition: RotorState.c:12
OnInit
override void OnInit(IEntity owner)
Definition: SCR_RotorDamageManagerComponent.c:263
OnDamageStateChanged
override void OnDamageStateChanged(EDamageState state)
Definition: SCR_RotorDamageManagerComponent.c:171
GameMaterial
Definition: GameMaterial.c:12
SpinDirection
SpinDirection
Definition: SpinDirection.c:12