Dayz Explorer 1.28.160049
Loading...
Searching...
No Matches
emotemanager.c
Go to the documentation of this file.
2{
3 bool m_IsFullbody;
4 int m_callbackID; //Animation cmd ID
5 PlayerBase m_player;
6 EmoteManager m_Manager;
7
8 void ~EmoteCB()
9 {
10 if (m_Manager)
11 {
12 m_Manager.OnCallbackEnd();
13 }
14
15 if (GetGame() && m_player)
16 m_player.RequestHandAnimationStateRefresh();
17 }
18
19 bool CancelCondition()
20 {
21 return false;
22 }
23
24 bool IsEmoteCallback()
25 {
26 return IsGestureCallback();
27 }
28
29 override void OnAnimationEvent(int pEventID)
30 {
31 switch (pEventID)
32 {
33 case EmoteConstants.EMOTE_SUICIDE_DEATH :
34
35 if (GetGame().IsServer())
36 m_Manager.KillPlayer();
37
38 m_Manager.LogSuicide();
39 break;
40
41 case UA_ANIM_EVENT :
42 if (m_callbackID == DayZPlayerConstants.CMD_GESTUREFB_SURRENDERIN)
43 m_Manager.m_ItemToBeCreated = true;
44 break;
45
46 case EmoteConstants.EMOTE_SUICIDE_BLEED :
47 if (GetGame().IsServer())
48 m_Manager.CreateBleedingEffect(m_callbackID);
49 break;
50
51 case EmoteConstants.EMOTE_SUICIDE_SIMULATION_END :
52 if (GetGame().IsServer())
53 {
54 EntityAI itemInHands = m_player.GetHumanInventory().GetEntityInHands();
55 if (itemInHands)
56 {
57 vector m4[4];
58 itemInHands.GetTransform(m4);
59 m_player.GetInventory().DropEntityWithTransform(InventoryMode.SERVER, m_player, itemInHands, m4);
60 }
61 }
62
63 m_player.StartDeath();
64 break;
65 }
66 }
67
68 override bool IsGestureCallback()
69 {
70 return true;
71 }
72};
73
75{
76 static const int FORCE_NONE = 0;
77 static const int FORCE_DIFFERENT = 1;
78 static const int FORCE_ALL = 2;
79
81 protected int m_ForcePlayEmote;
82 protected int m_ID;
83
84 void EmoteLauncher(int emoteID, bool interrupts_same)
85 {
86 m_ID = emoteID;
87 m_InterruptsSameIDEmote = interrupts_same;
88 m_ForcePlayEmote = FORCE_NONE;
89 }
90
91 void SetForced(int mode)
92 {
93 m_ForcePlayEmote = mode;
94 }
95
97 {
98 return m_ForcePlayEmote;
99 }
100
101 int GetID()
102 {
103 return m_ID;
104 }
105}
106
107class EmoteManager
108{
124 protected bool m_ItemToHands; //deprecated
125 protected bool m_ItemIsOn;
126 protected bool m_MouseButtonPressed;
127 protected bool m_PlayerDies;
128 protected bool m_controllsLocked;
130 protected bool m_EmoteLockState;
132 protected int m_GestureID;
133 protected int m_PreviousGestureID;
134 protected int m_CurrentGestureID;
135 protected int m_LastMask;
136 protected int m_RPSOutcome;
138 protected const int CALLBACK_CMD_INVALID = -1;
139 protected const int CALLBACK_CMD_END = -2;
140 protected const int CALLBACK_CMD_GESTURE_INTERRUPT = -3;
141 protected const int CALLBACK_CMD_INSTACANCEL = -4;
142 PluginAdminLog m_AdminLog;
144
145 protected ref map<int, ref EmoteBase> m_NameEmoteMap; //<emote_ID,EmoteBase>
146 protected ref array<ref EmoteBase> m_EmoteClassArray; //registered 'EmoteBase' object refs
147 protected ref array<int> m_EmoteIDs; //IDs of registered emotes (found in 'EmoteConstants'). For quick access.
148 protected ref array<int> m_EmoteInputIDs; //input IDs for the registered 'EmoteBase' objects
149 protected SHumanCommandSwimSettings m_HumanSwimSettings;
150
152 {
153 m_Player = player;
154 m_HIC = m_Player.GetInputController();
155 m_ItemIsOn = false;
156 m_controllsLocked = false;
158 m_RPSOutcome = -1;
160
162 m_InterruptInputs.Insert("UAMoveForward");
163 m_InterruptInputs.Insert("UAMoveBack");
164 m_InterruptInputs.Insert("UATurnLeft");
165 m_InterruptInputs.Insert("UATurnRight");
166 m_InterruptInputs.Insert("UAMoveLeft");
167 m_InterruptInputs.Insert("UAMoveRight");
168 m_InterruptInputs.Insert("UAStand");
169 m_InterruptInputs.Insert("UACrouch");
170 m_InterruptInputs.Insert("UAProne");
171 m_InterruptInputs.Insert("UAGetOver");
172
174 m_HandInventoryLocation.SetHands(m_Player, null);
175
176 if (GetGame().IsServer())
177 {
178 m_AdminLog = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
179 }
180
182 m_ReservationTimer.Run(8, this, "CheckEmoteLockedState", null, true);
183
184 m_HumanSwimSettings = m_Player.GetDayZPlayerType().CommandSwimSettingsW();
185
187 }
188
190 {
191 if (m_ReservationTimer && m_ReservationTimer.IsRunning())
192 m_ReservationTimer.Stop();
193 }
194
196 {
198 if (!m_NameEmoteMap)
199 {
200 ec.ConstructEmotes(m_Player,m_NameEmoteMap);
204 int inputID;
205 int count = m_NameEmoteMap.Count();
206 UAInput inp;
207
208 for (int i = 0; i < count; i++)
209 {
210 m_EmoteClassArray.Insert(m_NameEmoteMap.GetElement(i));
211 m_EmoteIDs.Insert(m_NameEmoteMap.GetElement(i).GetID());
212 inp = GetUApi().GetInputByName(m_NameEmoteMap.GetElement(i).GetInputActionName());
213 inputID = inp.ID();
214 m_EmoteInputIDs.Insert(inputID);
215 }
216
217 if (m_EmoteInputIDs.Count() != m_EmoteClassArray.Count())
218 {
219 ErrorEx("Faulty emote data detected in 'ConstructData' method!",ErrorExSeverity.WARNING);
220 }
221 }
222 }
223
224 void SetGesture(int id)
225 {
226 m_GestureID = id;
227 }
228
230 {
231 return m_GestureID;
232 }
233
235 {
236 int count = m_EmoteInputIDs.Count();
237 for (int i = 0; i < count; ++i)
238 {
239 if (GetUApi().GetInputByID(m_EmoteInputIDs[i]).LocalPress())
240 {
241 return m_EmoteIDs[i];
242 }
243 }
244
245 return 0;
246 }
247
249 bool DetermineEmoteData(EmoteBase emote, out int callback_ID, out int stancemask, out bool is_fullbody)
250 {
251 if (emote.DetermineOverride(callback_ID, stancemask, is_fullbody))
252 {
253 return emote.EmoteFBStanceCheck(stancemask);
254 }
255 else if (emote.GetAdditiveCallbackUID() != 0 && m_Player.IsPlayerInStance(emote.GetStanceMaskAdditive()))
256 {
257 callback_ID = emote.GetAdditiveCallbackUID();
258 stancemask = emote.GetStanceMaskAdditive();
259 is_fullbody = false;
260 return true;
261 }
262 else if (emote.GetFullbodyCallbackUID() != 0 && emote.EmoteFBStanceCheck(emote.GetStanceMaskFullbody()))
263 {
264 callback_ID = emote.GetFullbodyCallbackUID();
265 stancemask = emote.GetStanceMaskFullbody();
266 is_fullbody = true;
267 return true;
268 }
269
270 return false;
271 }
272
273 //Called from players commandhandler each frame, checks input
274 void Update(float deltaT)
275 {
276 // no updates on restrained characters
278 return;
279
281 {
282 if (GetGame().IsServer() && m_Callback && !m_Player.GetItemInHands())
283 {
284 m_Player.GetHumanInventory().CreateInHands("SurrenderDummyItem");
285 }
286 m_ItemToBeCreated = false;
287 }
288
289 int gestureSlot = 0;
290 #ifndef SERVER
291 gestureSlot = DetermineGestureIndex();
292 #endif
293 //deferred emote cancel
294 if (m_InstantCancelEmote) //'hard' cancel
295 {
296 if (m_Callback)
297 {
298 m_Callback.Cancel();
299 }
300
301 if (m_MenuEmote)
302 {
303 m_MenuEmote = null;
304 }
306 m_InstantCancelEmote = false;
308 if (m_IsSurrendered)
310 else
311 SetEmoteLockState(false);
312 }
313 else if (m_CancelEmote) //'soft' cancel
314 {
315 if (m_IsSurrendered)
316 {
318 }
319 else if (m_Callback)
320 {
321 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_INTERRUPT);
322 }
323
325 m_CancelEmote = false;
326 }
327
328 if (m_MenuEmote && m_MenuEmote.GetForced() > EmoteLauncher.FORCE_NONE && !GetGame().IsDedicatedServer()) //forced emote playing
329 {
331 }
332 else if (m_Callback)
333 {
334 bool uiGesture = false;
335 if (!GetGame().IsDedicatedServer())
336 {
337 uiGesture = GetGame().GetUIManager().IsMenuOpen(MENU_GESTURES);
338
340 {
342 }
343
345 {
347 }
348 }
349
350 if (gestureSlot > 0 || m_GestureInterruptInput || (m_HIC.IsSingleUse() && !uiGesture) || (m_HIC.IsContinuousUseStart() && !uiGesture) || (m_Callback.m_IsFullbody && !uiGesture && m_HIC.IsWeaponRaised()))
351 {
352 if (m_CurrentGestureID == EmoteConstants.ID_EMOTE_SUICIDE && m_HIC.IsSingleUse())
353 {
354 if (m_Callback.GetState() == m_Callback.STATE_LOOP_LOOP)
355 {
357 }
358 else
359 {
360 return;
361 }
362 }
363 else if ((m_CurrentGestureID == EmoteConstants.ID_EMOTE_THUMB || m_CurrentGestureID == EmoteConstants.ID_EMOTE_THUMBDOWN) && m_HIC.IsSingleUse())
364 {
365 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_ACTION);
366 }
367 else if (m_HIC.IsSingleUse() && (m_CurrentGestureID == EmoteConstants.ID_EMOTE_RPS || m_CurrentGestureID == EmoteConstants.ID_EMOTE_RPS_R || m_CurrentGestureID == EmoteConstants.ID_EMOTE_RPS_P || m_CurrentGestureID == EmoteConstants.ID_EMOTE_RPS_S))
368 {
369 if (m_RPSOutcome != -1)
370 {
371 if (m_RPSOutcome == 0)
372 {
373 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_RPS_ROCK);
374 }
375 else if (m_RPSOutcome == 1)
376 {
377 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_RPS_PAPER);
378 }
379 else if (m_RPSOutcome == 2)
380 {
381 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_RPS_SCISSORS);
382 }
383 m_RPSOutcome = -1;
384 }
385 else
386 {
387 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_END);
388 }
389 }
390 else if (m_CurrentGestureID != EmoteConstants.ID_EMOTE_SUICIDE || (m_CurrentGestureID == EmoteConstants.ID_EMOTE_SUICIDE && m_Callback.GetState() < 3))
391 {
393 }
394 else if (m_CurrentGestureID == EmoteConstants.ID_EMOTE_SUICIDE)
395 {
397 }
398 }
399
400 if (m_LastMask != -1 && m_Player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_PRONE))
401 {
402 m_Callback.Cancel();
403 }
404
406 {
408 }
409
411 {
413 }
414
416 {
418 }
419 }
420 //no m_Callback exists
421 else
422 {
423 if (m_bEmoteIsRequestPending && (m_Player.IsUnconscious() || !m_Player.IsAlive()))
424 {
426 }
427
429 {
430 OnEmoteEnd();
431 }
432 else if (!m_Player.GetItemInHands() && m_IsSurrendered && !m_ItemToBeCreated && (!m_MenuEmote || m_MenuEmote.GetForced() != EmoteLauncher.FORCE_NONE)) //play only when there is time to do so
433 {
434 PlaySurrenderInOut(false);
435 return;
436 }
437 // getting out of surrender state
438 else if (m_IsSurrendered && m_Player.GetItemInHands() && (m_HIC.IsSingleUse() || m_HIC.IsContinuousUseStart() || m_HIC.IsWeaponRaised()))
439 {
440 if (m_Player.GetItemInHands())
441 m_Player.GetItemInHands().DeleteSafe();//Note, this keeps item 'alive' until it is released by all the systems (inventory swapping etc.)
442 return;
443 }
444 // fallback in case lock does not end properly
445 else if (m_IsSurrendered && (!m_Player.GetItemInHands() || (m_Player.GetItemInHands() && m_Player.GetItemInHands().GetType() != "SurrenderDummyItem" && m_EmoteLockState)))
446 {
448 return;
449 }
450 //actual emote launch
452 {
454 }
455 //client-side emote launcher
456 else if (!m_bEmoteIsPlaying && m_MenuEmote && !GetGame().IsDedicatedServer())
457 {
459 }
460 else if (!m_MenuEmote && gestureSlot > 0)
461 {
462 CreateEmoteCBFromMenu(gestureSlot,true); //translation no longer needed
463 }
464 }
465 }
466
468 {
470
471 if (m_PlayerDies)
472 {
473 m_Player.SetHealth(0.0);
474 return;
475 }
476
477 //surrender "state" OFF switch only
478 if (m_CurrentGestureID == EmoteConstants.ID_EMOTE_SURRENDER)
479 {
480 if (m_IsSurrendered && !m_Player.GetItemInHands())
481 {
482 m_IsSurrendered = false;
483 }
484 }
485
487 m_bEmoteIsPlaying = false;
489
490 if (m_IsSurrendered)
491 return;
492
494 SetEmoteLockState(false);
495
496 // back to the default - shoot from camera - if not set already
499 }
500
501 //server-side
502 bool OnInputUserDataProcess(int userDataType, ParamsReadContext ctx)
503 {
504 if (userDataType == INPUT_UDT_GESTURE)
505 {
506 int forced = EmoteLauncher.FORCE_NONE;
507 int gestureID = -1;
508 int random = -1;
509
510 if (ctx.Read(gestureID))
511 {
512 ctx.Read(forced);
513 if (ctx.Read(random))
514 {
515 m_RPSOutcome = random;
516 }
517
518 //server-side check, sends CALLBACK_CMD_INSTACANCEL as a fail
519 if (forced == EmoteLauncher.FORCE_NONE && !CanPlayEmote(gestureID))
520 gestureID = CALLBACK_CMD_INSTACANCEL;
521
523 pCtx.Write(gestureID);
524 pCtx.Write(forced);
525 m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_GESTURE_REQUEST, pCtx);
527 }
528 return true;
529 }
530 return false;
531 }
532
533 //server and client
534 void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
535 {
536 int forced;
537 int gesture_id;
538 if (!m_CancelEmote)
539 {
540 pCtx.Read(gesture_id);
541 pCtx.Read(forced);
542
543 EmoteBase emoteData;
544 if ((m_Callback || m_IsSurrendered) && (forced == EmoteLauncher.FORCE_ALL || (forced == EmoteLauncher.FORCE_DIFFERENT && m_CurrentGestureID != gesture_id)))
545 {
546 if (m_Callback)
547 {
548 if (m_NameEmoteMap.Find(m_CurrentGestureID,emoteData) && emoteData.CanBeCanceledNormally(m_Callback))
549 m_CancelEmote = true;
550 else
551 return;
552 }
553 m_CancelEmote = true;
554 }
555
556 if (gesture_id == CALLBACK_CMD_INSTACANCEL)
557 {
558 if (m_Callback)
559 {
560 if (m_NameEmoteMap.Find(m_CurrentGestureID,emoteData) && !emoteData.CanBeCanceledNormally(m_Callback))
561 {
562 m_InstantCancelEmote = false;
563 return;
564 }
565 }
567 }
568
569 m_DeferredEmoteExecution = gesture_id;
570 }
571 else
572 m_CancelEmote = false;
573 }
574
576 {
577 EmoteBase emoteData;
578 if (m_NameEmoteMap.Find(m_CurrentGestureID,emoteData))
579 emoteData.OnCallbackEnd();
580 }
581
583 {
584 if (m_Player.GetItemInHands() && SurrenderDummyItem.Cast(m_Player.GetItemInHands()))
585 m_Player.GetItemInHands().Delete();
586 }
587
588 bool PlayEmote(int id)
589 {
592
593 if (CanPlayEmote(id))
594 {
595 EmoteBase emote;
596 m_NameEmoteMap.Find(id,emote);
597
598 if (m_AdminLog)
599 m_AdminLog.OnEmote(m_Player, emote);
600
603 if (id > 0)
604 {
605 if (emote)
606 {
607 int callback_ID;
608 int stancemask;
609 bool is_fullbody;
610 if (DetermineEmoteData(emote,callback_ID,stancemask,is_fullbody))
611 {
612 if (!emote.EmoteStartOverride(EmoteCB,callback_ID,stancemask,is_fullbody))
613 {
614 emote.OnBeforeStandardCallbackCreated(callback_ID,stancemask,is_fullbody);
615 CreateEmoteCallback(EmoteCB,callback_ID,stancemask,is_fullbody);
616 }
617
618 if (emote.GetHideItemInHands())
619 {
621 }
622 }
623 else
624 {
625 ErrorEx("EmoteManager | DetermineEmoteData failed!");
626 }
627 }
628 }
629 }
630
632 return m_bEmoteIsPlaying;
633 }
634
635 //creates Emote callback
636 protected void CreateEmoteCallback(typename callbacktype, int id, int mask, bool fullbody)
637 {
638 if (m_Player)
639 {
640 m_LastMask = -1;
641
642 if (fullbody)
643 {
644 Class.CastTo(m_Callback, m_Player.StartCommand_Action(id,callbacktype,mask));
645 m_Callback.m_IsFullbody = true;
646 m_Callback.EnableCancelCondition(true);
647 }
648 else if (m_Player.IsPlayerInStance(mask))
649 {
650 m_LastMask = mask; //character is probably not prone now
651 Class.CastTo(m_Callback, m_Player.AddCommandModifier_Action(id,callbacktype));
652 }
653
654 if (m_Callback)
655 {
656 m_bEmoteIsPlaying = true;
657 m_Callback.m_callbackID = id;
658 m_Callback.m_player = m_Player;
659 m_Callback.m_Manager = this;
660 }
661 }
662 }
663
664 protected void HideItemInHands()
665 {
666 m_item = m_Player.GetItemInHands();
667 if (m_Callback && m_item)
668 {
669 m_Player.TryHideItemInHands(true);
670 }
671 }
672
673 protected void ShowItemInHands()
674 {
675 if (m_item)
676 {
677 m_Player.TryHideItemInHands(false);
678 }
679 }
680
682 {
683 if (!GetGame().IsClient())
685 }
686
687 protected void CommitSuicide()
688 {
689 Weapon_Base weapon;
690 WeaponEventBase weapon_event = new WeaponEventTrigger;
691
692 if (Weapon_Base.CastTo(weapon,m_Player.GetItemInHands()))
693 {
694 if (weapon.CanFire())
695 {
696 m_Callback.RegisterAnimationEvent("Simulation_End",EmoteConstants.EMOTE_SUICIDE_SIMULATION_END);
697 m_Player.SetSuicide(true);
698 weapon.ProcessWeaponEvent(weapon_event);
699 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_FINISH);
700 if (m_Player.IsAlive())
701 {
702 EntityAI helm = m_Player.FindAttachmentBySlotName("Headgear");
703 if (helm && GetGame().IsServer())
704 {
705 float damage = helm.GetMaxHealth("","");
706 helm.AddHealth("","", -damage/2);
707 }
708 GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).Call(this.KillPlayer);
709 if (m_AdminLog)
710 {
711 m_AdminLog.Suicide(m_Player);
712 }
713 }
714 }
715 else
716 {
717 if (!weapon.IsDamageDestroyed())
718 {
719 weapon.ProcessWeaponEvent(weapon_event);
720 }
721 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_END);
722 }
723 }
724 else if (m_Player.GetItemInHands() && m_Player.GetItemInHands().ConfigIsExisting("suicideAnim"))
725 {
726 m_Callback.RegisterAnimationEvent("Death",EmoteConstants.EMOTE_SUICIDE_DEATH);
727 m_Callback.RegisterAnimationEvent("Bleed",EmoteConstants.EMOTE_SUICIDE_BLEED);
728 m_Callback.RegisterAnimationEvent("Simulation_End",EmoteConstants.EMOTE_SUICIDE_SIMULATION_END);
729 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_FINISH);
730 m_Player.SetSuicide(true);
731 }
732 else
733 {
734 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_FINISH);
735 }
736 }
737
739 {
740 if (GetGame().IsServer())
741 {
742 m_Player.SetHealth(0);
743 }
744 }
745
747 {
748 if (GetGame().IsServer())
749 {
750 PlayerIdentity identity = m_Player.GetIdentity();
751 if (identity)
752 {
753 if (m_AdminLog)
754 m_AdminLog.Suicide(m_Player);
755 }
756 }
757 }
758
759 void CreateEmoteCBFromMenu(int id, bool interrupts_same = false)
760 {
761 m_MenuEmote = new EmoteLauncher(id,interrupts_same);
762 }
763
765 {
766 return m_MenuEmote;
767 }
768
770 {
771 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_INTERRUPT);
772
773 if (m_MenuEmote)
774 m_MenuEmote = null;
775
777 }
778
780 {
781 if (m_CurrentGestureID == EmoteConstants.ID_EMOTE_DANCE)
782 {
783 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_INTERRUPT);
784 }
785 else
786 {
787 m_Callback.InternalCommand(DayZPlayerConstants.CMD_ACTIONINT_END);
788 }
789
790 if (m_MenuEmote)
791 m_MenuEmote = null;
793 }
794
795 //sends request (client)
797 {
798 int forced = EmoteLauncher.FORCE_NONE;
799 if (m_MenuEmote)
800 {
801 forced = m_MenuEmote.GetForced();
802 }
803
804 m_RPSOutcome = -1;
805 switch (id)
806 {
807 case EmoteConstants.ID_EMOTE_RPS :
808 m_RPSOutcome = Math.RandomInt(0,3);
809 break;
810
811 case EmoteConstants.ID_EMOTE_RPS_R :
812 m_RPSOutcome = 0;
813 break;
814
815 case EmoteConstants.ID_EMOTE_RPS_P :
816 m_RPSOutcome = 1;
817 break;
818
819 case EmoteConstants.ID_EMOTE_RPS_S :
820 m_RPSOutcome = 2;
821 break;
822 }
823
825 if (GetGame().IsMultiplayer() && GetGame().IsClient())
826 {
827 bool canProceed = true; //running callbacks in certain state can block additional actions
829 if (m_Callback && emoteData)
830 {
831 canProceed = emoteData.CanBeCanceledNormally(m_Callback);
832 }
833
834 if (ctx.CanStoreInputUserData() && ((CanPlayEmote(id) && CanPlayEmoteClientCheck(id)) || forced) && canProceed)
835 {
836 ctx.Write(INPUT_UDT_GESTURE);
837 ctx.Write(id);
838 ctx.Write(forced);
839 if (m_RPSOutcome != -1)
840 {
841 ctx.Write(m_RPSOutcome);
842 }
843 ctx.Send();
845 }
846 else
847 {
849 }
850 m_MenuEmote = NULL;
852 }
853 else if (!GetGame().IsMultiplayer())
854 {
855 if (id == CALLBACK_CMD_END)
856 {
858 }
859 else if (id == CALLBACK_CMD_GESTURE_INTERRUPT)
860 {
862 }
863 else if (CanPlayEmote(id) && CanPlayEmoteClientCheck(id))
864 {
865 PlayEmote(id);
866 }
867 else
868 {
870 }
871 m_MenuEmote = NULL;
872 }
873 }
874
876 {
877 return m_controllsLocked;
878 }
879
880 bool CanPlayEmote(int id)
881 {
882 //special cases
884 {
885 return true;
886 }
887
888 if (!m_Player || !m_Player.IsAlive() || (!IsEmotePlaying() && (m_Player.GetCommand_Action() || m_Player.GetCommandModifier_Action())) || m_Player.GetThrowing().IsThrowingModeEnabled())
889 {
890 //Debug.Log("!CanPlayEmote | reason: 1");
891 return false;
892 }
893
894 ItemBase item = m_Player.GetItemInHands();
895 if (item)
896 {
897 if (item.IsHeavyBehaviour() && id != EmoteConstants.ID_EMOTE_SURRENDER)
898 {
899 //Debug.Log("!CanPlayEmote | reason: 2");
900 return false;
901 }
902
903 SurrenderDummyItem sda;
904 if (m_Player.IsItemsToDelete() && Class.CastTo(sda,item) && !sda.IsSetForDeletion())
905 {
906 //Debug.Log("!CanPlayEmote | reason: 3");
907 return false;
908 }
909 }
910
911 if ((m_Player.GetWeaponManager() && m_Player.GetWeaponManager().IsRunning()) || (m_Player.GetActionManager() && m_Player.GetActionManager().GetRunningAction()))
912 {
913 //Debug.Log("!CanPlayEmote | reason: 4");
914 return false;
915 }
916
917 if (m_HIC.IsWeaponRaised() || m_Player.IsRolling() || m_Player.IsClimbing() || m_Player.IsRestrainStarted() || m_Player.IsFighting() || m_Player.IsSwimming() || m_Player.IsClimbingLadder() || m_Player.IsFalling() || m_Player.IsUnconscious() || m_Player.IsJumpInProgress() || m_Player.IsRestrained()) // rework conditions into something better?
918 {
919 //Debug.Log("!CanPlayEmote | reason: 5");
920 return false;
921 }
922
923 if (m_Player.GetCommand_Vehicle())
924 {
925 //Debug.Log("!CanPlayEmote | reason: 6");
926 return false;
927 }
928
929 HumanCommandMove cm = m_Player.GetCommand_Move();
930 if (cm)
931 {
932 if (cm.IsOnBack() && id != EmoteConstants.ID_EMOTE_SURRENDER)
933 return false;
934 if (cm.IsChangingStance())
935 return false;
936 }
937
938 //"locks" player in surrender state
939 if (m_IsSurrendered && (id != EmoteConstants.ID_EMOTE_SURRENDER))
940 {
941 //Debug.Log("!CanPlayEmote | reason: 8");
942 return false;
943 }
944
945 if (m_Player.GetDayZPlayerInventory().IsProcessing())
946 {
947 //Debug.Log("!CanPlayEmote | reason: 9");
948 return false;
949 }
950
951 EmoteBase emote;
952 if (m_NameEmoteMap.Find(id,emote))
953 {
954 int callback_ID;
955 int stancemask;
956 bool is_fullbody;
957 if (DetermineEmoteData(emote,callback_ID,stancemask,is_fullbody) && emote.EmoteCondition(stancemask))
958 {
959 return true;
960 }
961 //Debug.Log("!CanPlayEmote | reason: 10");
962 }
963
964 return false;
965 }
966
968 {
969 if (!GetGame().IsClient())
970 return true;
971
972 if (GetGame().GetUIManager().FindMenu(MENU_INVENTORY))
973 {
974 //Debug.Log("!CanPlayEmoteClientCheck | reason: 1");
975 return false;
976 }
977
978 return true;
979 }
980
981 void PlaySurrenderInOut(bool state)
982 {
984 m_CurrentGestureID = EmoteConstants.ID_EMOTE_SURRENDER;
985
986 if (state)
987 {
988 ItemBase item = m_Player.GetItemInHands();
989 if (item)
990 {
991 if (!m_Player.CanDropEntity(item))
992 return;
993
994 if (m_Player.GetInventory().HasInventoryReservation(null, m_HandInventoryLocation))
995 m_Player.GetInventory().ClearInventoryReservationEx(null, m_HandInventoryLocation);
996
997 if (GetGame().IsMultiplayer())
998 {
999 if (GetGame().IsServer())
1000 m_Player.ServerDropEntity(item);
1001 }
1002 else
1003 {
1004 m_Player.PhysicalPredictiveDropItem(item); //SP only
1005 }
1006 }
1007
1008 CreateEmoteCallback(EmoteCB,DayZPlayerConstants.CMD_GESTUREFB_SURRENDERIN,DayZPlayerConstants.STANCEMASK_ALL,true);
1009
1010 if (m_Callback)
1011 {
1012 m_Callback.RegisterAnimationEvent("ActionExec", UA_ANIM_EVENT);
1013 m_IsSurrendered = true; //sets state immediately on anim start
1014 }
1015 }
1016 else
1017 {
1018 if (m_Player.IsAlive() && !m_Player.IsUnconscious())
1019 {
1020 CreateEmoteCallback(EmoteCB,DayZPlayerConstants.CMD_GESTUREFB_SURRENDEROUT,DayZPlayerConstants.STANCEMASK_ALL,true);
1021 }
1022 else
1023 {
1024 OnEmoteEnd();
1025 }
1026 }
1027 }
1028
1030 void SetEmoteLockState(bool state)
1031 {
1032 //separate inventory access locking
1033 if (state != m_InventoryAccessLocked)
1034 {
1035 m_Player.SetInventorySoftLock(state);
1037 }
1038
1039 if (GetGame().IsClient() && m_InventoryAccessLocked && GetGame().GetUIManager().FindMenu(MENU_INVENTORY))
1040 m_Player.CloseInventoryMenu();
1041
1042 //Movement lock in fullbody anims
1043 if (state && m_Callback && m_Callback.m_IsFullbody)
1044 m_controllsLocked = true;
1045 else
1046 m_controllsLocked = false;
1047
1048 if (state == m_EmoteLockState)
1049 return;
1050
1052 {
1054 m_HandInventoryLocation.SetHands(m_Player,null);
1055 }
1056
1057 if (!state)
1058 {
1059 if (m_Player.GetInventory().HasInventoryReservation(null, m_HandInventoryLocation))
1060 m_Player.GetInventory().ClearInventoryReservationEx(null, m_HandInventoryLocation);
1061
1062 if (m_Player.GetActionManager())
1063 m_Player.GetActionManager().EnableActions(true);
1064 }
1065 else
1066 {
1067 if (!m_Player.GetInventory().HasInventoryReservation(null, m_HandInventoryLocation))
1068 m_Player.GetInventory().AddInventoryReservationEx(null, m_HandInventoryLocation, GameInventory.c_InventoryReservationTimeoutMS);
1069
1070 if (m_Player.GetActionManager())
1071 m_Player.GetActionManager().EnableActions(false);
1072 }
1073 m_EmoteLockState = state;
1074 }
1075
1077 {
1078 if (!m_Player.GetItemInHands() || (m_Player.GetItemInHands() && !SurrenderDummyItem.Cast(m_Player.GetItemInHands())))
1079 return;
1080
1081 //refreshes reservation in case of unwanted timeout
1083 {
1084 m_Player.GetInventory().ExtendInventoryReservationEx(null, m_HandInventoryLocation, 10000);
1085 }
1086 }
1087
1090 {
1091 if (m_IsSurrendered && data)
1092 {
1094 data.End();
1095 }
1096 }
1097
1099 protected void ClearSurrenderState()
1100 {
1101 if (m_IsSurrendered)
1102 {
1103 SurrenderDummyItem dummyItem = SurrenderDummyItem.Cast(m_Player.GetItemInHands());
1104 if (dummyItem)
1105 dummyItem.DeleteSafe();
1106 m_IsSurrendered = false;
1108 }
1109 }
1110
1111 void ForceSurrenderState(bool state)
1112 {
1113 m_IsSurrendered = state;
1115 }
1116
1119 {
1120 if ((GetGame().IsMultiplayer() && GetGame().IsServer()) || !GetGame().IsMultiplayer())
1121 {
1123 pCtx.Write(CALLBACK_CMD_INSTACANCEL);
1124 pCtx.Write(EmoteLauncher.FORCE_ALL);
1125 m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_GESTURE_REQUEST, pCtx);
1126 }
1127 }
1128
1129 //sent from server to cancel generic emote callback
1131 {
1134
1135 m_Player.SendSyncJuncture(DayZPlayerSyncJunctures.SJ_GESTURE_REQUEST, pCtx);
1136 }
1137
1139 {
1140 //init pass
1142 {
1145
1146 for (int i = 0; i < m_InterruptInputsCount; i++)
1147 {
1148 m_InterruptInputDirect.Insert(GetUApi().GetInputByName(m_InterruptInputs[i]).GetPersistentWrapper());
1149 }
1150 }
1151
1152 //interrupts any callback if restrain action is in progress, takes priority
1153 if (!m_Callback.m_IsFullbody)
1154 return false;
1155
1156 for (int idx = 0; idx < m_InterruptInputsCount; idx++)
1157 {
1158 if (m_InterruptInputDirect[idx].InputP().LocalPress())
1159 {
1160 return true;
1161 }
1162 }
1163
1164 return false;
1165 }
1166
1168 {
1169 float waterLevel = m_Player.GetCurrentWaterLevel();
1170
1171 if (m_Player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_PRONE | DayZPlayerConstants.STANCEMASK_PRONE) && waterLevel >= m_HumanSwimSettings.m_fToCrouchLevel)
1172 {
1173 return true;
1174 }
1175 else if (m_Player.IsPlayerInStance(DayZPlayerConstants.STANCEMASK_CROUCH | DayZPlayerConstants.STANCEIDX_RAISEDCROUCH) && waterLevel >= m_HumanSwimSettings.m_fToErectLevel)
1176 {
1177 return true;
1178 }
1179
1180 return m_Player.GetModifiersManager() && m_Player.GetModifiersManager().IsModifierActive(eModifiers.MDF_DROWNING);
1181 }
1182
1187
1192
1193 void CreateBleedingEffect(int Callback_ID)
1194 {
1195 if (GetGame().IsServer() && m_Player.IsAlive())
1196 {
1197 switch (Callback_ID)
1198 {
1199 case DayZPlayerConstants.CMD_SUICIDEFB_1HD :
1200 m_Player.GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("Neck");
1201 break;
1202
1203 case DayZPlayerConstants.CMD_SUICIDEFB_FIREAXE :
1204 m_Player.GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("LeftForeArmRoll");
1205 break;
1206
1207 case DayZPlayerConstants.CMD_SUICIDEFB_PITCHFORK :
1208 m_Player.GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("Spine2");
1209 break;
1210
1211 case DayZPlayerConstants.CMD_SUICIDEFB_SWORD :
1212 m_Player.GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("Spine2");
1213 break;
1214
1215 case DayZPlayerConstants.CMD_SUICIDEFB_SPEAR :
1216 m_Player.GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("Head");
1217 break;
1218
1219 case DayZPlayerConstants.CMD_SUICIDEFB_WOODAXE :
1220 m_Player.GetBleedingManagerServer().AttemptAddBleedingSourceBySelection("LeftForeArmRoll");
1221 break;
1222
1223 default :
1224 ErrorEx("EmoteManager.c | CreateBleedingEffect | WRONG ID",ErrorExSeverity.INFO);
1225 break;
1226 }
1227 }
1228 }
1229
1232 protected void PickEmote(int gestureslot)
1233 {
1234 }
1235};
1236
1238{
1240 void End();
1241}
1242
1247{
1249
1250 void ChainedDropAndKillPlayerLambda (EntityAI old_item, string new_item_type, PlayerBase player)
1251 {
1252 m_Player = player;
1254 vector mtx[4];
1255 old_item.GetTransform(mtx);
1256 gnd.SetGround(old_item, mtx);
1257
1258 OverrideNewLocation(gnd);
1259 }
1260
1261 override void Execute (HumanInventoryWithFSM fsm_to_notify = null)
1262 {
1263 if (PrepareLocations())
1264 {
1265 vector transform[4];
1266
1267 m_Player.GetInventory().TakeToDst(InventoryMode.SERVER, m_OldLocation, m_NewLocation);
1269 }
1270
1271 m_Player.SetHealth(0);
1272
1273 if (LogManager.IsInventoryHFSMLogEnable()) hndDebugPrint("[syncinv] player=" + Object.GetDebugName(m_Player) + " STS = " + m_Player.GetSimulationTimeStamp() + " ChainedDropAndKillPlayerLambda");
1274 }
1275}
InventoryMode
NOTE: PREDICTIVE is not to be used at all in multiplayer.
Definition inventory.c:22
const int INPUT_UDT_GESTURE
Definition _constants.c:18
drops weapon in hands to ground and then calls kill
Super root of all classes in Enforce script.
Definition enscript.c:11
DayZPlayerImplementThrowing GetThrowing()
override bool IsShootingFromCamera()
void OverrideShootFromCamera(bool pState)
WeaponManager GetWeaponManager()
void SetSuicide(bool state)
override float GetCurrentWaterLevel()
override void OnItemInHandsChanged()
bool IsFighting()
DayZPlayerInventory GetDayZPlayerInventory()
bool IsRestrained()
void OnCallbackEnd()
bool EmoteFBStanceCheck(int stancemask)
Checks for valid stance mask.
Definition emotebase.c:23
bool CanBeCanceledNormally(notnull EmoteCB callback)
Definition emotebase.c:17
bool DetermineOverride(out int callback_ID, out int stancemask, out bool is_fullbody)
Definition emotebase.c:39
int GetAdditiveCallbackUID()
Definition emotebase.c:85
int GetFullbodyCallbackUID()
Definition emotebase.c:90
int GetStanceMaskAdditive()
Definition emotebase.c:75
bool EmoteStartOverride(typename callbacktype, int id, int mask, bool fullbody)
Definition emotebase.c:47
int GetStanceMaskFullbody()
Definition emotebase.c:80
bool EmoteCondition(int stancemask)
Definition emotebase.c:12
void OnBeforeStandardCallbackCreated(int callback_ID, int stancemask, bool is_fullbody)
bool GetHideItemInHands()
Definition emotebase.c:95
void SetForced(int mode)
bool m_InterruptsSameIDEmote
void EmoteLauncher(int emoteID, bool interrupts_same)
script counterpart to engine's class Inventory
Definition inventory.c:79
const int c_InventoryReservationTimeoutMS
reservations
Definition inventory.c:712
HumanInventory... with FSM (synchronous, no anims)
InventoryLocation.
Definition enmath.c:7
The class that will be instanced (moddable)
Definition gameplay.c:389
base class for transformation operations (creating one item from another)
Serialization general interface. Serializer API works with:
Definition serializer.c:56
signalize mechanism manipulation
Definition events.c:35
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
DayZPlayerConstants
defined in C++
Definition dayzplayer.c:602
eModifiers
Definition emodifiers.c:2
override void OnCallbackEnd()
void ChainedDropAndKillPlayerLambda(EntityAI old_item, string new_item_type, PlayerBase player)
bool m_ItemToHands
EmoteCB m_Callback
ref Timer m_ReservationTimer
ref array< int > m_EmoteInputIDs
const int CALLBACK_CMD_END
void ForceSurrenderState(bool state)
void RequestCommitSuicide()
int m_InterruptInputsCount
void HideItemInHands()
void CheckEmoteLockedState()
bool m_controllsLocked
void EmoteManager(PlayerBase player)
int m_RPSOutcome
void CreateEmoteCBFromMenu(int id, bool interrupts_same=false)
void AfterStoreLoad()
const int CALLBACK_CMD_INVALID
int m_CurrentGestureID
ref array< string > m_InterruptInputs
bool m_CancelEmote
bool CanPlayEmoteClientCheck(int id)
ref array< int > m_EmoteIDs
bool CanPlayEmote(int id)
int m_DeferredEmoteExecution
bool IsControllsLocked()
void ShowItemInHands()
ItemBase m_item
PluginAdminLog m_AdminLog
ref InventoryLocation m_HandInventoryLocation
void InterruptCallbackCommand()
void ConstructData()
void PostSurrenderRequestServer()
server only
int m_LastMask
void PlaySurrenderInOut(bool state)
int DetermineGestureIndex()
void CreateBleedingEffect(int Callback_ID)
void SetGesture(int id)
map< int, ref EmoteBase > GetNameEmoteMap()
void CommitSuicide()
bool m_GestureInterruptInput
void ClearSurrenderState()
clears surrender state only
bool m_InventoryAccessLocked
bool OnInputUserDataProcess(int userDataType, ParamsReadContext ctx)
const int CALLBACK_CMD_INSTACANCEL
void KillPlayer()
void OnEmoteEnd()
void ServerRequestEmoteCancel()
void ~EmoteManager()
void EndSurrenderRequest(SurrenderData data=null)
directly force-ends surrender state AND requests hard cancel
void SetEmoteLockState(bool state)
ref EmoteLauncher m_MenuEmote
void CreateEmoteCallback(typename callbacktype, int id, int mask, bool fullbody)
bool InterruptGestureCheck()
bool m_PlayerDies
bool InterruptWaterCheck()
void OnSyncJuncture(int pJunctureID, ParamsReadContext pCtx)
int m_GestureID
void PickEmote(int gestureslot)
Deprecated.
bool IsEmotePlaying()
bool DetermineEmoteData(EmoteBase emote, out int callback_ID, out int stancemask, out bool is_fullbody)
Also includes a stance check for FB callbacks.
bool m_EmoteLockState
SHumanCommandSwimSettings m_HumanSwimSettings
override void Execute(HumanInventoryWithFSM fsm_to_notify=null)
bool m_ItemToBeCreated
bool m_IsSurrendered
const int CALLBACK_CMD_GESTURE_INTERRUPT
ref map< int, ref EmoteBase > m_NameEmoteMap
HumanInputController m_HIC
ref array< ref EmoteBase > m_EmoteClassArray
void EndCallbackCommand()
bool m_bEmoteIsPlaying
void LogSuicide()
bool m_MouseButtonPressed
bool m_InstantCancelEmote
EmoteLauncher GetEmoteLauncher()
bool m_bEmoteIsRequestPending
bool m_ItemIsOn
void SendEmoteRequestSync(int id)
int m_PreviousGestureID
int GetGesture()
bool PlayEmote(int id)
ref array< UAIDWrapper > m_InterruptInputDirect
proto native CGame GetGame()
ErrorExSeverity
Definition endebug.c:62
enum ShapeType ErrorEx
const int MENU_GESTURES
Definition constants.c:194
const int MENU_INVENTORY
Definition constants.c:180
const int CALL_CATEGORY_GAMEPLAY
Definition tools.c:10
const int UA_ANIM_EVENT
Definition constants.c:473
DayZPlayer m_Player
Definition hand_events.c:42
void hndDebugPrint(string s)
Definition handfsm.c:1
ModifiersManager m_Manager
PluginBase GetPlugin(typename plugin_type)
DayZPlayer m_player
proto native UAInputAPI GetUApi()