DayZ 1.24
Loading...
Searching...
No Matches
ZombieBase.c
Go to the documentation of this file.
2{
3 const float TARGET_CONE_ANGLE_CHASE = 20;
4 const float TARGET_CONE_ANGLE_FIGHT = 30;
5 const float ORIENTATION_SYNC_THRESHOLD = 30; //threshold for local heading/orientation sync
6
7 const float SHOCK_TO_STUN_MULTIPLIER = 2.82;
8
10 protected int m_StanceVariation = 0;
11 protected int m_LastMindState = -1;
12 protected float m_LastMovementSpeed = -1;
13
14 protected bool m_KnuckleLand = false;
15 protected float m_KnuckleOutTimer = 0;
16
17 protected int m_MindState = -1;
18 protected int m_OrientationLocal = -1; //local 'companion' value for sync checking
19 protected int m_OrientationSynced = -1;
20 protected float m_OrientationTimer;
21 protected float m_MovementSpeed = -1;
22
24 protected float m_DeltaTime;
25
28
31
32 //static ref map<int,ref array<string>> m_FinisherSelectionMap; //! which selections in the FireGeometry trigger which finisher on hit (when applicable)
33
34 protected bool m_IsCrawling; //'DayZInfectedCommandCrawl' is transition to crawl only, 'DayZInfectedCommandMove' used after that, hence this VARIABLE_WET
35
36 protected bool m_FinisherInProgress = false; //is this object being backstabbed?
37
39
40
41 //-------------------------------------------------------------
43 {
44 Init();
45 }
46
47 void Init()
48 {
49 SetEventMask(EntityEvent.INIT);
50
51 m_IsCrawling = false;
52
53 RegisterNetSyncVariableInt("m_MindState", -1, 4);
54 RegisterNetSyncVariableInt("m_OrientationSynced", 0, 359);
55 RegisterNetSyncVariableFloat("m_MovementSpeed", -1, 3);
56 RegisterNetSyncVariableBool("m_IsCrawling");
57
59 m_DefaultHitPosition = SetDefaultHitPosition(GetDayZInfectedType().GetDefaultHitPositionComponent());
60
62 if (!GetGame().IsDedicatedServer())
63 {
64 m_LastSoundVoiceAW = null;
65 m_InfectedSoundEventHandler = new InfectedSoundEventHandler(this);
66 }
67
72
73 m_OrientationTimer = 0;
74
76 }
77
80 {
81 DebugSound("[Infected @ " + this + "][OnVariablesSynchronized]");
82 HandleSoundEvents();
83
84 if (m_OrientationLocal != m_OrientationSynced)
85 m_OrientationLocal = m_OrientationSynced;
86 }
87
88 //-------------------------------------------------------------
89 override void EOnInit(IEntity other, int extra)
90 {
91 if (!GetGame().IsMultiplayer() || GetGame().IsServer())
92 {
93 m_StanceVariation = Math.RandomInt(0, 4);
94
96 moveCommand.SetStanceVariation(m_StanceVariation);
97 }
98 }
99
100 override bool IsZombie()
101 {
102 return true;
103 }
104
105 override bool IsDanger()
106 {
107 return true;
108 }
109
110 override bool IsZombieMilitary()
111 {
112 return false;
113 }
114
115 bool IsMale()
116 {
117 return true;
118 }
119
120 override bool CanBeBackstabbed()
121 {
122 return true;
123 }
124
125 //-------------------------------------------------------------
127 {
128 return AnimBootsType.Boots;
129 }
130
131 override bool CanBeSkinned()
132 {
133 return false;
134 }
135 //-------------------------------------------------------------
136 override bool IsHealthVisible()
137 {
138 return false;
139 }
140 //-------------------------------------------------------------
142 {
143 return false;
144 }
145
147 override string GetHitComponentForAI()
148 {
149 return GetDayZInfectedType().GetHitComponentForAI();
150 }
151
153 override string GetDefaultHitComponent()
154 {
155 return GetDayZInfectedType().GetDefaultHitComponent();
156 }
157
159 {
160 return m_DefaultHitPosition;
161 }
162
164 {
165 return GetSelectionPositionMS(pSelection);
166 }
167
170 {
171 return GetDayZInfectedType().GetSuitableFinisherHitComponents();
172 }
173
175 {
176 return m_MindState;
177 }
178
181 {
182 return m_OrientationSynced;
183 }
184
185 //-------------------------------------------------------------
189
191 {
192 m_DeltaTime = pDt;
193
196 return;
197
199 if (pCurrentCommandID != DayZInfectedConstants.COMMANDID_DEATH)
200 {
201 if (HandleDeath(pCurrentCommandID))
202 return;
203 }
204 else if (!pCurrentCommandFinished)
205 return;
206
207
209 HandleMove(pCurrentCommandID);
210 HandleOrientation(pDt, pCurrentCommandID);
211
214 {
217 moveCommand.SetStanceVariation(m_StanceVariation);
218
219 return;
220 }
221
224 return;
225
227 if (HandleCrawlTransition(pCurrentCommandID))
228 return;
229
231 if (HandleDamageHit(pCurrentCommandID))
232 return;
233
235 if (inputController)
236 {
237 if (HandleVault(pCurrentCommandID, inputController, pDt))
238 return;
239
240 if (HandleMindStateChange(pCurrentCommandID, inputController, pDt))
241 return;
242
243 if (FightLogic(pCurrentCommandID, inputController, pDt))
244 return;
245 }
246
249 return;
250 }
251
252 //-------------------------------------------------------------
256
258 {
259 if (GetPluginManager())
260 {
261 PluginDayZInfectedDebug infectedDebug = PluginDayZInfectedDebug.Cast(GetPluginManager().GetPluginByType(PluginDayZInfectedDebug));
262 if (infectedDebug)
263 infectedDebug.CommandHandler(this);
264 }
265 }
266 //-------------------------------------------------------------
270
272 {
274 m_MovementSpeed = ic.GetMovementSpeed();
275 if (Math.AbsFloat(m_LastMovementSpeed - m_MovementSpeed) >= 0.9 && m_LastMovementSpeed != m_MovementSpeed)
276 SetSynchDirty();
277
278 m_LastMovementSpeed = m_MovementSpeed;
279 }
280
281 //-------------------------------------------------------------
285
287 {
288 m_OrientationTimer += pDt;
289
290 int yaw = Math.Round(GetOrientation()[0]);
292
293 //atan2(sin(x-y), cos(x-y))
294 float angleSourceRad = m_OrientationSynced * Math.DEG2RAD;
295 float angleTargetRad = yaw * Math.DEG2RAD;
296
300
301 if (m_OrientationTimer >= 2.0 || m_OrientationSynced == -1 || Math.AbsInt(angleDiffRad) > ORIENTATION_SYNC_THRESHOLD)
302 {
303 m_OrientationTimer = 0.0;
304
305 if (m_OrientationSynced == -1 || Math.AbsInt(angleDiffRad) > 5)
306 {
307 //Print("DbgSyncOrientation | HandleMove | original: " + m_OrientationSynced + " | target: " + yaw + " | diff: " + angleDiffRad);
308 m_OrientationSynced = yaw;
309 SetSynchDirty();
310 }
311 }
312 }
313
314 //-------------------------------------------------------------
318
319 float m_DamageHitDirection = 0;
320 int m_DeathType = 0;
321
323 {
324 if (!IsAlive() || m_FinisherInProgress)
325 {
326 StartCommand_Death(m_DeathType, m_DamageHitDirection);
327 m_MovementSpeed = -1;
328 m_MindState = -1;
329 SetSynchDirty();
330 return true;
331 }
332
333 return false;
334 }
335
337 {
338 bool ret = EvaluateDeathAnimation(pSource, data.m_DamageZone, data.m_AmmoType, pAnimType, pAnimHitDir);
339
340 return ret;
341 }
342
344 {
346 bool doPhxImpulse = GetGame().ConfigGetInt("cfgAmmo " + pAmmoType + " doPhxImpulse") > 0;
347
350
352 pAnimHitDir = ComputeHitDirectionAngle(pSource);
353
355 if (doPhxImpulse)
356 {
357 vector impulse = 80 * m_TransportHitVelocity;
358 impulse[1] = 80 * 1.5;
359 //Print("Impulse: " + impulse.ToString());
360
362 }
363
364 return true;
365 }
366
367 //-------------------------------------------------------------
371
372 int m_ActiveVaultType = -1;
373
375 {
376 if (height <= 0.6)
377 return 0;
378 else if (height <= 1.1)
379 return 1;
380 else if (height <= 1.6)
381 return 2;
382 else
383 return 3;
384 }
385
387 {
388 if (pCurrentCommandID == DayZInfectedConstants.COMMANDID_VAULT)
389 {
391 if (vaultCmd && vaultCmd.WasLand())
392 {
393 m_KnuckleOutTimer = 0;
394 m_KnuckleLand = true;
395 }
396 if (m_KnuckleLand)
397 {
398 m_KnuckleOutTimer += pDt;
399 if (m_KnuckleOutTimer > 2.0)
401 }
402
403 return true;
404 }
405
406 if (pInputController.IsVault())
407 {
408 float vaultHeight = pInputController.GetVaultHeight();
409 int vaultType = GetVaultType(vaultHeight);
410 m_KnuckleLand = false;
412 return true;
413 }
414
415 return false;
416 }
417
418 //-------------------------------------------------------------
422
424 {
426
427 m_MindState = pInputController.GetMindState();
428 if (m_LastMindState != m_MindState)
429 {
430 switch (m_MindState)
431 {
432 case DayZInfectedConstants.MINDSTATE_CALM:
433 if (moveCommand && !moveCommand.IsTurning())
434 moveCommand.SetIdleState(0);
435 break;
436
437 case DayZInfectedConstants.MINDSTATE_DISTURBED:
438 if (moveCommand && !moveCommand.IsTurning())
439 moveCommand.SetIdleState(1);
440 break;
441
442 case DayZInfectedConstants.MINDSTATE_CHASE:
443 if (moveCommand && !moveCommand.IsTurning() && (m_LastMindState < DayZInfectedConstants.MINDSTATE_CHASE))
444 moveCommand.SetIdleState(2);
445 break;
446 }
447
448 m_LastMindState = m_MindState;
449 m_AttackCooldownTime = 0.0;
450 SetSynchDirty();
451 }
452 return false;
453 }
454
455 //-------------------------------------------------------------
459
460 protected void HandleSoundEvents()
461 {
463 if (!m_InfectedSoundEventHandler)
464 return;
465
467 if (!IsAlive())
468 {
470 m_InfectedSoundEventHandler.Stop();
471 return;
472 }
473
474 switch (m_MindState)
475 {
476 case DayZInfectedConstants.MINDSTATE_CALM:
477 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_CALM_MOVE);
478 break;
479 case DayZInfectedConstants.MINDSTATE_ALERTED:
480 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_ALERTED_MOVE);
481 break;
482 case DayZInfectedConstants.MINDSTATE_DISTURBED:
483 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_DISTURBED_IDLE);
484 break
485 case DayZInfectedConstants.MINDSTATE_CHASE:
486 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_CHASE_MOVE);
487 break;
488 default:
489 m_InfectedSoundEventHandler.Stop();
490 break;
491 }
492
493 DebugSound("[Infected @ " + this + "][MindState]" + typename.EnumToString(DayZInfectedConstants, m_MindState));
494 DebugSound("[Infected @ " + this + "][SoundEventID]" + typename.EnumToString(EInfectedSoundEventID, m_InfectedSoundEventHandler.GetCurrentStateEventID()));
495 }
496
498 {
502 if (!GetGame().IsDedicatedServer())
503 {
505 if (!soundParams.IsValid())
506 {
507 //SoundError("Invalid sound set.");
508 return null;
509 }
510
512 soundObject = soundObjectBuilder.BuildSoundObject();
513 AttenuateSoundIfNecessary(soundObject);
514
516 }
517
518 return null;
519 }
520
522 {
523 //super.OnSoundVoiceEvent(event_id, event_user_string);
524 AnimSoundVoiceEvent voice_event = GetCreatureAIType().GetSoundVoiceEvent(event_id);
525 if (voice_event != null)
526 {
528 if (m_InfectedSoundEventHandler) // && m_InfectedSoundEventHandler.IsPlaying())
529 {
530 m_InfectedSoundEventHandler.Stop();
531 DebugSound("[Infected @ " + this + "][SoundEvent] InfectedSoundEventHandler - stop all");
532 }
533
535 if (m_LastSoundVoiceAW != null)
536 {
537 DebugSound("[Infected @ " + this + "][AnimVoiceEvent] Stopping LastAW");
538 m_LastSoundVoiceAW.Stop();
539 }
540
542 ProcessSoundVoiceEvent(voice_event, m_LastSoundVoiceAW);
543
544 HandleSoundEvents();
545 }
546 }
547
549 {
550 if (!GetGame().IsDedicatedServer())
551 {
552 SoundObjectBuilder objectBuilder = sound_event.GetSoundBuilder();
553 if (NULL != objectBuilder)
554 {
555 objectBuilder.AddEnvSoundVariables(GetPosition());
556 SoundObject soundObject = objectBuilder.BuildSoundObject();
557 AttenuateSoundIfNecessary(soundObject);
559 }
560 }
561
562 if (GetGame().IsServer())
563 {
564 if (sound_event.m_NoiseParams != NULL)
565 GetGame().GetNoiseSystem().AddNoise(this, sound_event.m_NoiseParams);
566 }
567 }
568
569 //-------------------------------------------------------------
573
574 EntityAI m_ActualTarget = null;
575 float m_AttackCooldownTime = 0;
576 DayZInfectedAttackType m_ActualAttackType = null;
577
579 {
580 if (pCurrentCommandID == DayZInfectedConstants.COMMANDID_MOVE)
581 {
582 // we attack only in chase & fight state
583 int mindState = pInputController.GetMindState();
584 if (mindState == DayZInfectedConstants.MINDSTATE_CHASE)
585 return ChaseAttackLogic(pCurrentCommandID, pInputController, pDt);
586 else if (mindState == DayZInfectedConstants.MINDSTATE_FIGHT)
587 return FightAttackLogic(pCurrentCommandID, pInputController, pDt);
588 }
589 else if (pCurrentCommandID == DayZInfectedConstants.COMMANDID_ATTACK)
590 {
592 if (attackCommand && attackCommand.WasHit())
593 {
594 if (m_ActualTarget != null)
595 {
596 if (m_ActualTarget.GetMeleeTargetType() == EMeleeTargetType.NONALIGNABLE)
597 return false;
598
599 bool playerInBlockStance = false;
600 vector targetPos = m_ActualTarget.GetPosition();
603
604 PlayerBase playerTarget = PlayerBase.Cast(m_ActualTarget);
605 if (playerTarget)
606 playerInBlockStance = playerTarget.GetMeleeFightLogic() && playerTarget.GetMeleeFightLogic().IsInBlock();
607
608 if (vector.DistanceSq(targetPos, zombiePos) <= m_ActualAttackType.m_Distance * m_ActualAttackType.m_Distance)
609 {
612 {
614 if (m_ActualAttackType.m_IsHeavy == 1)
615 {
616 hitPosWS = m_ActualTarget.ModelToWorld(m_ActualTarget.GetDefaultHitPosition());
617 DamageSystem.CloseCombatDamageName(this, m_ActualTarget, m_ActualTarget.GetHitComponentForAI(), "MeleeZombie", hitPosWS);
618 }
619 else
620 {
622 hitPosWS = m_ActualTarget.ModelToWorld(m_ActualTarget.GetDefaultHitPosition());
623 DamageSystem.CloseCombatDamageName(this, m_ActualTarget, m_ActualTarget.GetHitComponentForAI(), "Dummy_Light", hitPosWS);
624 }
625 }
626 else
627 {
628 hitPosWS = m_ActualTarget.ModelToWorld(m_ActualTarget.GetDefaultHitPosition());
629 DamageSystem.CloseCombatDamageName(this, m_ActualTarget, m_ActualTarget.GetHitComponentForAI(), m_ActualAttackType.m_AmmoType, hitPosWS);
630 }
631 }
632 }
633 }
634
635 return true;
636 }
637
638 return false;
639 }
640
642 {
643 // always update target - it can be destroyed
644 m_ActualTarget = pInputController.GetTargetEntity();
645
647 PlayerBase pb = PlayerBase.Cast(m_ActualTarget);
648 if (pb && pb.GetCommand_Vehicle())
649 return false;
650
651 if (m_ActualTarget == NULL)
652 return false;
653
654 vector targetPos = m_ActualTarget.GetPosition();
656 return false;
657
659 int pitch = GetAttackPitch(m_ActualTarget);
660
661 m_ActualAttackType = GetDayZInfectedType().ChooseAttack(DayZInfectedAttackGroupType.CHASE, targetDist, pitch);
662 if (m_ActualAttackType)
663 {
664 Object target = DayZPlayerUtils.GetMeleeTarget(this.GetPosition(), this.GetDirection(), TARGET_CONE_ANGLE_CHASE, m_ActualAttackType.m_Distance, -1.0, 2.0, this, m_TargetableObjects, m_AllTargetObjects);
666 if (m_ActualTarget != target)
667 {
668 m_AllTargetObjects.Clear();
669 return false;
670 }
671
672 StartCommand_Attack(m_ActualTarget, m_ActualAttackType.m_Type, m_ActualAttackType.m_Subtype);
673 m_AttackCooldownTime = m_ActualAttackType.m_Cooldown;
674 return true;
675 }
676
677 return false;
678 }
679
681 {
682 // always update target - it can be destroyed
683 m_ActualTarget = pInputController.GetTargetEntity();
684
686 PlayerBase pb = PlayerBase.Cast(m_ActualTarget);
687 if (pb && pb.GetCommand_Vehicle())
688 return false;
689
690 if (m_AttackCooldownTime > 0)
691 {
692 m_AttackCooldownTime -= pDt * GameConstants.AI_ATTACKSPEED;
693 return false;
694 }
695
696 if (m_ActualTarget == null)
697 return false;
698
699 vector targetPos = m_ActualTarget.GetPosition();
701 int pitch = GetAttackPitch(m_ActualTarget);
702
704 return false;
705
706 m_ActualAttackType = GetDayZInfectedType().ChooseAttack(DayZInfectedAttackGroupType.FIGHT, targetDist, pitch);
707 if (m_ActualAttackType)
708 {
709 Object target = DayZPlayerUtils.GetMeleeTarget(this.GetPosition(), this.GetDirection(), TARGET_CONE_ANGLE_FIGHT, m_ActualAttackType.m_Distance, -1.0, 2.0, this, m_TargetableObjects, m_AllTargetObjects);
711 if (m_AllTargetObjects.Count() > 0 && m_AllTargetObjects[0] != m_ActualTarget)
712 {
713 m_AllTargetObjects.Clear();
714 return false;
715 }
716
717 StartCommand_Attack(m_ActualTarget, m_ActualAttackType.m_Type, m_ActualAttackType.m_Subtype);
718 m_AttackCooldownTime = m_ActualAttackType.m_Cooldown;
719 return true;
720 }
721
722 return false;
723 }
724
726 {
728
729 attackRefPos = target.GetDefaultHitPosition();
731 if (attackRefPos != vector.Zero)
732 attackRefPos = target.ModelToWorld(attackRefPos);
733 else
734 attackRefPos = target.GetPosition();
735
736 // Now we have only erect stance, we need to get head position later too
737 float headPosY = GetPosition()[1];
738 headPosY += 1.8;
739
740 float diff = Math.AbsFloat(attackRefPos[1] - headPosY);
741
742 if (diff < 0.3)
743 return 0;
744
745 if (headPosY > attackRefPos[1])
746 return -1;
747 else
748 return 1;
749 }
750
751 //-------------------------------------------------------------
755
756 int m_CrawlTransition = -1;
757
759 {
760 if (m_CrawlTransition != -1)
761 {
762 StartCommand_Crawl(m_CrawlTransition);
763
764 m_CrawlTransition = -1;
765 m_IsCrawling = true;
766 SetSynchDirty();
767 return true;
768 }
769
770 return pCurrentCommandID == DayZInfectedConstants.COMMANDID_CRAWL;
771 }
772
774 {
775 pAnimType = -1;
776 if (pComponent == "LeftLeg" && GetHealth(pComponent, "Health") == 0)
777 pAnimType = 0;
778 else if (pComponent == "RightLeg" && GetHealth(pComponent, "Health") == 0)
779 pAnimType = 2;
780
781 if (pAnimType != -1)
782 {
783 vector targetDirection = GetDirection();
784 vector toSourceDirection = (pSource.GetPosition() - GetPosition());
785
786 targetDirection[1] = 0;
787 toSourceDirection[1] = 0;
788
789 targetDirection.Normalize();
790 toSourceDirection.Normalize();
791
793 if (cosFi >= 0) // front
794 pAnimType++;
795 }
796
797 return pAnimType != -1;
798 }
799
800 //-------------------------------------------------------------
804
805 bool m_DamageHitToProcess = false;
806
807 bool m_DamageHitHeavy = false;
808 int m_DamageHitType = 0;
809 float m_ShockDamage = 0;
810
811 const float HIT_INTERVAL_MIN = 0.3; // Minimum time in seconds before a COMMANDID_HIT to COMMANDID_HIT transition is allowed
812 float m_HitElapsedTime = HIT_INTERVAL_MIN;
813
815 {
816 if (pCurrentCommandID == DayZInfectedConstants.COMMANDID_HIT)
817 {
818 // Throttle hit command up to a fixed rate
819 if (m_HitElapsedTime < HIT_INTERVAL_MIN)
820 {
821 m_HitElapsedTime += m_DeltaTime;
822 m_DamageHitToProcess = false;
823 m_ShockDamage = 0;
824 return false;
825 }
826 }
827
828 if (m_DamageHitToProcess)
829 {
830 int randNum = Math.RandomIntInclusive(0, 100);
831 float stunChange = SHOCK_TO_STUN_MULTIPLIER * m_ShockDamage;
832
833 if (m_DamageHitHeavy || randNum <= stunChange || (m_MindState == DayZInfectedConstants.MINDSTATE_CALM || m_MindState == DayZInfectedConstants.MINDSTATE_DISTURBED))
834 {
835 StartCommand_Hit(m_DamageHitHeavy, m_DamageHitType, m_DamageHitDirection);
836 m_HitElapsedTime = 0;
837 }
838
839 m_DamageHitToProcess = false;
840 m_ShockDamage = 0;
841 m_HeavyHitOverride = false;
842 return true;
843 }
844
845 return false;
846 }
847
850 {
851 int invertHitDir = 0; //Used to flip the heavy hit animation direction
852
854 pHeavyHit = ((GetGame().ConfigGetInt("cfgAmmo " + pAmmoType + " hitAnimation") > 0) || m_HeavyHitOverride);
855 invertHitDir = GetGame().ConfigGetInt("cfgAmmo " + pAmmoType + " invertHitDir");
856
858 pAnimType = 0; // belly
859
860 if (!pHeavyHit)
861 {
862 if (pComponent == "Torso") // body
863 pAnimType = 1;
864 else if (pComponent == "Head") // head
865 pAnimType = 2;
866 }
867
869 //pAnimHitDir = ComputeHitDirectionAngle(pSource);
870 pAnimHitDir = ComputeHitDirectionAngleEx(pSource, invertHitDir);
872 //m_ShockDamage = GetGame().ConfigGetFloat( "CfgAmmo " + pAmmoType + " DamageApplied " + "Shock " + "damage");
873 return true;
874 }
875
877 {
878 vector targetDirection = GetDirection();
879 vector toSourceDirection = (pSource.GetPosition() - GetPosition());
880
881 targetDirection[1] = 0;
882 toSourceDirection[1] = 0;
883
884 targetDirection.Normalize();
885 toSourceDirection.Normalize();
886
889
890 float dirAngle = Math.Acos(cosFi) * Math.RAD2DEG;
891 if (cross[1] < 0)
893
894 return dirAngle;
895 }
896
898 {
899 vector targetDirection = GetDirection();
900 vector toSourceDirection = (pSource.GetPosition() - GetPosition());
901
902 targetDirection[1] = 0;
903 toSourceDirection[1] = 0;
904
905 targetDirection.Normalize();
906 toSourceDirection.Normalize();
907
910
911 float dirAngle = Math.Acos(cosFi) * Math.RAD2DEG;
912
913 // We will invert direction of the hit
914 if (invertHitDir > 0)
915 dirAngle -= 180;
916
917 if (cross[1] < 0)
919
920 return dirAngle;
921 }
922
923 //-------------------------------------------------------------
927
929 {
931
932 m_TransportHitRegistered = false;
933
934 if (!IsAlive())
935 {
937 data.m_Component = component;
938 data.m_DamageZone = dmgZone;
939 data.m_AmmoType = ammo;
940 EvaluateDeathAnimationEx(source, data, m_DeathType, m_DamageHitDirection);
941 }
942 else
943 {
944 int crawlTransitionType = -1;
945 if (EvaluateCrawlTransitionAnimation(source, dmgZone, ammo, crawlTransitionType))
946 {
947 m_CrawlTransition = crawlTransitionType;
948 return;
949 }
950
951 if (EvaluateDamageHitAnimation(source, dmgZone, ammo, m_DamageHitHeavy, m_DamageHitType, m_DamageHitDirection))
952 {
953 if (dmgZone)
954 m_ShockDamage = damageResult.GetDamage(dmgZone, "Shock");
955 m_DamageHitToProcess = true;
956 return;
957 }
958 }
959 }
960
961 override void EEHitByRemote(int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos)
962 {
964 }
965
967 protected void DebugSound(string s)
968 {
969 //Print(s);
970 }
971
972 //-------------------------------------------------------------
976
977 override protected void EOnContact(IEntity other, Contact extra)
978 {
979 if (!IsAlive())
980 return;
981
983 if (transport)
984 {
985 if (GetGame().IsServer())
986 RegisterTransportHit(transport);
987 }
988 }
989
991 {
992 if (!IsAlive())
993 return false;
994 return super.CanReceiveAttachment(attachment, slotId);
995 }
996
997 override vector GetCenter()
998 {
999 return GetBonePositionWS(GetBoneIndexByName("spine3"));
1000 }
1001
1003 override bool IsBeingBackstabbed()
1004 {
1005 return m_FinisherInProgress;
1006 }
1007
1009 {
1010 // disable AI simulation
1011 GetAIAgent().SetKeepInIdle(true);
1012
1013 // select death animation
1014 switch (backstabType)
1015 {
1016 case EMeleeHitType.FINISHER_LIVERSTAB:
1017 m_DeathType = DayZInfectedDeathAnims.ANIM_DEATH_BACKSTAB;
1018 break;
1019
1020 case EMeleeHitType.FINISHER_NECKSTAB:
1021 m_DeathType = DayZInfectedDeathAnims.ANIM_DEATH_NECKSTAB;
1022 break;
1023
1024 default:
1025 m_DeathType = DayZInfectedDeathAnims.ANIM_DEATH_DEFAULT;
1026 }
1027
1028 // set flag - death command will be executed
1029 m_FinisherInProgress = true;
1030
1031 //Print("DbgZombies | DumbZombie on: " + GetGame().GetTime());
1032 }
1033
1036 {
1037 return m_IsCrawling;
1038 }
1039
1040 // called from command death when stealth attack wan't successful
1042 {
1043 // enable AI simulation again
1044 GetAIAgent().SetKeepInIdle(false);
1045
1046 // reset flag
1047 m_FinisherInProgress = false;
1048
1049 //Print("DbgZombies | DumbZombie off: " + GetGame().GetTime());
1050 }
1051
1053 {
1055 GetActionComponentNameList(componentIndex, CachedObjectsArrays.ARRAY_STRING, "fire");
1056
1057 int pivot = -1;
1058
1059
1060 for (int i = 0; i < CachedObjectsArrays.ARRAY_STRING.Count() && pivot == -1; i++)
1062
1065
1066 if (pivot == -1)
1068 else
1069 {
1070 vector rotMatrix[3];
1072
1073 parentTransMat[0] = rotMatrix[0];
1074 parentTransMat[1] = rotMatrix[1];
1075 parentTransMat[2] = rotMatrix[2];
1077 }
1078
1079 arrow.GetTransform(arrowTransMat);
1081 // orthogonalize matrix - parent might be skewed
1083 arrow.SetTransform(arrowTransMat);
1084
1086 }
1087
1088 override bool IsManagingArrows()
1089 {
1090 return true;
1091 }
1092
1094 {
1095 return m_ArrowManager;
1096 }
1097}
1098
1100class ZombieHitData
1101{
1105}
RepairCarChassisActionReciveData m_DamageZone
ref ArrowManagerBase m_ArrowManager
Definition AnimalBase.c:24
vector GetOrientation()
AnimBootsType
bool ModCommandHandlerInside(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Definition DayZAnimal.c:127
proto native int GetBoneIndexByName(string pBoneName)
returns bone index for a name (-1 if pBoneName doesn't exist)
bool ModCommandHandlerBefore(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Definition DayZAnimal.c:122
bool ModCommandHandlerAfter(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Definition DayZAnimal.c:132
override Widget Init()
Definition DayZGame.c:120
DayZInfectedConstants
Definition DayZInfected.c:2
DayZInfectedAttackGroupType
ref array< Object > m_AllTargetObjects
All potential targets found during most recent TargetSelection.
ref array< typename > m_TargetableObjects
Typenames of all directly/preferred targetable objects (1st Pass + 2nd Pass)
void DayZPlayerUtils()
cannot be instantiated
EMeleeTargetType
void PlaySound()
string m_AmmoType
void InfectedSoundEventHandler(ZombieBase pInfected)
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
PluginManager GetPluginManager()
Returns registred plugin by class type, better is to use global funtion GetPlugin(typename plugin_typ...
class SoundObjectBuilder SoundObject(SoundParams soundParams)
void SoundObjectBuilder(SoundParams soundParams)
class JsonUndergroundAreaTriggerData GetPosition
class ZombieBase extends DayZInfected m_Component
an extendable data container
proto void Stop()
static ref TStringArray ARRAY_STRING
void CommandHandler(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Definition ZombieBase.c:190
int GetMindStateSynced()
Definition ZombieBase.c:174
bool m_IsCrawling
Definition ZombieBase.c:34
override void OnSoundVoiceEvent(int event_id, string event_user_string)
Definition ZombieBase.c:521
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Definition ZombieBase.c:928
ref ArrowManagerBase m_ArrowManager
Definition ZombieBase.c:38
bool FightLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Definition ZombieBase.c:578
ref InfectedSoundEventHandler m_InfectedSoundEventHandler
Definition ZombieBase.c:27
void CommandHandlerDebug(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Definition ZombieBase.c:257
override bool IsManagingArrows()
bool HandleVault(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Definition ZombieBase.c:386
override array< string > GetSuitableFinisherHitComponents()
returns suitable hit components for finisher attacks; DEPRECATED
Definition ZombieBase.c:169
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
Definition ZombieBase.c:990
void ProcessSoundVoiceEvent(AnimSoundVoiceEvent sound_event, out AbstractWave aw)
Definition ZombieBase.c:548
int GetOrientationSynced()
returns rounded zombie yaw for sync purposes
Definition ZombieBase.c:180
float m_DeltaTime
Definition ZombieBase.c:24
bool IsCrawling()
returns true if crawling; 'DayZInfectedCommandCrawl' is only for the transition, after that it remain...
void ZombieBase()
Definition ZombieBase.c:42
override bool IsDanger()
Definition ZombieBase.c:105
override void EOnInit(IEntity other, int extra)
Definition ZombieBase.c:89
override void AddArrow(Object arrow, int componentIndex, vector closeBonePosWS, vector closeBoneRotWS)
void OnRecoverFromDeath()
override void EEHitByRemote(int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos)
Definition ZombieBase.c:961
ref array< Object > m_AllTargetObjects
Definition ZombieBase.c:29
AbstractWave ProcessVoiceFX(string pSoundSetName)
Definition ZombieBase.c:497
void HandleOrientation(float pDt, int pCurrentCommandID)
Definition ZombieBase.c:286
override bool CanBeSkinned()
Definition ZombieBase.c:131
override bool IsZombie()
Definition ZombieBase.c:100
bool HandleDamageHit(int pCurrentCommandID)
Definition ZombieBase.c:814
void HandleSoundEvents()
Definition ZombieBase.c:460
bool EvaluateCrawlTransitionAnimation(EntityAI pSource, string pComponent, string pAmmoType, out int pAnimType)
Definition ZombieBase.c:773
vector SetDefaultHitPosition(string pSelection)
Definition ZombieBase.c:163
AbstractWave m_LastSoundVoiceAW
Definition ZombieBase.c:26
override AnimBootsType GetBootsType()
Definition ZombieBase.c:126
bool FightAttackLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Definition ZombieBase.c:680
bool HandleCrawlTransition(int pCurrentCommandID)
Definition ZombieBase.c:758
void Init()
Definition ZombieBase.c:47
void HandleMove(int pCurrentCommandID)
Definition ZombieBase.c:271
void DebugSound(string s)
sound debug messages
Definition ZombieBase.c:967
vector m_DefaultHitPosition
Definition ZombieBase.c:23
override bool IsHealthVisible()
Definition ZombieBase.c:136
bool EvaluateDeathAnimationEx(EntityAI pSource, ZombieHitData data, out int pAnimType, out float pAnimHitDir)
Definition ZombieBase.c:336
override bool IsRefresherSignalingViable()
Definition ZombieBase.c:141
bool EvaluateDamageHitAnimation(EntityAI pSource, string pComponent, string pAmmoType, out bool pHeavyHit, out int pAnimType, out float pAnimHitDir)
selects animation type and direction based on damage system data
Definition ZombieBase.c:849
override string GetDefaultHitComponent()
returns default hit component (fallback)
Definition ZombieBase.c:153
override bool IsBeingBackstabbed()
returns true if backstab is in progress; used for suspending of AI targeting and other useful things ...
void EOnContact(IEntity other, Contact extra)
Definition ZombieBase.c:977
override vector GetCenter()
Definition ZombieBase.c:997
bool HandleDeath(int pCurrentCommandID)
Definition ZombieBase.c:322
ref array< typename > m_TargetableObjects
Definition ZombieBase.c:30
override void OnVariablesSynchronized()
synced variable(s) handler
Definition ZombieBase.c:79
override string GetHitComponentForAI()
returns hit component for attacking AI
Definition ZombieBase.c:147
int GetAttackPitch(EntityAI target)
Definition ZombieBase.c:725
float ComputeHitDirectionAngleEx(EntityAI pSource, int invertHitDir=0)
Definition ZombieBase.c:897
override void SetBeingBackstabbed(int backstabType)
override bool IsZombieMilitary()
Definition ZombieBase.c:110
bool IsMale()
Definition ZombieBase.c:115
override bool CanBeBackstabbed()
Definition ZombieBase.c:120
int GetVaultType(float height)
Definition ZombieBase.c:374
override vector GetDefaultHitPosition()
Definition ZombieBase.c:158
float m_OrientationTimer
Definition ZombieBase.c:20
bool EvaluateDeathAnimation(EntityAI pSource, string pComponent, string pAmmoType, out int pAnimType, out float pAnimHitDir)
Definition ZombieBase.c:343
bool HandleMindStateChange(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Definition ZombieBase.c:423
float ComputeHitDirectionAngle(EntityAI pSource)
Definition ZombieBase.c:876
override ArrowManagerBase GetArrowManager()
bool ChaseAttackLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Definition ZombieBase.c:641
override int GetMeleeTargetType()
Definition Building.c:234
Definition EnMath.c:7
Base native class for all motorized wheeled vehicles.
Definition Car.c:75
static proto native float DistanceSq(vector v1, vector v2)
Returns the square distance between tips of two 3D vectors.
static float Dot(vector v1, vector v2)
Returns Dot product of vector v1 and vector v2.
Definition EnConvert.c:271
static const vector Zero
Definition EnConvert.c:110
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
string GetDefaultHitPositionComponent()
Definition dayzplayer.c:497
proto native CGame GetGame()
const float AI_MAX_BLOCKABLE_ANGLE
Definition constants.c:915
const float AI_ATTACKSPEED
Definition constants.c:914
EntityEvent
Entity events for event-mask, or throwing event from code.
Definition EnEntity.c:44
static proto float AngleFromPosition(vector origin, vector originDir, vector target)
Angle that a target is from the direction of an origin.
static proto void YawPitchRollMatrix(vector ang, out vector mat[3])
Creates rotation matrix from angles.
static proto void MatrixInvMultiply4(vector mat0[4], vector mat1[4], out vector res[4])
Invert-transforms matrix.
static proto void MatrixOrthogonalize4(vector mat[4])
Orthogonalizes matrix.
static proto float NormalizeAngle(float ang)
Normalizes the angle (0...360)
static proto float Acos(float c)
Returns angle in radians from cosinus.
static proto float Cos(float angle)
Returns cosinus of angle in radians.
static proto int AbsInt(int i)
Returns absolute value.
static proto float Round(float f)
Returns mathematical round of value.
static proto float Atan2(float y, float x)
Returns angle in radians from tangent.
static proto float Sin(float angle)
Returns sinus of angle in radians.
static proto int RandomInt(int min, int max)
Returns a random int number between and min [inclusive] and max [exclusive].
static const float RAD2DEG
Definition EnMath.c:16
static const float DEG2RAD
Definition EnMath.c:17
static proto float AbsFloat(float f)
Returns absolute value.
static int RandomIntInclusive(int min, int max)
Returns a random int number between and min [inclusive] and max [inclusive].
Definition EnMath.c:54
proto void dBodyApplyImpulse(notnull IEntity body, vector impulse)
Applies impuls on a rigidbody (origin)
proto native void AddChild(Widget child, bool immedUpdate=true)
proto native HumanCommandMove GetCommand_Move()
proto native HumanCommandMove StartCommand_Move()
--— MOVE --—
proto native HumanCommandDeathCallback StartCommand_Death(int pType, float pDirection, typename pCallbackClass, bool pKeepInLocalSpaceAfterLeave=false)
--— Death --—
enum HumanMoveCommandID GetTransformWS(out vector pTm[4])
gets human transform in World Space
proto native HumanInputController GetInputController()
returns human input controller