6 class SCR_MeleeHitDataClass
27 #ifdef SCR_MELEE_DEBUG
28 ref array<ref Shape> m_aDbgSamplePositionsShapes;
29 ref array<ref Shape> m_aDbgCollisionShapes;
32 private ref SCR_MeleeHitDataClass m_MeleeHitData;
33 private bool m_bMeasurementDone;
34 private bool m_bAttackAlreadyExecuted =
false;
35 private bool m_bMeleeAttackStarted =
false;
36 private float m_fMWPWeaponRange = 1;
43 if (!m_OnMeleePerformed)
46 return m_OnMeleePerformed;
53 if (m_bAttackAlreadyExecuted)
56 #ifdef SCR_MELEE_DEBUG
61 CollectMeleeWeaponProperties();
62 m_bAttackAlreadyExecuted =
true;
68 void SetMeleeAttackStarted(
bool started)
70 m_bMeleeAttackStarted = started;
77 protected bool TraceFilter(notnull IEntity e)
79 return !SCR_ArmorDamageManagerComponent.Cast(e.FindComponent(SCR_ArmorDamageManagerComponent));
86 protected bool CheckCollisionsSimple(out SCR_MeleeHitDataClass pHitData)
88 ChimeraCharacter character = ChimeraCharacter.Cast(
GetOwner());
89 TraceSphere param =
new TraceSphere();
90 param.Exclude = character;
91 param.LayerMask = EPhysicsLayerDefs.Projectile;
92 param.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
94 param.Start = character.EyePosition();
96 param.End = param.Start + GetPlayersDirection(character) * m_fMWPWeaponRange;
99 float hit = character.GetWorld().TraceMove(param, TraceFilter);
104 vector dir = (param.End - param.Start);
106 pHitData.m_Entity = param.TraceEnt;
107 pHitData.m_iColliderIndex = param.ColliderIndex;
108 pHitData.m_vHitPosition = dir * hit + param.Start;
109 pHitData.m_vHitDirection = dir.Normalized();
110 pHitData.m_vHitNormal = param.TraceNorm;
111 pHitData.m_SurfaceProps = param.SurfaceProps;
112 pHitData.m_iNodeIndex = param.NodeIndex;
114 #ifdef SCR_MELEE_DEBUG_MSG
115 MCDbgPrint(
"Check collision from: "+param.Start);
116 MCDbgPrint(
"Check collision to: "+param.End);
117 MCDbgPrint(
"Check collision range: " +vector.Distance(param.End, param.Start));
118 MCDbgPrint(
"Check collision entity: "+pHitData.m_Entity.ToString());
119 MCDbgPrint(
"Check collision hitzone: "+pHitData.m_sHitZoneName);
120 MCDbgPrint(
"Check collision hitPos: "+pHitData.m_vHitPosition);
130 protected void CollectMeleeWeaponProperties()
132 BaseWeaponManagerComponent wpnManager = BaseWeaponManagerComponent.Cast(
GetOwner().FindComponent(BaseWeaponManagerComponent));
141 m_MeleeHitData.m_Weapon = currentSlot.GetWeaponEntity();
143 IEntity weaponEntity = currentSlot.GetWeaponEntity();
148 if (!meleeWeaponProperties)
151 m_MeleeHitData.m_fDamage = meleeWeaponProperties.GetWeaponDamage();
152 m_fMWPWeaponRange = meleeWeaponProperties.GetWeaponRange();
157 protected vector GetPlayersDirection(ChimeraCharacter character)
161 Math3D.AnglesToMatrix(character.GetCharacterController().GetInputContext().GetAimingAngles() * Math.RAD2DEG, aimMat);
168 protected void HandleMeleeSound()
170 IEntity weapon = m_MeleeHitData.m_Weapon;
178 int surfaceInt = material.GetSoundInfo().GetSignalValue();
180 PlaySound(m_MeleeHitData.m_Weapon, m_MeleeHitData.m_vHitPosition, m_MeleeHitData.m_iColliderIndex, surfaceInt);
182 RplComponent weaponRpl = RplComponent.Cast(m_MeleeHitData.m_Weapon.FindComponent(RplComponent));
186 Rpc(RPC_HandleMeleeSound, weaponRpl.Id(), m_MeleeHitData.m_vHitPosition, m_MeleeHitData.m_iColliderIndex, surfaceInt);
189 if (DiagMenu.GetBool(
SCR_DebugMenuID.DEBUGUI_SOUNDS_PRINT_MELEESURFACE))
191 Print(
string.Format(
"HitZone: %1", m_MeleeHitData.m_iColliderIndex), LogLevel.NORMAL);
192 Print(
string.Format(
"Surface: %1", surfaceInt), LogLevel.NORMAL);
193 Print(
string.Format(
"-------------------------------------"), LogLevel.NORMAL);
199 protected void PlaySound(IEntity weaponEntity, vector
position,
int signalValue0,
int signalValue1)
201 SoundComponent soundComp = SoundComponent.Cast(weaponEntity.FindComponent(SoundComponent));
205 soundComp.SetSignalValueStr(
"HitZone", signalValue0);
206 soundComp.SetSignalValueStr(
"Surface", signalValue1);
209 Math3D.MatrixIdentity3(transform);
212 soundComp.SoundEventTransform(
SCR_SoundEvent.SOUND_MELEE_IMPACT, transform);
216 [
RplRpc(RplChannel.Unreliable, RplRcver.Broadcast)]
217 protected void RPC_HandleMeleeSound(RplId weaponID, vector
position,
int signalValue0,
int signalValue1)
219 RplComponent weaponRpl = RplComponent.Cast(Replication.FindItem(weaponID));
223 IEntity weaponEntity = weaponRpl.GetEntity();
227 PlaySound(weaponEntity,
position, signalValue0, signalValue1);
235 protected SCR_DamageManagerComponent SearchHierarchyForDamageManager(IEntity startEntity, out
HitZone hitZone)
240 SCR_DamageManagerComponent damageManager;
243 damageManager = SCR_DamageManagerComponent.GetDamageManager(startEntity);
247 startEntity = startEntity.GetParent();
251 hitZone = damageManager.GetDefaultHitZone();
253 return damageManager;
258 protected void ProcessMeleeAttack()
260 RplComponent rplComponent = RplComponent.Cast(
GetOwner().FindComponent(RplComponent));
261 if (rplComponent && rplComponent.IsProxy())
264 if (!CheckCollisionsSimple(m_MeleeHitData))
267 if (m_MeleeHitData.m_Weapon)
270 #ifdef SCR_MELEE_DEBUG
271 m_aDbgSamplePositionsShapes.Clear();
272 Debug_DrawSphereAtPos(m_MeleeHitData.m_vHitPosition, m_aDbgSamplePositionsShapes, 0xff00ff00, 0.03, ShapeFlags.NOZBUFFER);
275 vector hitPosDirNorm[3];
276 hitPosDirNorm[0] = m_MeleeHitData.m_vHitPosition;
277 hitPosDirNorm[1] = m_MeleeHitData.m_vHitDirection;
278 hitPosDirNorm[2] = m_MeleeHitData.m_vHitNormal;
280 if (m_OnMeleePerformed)
281 m_OnMeleePerformed.Invoke(
GetOwner());
285 if (destructibleEntity)
287 destructibleEntity.HandleDamage(
EDamageType.MELEE, m_MeleeHitData.m_fDamage, hitPosDirNorm);
293 SCR_DamageManagerComponent damageManager = SearchHierarchyForDamageManager(m_MeleeHitData.m_Entity, hitZone);
294 if (!hitZone && damageManager)
295 hitZone = damageManager.GetDefaultHitZone();
307 protected void Do_OnFrameCleanup()
309 m_bAttackAlreadyExecuted =
false;
310 m_bMeasurementDone =
false;
313 #ifdef SCR_MELEE_DEBUG
317 protected void Do_ClearDbgShapes()
319 m_aDbgSamplePositionsShapes.Clear();
320 m_aDbgCollisionShapes.Clear();
330 protected void Debug_DrawSphereAtPos(vector v, array<ref Shape> dbgShapes,
int color = COLOR_BLUE,
float size = 0.03, ShapeFlags shapeFlags = ShapeFlags.VISIBLE)
332 shapeFlags = ShapeFlags.NOOUTLINE | shapeFlags;
335 Math3D.MatrixIdentity4(matx);
343 protected void Debug_DrawSphereAtPos(vector pos,
int color, array<ref Shape> dbgShapes)
346 Math3D.MatrixIdentity4(matx);
348 int shapeFlags = ShapeFlags.NOOUTLINE|ShapeFlags.NOZBUFFER|ShapeFlags.TRANSP;
349 Shape s = Shape.CreateSphere(color, shapeFlags, pos, 0.05);
355 protected void Debug_DrawLineSimple(vector start, vector end, array<ref Shape> dbgShapes)
361 int shapeFlags = ShapeFlags.NOOUTLINE;
362 Shape s = Shape.CreateLines(ARGBF(1, 1, 1, 1), shapeFlags, p, 2);
366 #ifdef SCR_MELEE_DEBUG_MSG
370 protected void MCDbgPrint(
string msg =
"")
372 Print(
"\\_ SCR_MELEE_DEBUG] " +
GetGame().GetTickCount().ToString() +
" ** " + msg, LogLevel.NORMAL);
383 void Update(
float timeSlice)
385 if (!m_bAttackAlreadyExecuted || !m_bMeleeAttackStarted || m_bMeasurementDone)
389 #ifdef SCR_MELEE_DEBUG
390 vector start = ChimeraCharacter.Cast(
GetOwner()).EyePosition();
392 vector end = start + GetPlayersDirection() * m_fMWPWeaponRange;
394 Debug_DrawLineSimple(start, end, m_aDbgCollisionShapes);
395 Debug_DrawSphereAtPos(start, ARGBF(0.75, 0, 0, 1), m_aDbgCollisionShapes);
396 Debug_DrawSphereAtPos(end, ARGBF(0.75, 0, 0, 1), m_aDbgCollisionShapes);
399 ProcessMeleeAttack();
400 m_bMeasurementDone =
true;
404 override void OnPostInit(IEntity owner)
406 super.OnPostInit(owner);
407 SetEventMask(owner, EntityEvent.INIT);
411 override void EOnInit(IEntity owner)
413 m_MeleeHitData =
new SCR_MeleeHitDataClass;
415 if (!
GetGame().GetWorldEntity())
419 DiagMenu.RegisterBool(
SCR_DebugMenuID.DEBUGUI_SOUNDS_PRINT_MELEESURFACE,
"",
"Print Melee Surface",
"Sounds");
422 #ifdef SCR_MELEE_DEBUG
423 m_aDbgSamplePositionsShapes = {};
424 m_aDbgCollisionShapes = {};