DayZ 1.27
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
ZombieBase.c
См. документацию.
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
42 //-------------------------------------------------------------
44 {
45 Init();
46 }
47
48 void Init()
49 {
50 SetEventMask(EntityEvent.INIT);
51
52 m_IsCrawling = false;
53
54 RegisterNetSyncVariableInt("m_MindState", -1, 4);
55 RegisterNetSyncVariableInt("m_OrientationSynced", 0, 359);
56 RegisterNetSyncVariableFloat("m_MovementSpeed", -1, 3);
57 RegisterNetSyncVariableBool("m_IsCrawling");
58
61
63 if ( !GetGame().IsDedicatedServer() )
64 {
65 m_LastSoundVoiceAW = null;
67 }
68
73
75
77 }
78
81 {
82 DebugSound("[Infected @ " + this + "][OnVariablesSynchronized]");
84
86 {
88 }
89 }
90
91 //-------------------------------------------------------------
92 override void EOnInit(IEntity other, int extra)
93 {
94 if ( !GetGame().IsMultiplayer() || GetGame().IsServer() )
95 {
97
98 DayZInfectedCommandMove moveCommand = GetCommand_Move();
99 moveCommand.SetStanceVariation(m_StanceVariation);
100 }
101 }
102
103 override bool IsZombie()
104 {
105 return true;
106 }
107
108 override bool IsDanger()
109 {
110 return true;
111 }
112
113 override bool IsZombieMilitary()
114 {
115 return false;
116 }
117
118 bool IsMale()
119 {
120 return true;
121 }
122
123 override bool CanBeBackstabbed()
124 {
125 return true;
126 }
127
128 //-------------------------------------------------------------
130 {
131 return AnimBootsType.Boots;
132 }
133
134 override bool CanBeSkinned()
135 {
136 return false;
137 }
138 //-------------------------------------------------------------
139 override bool IsHealthVisible()
140 {
141 return false;
142 }
143 //-------------------------------------------------------------
145 {
146 return false;
147 }
148
150 {
151 return IsAlive();
152 }
153
155 override string GetHitComponentForAI()
156 {
157 return GetDayZInfectedType().GetHitComponentForAI();
158 }
159
161 override string GetDefaultHitComponent()
162 {
163 return GetDayZInfectedType().GetDefaultHitComponent();
164 }
165
167 {
169 }
170
171 protected vector SetDefaultHitPosition(string pSelection)
172 {
173 return GetSelectionPositionMS(pSelection);
174 }
175
178 {
179 return GetDayZInfectedType().GetSuitableFinisherHitComponents();
180 }
181
183 {
184 return m_MindState;
185 }
186
189 {
190 return m_OrientationSynced;
191 }
192
193 //-------------------------------------------------------------
197
198 void CommandHandler(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
199 {
200 m_DeltaTime = pDt;
201
203 if ( ModCommandHandlerBefore(pDt, pCurrentCommandID, pCurrentCommandFinished) )
204 {
205 return;
206 }
207
209 if ( pCurrentCommandID != DayZInfectedConstants.COMMANDID_DEATH )
210 {
211 if ( HandleDeath(pCurrentCommandID) )
212 return;
213 }
214 else if (!pCurrentCommandFinished)
215 {
216 return;
217 }
218
219
221 HandleMove(pCurrentCommandID);
222 HandleOrientation(pDt,pCurrentCommandID);
223
225 if (pCurrentCommandFinished)
226 {
228 DayZInfectedCommandMove moveCommand = StartCommand_Move();
229 moveCommand.SetStanceVariation(m_StanceVariation);
230
231 return;
232 }
233
235 if ( ModCommandHandlerInside(pDt, pCurrentCommandID, pCurrentCommandFinished) )
236 {
237 return;
238 }
239
241 if ( HandleCrawlTransition(pCurrentCommandID) )
242 {
243 return;
244 }
245
247 if ( HandleDamageHit(pCurrentCommandID) )
248 {
249 return;
250 }
251
252 DayZInfectedInputController inputController = GetInputController();
253 if ( inputController )
254 {
255 if ( HandleVault(pCurrentCommandID, inputController, pDt) )
256 {
257 return;
258 }
259
260 if ( HandleMindStateChange(pCurrentCommandID, inputController, pDt) )
261 {
262 return;
263 }
264
265 if ( FightLogic(pCurrentCommandID, inputController, pDt) )
266 {
267 return;
268 }
269 }
270
272 if ( ModCommandHandlerAfter(pDt, pCurrentCommandID, pCurrentCommandFinished) )
273 {
274 return;
275 }
276 }
277
278 //-------------------------------------------------------------
282
283 void CommandHandlerDebug(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
284 {
285 if ( GetPluginManager() )
286 {
287 PluginDayZInfectedDebug infectedDebug = PluginDayZInfectedDebug.Cast(GetPluginManager().GetPluginByType(PluginDayZInfectedDebug));
288 if ( infectedDebug )
289 infectedDebug.CommandHandler(this);
290 }
291 }
292 //-------------------------------------------------------------
296
297 void HandleMove(int pCurrentCommandID)
298 {
299 DayZInfectedInputController ic = GetInputController();
302 {
303 SetSynchDirty();
304 }
305
307 }
308
309 //-------------------------------------------------------------
313
314 void HandleOrientation(float pDt, int pCurrentCommandID)
315 {
316 m_OrientationTimer += pDt;
317
318 int yaw = Math.Round(GetOrientation()[0]);
319 yaw = Math.NormalizeAngle(yaw);
320
321 //atan2(sin(x-y), cos(x-y))
322 float angleSourceRad = m_OrientationSynced * Math.DEG2RAD;
323 float angleTargetRad = yaw * Math.DEG2RAD;
324
325 float angleDiffRad = Math.Atan2(Math.Sin(angleTargetRad - angleSourceRad), Math.Cos(angleSourceRad - angleTargetRad));
326 angleDiffRad *= Math.RAD2DEG;
327 angleDiffRad = Math.Round(angleDiffRad);
328
329 if (m_OrientationTimer >= 2.0 || m_OrientationSynced == -1 || Math.AbsInt(angleDiffRad) > ORIENTATION_SYNC_THRESHOLD)
330 {
331 m_OrientationTimer = 0.0;
332
333 if (m_OrientationSynced == -1 || Math.AbsInt(angleDiffRad) > 5)
334 {
336 SetSynchDirty();
337 }
338 }
339 }
340
341 //-------------------------------------------------------------
345
347 int m_DeathType = 0;
348
349 bool HandleDeath(int pCurrentCommandID)
350 {
351 if ( !IsAlive() || m_FinisherInProgress )
352 {
353 StartCommand_Death(m_DeathType, m_DamageHitDirection);
354 m_MovementSpeed = -1;
355 m_MindState = -1;
356 SetSynchDirty();
357 return true;
358 }
359
360 return false;
361 }
362
363 bool EvaluateDeathAnimationEx(EntityAI pSource, ZombieHitData data, out int pAnimType, out float pAnimHitDir)
364 {
365 bool ret = EvaluateDeathAnimation(pSource,data.m_DamageZone,data.m_AmmoType,pAnimType,pAnimHitDir);
366
367 return ret;
368 }
369
370 bool EvaluateDeathAnimation(EntityAI pSource, string pComponent, string pAmmoType, out int pAnimType, out float pAnimHitDir)
371 {
373 bool doPhxImpulse = GetGame().ConfigGetInt("cfgAmmo " + pAmmoType + " doPhxImpulse") > 0;
374
376 pAnimType = doPhxImpulse;
377
379 pAnimHitDir = ComputeHitDirectionAngle(pSource);
380
382 if ( doPhxImpulse )
383 {
384 vector impulse = 80 * m_TransportHitVelocity;
385 impulse[1] = 80 * 1.5;
386 //Print("Impulse: " + impulse.ToString());
387
388 dBodyApplyImpulse(this, impulse);
389 }
390
391 return true;
392 }
393
394 //-------------------------------------------------------------
398
400
401 int GetVaultType(float height)
402 {
403 if ( height <= 0.6 )
404 return 0;
405 else if ( height <= 1.1 )
406 return 1;
407 else if ( height <= 1.6 )
408 return 2;
409 else
410 return 3;
411 }
412
413 bool HandleVault(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
414 {
415 if ( pCurrentCommandID == DayZInfectedConstants.COMMANDID_VAULT )
416 {
417 DayZInfectedCommandVault vaultCmd = GetCommand_Vault();
418 if ( vaultCmd && vaultCmd.WasLand() )
419 {
421 m_KnuckleLand = true;
422 }
423 if ( m_KnuckleLand )
424 {
425 m_KnuckleOutTimer += pDt;
426 if ( m_KnuckleOutTimer > 2.0 )
427 StartCommand_Vault(-1);
428 }
429
430 return true;
431 }
432
433 if ( pInputController.IsVault() )
434 {
435 float vaultHeight = pInputController.GetVaultHeight();
436 int vaultType = GetVaultType(vaultHeight);
437 m_KnuckleLand = false;
438 StartCommand_Vault(vaultType);
439 return true;
440 }
441
442 return false;
443 }
444
445 //-------------------------------------------------------------
449
450 bool HandleMindStateChange(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
451 {
452 DayZInfectedCommandMove moveCommand = GetCommand_Move();
453
454 m_MindState = pInputController.GetMindState();
456 {
457 switch ( m_MindState )
458 {
459 case DayZInfectedConstants.MINDSTATE_CALM:
460 if ( moveCommand && !moveCommand.IsTurning() )
461 moveCommand.SetIdleState(0);
462 break;
463
464 case DayZInfectedConstants.MINDSTATE_DISTURBED:
465 if ( moveCommand && !moveCommand.IsTurning() )
466 moveCommand.SetIdleState(1);
467 break;
468
469 case DayZInfectedConstants.MINDSTATE_CHASE:
470 if ( moveCommand && !moveCommand.IsTurning() && (m_LastMindState < DayZInfectedConstants.MINDSTATE_CHASE) )
471 moveCommand.SetIdleState(2);
472 break;
473 }
474
477 SetSynchDirty();
478 }
479 return false;
480 }
481
482 //-------------------------------------------------------------
486
487 protected void HandleSoundEvents()
488 {
491 {
492 return;
493 }
494
496 if ( !IsAlive() )
497 {
500 return;
501 }
502
503 switch ( m_MindState )
504 {
505 case DayZInfectedConstants.MINDSTATE_CALM:
506 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_CALM_MOVE);
507 break;
508 case DayZInfectedConstants.MINDSTATE_ALERTED:
509 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_ALERTED_MOVE);
510 break;
511 case DayZInfectedConstants.MINDSTATE_DISTURBED:
512 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_DISTURBED_IDLE);
513 break
514 case DayZInfectedConstants.MINDSTATE_CHASE:
515 m_InfectedSoundEventHandler.PlayRequest(EInfectedSoundEventID.MINDSTATE_CHASE_MOVE);
516 break;
517 default:
519 break;
520 }
521
522 DebugSound("[Infected @ " + this + "][MindState]" + typename.EnumToString(DayZInfectedConstants, m_MindState));
523 DebugSound("[Infected @ " + this + "][SoundEventID]" + typename.EnumToString(EInfectedSoundEventID, m_InfectedSoundEventHandler.GetCurrentStateEventID()));
524 }
525
526 AbstractWave ProcessVoiceFX(string pSoundSetName)
527 {
528 SoundParams soundParams;
529 SoundObjectBuilder soundObjectBuilder;
530 SoundObject soundObject;
531 if (!GetGame().IsDedicatedServer())
532 {
533 soundParams = new SoundParams( pSoundSetName );
534 if ( !soundParams.IsValid() )
535 {
536 //SoundError("Invalid sound set.");
537 return null;
538 }
539
540 soundObjectBuilder = new SoundObjectBuilder( soundParams );
541 soundObject = soundObjectBuilder.BuildSoundObject();
542 AttenuateSoundIfNecessary(soundObject);
543
544 return PlaySound(soundObject, soundObjectBuilder);
545 }
546
547 return null;
548 }
549
550 override void OnSoundVoiceEvent(int event_id, string event_user_string)
551 {
552 //super.OnSoundVoiceEvent(event_id, event_user_string);
553 AnimSoundVoiceEvent voice_event = GetCreatureAIType().GetSoundVoiceEvent(event_id);
554 if (voice_event != null)
555 {
557 if (m_InfectedSoundEventHandler) // && m_InfectedSoundEventHandler.IsPlaying())
558 {
560 DebugSound("[Infected @ " + this + "][SoundEvent] InfectedSoundEventHandler - stop all");
561 }
562
564 if (m_LastSoundVoiceAW != null)
565 {
566 DebugSound("[Infected @ " + this + "][AnimVoiceEvent] Stopping LastAW");
567 m_LastSoundVoiceAW.Stop();
568 }
569
572
574 }
575 }
576
577 protected void ProcessSoundVoiceEvent(AnimSoundVoiceEvent sound_event, out AbstractWave aw)
578 {
579 if (!GetGame().IsDedicatedServer())
580 {
581 SoundObjectBuilder objectBuilder = sound_event.GetSoundBuilder();
582 if (NULL != objectBuilder)
583 {
584 objectBuilder.AddEnvSoundVariables(GetPosition());
585 SoundObject soundObject = objectBuilder.BuildSoundObject();
586 AttenuateSoundIfNecessary(soundObject);
587 aw = PlaySound(soundObject, objectBuilder);
588 }
589 }
590
591 if (GetGame().IsServer())
592 {
593 if (sound_event.m_NoiseParams != NULL)
594 GetGame().GetNoiseSystem().AddNoise(this, sound_event.m_NoiseParams, NoiseAIEvaluate.GetNoiseReduction(GetGame().GetWeather()));
595 }
596 }
597
598 //-------------------------------------------------------------
602
606
607 bool FightLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
608 {
609 if (pCurrentCommandID == DayZInfectedConstants.COMMANDID_MOVE)
610 {
611 // we attack only in chase & fight state
612 int mindState = pInputController.GetMindState();
613 if (mindState == DayZInfectedConstants.MINDSTATE_CHASE)
614 {
615 return ChaseAttackLogic(pCurrentCommandID, pInputController, pDt);
616 }
617 else if (mindState == DayZInfectedConstants.MINDSTATE_FIGHT)
618 {
619 return FightAttackLogic(pCurrentCommandID, pInputController, pDt);
620 }
621 }
622 else if (pCurrentCommandID == DayZInfectedConstants.COMMANDID_ATTACK)
623 {
624 DayZInfectedCommandAttack attackCommand = GetCommand_Attack();
625 if (attackCommand && attackCommand.WasHit())
626 {
627 if (m_ActualTarget != null)
628 {
629 if (m_ActualTarget.GetMeleeTargetType() == EMeleeTargetType.NONALIGNABLE)
630 return false;
631
632 bool playerInBlockStance = false;
633 vector targetPos = m_ActualTarget.GetPosition();
634 vector hitPosWS = targetPos;
635 vector zombiePos = GetPosition();
636
637 PlayerBase playerTarget = PlayerBase.Cast(m_ActualTarget);
638 if (playerTarget)
639 {
640 playerInBlockStance = playerTarget.GetMeleeFightLogic() && playerTarget.GetMeleeFightLogic().IsInBlock();
641 }
642
643 if (vector.DistanceSq(targetPos, zombiePos) <= m_ActualAttackType.m_Distance * m_ActualAttackType.m_Distance)
644 {
646 if (playerInBlockStance && (Math.RAD2DEG * Math.AbsFloat(Math3D.AngleFromPosition(targetPos, MiscGameplayFunctions.GetHeadingVector(playerTarget), zombiePos))) <= GameConstants.AI_MAX_BLOCKABLE_ANGLE)
647 {
649 if (m_ActualAttackType.m_IsHeavy == 1)
650 {
651 hitPosWS = m_ActualTarget.ModelToWorld(m_ActualTarget.GetDefaultHitPosition());
652 DamageSystem.CloseCombatDamageName(this, m_ActualTarget, m_ActualTarget.GetHitComponentForAI(), "MeleeZombie", hitPosWS);
653 }
654 else
655 {
657 hitPosWS = m_ActualTarget.ModelToWorld(m_ActualTarget.GetDefaultHitPosition());
658 DamageSystem.CloseCombatDamageName(this, m_ActualTarget, m_ActualTarget.GetHitComponentForAI(), "Dummy_Light", hitPosWS);
659 }
660 }
661 else
662 {
663 hitPosWS = m_ActualTarget.ModelToWorld(m_ActualTarget.GetDefaultHitPosition());
664 DamageSystem.CloseCombatDamageName(this, m_ActualTarget, m_ActualTarget.GetHitComponentForAI(), m_ActualAttackType.m_AmmoType, hitPosWS);
665 }
666 }
667 }
668 }
669
670 return true;
671 }
672
673 return false;
674 }
675
676 bool ChaseAttackLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
677 {
678 // always update target - it can be destroyed
679 m_ActualTarget = pInputController.GetTargetEntity();
680
683 if ( pb && pb.GetCommand_Vehicle() )
684 {
685 return false;
686 }
687
688 if ( m_ActualTarget == NULL )
689 return false;
690
691 vector targetPos = m_ActualTarget.GetPosition();
692 if ( !CanAttackToPosition(targetPos) )
693 return false;
694
695 float targetDist = vector.Distance(targetPos, this.GetPosition());
696 int pitch = GetAttackPitch(m_ActualTarget);
697
698 m_ActualAttackType = GetDayZInfectedType().ChooseAttack(DayZInfectedAttackGroupType.CHASE, targetDist, pitch);
700 {
701 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);
703 if (m_ActualTarget != target)
704 {
705 m_AllTargetObjects.Clear();
706 return false;
707 }
708
709 StartCommand_Attack(m_ActualTarget, m_ActualAttackType.m_Type, m_ActualAttackType.m_Subtype);
711 return true;
712 }
713
714 return false;
715 }
716
717 bool FightAttackLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
718 {
719 // always update target - it can be destroyed
720 m_ActualTarget = pInputController.GetTargetEntity();
721
724 if (pb && pb.GetCommand_Vehicle())
725 return false;
726
727 if (m_AttackCooldownTime > 0)
728 {
730 return false;
731 }
732
733 if (m_ActualTarget == null)
734 return false;
735
736 vector targetPos = m_ActualTarget.GetPosition();
737 float targetDist = vector.Distance(targetPos, this.GetPosition());
738 int pitch = GetAttackPitch(m_ActualTarget);
739
740 if (!CanAttackToPosition(targetPos))
741 return false;
742
743 m_ActualAttackType = GetDayZInfectedType().ChooseAttack(DayZInfectedAttackGroupType.FIGHT, targetDist, pitch);
745 {
746 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);
749 {
750 m_AllTargetObjects.Clear();
751 return false;
752 }
753
754 StartCommand_Attack(m_ActualTarget, m_ActualAttackType.m_Type, m_ActualAttackType.m_Subtype);
756 return true;
757 }
758
759 return false;
760 }
761
763 {
764 vector attackRefPos;
765
766 attackRefPos = target.GetDefaultHitPosition();
768 if ( attackRefPos != vector.Zero )
769 {
770 attackRefPos = target.ModelToWorld(attackRefPos);
771 }
772 else
773 {
774 attackRefPos = target.GetPosition();
775 }
776
777 // Now we have only erect stance, we need to get head position later too
778 float headPosY = GetPosition()[1];
779 headPosY += 1.8;
780
781 float diff = Math.AbsFloat(attackRefPos[1] - headPosY);
782
783 if ( diff < 0.3 )
784 return 0;
785
786 if ( headPosY > attackRefPos[1] )
787 return -1;
788 else
789 return 1;
790 }
791
792 //-------------------------------------------------------------
796
798
799 bool HandleCrawlTransition(int pCurrentCommandID)
800 {
801 if ( m_CrawlTransition != -1 )
802 {
803 StartCommand_Crawl(m_CrawlTransition);
804
806 m_IsCrawling = true;
807 SetSynchDirty();
808 return true;
809 }
810
811 return pCurrentCommandID == DayZInfectedConstants.COMMANDID_CRAWL;
812 }
813
814 bool EvaluateCrawlTransitionAnimation(EntityAI pSource, string pComponent, string pAmmoType, out int pAnimType)
815 {
816 pAnimType = -1;
817 if ( pComponent == "LeftLeg" && GetHealth(pComponent, "Health") == 0 )
818 pAnimType = 0;
819 else if ( pComponent == "RightLeg" && GetHealth(pComponent, "Health") == 0 )
820 pAnimType = 2;
821
822 if ( pAnimType != -1 )
823 {
824 vector targetDirection = GetDirection();
825 vector toSourceDirection = (pSource.GetPosition() - GetPosition());
826
827 targetDirection[1] = 0;
828 toSourceDirection[1] = 0;
829
830 targetDirection.Normalize();
831 toSourceDirection.Normalize();
832
833 float cosFi = vector.Dot(targetDirection, toSourceDirection);
834 if ( cosFi >= 0 ) // front
835 pAnimType++;
836 }
837
838 return pAnimType != -1;
839 }
840
841 //-------------------------------------------------------------
845
847
848 bool m_DamageHitHeavy = false;
850 float m_ShockDamage = 0;
851
852 const float HIT_INTERVAL_MIN = 0.3; // Minimum time in seconds before a COMMANDID_HIT to COMMANDID_HIT transition is allowed
854
855 bool HandleDamageHit(int pCurrentCommandID)
856 {
857 if ( pCurrentCommandID == DayZInfectedConstants.COMMANDID_HIT )
858 {
859 // Throttle hit command up to a fixed rate
861 {
863 m_DamageHitToProcess = false;
864 m_ShockDamage = 0;
865 return false;
866 }
867 }
868
870 {
871 int randNum = Math.RandomIntInclusive(0, 100);
872 float stunChange = SHOCK_TO_STUN_MULTIPLIER * m_ShockDamage;
873
874 if ( m_DamageHitHeavy || randNum <= stunChange || ( m_MindState == DayZInfectedConstants.MINDSTATE_CALM || m_MindState == DayZInfectedConstants.MINDSTATE_DISTURBED ) )
875 {
878 }
879
880 m_DamageHitToProcess = false;
881 m_ShockDamage = 0;
882 m_HeavyHitOverride = false;
883 return true;
884 }
885
886 return false;
887 }
888
890 bool EvaluateDamageHitAnimation(EntityAI pSource, string pComponent, string pAmmoType, out bool pHeavyHit, out int pAnimType, out float pAnimHitDir)
891 {
892 int invertHitDir = 0; //Used to flip the heavy hit animation direction
893
895 pHeavyHit = ((GetGame().ConfigGetInt("cfgAmmo " + pAmmoType + " hitAnimation") > 0) || m_HeavyHitOverride);
896 invertHitDir = GetGame().ConfigGetInt("cfgAmmo " + pAmmoType + " invertHitDir");
897
899 pAnimType = 0; // belly
900
901 if ( !pHeavyHit )
902 {
903 if ( pComponent == "Torso" ) // body
904 pAnimType = 1;
905 else if ( pComponent == "Head" ) // head
906 pAnimType = 2;
907 }
908
910 //pAnimHitDir = ComputeHitDirectionAngle(pSource);
911 pAnimHitDir = ComputeHitDirectionAngleEx(pSource, invertHitDir);
913 //m_ShockDamage = GetGame().ConfigGetFloat( "CfgAmmo " + pAmmoType + " DamageApplied " + "Shock " + "damage");
914 return true;
915 }
916
918 {
919 vector targetDirection = GetDirection();
920 vector toSourceDirection = (pSource.GetPosition() - GetPosition());
921
922 targetDirection[1] = 0;
923 toSourceDirection[1] = 0;
924
925 targetDirection.Normalize();
926 toSourceDirection.Normalize();
927
928 float cosFi = vector.Dot(targetDirection, toSourceDirection);
929 vector cross = targetDirection * toSourceDirection;
930
931 float dirAngle = Math.Acos(cosFi) * Math.RAD2DEG;
932 if ( cross[1] < 0 )
933 dirAngle = -dirAngle;
934
935 return dirAngle;
936 }
937
938 float ComputeHitDirectionAngleEx(EntityAI pSource, int invertHitDir = 0)
939 {
940 vector targetDirection = GetDirection();
941 vector toSourceDirection = (pSource.GetPosition() - GetPosition());
942
943 targetDirection[1] = 0;
944 toSourceDirection[1] = 0;
945
946 targetDirection.Normalize();
947 toSourceDirection.Normalize();
948
949 float cosFi = vector.Dot(targetDirection, toSourceDirection);
950 vector cross = targetDirection * toSourceDirection;
951
952 float dirAngle = Math.Acos(cosFi) * Math.RAD2DEG;
953
954 // We will invert direction of the hit
955 if ( invertHitDir > 0 )
956 dirAngle -= 180;
957
958 if ( cross[1] < 0 )
959 dirAngle = -dirAngle;
960
961 return dirAngle;
962 }
963
964 //-------------------------------------------------------------
968
969 override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
970 {
971 super.EEHitBy(damageResult, damageType, source, component, dmgZone, ammo, modelPos, speedCoef);
972
973 m_TransportHitRegistered = false;
974
975 if ( !IsAlive() )
976 {
977 ZombieHitData data = new ZombieHitData;
978 data.m_Component = component;
979 data.m_DamageZone = dmgZone;
980 data.m_AmmoType = ammo;
982 }
983 else
984 {
985 int crawlTransitionType = -1;
986 if ( EvaluateCrawlTransitionAnimation(source, dmgZone, ammo, crawlTransitionType) )
987 {
988 m_CrawlTransition = crawlTransitionType;
989 return;
990 }
991
993 {
994 if ( dmgZone )
995 m_ShockDamage = damageResult.GetDamage( dmgZone, "Shock" );
997 return;
998 }
999 }
1000 }
1001
1002 override void EEHitByRemote(int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos)
1003 {
1004 super.EEHitByRemote(damageType, source, component, dmgZone, ammo, modelPos);
1005 }
1006
1008 protected void DebugSound(string s)
1009 {
1010 //Print(s);
1011 }
1012
1013 //-------------------------------------------------------------
1017
1018 override protected void EOnContact(IEntity other, Contact extra)
1019 {
1020 if ( !IsAlive() )
1021 return;
1022
1023 Transport transport = Transport.Cast(other);
1024 if ( transport )
1025 {
1026 if ( GetGame().IsServer() )
1027 {
1028 RegisterTransportHit(transport);
1029 }
1030 }
1031 }
1032
1033 override bool CanReceiveAttachment(EntityAI attachment, int slotId)
1034 {
1035 if ( !IsAlive() )
1036 {
1037 return false;
1038 }
1039 return super.CanReceiveAttachment(attachment, slotId);
1040 }
1041
1043 {
1044 return GetBonePositionWS( GetBoneIndexByName( "spine3" ) );
1045 }
1046
1048 override bool IsBeingBackstabbed()
1049 {
1050 return m_FinisherInProgress;
1051 }
1052
1053 override void SetBeingBackstabbed(int backstabType)
1054 {
1055 // disable AI simulation
1056 GetAIAgent().SetKeepInIdle(true);
1057
1058 // select death animation
1059 switch (backstabType)
1060 {
1061 case EMeleeHitType.FINISHER_LIVERSTAB:
1062 m_DeathType = DayZInfectedDeathAnims.ANIM_DEATH_BACKSTAB;
1063 break;
1064
1065 case EMeleeHitType.FINISHER_NECKSTAB:
1066 m_DeathType = DayZInfectedDeathAnims.ANIM_DEATH_NECKSTAB;
1067 break;
1068
1069 default:
1070 m_DeathType = DayZInfectedDeathAnims.ANIM_DEATH_DEFAULT;
1071 }
1072
1073 // set flag - death command will be executed
1074 m_FinisherInProgress = true;
1075 }
1076
1079 {
1080 return m_IsCrawling;
1081 }
1082
1083 // called from command death when stealth attack wan't successful
1085 {
1086 // enable AI simulation again
1087 GetAIAgent().SetKeepInIdle(false);
1088
1089 // reset flag
1090 m_FinisherInProgress = false;
1091 }
1092
1093 override void AddArrow(Object arrow, int componentIndex, vector closeBonePosWS, vector closeBoneRotWS)
1094 {
1096 GetActionComponentNameList(componentIndex, CachedObjectsArrays.ARRAY_STRING, "fire");
1097
1098 int pivot = -1;
1099
1100
1101 for (int i = 0; i < CachedObjectsArrays.ARRAY_STRING.Count() && pivot == -1; i++)
1102 {
1104 }
1105
1106 vector parentTransMat[4];
1107 vector arrowTransMat[4];
1108
1109 if (pivot == -1)
1110 {
1111 GetTransformWS(parentTransMat);
1112 }
1113 else
1114 {
1115 vector rotMatrix[3];
1116 Math3D.YawPitchRollMatrix(closeBoneRotWS * Math.RAD2DEG,rotMatrix);
1117
1118 parentTransMat[0] = rotMatrix[0];
1119 parentTransMat[1] = rotMatrix[1];
1120 parentTransMat[2] = rotMatrix[2];
1121 parentTransMat[3] = closeBonePosWS;
1122 }
1123
1124 arrow.GetTransform(arrowTransMat);
1125 Math3D.MatrixInvMultiply4(parentTransMat, arrowTransMat, arrowTransMat);
1126 // orthogonalize matrix - parent might be skewed
1127 Math3D.MatrixOrthogonalize4(arrowTransMat);
1128 arrow.SetTransform(arrowTransMat);
1129
1130 AddChild(arrow, pivot);
1131 }
1132
1133 override bool IsManagingArrows()
1134 {
1135 return true;
1136 }
1137
1139 {
1140 return m_ArrowManager;
1141 }
1142}
1143
1145class ZombieHitData
1146{
1150}
RepairTentActionReciveData m_DamageZone
vector GetOrientation()
Определения AreaDamageManager.c:306
AnimBootsType
Определения DayZAnimEvents.c:98
bool ModCommandHandlerInside(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Определения DayZAnimal.c:136
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)
Определения DayZAnimal.c:131
bool ModCommandHandlerAfter(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Определения DayZAnimal.c:141
override Widget Init()
Определения DayZGame.c:127
DayZInfectedConstants
Определения DayZInfected.c:2
DayZInfectedAttackGroupType
Определения DayZInfectedType.c:14
EMeleeHitType
Определения DayZPlayerImplementMeleeCombat.c:2
void DayZPlayerUtils()
cannot be instantiated
Определения DayZPlayerUtils.c:465
EMeleeTargetType
Определения EMeleeTargetType.c:2
void PlaySound()
Определения HungerSoundHandler.c:38
string m_AmmoType
Определения ImpactEffects.c:18
void InfectedSoundEventHandler(ZombieBase pInfected)
Определения InfectedSoundEventHandler.c:21
EInfectedSoundEventID
Определения InfectedSoundEventHandler.c:2
class BoxCollidingParams component
ComponentInfo for BoxCollidingResult.
PluginManager GetPluginManager()
Returns registred plugin by class type, better is to use global funtion GetPlugin(typename plugin_typ...
Определения PluginManager.c:274
class ZombieBase extends DayZInfected m_Component
an extendable data container
Определения AnimalBase.c:95
proto native NoiseSystem GetNoiseSystem()
proto native int ConfigGetInt(string path)
Get int value from config on path.
static ref TStringArray ARRAY_STRING
Определения UtilityClasses.c:49
Определения EnPhysics.c:305
proto native float GetMovementSpeed()
void CommandHandler(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Определения ZombieBase.c:198
int m_StanceVariation
server / singleplayer properties
Определения ZombieBase.c:10
int GetMindStateSynced()
Определения ZombieBase.c:182
float m_KnuckleOutTimer
Определения ZombieBase.c:15
bool m_IsCrawling
Определения ZombieBase.c:34
override void OnSoundVoiceEvent(int event_id, string event_user_string)
Определения ZombieBase.c:550
override void EEHitBy(TotalDamageResult damageResult, int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos, float speedCoef)
Определения ZombieBase.c:969
bool m_FinisherInProgress
Определения ZombieBase.c:36
ref ArrowManagerBase m_ArrowManager
Определения ZombieBase.c:38
bool FightLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Определения ZombieBase.c:607
const float TARGET_CONE_ANGLE_CHASE
Определения ZombieBase.c:3
const float HIT_INTERVAL_MIN
Определения ZombieBase.c:852
int m_MindState
Определения ZombieBase.c:17
ref InfectedSoundEventHandler m_InfectedSoundEventHandler
Определения ZombieBase.c:27
void CommandHandlerDebug(float pDt, int pCurrentCommandID, bool pCurrentCommandFinished)
Определения ZombieBase.c:283
override bool IsManagingArrows()
Определения ZombieBase.c:1133
bool HandleVault(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Определения ZombieBase.c:413
override array< string > GetSuitableFinisherHitComponents()
returns suitable hit components for finisher attacks; DEPRECATED
Определения ZombieBase.c:177
override bool CanReceiveAttachment(EntityAI attachment, int slotId)
Определения ZombieBase.c:1033
int m_CrawlTransition
Определения ZombieBase.c:797
void ProcessSoundVoiceEvent(AnimSoundVoiceEvent sound_event, out AbstractWave aw)
Определения ZombieBase.c:577
int GetOrientationSynced()
returns rounded zombie yaw for sync purposes
Определения ZombieBase.c:188
float m_DeltaTime
Определения ZombieBase.c:24
bool m_DamageHitHeavy
Определения ZombieBase.c:848
int m_DamageHitType
Определения ZombieBase.c:849
bool IsCrawling()
returns true if crawling; 'DayZInfectedCommandCrawl' is only for the transition, after that it remain...
Определения ZombieBase.c:1078
override bool IsSelfAdjustingTemperature()
Определения ZombieBase.c:149
const float SHOCK_TO_STUN_MULTIPLIER
Определения ZombieBase.c:7
void ZombieBase()
Определения ZombieBase.c:43
int m_OrientationLocal
Определения ZombieBase.c:18
float m_MovementSpeed
Определения ZombieBase.c:21
override bool IsDanger()
Определения ZombieBase.c:108
float m_LastMovementSpeed
Определения ZombieBase.c:12
override void EOnInit(IEntity other, int extra)
Определения ZombieBase.c:92
override void AddArrow(Object arrow, int componentIndex, vector closeBonePosWS, vector closeBoneRotWS)
Определения ZombieBase.c:1093
void OnRecoverFromDeath()
Определения ZombieBase.c:1084
override void EEHitByRemote(int damageType, EntityAI source, int component, string dmgZone, string ammo, vector modelPos)
Определения ZombieBase.c:1002
ref array< Object > m_AllTargetObjects
Определения ZombieBase.c:29
DayZInfectedAttackType m_ActualAttackType
Определения ZombieBase.c:605
EntityAI m_ActualTarget
Определения ZombieBase.c:603
AbstractWave ProcessVoiceFX(string pSoundSetName)
Определения ZombieBase.c:526
const float ORIENTATION_SYNC_THRESHOLD
Определения ZombieBase.c:5
int m_ActiveVaultType
Определения ZombieBase.c:399
void HandleOrientation(float pDt, int pCurrentCommandID)
Определения ZombieBase.c:314
override bool CanBeSkinned()
Определения ZombieBase.c:134
override bool IsZombie()
Определения ZombieBase.c:103
bool HandleDamageHit(int pCurrentCommandID)
Определения ZombieBase.c:855
void HandleSoundEvents()
Определения ZombieBase.c:487
bool EvaluateCrawlTransitionAnimation(EntityAI pSource, string pComponent, string pAmmoType, out int pAnimType)
Определения ZombieBase.c:814
vector SetDefaultHitPosition(string pSelection)
Определения ZombieBase.c:171
float m_HitElapsedTime
Определения ZombieBase.c:853
AbstractWave m_LastSoundVoiceAW
Определения ZombieBase.c:26
override AnimBootsType GetBootsType()
Определения ZombieBase.c:129
bool FightAttackLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Определения ZombieBase.c:717
bool HandleCrawlTransition(int pCurrentCommandID)
Определения ZombieBase.c:799
float m_DamageHitDirection
Определения ZombieBase.c:346
void Init()
Определения ZombieBase.c:48
void HandleMove(int pCurrentCommandID)
Определения ZombieBase.c:297
void DebugSound(string s)
sound debug messages
Определения ZombieBase.c:1008
float m_AttackCooldownTime
Определения ZombieBase.c:604
vector m_DefaultHitPosition
Определения ZombieBase.c:23
override bool IsHealthVisible()
Определения ZombieBase.c:139
bool EvaluateDeathAnimationEx(EntityAI pSource, ZombieHitData data, out int pAnimType, out float pAnimHitDir)
Определения ZombieBase.c:363
override bool IsRefresherSignalingViable()
Определения ZombieBase.c:144
float m_ShockDamage
Определения ZombieBase.c:850
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
Определения ZombieBase.c:890
override string GetDefaultHitComponent()
returns default hit component (fallback)
Определения ZombieBase.c:161
override bool IsBeingBackstabbed()
returns true if backstab is in progress; used for suspending of AI targeting and other useful things ...
Определения ZombieBase.c:1048
void EOnContact(IEntity other, Contact extra)
Определения ZombieBase.c:1018
override vector GetCenter()
Определения ZombieBase.c:1042
bool m_DamageHitToProcess
Определения ZombieBase.c:846
bool HandleDeath(int pCurrentCommandID)
Определения ZombieBase.c:349
ref array< typename > m_TargetableObjects
Определения ZombieBase.c:30
override void OnVariablesSynchronized()
synced variable(s) handler
Определения ZombieBase.c:80
bool m_KnuckleLand
Определения ZombieBase.c:14
int m_OrientationSynced
Определения ZombieBase.c:19
override string GetHitComponentForAI()
returns hit component for attacking AI
Определения ZombieBase.c:155
int GetAttackPitch(EntityAI target)
Определения ZombieBase.c:762
float ComputeHitDirectionAngleEx(EntityAI pSource, int invertHitDir=0)
Определения ZombieBase.c:938
int m_LastMindState
Определения ZombieBase.c:11
override void SetBeingBackstabbed(int backstabType)
Определения ZombieBase.c:1053
override bool IsZombieMilitary()
Определения ZombieBase.c:113
const float TARGET_CONE_ANGLE_FIGHT
Определения ZombieBase.c:4
bool IsMale()
Определения ZombieBase.c:118
int m_DeathType
Определения ZombieBase.c:347
override bool CanBeBackstabbed()
Определения ZombieBase.c:123
int GetVaultType(float height)
Определения ZombieBase.c:401
override vector GetDefaultHitPosition()
Определения ZombieBase.c:166
float m_OrientationTimer
Определения ZombieBase.c:20
bool EvaluateDeathAnimation(EntityAI pSource, string pComponent, string pAmmoType, out int pAnimType, out float pAnimHitDir)
Определения ZombieBase.c:370
bool HandleMindStateChange(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Определения ZombieBase.c:450
float ComputeHitDirectionAngle(EntityAI pSource)
Определения ZombieBase.c:917
override ArrowManagerBase GetArrowManager()
Определения ZombieBase.c:1138
bool ChaseAttackLogic(int pCurrentCommandID, DayZInfectedInputController pInputController, float pDt)
Определения ZombieBase.c:676
Определения ZombieBase.c:2
proto native float GetVaultHeight()
Same as 'DayZCreatureAIInputController::GetJumpHeight'.
proto native int GetMindState()
proto native bool IsVault()
Same as 'DayZCreatureAIInputController::IsJump'.
proto native EntityAI GetTargetEntity()
Определения Building.c:6
Определения constants.c:659
Определения EnEntity.c:165
Определения EnMath3D.c:28
Определения EnMath.c:7
static float GetNoiseReduction(Weather weather)
Определения SensesAIEvaluate.c:18
proto void AddNoise(EntityAI source_entity, NoiseParams noise_params, float external_strenght_multiplier=1.0)
Определения ObjectTyped.c:2
Определения PlayerBaseClient.c:2
Определения Sound.c:112
proto native float GetDamage(string zoneName, string healthType)
Определения DamageSystem.c:2
Base native class for all motorized wheeled vehicles.
Определения Boat.c:28
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
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.
Определения EnConvert.c:271
static const vector Zero
Определения EnConvert.c:110
proto float Normalize()
Normalizes vector. Returns length.
static proto native float Distance(vector v1, vector v2)
Returns the distance between tips of two 3D vectors.
Определения EnConvert.c:106
string GetDefaultHitPositionComponent()
Определения dayzplayer.c:502
proto native CGame GetGame()
const float AI_MAX_BLOCKABLE_ANGLE
Определения constants.c:1064
const float AI_ATTACKSPEED
Определения constants.c:1063
EntityEvent
Entity events for event-mask, or throwing event from code.
Определения EnEntity.c:45
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
Определения EnMath.c:16
static const float DEG2RAD
Определения 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].
Определения EnMath.c:54
proto void dBodyApplyImpulse(notnull IEntity body, vector impulse)
Applies impuls on a rigidbody (origin)
class AbstractSoundScene SoundObjectBuilder(SoundParams soundParams)
class JsonUndergroundAreaTriggerData GetPosition
Определения UndergroundAreaLoader.c:9
void AbstractWave()
Определения Sound.c:167
class SoundObject SoundParams(string name)
proto native void AddChild(Widget child, bool immedUpdate=true)