Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_EditorManagerEntity.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/Editor", description: "Core Editor manager", color: "251 91 0 255", icon: "WBData/EntityEditorProps/entityEditor.png")]
5
8
27{
29 //--- Attributes
30 [Attribute("true", UIWidgets.Auto, "Are default modes created automatically?", category: "Editor Manager")]
31 private bool m_bIsAutoModes;
32
33 [Attribute("false", UIWidgets.Auto, "Is the editor launched by default?", category: "Editor Manager")]
34 private bool m_bIsAutoInit;
35
37 //--- Variables
38 private bool m_bIsOpened;
39 private bool m_bIsInTransition; //--- Opening or closing
40 private EEditorCanOpen m_CanOpen = EEditorCanOpen.SCRIPT;
41 private EEditorCanOpen m_CanClose = EEditorCanOpen.SCRIPT;
42 private EEditorCanOpen m_CanOpenSum;
43 private EEditorCanOpen m_CanCloseSum;
44
45 private RplComponent m_RplComponent;
46 private int m_iPlayerID;
47 private bool m_bInit;
48 private ref array<SCR_EditorModeEntity> m_Modes = {};
50 private EEditorMode m_PrevMode = -1;
51 private EEditorMode m_CurrentMode = -1;
52 private EEditorMode m_ProcessedMode = -1;
53 private SCR_EditorModeEntity m_CurrentModeEntity;
54 private bool m_bIsModeChangeRequested;
55 private bool m_bIsLimited;
56 protected SCR_NotificationsComponent m_NotificationsComponent;
57
58 private EEditorEventOperation m_iEventOperation = EEditorEventOperation.NONE;
59 private EEditorEvent m_iEvent = EEditorEvent.NONE;
60 private int m_iEventComponent;
61 private int m_iEventAttempt;
62 private float m_iEventProgress;
63 private float m_iEventProgressMax;
64 private float m_fEventAsyncStart;
65 private ref array<SCR_BaseEditorComponent> m_aEventComponentsActivate;
66 private ref array<SCR_BaseEditorComponent> m_aEventComponentsDeactivate;
67 private ref array<EEditorEvent> m_aEvents;
68 private ref array<SCR_VONEntryRadio> editorRadioEntries;
69
70 private ref ScriptInvoker Event_OnInit = new ScriptInvoker();
71 private ref ScriptInvoker Event_OnRequest = new ScriptInvoker();
72 private ref ScriptInvoker Event_OnOpened = new ScriptInvoker();
73 private ref ScriptInvoker Event_OnCanOpen = new ScriptInvoker();
74 private ref ScriptInvoker Event_OnCanClose = new ScriptInvoker();
75 private ref ScriptInvoker Event_OnPreActivate = new ScriptInvoker();
76 private ref ScriptInvoker Event_OnActivate = new ScriptInvoker();
77 private ref ScriptInvoker Event_OnPostActivate = new ScriptInvoker();
78 private ref ScriptInvoker Event_OnDeactivate = new ScriptInvoker();
79 private ref ScriptInvoker Event_OnClosed = new ScriptInvoker();
80 private ref ScriptInvoker Event_OnDebug = new ScriptInvoker();
81 private ref ScriptInvoker Event_OnOpenedServer = new ScriptInvoker();
82 private ref ScriptInvoker Event_OnOpenedServerCallback = new ScriptInvoker();
83 private ref ScriptInvoker Event_OnClosedServer = new ScriptInvoker();
84 private ref ScriptInvoker Event_OnClosedServerCallback = new ScriptInvoker();
85 private ref ScriptInvoker Event_OnModeAdd = new ScriptInvoker();
86 private ref ScriptInvoker Event_OnModeRemove = new ScriptInvoker();
87 private ref ScriptInvoker Event_OnModeChangeRequest = new ScriptInvoker();
88 private ref ScriptInvoker Event_OnModeChange = new ScriptInvoker();
89 private ref ScriptInvoker Event_OnLimitedChange = new ScriptInvoker();
90 private ref ScriptInvoker Event_OnAsyncLoad = new ScriptInvoker();
91 private ref ScriptInvoker Event_OnCanEndGameChanged = new ScriptInvoker();
92
94 //--- Opening
95
96 //------------------------------------------------------------------------------------------------
99 override bool IsOpened()
100 {
101 if (m_bIsInTransition)
102 return !m_bIsOpened; //--- Don't return current state until async loading is finished
103 else
104 return m_bIsOpened;
105 }
106
107 //------------------------------------------------------------------------------------------------
110 void Toggle()
111 {
112 if (m_bIsOpened)
113 Close();
114 else
115 Open();
116 }
117
118 //------------------------------------------------------------------------------------------------
122 void Open(bool showErrorNotification = true)
123 {
124 if (m_bIsOpened || !IsAuthority()) return; //--- Exit when already opened or attempting to edit non-local editor
125 if (!CanOpen())
126 {
127 if (showErrorNotification)
128 SCR_NotificationsComponent.SendToPlayer(GetPlayerID(), ENotification.EDITOR_CANNOT_OPEN);
129
130 return;
131 }
132
133 int playerId = GetPlayerID();
134 PlayerManager playerManager = GetGame().GetPlayerManager();
135
136 // Unscope when going into game master to avoid issues with ADS camera
137 IEntity player = playerManager.GetPlayerControlledEntity(playerId);
138 if (player)
139 {
140 CharacterControllerComponent characterCont = CharacterControllerComponent.Cast(player.FindComponent(CharacterControllerComponent));
141 if (characterCont)
142 characterCont.SetWeaponADS(false);
143 }
144
145 // VON
146 PlayerController playerController = playerManager.GetPlayerController(playerId);
147 if (playerController)
148 {
149 SCR_VONController vonCont = SCR_VONController.Cast(playerController.FindComponent(SCR_VONController));
150 SCR_VoNComponent editorVonComponent = SCR_VoNComponent.Cast(FindComponent(SCR_VoNComponent));
151
152 // Connect the VON component used by the editor.
153 editorVonComponent.ConnectEditorToVoNSystem(m_iPlayerID);
154
155 // Tell SCR_VONController to use the SCR_VoNComponent attached to this editor manager.
156 vonCont.SetVONComponent(editorVonComponent);
157
158 // Give editor radio transceivers
159 if (!vonCont.m_bIsEditorRadioAdded)
160 {
161 vonCont.m_bIsEditorRadioAdded = true;
162
163 SCR_RadioComponent radioGadget = SCR_RadioComponent.Cast(FindComponent(SCR_RadioComponent));
164 radioGadget.OnPostInit(this);
165 BaseRadioComponent radioComp = radioGadget.GetRadioComponent();
166
167 // This could be a good place to set the power of the radioComp. But this is not possible because, the SetPower() function needs
168 // to check if the owner of the radio is a active game master for it to work. That is not the case at this time.
169
170 int transceiversCount = radioComp.TransceiversCount();
171 editorRadioEntries = new array<SCR_VONEntryRadio>();
172 editorRadioEntries.Resize(transceiversCount);
173 for (int i = 0; i < transceiversCount; i++)
174 {
175 BaseTransceiver transceiver = radioComp.GetTransceiver(i);
176 EditorFactionTransceiver editorFactionTransceiver = EditorFactionTransceiver.Cast(transceiver);
177 if (editorFactionTransceiver)
178 {
179 SCR_VONEntryRadio editorRadioEntry = new SCR_VONEntryRadio();
180 editorRadioEntry.SetRadioEntry(transceiver, i + 1, radioGadget);
181 editorRadioEntry.SetChannelTextOverwrite("GM " + editorFactionTransceiver.GetEditorFaction());
182 vonCont.AddEntry(editorRadioEntry);
183
184 editorRadioEntries[i] = editorRadioEntry;
185 }
186 else
187 {
188 SCR_VONEntryRadio editorRadioEntry = new SCR_VONEntryRadio();
189 editorRadioEntry.SetRadioEntry(transceiver, i + 1, radioGadget);
190 editorRadioEntry.SetChannelTextOverwrite("GM");
191 editorRadioEntry.SetFrequencyTextOverwrite(" GM");
192 vonCont.AddEntry(editorRadioEntry);
193
194 editorRadioEntries[i] = editorRadioEntry;
195 }
196 }
197 }
198 }
199
201 Rpc(ToggleServer, true);
202 }
203
204 //------------------------------------------------------------------------------------------------
208 void Close(bool showErrorNotification = true)
209 {
210 if (!m_CurrentModeEntity || m_CurrentModeEntity.GetPreventClose())
211 return;
212
213 if (!m_bIsOpened || !IsAuthority())
214 return; //--- Exit when already closed or attempting to edit non-local editor
215
216 if (!CanClose())
217 {
218 if (showErrorNotification)
219 SCR_NotificationsComponent.SendToPlayer(GetPlayerID(), ENotification.EDITOR_CANNOT_CLOSE);
220
221 return;
222 }
223
224 // VON
225 int playerId = GetPlayerID();
226 PlayerManager playerManager = GetGame().GetPlayerManager();
227 PlayerController playerController = playerManager.GetPlayerController(playerId);
228 if (playerController)
229 {
230 SCR_VONController vonCont = SCR_VONController.Cast(playerController.FindComponent(SCR_VONController));
231 SCR_VoNComponent editorVonComponent = SCR_VoNComponent.Cast(FindComponent(SCR_VoNComponent));
232
233 // Disconnect the VON component used by editor.
234 editorVonComponent.DisconnectEditorFromVoNSystem();
235
236 IEntity player = playerManager.GetPlayerControlledEntity(playerId);
237 if (player)
238 {
239 SCR_VoNComponent charVonComponent = SCR_VoNComponent.Cast(player.FindComponent(SCR_VoNComponent));
240
241 // Tell SCR_VONController to use the SCR_VoNComponent attached to the player character.
242 vonCont.SetVONComponent(charVonComponent);
243
244 // Remove editor radio transceivers
245 if (editorRadioEntries)
246 {
247 foreach (SCR_VONEntryRadio entry : editorRadioEntries)
248 {
249 if (entry)
250 vonCont.RemoveEntry(entry);
251 }
252 editorRadioEntries.Clear();
253 }
254
255 vonCont.m_bIsEditorRadioAdded = false;
256 }
257 }
258
259 StartEvents(EEditorEventOperation.REQUEST_CLOSE);
260 //Event_OnRequest.Invoke(false);
261 Rpc(ToggleServer, false);
262 }
263
264 //------------------------------------------------------------------------------------------------
265 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
266 protected void ToggleServer(bool open)
267 {
268 if (m_bIsOpened == open || RplSession.Mode() == RplMode.Client) return;
269
270 // Attempting to open when it's not allowed
271 if (open && !CanOpen())
272 {
273 SCR_NotificationsComponent.SendToPlayer(GetPlayerID(), ENotification.EDITOR_CANNOT_OPEN);
274 return;
275 }
276 // Attempting to close when it's not allowed
277 if (!open && !CanClose())
278 {
279 SCR_NotificationsComponent.SendToPlayer(GetPlayerID(), ENotification.EDITOR_CANNOT_CLOSE);
280 return;
281 }
282
283 m_bIsOpened = open;
284 Rpc(ToggleOwner, m_bIsOpened);
285
286 if (m_bIsOpened)
287 {
288 if (m_CurrentModeEntity)
289 m_CurrentModeEntity.ActivateModeServer();
290
291 Event_OnOpenedServer.Invoke();
292 }
293 else
294 {
295 if (m_CurrentModeEntity)
296 m_CurrentModeEntity.DeactivateModeServer();
297
298 Event_OnClosedServer.Invoke();
299 }
300 }
301
302 //------------------------------------------------------------------------------------------------
303 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
304 protected void ToggleOwner(bool open)
305 {
306 m_bIsOpened = open;
307 if (m_bIsOpened)
309 else
311
312 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_IS_OPENED, m_bIsOpened);
313 }
314
315 //------------------------------------------------------------------------------------------------
316 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
317 protected void ToggleOwnerServerCallback(bool open)
318 {
319 if (open)
320 Event_OnOpenedServerCallback.Invoke();
321 else
322 Event_OnClosedServerCallback.Invoke();
323 }
324
325 //------------------------------------------------------------------------------------------------
326 protected int GetEnumSum(typename enumType)
327 {
328 int enumCount = enumType.GetVariableCount();
329 int val, sum;
330
331 for (int i = 0; i < enumCount; i++)
332 {
333 if (enumType.GetVariableType(i) == int && enumType.GetVariableValue(null, i, val))
334 {
335 sum += val;
336 }
337 }
338 return sum;
339 }
340
342 //--- Access
343
344 //------------------------------------------------------------------------------------------------
348 {
349 if (m_bIsOpened)
350 return CanClose();
351 else
352 return CanOpen();
353 }
354
355 //------------------------------------------------------------------------------------------------
358 bool CanOpen()
359 {
360 //--- No modes available
361 if (m_Modes.IsEmpty())
362 return false;
363
365 if (!gameMode || gameMode.GetState() == SCR_EGameModeState.POSTGAME)
366 return false;
367
368 if (IsLimited())
369 return m_CanOpen == m_CanOpenSum;
370 else
371 return m_CanOpen | EEditorCanOpen.ALIVE == m_CanOpenSum;
372 }
373
374 //------------------------------------------------------------------------------------------------
378 bool CanOpen(EEditorCanOpen accessType)
379 {
380 return m_CanOpen & accessType;
381 }
382
383 //------------------------------------------------------------------------------------------------
387 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
388 void SetCanOpen(bool canOpen, EEditorCanOpen accessType)
389 {
390 if (canOpen == CanOpen(accessType) || RplSession.Mode() == RplMode.Client) return;
391
392 if (canOpen)
393 m_CanOpen = m_CanOpen | accessType;
394 else
395 m_CanOpen = m_CanOpen &~ accessType;
396
397 Rpc(SetCanOpenOwner, m_CanOpen);
398
399 //--- Opening disabled, close the editor if it's
400 if (!CanOpen() && IsOpened()) ToggleServer(false);
401 }
402
403 //------------------------------------------------------------------------------------------------
404 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
405 protected void SetCanOpenOwner(EEditorCanOpen canOpen)
406 {
407 m_CanOpen = canOpen;
408 Event_OnCanOpen.Invoke(m_CanOpen);
409 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_OPEN, CanOpen(EEditorCanOpen.SCRIPT));
410 }
411
412 //------------------------------------------------------------------------------------------------
413 protected void SetCanOpenDebug(bool canOpen, EEditorCanOpen accessType = EEditorCanOpen.SCRIPT)
414 {
415 if (canOpen == CanOpen(accessType)) return;
416 Rpc(SetCanOpen, canOpen, accessType);
417 }
418
419 //------------------------------------------------------------------------------------------------
422 bool CanClose()
423 {
424 return m_CanClose == m_CanCloseSum;
425 }
426
427 //------------------------------------------------------------------------------------------------
431 bool CanClose(EEditorCanClose accessType)
432 {
433 return m_CanClose & accessType;
434 }
435
436 //------------------------------------------------------------------------------------------------
440 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
441 void SetCanClose(bool canClose, EEditorCanClose accessType)
442 {
443 if (canClose == CanClose(accessType) || RplSession.Mode() == RplMode.Client) return;
444
445 if (canClose)
446 m_CanClose = m_CanClose | accessType;
447 else
448 m_CanClose = m_CanClose &~ accessType;
449
450 Rpc(SetCanCloseOwner, m_CanClose);
451 }
452
453 //------------------------------------------------------------------------------------------------
454 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
455 protected void SetCanCloseOwner(EEditorCanClose canClose)
456 {
457 m_CanClose = canClose;
458 Event_OnCanClose.Invoke(m_CanClose);
459 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_CLOSE, CanClose(EEditorCanClose.SCRIPT));
460 }
461
462 //------------------------------------------------------------------------------------------------
463 protected void SetCanCloseDebug(bool canClose, EEditorCanClose accessType = EEditorCanClose.SCRIPT)
464 {
465 if (canClose == CanClose(accessType)) return;
466 Rpc(SetCanClose, canClose, accessType);
467 }
468
470 //--- Setters & Getters
471
472 //------------------------------------------------------------------------------------------------
475 void SetAutoInit(bool isAutoInit = false)
476 {
477 m_bIsAutoInit = isAutoInit;
478 }
479
480 //------------------------------------------------------------------------------------------------
483 {
484 return m_bIsAutoInit;
485 }
486
487 //------------------------------------------------------------------------------------------------
491 void SetAutoModes(bool isAutoModes = false)
492 {
493 m_bIsAutoModes = isAutoModes;
494 }
495
496 //------------------------------------------------------------------------------------------------
500 {
501 return m_iPlayerID;
502 }
503
504 //------------------------------------------------------------------------------------------------
505 protected bool IsAuthority()
506 {
507 return this == GetInstance() || RplSession.Mode() != RplMode.Client;
508 }
509
510 //------------------------------------------------------------------------------------------------
511 bool IsOwner()
512 {
513 //--- Ignore when not initialized, e.g., when setting up the entity by a game mode before its ownership is transferred to client
514 return m_bInit && m_RplComponent && m_RplComponent.IsOwner();
515 }
516
517 //------------------------------------------------------------------------------------------------
521 {
522 return m_bIsInTransition;
523 }
524
525 //------------------------------------------------------------------------------------------------
530 {
531 return m_bIsLimited || DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_FORCE_LIMITED);
532 }
533
534 //------------------------------------------------------------------------------------------------
538 static bool IsLimitedInstance()
539 {
540 SCR_EditorManagerEntity editorManager = SCR_EditorManagerEntity.GetInstance();
541 return !editorManager || editorManager.IsLimited();
542 }
544 {
545 return this;
546 }
547
548 //------------------------------------------------------------------------------------------------
555 void SendNotification(ENotification notificationID, int selfID = 0, int targetID = 0, vector position = vector.Zero)
556 {
557 //Send notification
558 SCR_NotificationsComponent.SendLocal(notificationID, position, selfID, targetID);
559 }
560
561 /*
562 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
563 protected void SendNotificationRpc(EEditorNotification notificationType)
564 {
565 SendNotificationImpl(notificationType);
566 }*/
567
568 //------------------------------------------------------------------------------------------------
569 protected void UpdateLimited()
570 {
571 //--- Check if the editor is in limited mode
572 bool limitedPrev = m_bIsLimited;
573 m_bIsLimited = true;
574 foreach (SCR_EditorModeEntity mode : m_Modes)
575 {
576 if (mode && !mode.IsLimited())
577 {
578 m_bIsLimited = false;
579 break;
580 }
581 }
582
583 //--- Assign player role used by game code systems
584 if (Replication.IsServer() && GetGame().GetGameMode())
585 {
586 if (m_bIsLimited)
587 GetGame().GetPlayerManager().ClearPlayerRole(m_iPlayerID, EPlayerRole.GAME_MASTER);
588 else
589 GetGame().GetPlayerManager().GivePlayerRole(m_iPlayerID, EPlayerRole.GAME_MASTER);
590 }
591
592 if (m_bIsLimited != limitedPrev)
593 Event_OnLimitedChange.Invoke(m_bIsLimited);
594 }
595
597 {
598 NwkMovementComponent nwkComponent = NwkMovementComponent.Cast(FindComponent(NwkMovementComponent));
599 if(nwkComponent)
600 {
601 nwkComponent.EnableSimulation(enable);
602 }
603 }
604
606 //--- Events
607
608 //------------------------------------------------------------------------------------------------
610 {
611 return Event_OnInit;
612 }
613
614 //------------------------------------------------------------------------------------------------
616 {
617 return Event_OnOpened;
618 }
619
620 //------------------------------------------------------------------------------------------------
622 {
623 return Event_OnPreActivate;
624 }
625
626 //------------------------------------------------------------------------------------------------
628 {
629 return Event_OnActivate;
630 }
631
632 //------------------------------------------------------------------------------------------------
634 {
635 return Event_OnPostActivate;
636 }
637
638 //------------------------------------------------------------------------------------------------
640 {
641 return Event_OnDeactivate;
642 }
643
644 //------------------------------------------------------------------------------------------------
646 {
647 return Event_OnClosed;
648 }
649
650 //------------------------------------------------------------------------------------------------
652 {
653 return Event_OnDebug;
654 }
655
656 //------------------------------------------------------------------------------------------------
658 {
659 return Event_OnOpenedServer;
660 }
661
662 //------------------------------------------------------------------------------------------------
664 {
665 return Event_OnOpenedServerCallback;
666 }
667
668 //------------------------------------------------------------------------------------------------
670 {
671 return Event_OnClosedServer;
672 }
673
674 //------------------------------------------------------------------------------------------------
676 {
677 return Event_OnClosedServerCallback;
678 }
679
680 //------------------------------------------------------------------------------------------------
682 {
683 return Event_OnOpenedServer;
684 }
685
686 //------------------------------------------------------------------------------------------------
688 {
689 return Event_OnClosedServer;
690 }
691
692 //------------------------------------------------------------------------------------------------
694 {
695 return Event_OnRequest;
696 }
697
698 //------------------------------------------------------------------------------------------------
700 {
701 return Event_OnCanOpen;
702 }
703
704 //------------------------------------------------------------------------------------------------
706 {
707 return Event_OnCanClose;
708 }
709
710 //------------------------------------------------------------------------------------------------
712 {
713 return Event_OnModeAdd;
714 }
715
716 //------------------------------------------------------------------------------------------------
718 {
719 return Event_OnModeRemove;
720 }
721
722 //------------------------------------------------------------------------------------------------
724 {
725 return Event_OnModeChangeRequest;
726 }
727
728 //------------------------------------------------------------------------------------------------
730 {
731 return Event_OnModeChange;
732 }
733
734 //------------------------------------------------------------------------------------------------
736 {
737 return Event_OnLimitedChange;
738 }
739
740 //------------------------------------------------------------------------------------------------
742 {
743 return Event_OnAsyncLoad;
744 }
745
746 //------------------------------------------------------------------------------------------------
748 {
749 return Event_OnCanEndGameChanged;
750 }
751
753 //-- Static
754
755 //------------------------------------------------------------------------------------------------
758 static bool ToggleInstance()
759 {
760 SCR_EditorManagerEntity instance = GetInstance();
761 if (!instance) return false;
762 instance.Toggle();
763 return true;
764 }
765
766 //------------------------------------------------------------------------------------------------
769 static bool OpenInstance()
770 {
771 SCR_EditorManagerEntity instance = GetInstance();
772 if (!instance)
773 return false;
774
775 instance.Open();
776 return true;
777 }
778
779 //------------------------------------------------------------------------------------------------
782 static bool CloseInstance()
783 {
784 SCR_EditorManagerEntity instance = GetInstance();
785 if (!instance)
786 return false;
787
788 instance.Close();
789 return true;
790 }
791
792 //------------------------------------------------------------------------------------------------
796 static bool IsOpenedInstance(bool includeLimited = true)
797 {
798 SCR_EditorManagerEntity instance = GetInstance();
799 return instance
800 && instance.IsOpened()
801 && (includeLimited || !instance.IsLimited());
802 }
803
804 //------------------------------------------------------------------------------------------------
807 static bool CanOpenInstance()
808 {
809 SCR_EditorManagerEntity instance = GetInstance();
810 if (!instance)
811 return false;
812
813 return instance.CanOpen();
814 }
815
816 //------------------------------------------------------------------------------------------------
819 static bool CanCloseInstance()
820 {
821 SCR_EditorManagerEntity instance = GetInstance();
822 if (!instance)
823 return false;
824
825 return instance.CanClose();
826 }
827
828 //------------------------------------------------------------------------------------------------
831 static SCR_EditorManagerEntity GetInstance()
832 {
833 ArmaReforgerScripted game = GetGame();
834 if (!game)
835 return null;
836
837 SCR_EditorManagerCore manager = SCR_EditorManagerCore.Cast(SCR_EditorManagerCore.GetInstance(SCR_EditorManagerCore));
838 if (!manager)
839 return null;
840
841 return manager.GetEditorManager();
842 }
843
845 //--- Editor modes
846 //--- @name Editor Modes
847 //--- Management of editor modes.
848
849 //------------------------------------------------------------------------------------------------
857 {
858 if (RplSession.Mode() == RplMode.Client)
859 return null;
860
861 RplComponent rplEditor = RplComponent.Cast(FindComponent(RplComponent));
862 if (!rplEditor)
863 return null;
864
866 if (!core)
867 return null;
868
869 if (FindModeEntity(mode))
870 {
871 Print(string.Format("Cannot create %1 mode manager, it already exists!", Type().EnumToString(EEditorMode, mode)), LogLevel.ERROR);
872 return null;
873 }
874
875 //--- Find default prefab
876 bool autoSelect;
877 if (prefab.IsEmpty())
878 {
879 array<SCR_EditorModePrefab> modePrefabs = {};
880 core.GetBaseModePrefabs(modePrefabs, -1, true);
881 foreach (SCR_EditorModePrefab basePrefab : modePrefabs)
882 {
883 if (mode == basePrefab.GetMode())
884 {
885 prefab = basePrefab.GetPrefab();
886 autoSelect = SCR_Enum.HasFlag(basePrefab.GetFlags(), EEditorModeFlag.AUTO_SELECT);
887 break;
888 }
889 }
890 }
891
892 //--- No prefab found, exit
893 if (prefab.IsEmpty())
894 {
895 Print(string.Format("No prefab found for editor mode '%1'!", Type().EnumToString(EEditorMode, mode)), LogLevel.ERROR);
896 return null;
897 }
898
899 //--- Spawn mode entity
900 EntitySpawnParams spawnParams = new EntitySpawnParams;
901 spawnParams.Parent = this;
902
903 SCR_EditorModeEntity modeEntity = SCR_EditorModeEntity.Cast(GetGame().SpawnEntityPrefab(Resource.Load(prefab), GetGame().GetWorld(), spawnParams));
904 if (!modeEntity)
905 {
906 Print(string.Format("Prefab %1 for editor mode %2 is not SCR_EditorModeEntity!", prefab.GetPath(), Type().EnumToString(EEditorMode, mode)), LogLevel.ERROR);
907 delete modeEntity;
908 return null;
909 }
910
911 if (!modeEntity.GetParent())
912 {
913 Print(string.Format("Prefab %1 for editor mode %2 is missing Hierarchy component!", prefab.GetPath(), Type().EnumToString(EEditorMode, mode)), LogLevel.ERROR);
914 delete modeEntity;
915 return null;
916 }
917
918 RplComponent rplMode = RplComponent.Cast(modeEntity.FindComponent(RplComponent));
919 if (!rplMode)
920 {
921 Print(string.Format("Prefab %1 for editor mode %2 is missing RplComponent!", prefab.GetPath(), Type().EnumToString(EEditorMode, mode)), LogLevel.ERROR);
922 delete modeEntity;
923 return null;
924 }
925
926 modeEntity.InitServer(this); //--- Called before AddMode, so events invoked from there can already work with variables defined in init
927
928 AddMode(modeEntity, isInit);
929
930 Rpc(CreateEditorModeOwner, mode, Replication.FindItemId(modeEntity), isInit);
931 SetCanOpen(true, EEditorCanOpen.MODES);
932
933 //--- Set current mode in certain conditions
934 if (
935 (
936 !m_CurrentModeEntity //--- There is no current mode
937 || (autoSelect && !IsOpened()) //--- Newly created mode has AUTO_SELECT flag and editor is not opened
938 )
939 && !m_Modes.Contains(null) //--- No mode was deleted in this frame (would try to run MODE_DELETE and MODE_CHANGE operations at the same time, failing both)
940 )
941 {
942 SetCurrentMode(mode);
943 }
944
945 return modeEntity;
946 }
947
948 //------------------------------------------------------------------------------------------------
952 void AddEditorModes(EEditorModeAccess access, EEditorMode modes, bool isInit = false)
953 {
954 SetEditorModes(access, GetEditorModes() | modes, isInit);
955 }
956
957 //------------------------------------------------------------------------------------------------
962 {
963 SetEditorModes(access, GetEditorModes() & ~modes, false);
964 }
965
966 //------------------------------------------------------------------------------------------------
970 void SetEditorModes(EEditorModeAccess access, EEditorMode modes, bool isInit = false)
971 {
972 EEditorMode preActiveModes = GetEditorModes();
973 m_ModesByAccess.Set(access, modes);
974 EEditorMode activeModes = GetEditorModes();
975
976 //--- Remove
977 array<EEditorMode> flags = {};
978 for (int i, count = SCR_Enum.BitToIntArray(preActiveModes & ~activeModes, flags); i < count; i++)
979 {
980 RplComponent.DeleteRplEntity(FindModeEntity(flags[i]), false);
981 }
982 RepairEditorModes(isInit);
983 }
984
985 //------------------------------------------------------------------------------------------------
987 {
989 if (SCR_Global.IsAdmin(m_iPlayerID) && Replication.IsRunning())
990 flags |= EEditorModeFlag.ADMIN; // admin mode is only meant to be available in MP
991
993 if (!core)
994 return;
995
996 EEditorMode modes = core.GetBaseModes(flags, true);
997 SetEditorModes(EEditorModeAccess.ROLE, modes, false);
998 }
999
1000 //------------------------------------------------------------------------------------------------
1002 {
1003 EEditorMode modes = GetEditorModes();
1004 array<EEditorMode> flags = {};
1005 SCR_Enum.BitToIntArray(modes, flags);
1006 foreach (EEditorMode mode : flags)
1007 {
1008 RplComponent.DeleteRplEntity(FindModeEntity(mode), false);
1009 }
1010 }
1011
1012 //------------------------------------------------------------------------------------------------
1014 void RepairEditorModes(bool isInit)
1015 {
1016 array<EEditorMode> flags = {};
1017 for (int i, count = SCR_Enum.BitToIntArray(GetEditorModes(), flags); i < count; i++)
1018 {
1019 if (!FindModeEntity(flags[i]))
1020 CreateEditorMode(flags[i], isInit);
1021 }
1022 }
1023
1024 //------------------------------------------------------------------------------------------------
1027 {
1028 EEditorMode modes;
1029 for (int i, count = m_ModesByAccess.Count(); i < count; i++)
1030 {
1031 modes |= m_ModesByAccess.GetElement(i);
1032 }
1033 return modes;
1034 }
1035
1036 //------------------------------------------------------------------------------------------------
1040 {
1041 foreach (SCR_EditorModeEntity modeEntity : m_Modes)
1042 {
1043 if (modeEntity && !modeEntity.IsDeleted())
1044 return modeEntity.GetModeType();
1045 }
1046 return -1;
1047 }
1048
1049 //------------------------------------------------------------------------------------------------
1052 {
1053 SetCurrentMode(m_PrevMode);
1054 }
1055
1056 //------------------------------------------------------------------------------------------------
1060 bool SetCurrentMode(bool isLimited)
1061 {
1062 foreach (SCR_EditorModeEntity modeEntity : m_Modes)
1063 {
1064 if (modeEntity.IsLimited() == isLimited)
1065 {
1066 SetCurrentMode(modeEntity.GetModeType());
1067 return true;
1068 }
1069 }
1070 return false;
1071 }
1072
1073 //------------------------------------------------------------------------------------------------
1077 {
1078 //--- Check also if existing entity exists, so it can be reset after all modes were removed and a previosuly current mode was added again.
1079 if (m_CurrentMode == mode && m_CurrentModeEntity)
1080 return;
1081
1082 m_bIsModeChangeRequested = true;
1083 Event_OnModeChangeRequest.Invoke(FindModeEntity(mode), m_CurrentModeEntity);
1084 Rpc(SetCurrentModeServer, mode);
1085 }
1086
1087 //------------------------------------------------------------------------------------------------
1091 {
1092 if (m_bIsModeChangeRequested && m_CurrentMode == m_ProcessedMode)
1093 return m_PrevMode; //--- Don't return current mode until async loading is finished
1094 else
1095 return m_CurrentMode;
1096 }
1097
1098 //------------------------------------------------------------------------------------------------
1102 {
1103 return m_CurrentModeEntity;
1104 }
1105
1106 //------------------------------------------------------------------------------------------------
1110 {
1111 foreach (SCR_EditorModeEntity modeEntity : m_Modes)
1112 {
1113 if (modeEntity && modeEntity.GetModeType() == mode)
1114 return true;
1115 }
1116 return false;
1117 }
1118
1119 //------------------------------------------------------------------------------------------------
1123 {
1124 foreach (SCR_EditorModeEntity modeEntity : m_Modes)
1125 {
1126 if (modeEntity && modeEntity.GetModeType() == mode) return modeEntity;
1127 }
1128 return null;
1129 }
1130
1131 //------------------------------------------------------------------------------------------------
1135 int GetModeEntities(out notnull array<SCR_EditorModeEntity> modeEntities)
1136 {
1137 modeEntities.Copy(m_Modes);
1138 return modeEntities.Count();
1139 }
1140
1141 //------------------------------------------------------------------------------------------------
1145 int GetModes(out notnull array<EEditorMode> modes)
1146 {
1147 modes.Clear();
1148 foreach (SCR_EditorModeEntity editorMode : m_Modes)
1149 {
1150 modes.Insert(editorMode.GetModeType());
1151 }
1152 return modes.Count();
1153 }
1154
1155 //------------------------------------------------------------------------------------------------
1159 {
1160 EEditorMode modes;
1161 foreach (SCR_EditorModeEntity editorMode : m_Modes)
1162 {
1163 modes = modes | editorMode.GetModeType();
1164 }
1165 return modes;
1166 }
1167
1168 //------------------------------------------------------------------------------------------------
1172 {
1173 return m_bIsModeChangeRequested;
1174 }
1175
1176 //------------------------------------------------------------------------------------------------
1177 protected void AddMode(notnull SCR_EditorModeEntity modeEntity, bool isInit)
1178 {
1179 //--- Mode already registered, ignore
1180 if (m_Modes.Find(modeEntity) >= 0) return;
1181
1182 int order = modeEntity.GetOrder();
1183 if (order < 0)
1184 {
1185 //--- When default order is used, place at the back
1186 m_Modes.Insert(modeEntity);
1187 }
1188 else
1189 {
1190 //--- Place according to custom order
1191 int index = 0;
1192 for (int c = m_Modes.Count() - 1; c >= 0; c--)
1193 {
1194 index = c;
1195 if (m_Modes[c] && order > m_Modes[c].GetOrder())
1196 {
1197 index++;
1198 break;
1199 }
1200 }
1201 m_Modes.InsertAt(modeEntity, index);
1202 }
1203
1204 //Notification
1205 if (!isInit && Replication.IsServer())
1206 {
1207 int playerID = GetPlayerID();
1208 if (playerID > 0)
1209 {
1210 if (!modeEntity.SendNotificationLocalOnly())
1211 SCR_NotificationsComponent.SendToUnlimitedEditorPlayersAndPlayer(playerID, modeEntity.GetOnAddNotification(), playerID);
1212 else if (SCR_PlayerController.GetLocalPlayerId() == playerID)
1213 SCR_NotificationsComponent.SendLocal(modeEntity.GetOnAddNotification(), playerID);
1214 }
1215 }
1216
1217
1218 UpdateLimited();
1219 Event_OnModeAdd.Invoke(modeEntity);
1220 }
1221
1222 //------------------------------------------------------------------------------------------------
1223 void RemoveMode(notnull SCR_EditorModeEntity modeEntity, bool OnDisconnnect)
1224 {
1225 if (!m_Modes.Contains(modeEntity))
1226 return;
1227
1228 if (IsOwner())
1229 {
1230 m_ProcessedMode = modeEntity.GetModeType();
1232 Rpc(RemoveModeServer, modeEntity.GetModeType());
1233 }
1234
1235 m_Modes.RemoveItem(modeEntity);
1236 UpdateLimited();
1237
1238 Event_OnModeRemove.Invoke(modeEntity);
1239
1240 if (!OnDisconnnect)
1241 {
1242 int playerID = GetPlayerID();
1243
1244 if (playerID > 0)
1245 {
1246 if (!modeEntity.SendNotificationLocalOnly())
1247 SCR_NotificationsComponent.SendToUnlimitedEditorPlayersAndPlayer(playerID, modeEntity.GetOnRemoveNotification(), playerID);
1248 else if (SCR_PlayerController.GetLocalPlayerId() == playerID)
1249 SCR_NotificationsComponent.SendLocal(modeEntity.GetOnRemoveNotification(), playerID);
1250 }
1251
1252 }
1253 }
1254
1255 //------------------------------------------------------------------------------------------------
1256 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1257 protected void RemoveModeServer(EEditorMode mode)
1258 {
1259 if (!m_Modes.IsEmpty())
1260 {
1261 //--- Current mode was removed, switch to another one
1262 if (mode == m_CurrentMode)
1263 {
1264 Close(false);
1265 SetCurrentMode(-1);
1266 }
1267
1268 //--- Close when removing the mode changed access rules (e.g., remaining mode is limited)
1269 if (!CanOpen() && IsOpened())
1270 ToggleServer(false);
1271 }
1272 else
1273 {
1274 //--- Last mode was removed, close editor
1275 //if (Replication.IsRunning()) //--- Call only when the world is not shutting down
1276 SetCanOpen(false, EEditorCanOpen.MODES);
1277 }
1278 }
1279
1280 //------------------------------------------------------------------------------------------------
1281 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
1282 protected void CreateEditorModeOwner(EEditorMode mode, int modeEntityId, bool isInit)
1283 {
1284 SCR_EditorModeEntity modeEntity = SCR_EditorModeEntity.Cast(Replication.FindItem(modeEntityId));
1285 if (!modeEntity) return;
1286
1287 AddMode(modeEntity, isInit);
1288 modeEntity.InitOwner();
1289
1290 m_ProcessedMode = mode;
1292 }
1293
1294 //------------------------------------------------------------------------------------------------
1295 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1297 {
1298 //--- Try to use the first enabled mode
1299 if (mode < 0)
1300 mode = GetDefaultMode();
1301
1302 //--- Ignore when there is no mode change, or when all modes were removed (i.e., GetDefaultMode() didn't find a replacement)
1303 if ((m_CurrentMode == mode && m_CurrentModeEntity) || mode == -1)
1304 return;
1305
1306 //--- Check if mode entity is enabled
1307 SCR_EditorModeEntity modeEntity = null;
1308 if (mode >= 0)
1309 {
1310 modeEntity = FindModeEntity(mode);
1311 if (!modeEntity)
1312 {
1313 Print(string.Format("SCR_EditorModeEntity for mode '%1' not found!", Type().EnumToString(EEditorMode, mode)), LogLevel.ERROR);
1314 return;
1315 }
1316 }
1317
1318 if (m_CurrentModeEntity && m_bIsOpened)
1319 m_CurrentModeEntity.DeactivateModeServer();
1320
1321 Rpc(SetCurrentModeOwner, mode);
1322 m_CurrentMode = mode;
1323 m_CurrentModeEntity = modeEntity;
1324
1325 if (m_CurrentModeEntity && m_bIsOpened)
1326 m_CurrentModeEntity.ActivateModeServer();
1327 }
1328
1329 //------------------------------------------------------------------------------------------------
1330 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
1332 {
1333 //--- When closing the game, instance reference is already removed. Don't set any mode in such case.
1334 if (!SCR_EditorManagerEntity.GetInstance()) return;
1335
1336 SCR_EditorModeEntity modeEntity = FindModeEntity(mode);
1337 if (!modeEntity && mode >= 0)
1338 {
1339 Print(string.Format("Editor mode '%1' not found!", Type().EnumToString(EEditorMode, mode)), LogLevel.ERROR);
1340 return;
1341 }
1342 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_MODE, Math.Log2(mode));
1343
1344 m_ProcessedMode = mode;
1346 }
1347
1349 //--- Authors logic (UGC)
1350 //------------------------------------------------------------------------------------------------
1351
1352 //------------------------------------------------------------------------------------------------
1353 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
1355 {
1357 if (!core)
1358 return;
1359
1360 set<SCR_EditableEntityAuthor> authors = core.GetAllAuthorsServer();
1361
1362 foreach (SCR_EditableEntityAuthor author : authors)
1363 {
1364 Rpc(RegisterAuthorOwner, author);
1365 }
1366
1368 }
1369
1370 //------------------------------------------------------------------------------------------------
1371 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
1373 {
1375 if (!core)
1376 return;
1377
1379 }
1380
1381 //------------------------------------------------------------------------------------------------
1382 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
1383 protected void RegisterAuthorOwner(notnull SCR_EditableEntityAuthor author)
1384 {
1386 if (core)
1387 core.AddAuthorOnRequest(author);
1388 }
1389
1390 //------------------------------------------------------------------------------------------------
1392 {
1394 }
1395
1397 //--- Component events
1398 //------------------------------------------------------------------------------------------------
1400 {
1401 //--- New operation requested when another one is being processed - close the editor to prevent conflicts!
1402 //--- Happens for example when editor mode is deleted while being processed.
1403 if (m_iEventOperation != EEditorEventOperation.NONE)
1404 {
1405 Print(string.Format("Editor operation %1 was requested while %2 was still running! Editor closed to prevent conflicts!", typename.EnumToString(EEditorEventOperation, type), typename.EnumToString(EEditorEventOperation, m_iEventOperation)), LogLevel.WARNING);
1406 m_aEvents = {EEditorEvent.EXIT_OPERATION};
1407 ProcessEvent();
1408 ToggleOwner(false);
1409 return;
1410 }
1411
1412 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_ASYNC_LOAD_DEBUG))
1413 {
1414 string currentMode = typename.EnumToString(EEditorMode, m_CurrentMode);
1415 if (!m_CurrentModeEntity)
1416 currentMode += " (null)";
1417 Print(string.Format("StartEvents: %1 | current mode: %2 | processed mode: %3", typename.EnumToString(EEditorEventOperation, type), currentMode, typename.EnumToString(EEditorMode, m_ProcessedMode)), LogLevel.DEBUG);
1418 }
1419
1420 m_iEventOperation = type;
1421 m_iEventProgress = 0;
1422
1423 switch (type)
1424 {
1425 case EEditorEventOperation.INIT:
1426 {
1427 GetAllComponents(m_aEventComponentsActivate);
1428 m_aEvents = {
1429 EEditorEvent.INIT,
1430 EEditorEvent.EXIT_OPERATION
1431 };
1432 ProcessEvent();
1433 break;
1434 }
1435 case EEditorEventOperation.DELETE:
1436 {
1437 FindEditorComponents(m_aEventComponentsDeactivate);
1438 if (IsOpened())
1439 {
1440 if (m_ProcessedMode == m_CurrentMode)
1441 {
1442 //--- Currently opened mode
1443 m_aEvents = {
1444 EEditorEvent.DEACTIVATE,
1445 EEditorEvent.DEACTIVATE_ASYNC,
1446 EEditorEvent.POST_DEACTIVATE,
1447 EEditorEvent.CLOSE,
1448 EEditorEvent.DELETE,
1449 EEditorEvent.EXIT_OPERATION,
1450 };
1451 }
1452 else
1453 {
1454 //--- Inactive mode in opened editor
1455 m_aEvents = {
1456 EEditorEvent.CLOSE,
1457 EEditorEvent.DELETE,
1458 EEditorEvent.EXIT_OPERATION,
1459 };
1460 }
1461 }
1462 else
1463 {
1464 m_aEvents = {
1465 EEditorEvent.DELETE,
1466 EEditorEvent.EXIT_OPERATION,
1467 };
1468 }
1469 ProcessEvent();
1470 break;
1471 }
1472 case EEditorEventOperation.REQUEST_OPEN:
1473 {
1474 GetAllComponents(m_aEventComponentsActivate);
1475 m_aEvents = {
1476 EEditorEvent.REQUEST_OPEN,
1477 EEditorEvent.EXIT_OPERATION
1478 };
1479 ProcessEvent();
1480 break;
1481 }
1482 case EEditorEventOperation.OPEN:
1483 {
1484 m_iEventProgressMax = 1;
1485
1486 FindEditorComponents(m_aEventComponentsActivate);
1487 if (m_CurrentModeEntity) m_CurrentModeEntity.FindEditorComponents(m_aEventComponentsActivate);
1488 m_aEventComponentsDeactivate = {};
1489 m_bIsInTransition = true;
1490
1491 m_aEvents = {
1492 EEditorEvent.OPEN_ALL,
1493 EEditorEvent.PRE_ACTIVATE,
1494 EEditorEvent.ACTIVATE,
1495 EEditorEvent.ACTIVATE_ASYNC,
1496 EEditorEvent.POST_ACTIVATE,
1497 EEditorEvent.EXIT_OPERATION,
1498 };
1499 ProcessEvent();
1500 break;
1501 }
1502 case EEditorEventOperation.REQUEST_CLOSE:
1503 {
1504 GetAllComponents(m_aEventComponentsActivate);
1505 m_aEvents = {
1506 EEditorEvent.REQUEST_CLOSE,
1507 EEditorEvent.EXIT_OPERATION
1508 };
1509 ProcessEvent();
1510 break;
1511 }
1512 case EEditorEventOperation.CLOSE:
1513 {
1514 m_iEventProgressMax = 1;
1515
1516 FindEditorComponents(m_aEventComponentsDeactivate);
1517 if (m_CurrentModeEntity) m_CurrentModeEntity.FindEditorComponents(m_aEventComponentsDeactivate);
1518 m_aEventComponentsActivate = {};
1519 m_bIsInTransition = true;
1520
1521 m_aEvents = {
1522 EEditorEvent.DEACTIVATE,
1523 EEditorEvent.DEACTIVATE_ASYNC,
1524 EEditorEvent.POST_DEACTIVATE,
1525 EEditorEvent.CLOSE,
1526 EEditorEvent.EXIT_OPERATION
1527 };
1528 ProcessEvent();
1529 break;
1530 }
1531 case EEditorEventOperation.MODE_CHANGE:
1532 {
1533 m_iEventProgressMax = 2;
1534
1535 FindModeEntity(m_ProcessedMode).FindEditorComponents(m_aEventComponentsActivate);
1536 m_aEventComponentsDeactivate = {};
1537 if (m_CurrentModeEntity) m_CurrentModeEntity.FindEditorComponents(m_aEventComponentsDeactivate);
1538
1539 if (IsOpened())
1540 m_aEvents = {
1541 EEditorEvent.PRE_ACTIVATE,
1542 EEditorEvent.DEACTIVATE,
1543 EEditorEvent.DEACTIVATE_ASYNC,
1544 EEditorEvent.UPDATE_MODE,
1545 EEditorEvent.ACTIVATE,
1546 EEditorEvent.ACTIVATE_ASYNC,
1547 EEditorEvent.POST_DEACTIVATE,
1548 EEditorEvent.POST_ACTIVATE,
1549 EEditorEvent.EXIT_OPERATION,
1550 };
1551 else
1552 m_aEvents = {
1553 EEditorEvent.UPDATE_MODE,
1554 EEditorEvent.EXIT_OPERATION,
1555 };
1556 ProcessEvent();
1557 break;
1558 }
1559 case EEditorEventOperation.MODE_CREATE:
1560 {
1561 FindModeEntity(m_ProcessedMode).FindEditorComponents(m_aEventComponentsActivate);
1562 if (IsOpened())
1563 m_aEvents = {
1564 EEditorEvent.INIT,
1565 EEditorEvent.OPEN,
1566 EEditorEvent.EXIT_OPERATION
1567 };
1568 else
1569 m_aEvents = {
1570 EEditorEvent.INIT,
1571 EEditorEvent.EXIT_OPERATION
1572 };
1573 ProcessEvent();
1574 break;
1575 }
1576 case EEditorEventOperation.MODE_DELETE:
1577 {
1578 FindModeEntity(m_ProcessedMode).FindEditorComponents(m_aEventComponentsDeactivate);
1579 if (IsOpened())
1580 {
1581 if (m_ProcessedMode == m_CurrentMode)
1582 {
1583 m_aEvents = {
1584 EEditorEvent.DEACTIVATE,
1585 EEditorEvent.DEACTIVATE_ASYNC,
1586 EEditorEvent.POST_DEACTIVATE,
1587 EEditorEvent.CLOSE,
1588 EEditorEvent.DELETE,
1589 EEditorEvent.EXIT_OPERATION,
1590 };
1591 }
1592 else
1593 {
1594 m_aEvents = {
1595 EEditorEvent.CLOSE,
1596 EEditorEvent.DELETE,
1597 EEditorEvent.EXIT_OPERATION,
1598 };
1599 }
1600 }
1601 else
1602 {
1603 m_aEvents = {
1604 EEditorEvent.DELETE,
1605 EEditorEvent.EXIT_OPERATION,
1606 };
1607 }
1608 ProcessEvent();
1609 break;
1610 }
1611 }
1612 }
1613
1614 //------------------------------------------------------------------------------------------------
1616 protected void ProcessEvent()
1617 {
1618 m_iEvent = m_aEvents[0];
1619
1620 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_ASYNC_LOAD_DEBUG) && m_iEventComponent == 0 && m_iEventAttempt == 0)
1621 {
1622 Print(typename.EnumToString(EEditorEvent, m_iEvent), LogLevel.NORMAL);
1623 }
1624
1625 switch (m_iEvent)
1626 {
1628 case EEditorEvent.INIT:
1629 {
1630 foreach (SCR_BaseEditorComponent component : m_aEventComponentsActivate)
1631 component.OnInitBase();
1632 break;
1633 }
1635 case EEditorEvent.REQUEST_OPEN:
1636 {
1637 foreach (SCR_BaseEditorComponent component : m_aEventComponentsActivate)
1638 component.OnRequestBase(true);
1639
1640 Event_OnRequest.Invoke(true);
1641 break;
1642 }
1644 case EEditorEvent.REQUEST_CLOSE:
1645 {
1646 foreach (SCR_BaseEditorComponent component : m_aEventComponentsActivate)
1647 if (component) component.OnRequestBase(false);
1648
1649 Event_OnRequest.Invoke(false);
1650 break;
1651 }
1653 case EEditorEvent.OPEN:
1654 {
1655 foreach (SCR_BaseEditorComponent component : m_aEventComponentsActivate)
1656 {
1657 if (component) component.OnOpenedBase();
1658 }
1659 break;
1660 }
1662 case EEditorEvent.OPEN_ALL:
1663 {
1664 array<SCR_BaseEditorComponent> allComponents;
1665 GetAllComponents(allComponents);
1666
1667 foreach (SCR_BaseEditorComponent component : allComponents)
1668 {
1669 if (component) component.OnOpenedBase();
1670 }
1671 break;
1672 }
1674 case EEditorEvent.PRE_ACTIVATE:
1675 {
1676 foreach (SCR_BaseEditorComponent component : m_aEventComponentsActivate)
1677 {
1678 if (component) component.OnPreActivateBase();
1679 }
1680
1681 SCR_EditorModeEntity processedMode = FindModeEntity(m_ProcessedMode);
1682 if (processedMode)
1683 processedMode.PreActivateMode();
1684
1685 Event_OnPreActivate.Invoke();
1686 break;
1687 }
1689 case EEditorEvent.DEACTIVATE:
1690 {
1691 foreach (SCR_BaseEditorComponent component : m_aEventComponentsDeactivate)
1692 {
1693 if (component) component.OnDeactivateBase();
1694 }
1695 if (m_ProcessedMode == m_CurrentMode && m_CurrentModeEntity)
1696 m_CurrentModeEntity.DeactivateMode();
1697
1698 Event_OnDeactivate.Invoke();
1699 break;
1700 }
1702 case EEditorEvent.DEACTIVATE_ASYNC:
1703 {
1704 bool instantContinue;
1705 if (ProcessAsyncEvent(false, instantContinue))
1706 {
1707 }
1708 else if (instantContinue)
1709 {
1710 ProcessEvent();
1711 return;
1712 }
1713 else
1714 {
1715 return;
1716 }
1717
1718 break;
1719 }
1721 case EEditorEvent.ACTIVATE:
1722 {
1723 foreach (SCR_BaseEditorComponent component : m_aEventComponentsActivate)
1724 {
1725 if (component)
1726 component.OnActivateBase();
1727 }
1728
1729 if (m_CurrentModeEntity)
1730 m_CurrentModeEntity.ActivateMode();
1731
1732 Event_OnActivate.Invoke();
1733 break;
1734 }
1736 case EEditorEvent.ACTIVATE_ASYNC:
1737 {
1738 bool instantContinue;
1739 if (ProcessAsyncEvent(true, instantContinue))
1740 {
1741 }
1742 else if (instantContinue)
1743 {
1744 ProcessEvent();
1745 return;
1746 }
1747 else
1748 {
1749 return;
1750 }
1751
1752 break;
1753 }
1755 case EEditorEvent.POST_DEACTIVATE:
1756 {
1757 foreach (SCR_BaseEditorComponent component : m_aEventComponentsDeactivate)
1758 {
1759 if (component)
1760 component.OnPostDeactivateBase();
1761 }
1762 break;
1763 }
1765 case EEditorEvent.POST_ACTIVATE:
1766 {
1767 foreach (SCR_BaseEditorComponent component : m_aEventComponentsActivate)
1768 {
1769 if (component) component.OnPostActivateBase();
1770 }
1771
1772 if (m_CurrentModeEntity)
1773 m_CurrentModeEntity.PostActivateMode();
1774
1775 Event_OnPostActivate.Invoke();
1776 break;
1777 }
1779 case EEditorEvent.CLOSE:
1780 {
1781 foreach (SCR_BaseEditorComponent component : m_aEventComponentsDeactivate)
1782 {
1783 if (component)
1784 component.OnClosedBase();
1785 }
1786 break;
1787 }
1789 case EEditorEvent.DELETE:
1790 {
1791 foreach (SCR_BaseEditorComponent component : m_aEventComponentsDeactivate)
1792 {
1793 if (component)
1794 component.OnDeleteBase();
1795 }
1796 break;
1797 }
1799 case EEditorEvent.UPDATE_MODE:
1800 {
1801 m_PrevMode = m_CurrentMode;
1802 m_CurrentMode = m_ProcessedMode;
1803 m_CurrentModeEntity = FindModeEntity(m_CurrentMode);
1804 break;
1805 }
1807 case EEditorEvent.EXIT_OPERATION:
1808 {
1809 //--- Set before invokers are called, so using getters in them will not see transition as active anymore
1810 m_bIsInTransition = false;
1811
1812 //--- Call invokers once all events are processed
1813 switch (m_iEventOperation)
1814 {
1815 case EEditorEventOperation.OPEN:
1816 {
1817 Event_OnAsyncLoad.Invoke(1);
1818 Event_OnOpened.Invoke();
1819 Rpc(ToggleOwnerServerCallback, true);
1820 break;
1821 }
1822 case EEditorEventOperation.CLOSE:
1823 {
1824 //--- Save stored user camera locations when leaving GM
1825 GetGame().UserSettingsChanged();
1826 GetGame().SaveUserSettings();
1827 Event_OnAsyncLoad.Invoke(1);
1828 Event_OnClosed.Invoke();
1829 Rpc(ToggleOwnerServerCallback, false);
1830 break;
1831 }
1832 case EEditorEventOperation.MODE_CHANGE:
1833 {
1834 m_bIsModeChangeRequested = false;
1835 if (IsOpened()) Event_OnAsyncLoad.Invoke(1);
1836 Event_OnModeChange.Invoke(m_CurrentModeEntity, FindModeEntity(m_PrevMode));
1837 break;
1838 }
1839 }
1840
1841 //--- Clean up
1842 m_iEventOperation = EEditorEventOperation.NONE;
1843 m_aEventComponentsActivate = null;
1844 m_aEventComponentsDeactivate = null;
1845 m_iEvent = EEditorEvent.NONE;
1846 m_ProcessedMode = 0;
1847 return;
1848 }
1849 }
1850
1851 //--- Next event
1852 m_aEvents.RemoveOrdered(0);
1853 if (!m_aEvents.IsEmpty())
1854 ProcessEvent();
1855 }
1856
1857 //------------------------------------------------------------------------------------------------
1858 protected bool ProcessAsyncEvent(bool toActivate, out bool instantContinue)
1859 {
1860 //--- Get components to be processed
1861 array<SCR_BaseEditorComponent> components;
1862 if (toActivate)
1863 components = m_aEventComponentsActivate;
1864 else
1865 components = m_aEventComponentsDeactivate;
1866
1867 //--- All processed, clean up and exit
1868 if (m_iEventComponent >= components.Count())
1869 {
1870 m_iEventComponent = 0;
1871 m_iEventAttempt = 0;
1872 return true;
1873 }
1874
1875 //--- Block input
1876 GetGame().GetInputManager().ActivateContext("DebugContext");
1877
1878 //--- Start timer
1879 if (m_iEventAttempt == 0)
1880 m_fEventAsyncStart = GetGame().GetWorld().GetWorldTime();
1881
1882 //--- Process component
1883 bool isProcessed;
1884 SCR_BaseEditorComponent component = components[m_iEventComponent];
1885 if (component)
1886 {
1887 if (toActivate)
1888 isProcessed = component.OnActivateAsyncBase(m_iEventAttempt);
1889 else
1890 isProcessed = component.OnDeactivateAsyncBase(m_iEventAttempt);
1891
1892 //--- Editor mode to which the component belongs to is being deleted - execute instantly, no time for async
1893 instantContinue = IsDeleted() || !component.GetOwner() || component.GetOwner().IsDeleted();
1894 }
1895 else
1896 {
1897 //--- Component was meanwhile deleted, skip it
1898 isProcessed = true;
1899 instantContinue = true;
1900 m_iEventAttempt = 0;
1901 }
1902
1903 if (isProcessed)
1904 {
1905 //--- Next component
1906 if (m_iEventAttempt == 0)
1907 instantContinue = true;
1908
1909 m_iEventComponent++;
1910 m_iEventAttempt = 0;
1911 m_iEventProgress += 1 / components.Count() / m_iEventProgressMax;
1912 Event_OnAsyncLoad.Invoke(m_iEventProgress);
1913
1914 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_ASYNC_LOAD_DEBUG) && component)
1915 Print(string.Format("%1 (%2), %3 ms", Math.Round(m_iEventProgress * 100), component.Type(), GetGame().GetWorld().GetWorldTime() - m_fEventAsyncStart), LogLevel.VERBOSE);
1916 }
1917 else
1918 {
1919 //--- Next attempt
1920 m_iEventAttempt++;
1921 }
1922 return false;
1923 }
1924
1925 //------------------------------------------------------------------------------------------------
1926 protected void GetAllComponents(out array<SCR_BaseEditorComponent> outComponents)
1927 {
1928 FindEditorComponents(outComponents);
1929 foreach (SCR_EditorModeEntity mode : m_Modes)
1930 {
1931 if (mode)
1932 mode.FindEditorComponents(outComponents);
1933 }
1934 }
1935
1937 //--- Actions
1938 //------------------------------------------------------------------------------------------------
1939 protected void Action_EditorToggle(float value, EActionTrigger reason)
1940 {
1941 Toggle();
1942 }
1943
1944 //------------------------------------------------------------------------------------------------
1946 {
1948 m_NotificationsComponent = SCR_NotificationsComponent.GetInstance();
1949
1951 {
1952 vector goToPosition;
1953 if (m_NotificationsComponent.GetLastNotificationLocation(goToPosition))
1954 {
1957 cursorManualCameraComponent.TeleportCamera(goToPosition);
1958 }
1959
1960 }
1961
1962 }
1963
1964 //--- Debug
1965
1966 //------------------------------------------------------------------------------------------------
1967 protected void ShowDebug()
1968 {
1969 array<string> debugTexts = new array<string>;
1970
1971 debugTexts.Insert(string.Format("CanOpen: %1/%2", m_CanOpen, m_CanOpenSum));
1972 debugTexts.Insert(string.Format("CanClose: %1/%2", m_CanClose, m_CanCloseSum));
1973
1974 string currentModeName = "N/A";
1975 if (m_CurrentModeEntity)
1976 currentModeName = typename.EnumToString(EEditorMode, m_CurrentModeEntity.GetModeType());
1977
1978 debugTexts.Insert(string.Format("Current Mode: %1", currentModeName));
1979 debugTexts.Insert(string.Format("Available Modes: %1", m_Modes.Count()));
1980 debugTexts.Insert(string.Format("Limited: %1", m_bIsLimited));
1981 debugTexts.Insert(string.Format("Entity Author name: %1", GetEntityAuthor()));
1982 debugTexts.Insert(string.Format("Entity Author UID: %1", GetEntityAuthorUID()));
1983 GetOnDebug().Invoke(debugTexts);
1984
1985 DbgUI.Begin("SCR_EditorManagerEntity", 0, 0);
1986 foreach (string text : debugTexts)
1987 {
1988 DbgUI.Text(text);
1989 }
1990 DbgUI.End();
1991 }
1992
1993 //------------------------------------------------------------------------------------------------
1994 protected SCR_EditableEntityAuthor GetEntityAuthor()
1995 {
1997 if (!entity)
1998 return null;
1999
2000 return entity.GetAuthor();
2001 }
2002
2003 //------------------------------------------------------------------------------------------------
2004 protected string GetEntityAuthorUID()
2005 {
2007 if (!entity)
2008 return string.Empty;
2009
2010 return entity.GetAuthorUID();
2011 }
2012
2013 //------------------------------------------------------------------------------------------------
2014 protected void ProcessDebug()
2015 {
2016#ifdef ENABLE_DIAG
2017 bool isOpened = DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_IS_OPENED);
2018 if (isOpened != IsOpened())
2019 {
2020 //--- Make sure the editor can be opened / closed
2021 if (isOpened)
2022 {
2023 SetCanOpenDebug(true, EEditorCanOpen.SCRIPT);
2024 }
2025 else
2026 {
2027 SetCanCloseDebug(true);
2028 }
2029 Toggle();
2030 }
2031
2032 bool canOpen = DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_OPEN);
2033 if (canOpen != CanOpen(EEditorCanOpen.SCRIPT))
2034 {
2035 SetCanOpenDebug(canOpen, EEditorCanOpen.SCRIPT);
2036 }
2037
2038 bool canClose = DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_CLOSE);
2039 if (canClose != CanClose(EEditorCanOpen.SCRIPT))
2040 {
2041 SetCanCloseDebug(canClose);
2042 }
2043
2044 if (m_CurrentModeEntity)
2045 {
2046 int debugMode = 1 << DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_MODE);
2047 if (m_CurrentMode != debugMode && FindModeEntity(debugMode))
2048 {
2049 SetCurrentMode(debugMode);
2050 }
2051 }
2052
2053 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_SHOW_DEBUG))
2054 ShowDebug();
2055
2056
2057 if(DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_CLEAR_SELECTED_BUDGET))
2058 {
2059 if(DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_BUDGET_TO_CLEAR) == 0)
2060 {
2063 }
2064 else if(DiagMenu.GetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_BUDGET_TO_CLEAR) == 1)
2066
2067 //Set Clear selected budget to false
2068 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_CLEAR_SELECTED_BUDGET, 0);
2069 }
2070#endif
2071 }
2072
2073
2074 [RplRpc(RplChannel.Reliable, RplRcver.Server)]
2076 {
2077 #ifdef ENABLE_DIAG
2079
2080 if(!core)
2081 return;
2082
2084 #endif
2085 }
2086
2088 //--- Init
2089
2090 //------------------------------------------------------------------------------------------------
2091 void InitServer(int playerID)
2092 {
2093 if (m_bInit)
2094 return;
2095
2096 m_bInit = true;
2097 m_iPlayerID = playerID;
2098
2099 InitComponents(true);
2100 Rpc(InitOwner, playerID);
2101
2102 //--- Initialize modes
2103 IEntity child = GetChildren();
2104 while (child)
2105 {
2106 SCR_EditorModeEntity modeEntity = SCR_EditorModeEntity.Cast(child);
2107 if (modeEntity) modeEntity.InitServer(this);
2108 child = child.GetSibling();
2109 }
2110 }
2111
2112 //------------------------------------------------------------------------------------------------
2113 [RplRpc(RplChannel.Reliable, RplRcver.Owner)]
2114 protected void InitOwner(int playerID)
2115 {
2116 if (GetInstance())
2117 return; //--- Exit when already initialized
2118
2120 if (!core || !core.SetEditorManager(this))
2121 return;
2122
2123 m_bInit = true;
2124 m_RplComponent = RplComponent.Cast(FindComponent(RplComponent));
2125 if (!m_RplComponent) Print("SCR_EditorManagerEntity is missing RplComponent component!", LogLevel.ERROR);
2126
2127 m_iPlayerID = playerID;
2128 InitComponents(false);
2129
2130 StartEvents(EEditorEventOperation.INIT); //--- Init on all editor components
2131 //Event_OnInit.Invoke();
2132 core.Event_OnEditorManagerInitOwner.Invoke(this); //--- External init
2133
2134 SetEventMask(EntityEvent.FRAME);
2135
2136 InputManager inputManager = GetGame().GetInputManager();
2137 if (inputManager)
2138 {
2139 inputManager.AddActionListener("EditorToggle", EActionTrigger.PRESSED, Action_EditorToggle);
2140 inputManager.AddActionListener("EditorLastNotificationTeleport", EActionTrigger.DOWN, Action_GoToLatestNotification);
2141 }
2142
2143 //--- Debug
2144 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_IS_OPENED, "", "Is Opened", "Editor");
2145 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_OPEN, "", "Can Open", "Editor");
2146 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_CLOSE, "", "Can Close", "Editor");
2147 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_SHOW_DEBUG, "", "Show Debug", "Editor");
2148 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_FORCE_LIMITED, "", "Force Limited", "Editor");
2149 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_ASYNC_LOAD_DEBUG, "", "Log Async Load", "Editor");
2150 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_SAVE_PHOTO_SCREENSHOT_SHOW, "", "Show Screenshot", "Editor");
2151 DiagMenu.RegisterRange(SCR_DebugMenuID.DEBUGUI_EDITOR_NETWORK_DELAY, "", "Simulated Network Delay", "Editor", "0 1000 0 100");
2152
2153 //--- Reset values, they're stored from the previous session
2154 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_IS_OPENED, m_bIsOpened);
2155 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_OPEN, m_CanOpen);
2156 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_CLOSE, m_CanClose);
2157
2158 typename enumType = EEditorMode;
2159 int enumCount = enumType.GetVariableCount();
2160 DiagMenu.RegisterRange(SCR_DebugMenuID.DEBUGUI_EDITOR_MODE, "", "Mode", "Editor", string.Format("0 %1 0 1", enumCount - 1));
2161 DiagMenu.SetValue(SCR_DebugMenuID.DEBUGUI_EDITOR_MODE, Math.Max(m_CurrentMode, 0));
2162
2163 DiagMenu.RegisterItem(SCR_DebugMenuID.DEBUGUI_EDITOR_BUDGET_TO_CLEAR, "", "Budget to clear", "Editor", "AI, Vehicles");
2164 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_EDITOR_CLEAR_SELECTED_BUDGET, "", "Clear selected budget", "Editor");
2165 }
2166
2167 //------------------------------------------------------------------------------------------------
2169 {
2170 if (m_CurrentMode < 0)
2171 {
2173 }
2174 }
2175
2176 //------------------------------------------------------------------------------------------------
2178 {
2179 if (m_bIsAutoInit && !m_bIsLimited)
2180 {
2181 Open(false);
2182 }
2183 m_bIsAutoInit = false;
2184 }
2185
2187 //--- Default functions
2188
2189 //------------------------------------------------------------------------------------------------
2190 override void EOnInit(IEntity owner)
2191 {
2192 super.EOnInit(owner);
2193
2194 ChimeraWorld world = GetGame().GetWorld();
2195 if (world)
2196 {
2197 world.RegisterEntityToBeUpdatedWhileGameIsPaused(this);
2198 }
2199 }
2200
2201 //------------------------------------------------------------------------------------------------
2202 override void EOnFrame(IEntity owner, float timeSlice) //--- Active only when the entity is local (see InitOwner())
2203 {
2204 if (m_iEvent == EEditorEvent.NONE)
2205 ProcessDebug();
2206 else
2207 ProcessEvent();
2208 }
2209
2210 //------------------------------------------------------------------------------------------------
2212 {
2213 m_CanOpenSum = GetEnumSum(EEditorCanOpen);
2214 m_CanCloseSum = GetEnumSum(EEditorCanClose);
2215
2216 SetFlags(EntityFlags.NO_TREE | EntityFlags.NO_LINK);
2217 }
2218
2219 //------------------------------------------------------------------------------------------------
2221 {
2222 while (!m_Modes.IsEmpty())
2223 {
2224 if (m_Modes[0])
2225 RemoveMode(m_Modes[0], true);
2226 else
2227 m_Modes.RemoveOrdered(0);
2228 }
2229
2230 if (m_CurrentModeEntity)
2231 m_CurrentModeEntity.DeactivateModeServer();
2232
2233 if (Replication.IsServer() && IsOpened())
2234 Event_OnClosedServer.Invoke();
2235
2236 if (IsOwner())
2238
2239 if (GetInstance() == this)
2240 {
2241 //--- Local entity
2242 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_IS_OPENED);
2243 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_OPEN);
2244 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_CAN_CLOSE);
2245 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_SHOW_DEBUG);
2246 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_MODE);
2247 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_ASYNC_LOAD_DEBUG);
2248 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_SAVE_PHOTO_SCREENSHOT_SHOW);
2249 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_NETWORK_DELAY);
2250
2251 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_BUDGET_TO_CLEAR);
2252 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_EDITOR_CLEAR_SELECTED_BUDGET);
2253 }
2254
2255 ChimeraWorld world = GetGame().GetWorld();
2256 if (world)
2257 {
2258 world.UnregisterEntityToBeUpdatedWhileGameIsPaused(this);
2259 }
2260 }
2261}
2262
2265{
2266 [Attribute(string.Format("%1", EEditorMode.EDIT), desc: "", uiwidget: UIWidgets.ComboBox, enums: ParamEnumArray.FromEnum(EEditorMode))]
2267 private EEditorMode m_Mode;
2268
2269 [Attribute("", UIWidgets.ResourceNamePicker, "Individual editor manager", "et")]
2270 private ResourceName m_Prefab;
2271
2272 [Attribute("", desc: "", uiwidget: UIWidgets.Flags, enums: ParamEnumArray.FromEnum(EEditorModeFlag))]
2273 private EEditorModeFlag m_Flags;
2274
2275 [Attribute()]
2277
2278 //------------------------------------------------------------------------------------------------
2280 {
2281 return m_Mode;
2282 }
2283
2284 //------------------------------------------------------------------------------------------------
2286 {
2287 return m_Prefab;
2288 }
2289
2290 //------------------------------------------------------------------------------------------------
2292 {
2293 return m_Flags;
2294 }
2295
2296 //------------------------------------------------------------------------------------------------
2298 {
2299 return m_ModeUIInfo;
2300 }
2301}
SCR_EAIThreatSectorFlags flags
ref DSGameConfig game
Definition DSConfig.c:81
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
EEditableEntityBudget
EEditorModeAccess
EEditorModeFlag
ENotification
EPlayerRole
Definition EPlayerRole.c:8
ArmaReforgerScripted GetGame()
Definition game.c:1398
RplMode
Mode of replication.
Definition RplMode.c:9
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
SCR_BaseGameMode GetGameMode()
bool m_bInit
RplComponent m_RplComponent
class SCR_CampaignHintStorage SCR_BaseContainerCustomTitleEnum(EHint, "m_eHintId")
void SendNotification(int msgId, notnull IEntity user, int assetId=-1, int catalogType=-1)
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
EDamageType type
vector position
SCR_DestructionSynchronizationComponentClass ScriptComponentClass int index
SCR_EGameModeState
override int GetPlayerID()
EEditorMode m_Modes
override ScriptInvoker GetOnPreActivate()
void Action_GoToLatestNotification(float value, EActionTrigger reason)
void SetCanClose(bool canClose, EEditorCanClose accessType)
void RequestAllAuthorsServer()
void UpdateLimited()
ScriptInvoker GetOnModeChange()
bool IsAuthority()
void SetCurrentModeOwner(EEditorMode mode)
ScriptInvoker GetOnModeChangeRequest()
override ScriptInvoker GetOnActivate()
void RemoveModeServer(EEditorMode mode)
ScriptInvoker GetOnLimitedChange()
void DeleteAllEditors()
override ScriptInvoker GetOnRequest()
SCR_EditorModeEntity GetCurrentModeEntity()
void Diag_RequestDeletionOfEntitiesOfBudget(EEditableEntityBudget budgetType)
bool CanClose()
void ToggleServer(bool open)
void SetCanOpenOwner(EEditorCanOpen canOpen)
int GetEnumSum(typename enumType)
void AddMode(notnull SCR_EditorModeEntity modeEntity, bool isInit)
void RestorePreviousMode()
Set editor mode to the previously selected one.
bool IsModeChangeRequested()
void ToggleOwnerServerCallback(bool open)
SCR_EditorModeEntity CreateEditorMode(EEditorMode mode, bool isInit, ResourceName prefab="")
ScriptInvoker GetOnAsyncLoad()
ref map< EEditorModeAccess, EEditorMode > m_ModesByAccess
override ScriptInvoker GetOnOpenedServerCallback()
override ScriptInvoker GetOnClosedServerCallback()
ScriptInvoker GetOnModeAdd()
bool IsLimited()
void SCR_EditorManagerEntity(IEntitySource src, IEntity parent)
override SCR_EditorManagerEntity GetManager()
void FinishAuthorsRequestOwner()
void SetAutoModes(bool isAutoModes=false)
void RegisterAuthorOwner(notnull SCR_EditableEntityAuthor author)
SCR_EditableEntityAuthor GetEntityAuthor()
void Action_EditorToggle(float value, EActionTrigger reason)
string GetEntityAuthorUID()
void RemoveEditorModes(EEditorModeAccess access, EEditorMode modes)
void PostInitServer()
void SetCurrentModeServer(EEditorMode mode)
override ScriptInvoker GetOnClosedServer()
bool IsAutoInit()
bool SetCurrentMode(bool isLimited)
SCR_EditorModeEntity FindModeEntity(EEditorMode mode)
override ScriptInvoker GetOnDeactivateServer()
EEditorMode GetEditorModes()
void ProcessDebug()
bool HasMode(EEditorMode mode)
void SetCanCloseOwner(EEditorCanClose canClose)
void AddEditorModes(EEditorModeAccess access, EEditorMode modes, bool isInit=false)
void RepairEditorModes(bool isInit)
Go thrugh current editor modes and make sure they all have a mode entity.
EEditorMode GetCurrentMode()
override ScriptInvoker GetOnOpened()
override ScriptInvoker GetOnActivateServer()
override ScriptInvoker GetOnPostActivate()
void RemoveMode(notnull SCR_EditorModeEntity modeEntity, bool OnDisconnnect)
void SetAutoInit(bool isAutoInit=false)
void CreateEditorModeOwner(EEditorMode mode, int modeEntityId, bool isInit)
ScriptInvoker GetOnModeRemove()
void SetCanOpenDebug(bool canOpen, EEditorCanOpen accessType=EEditorCanOpen.SCRIPT)
SCR_NotificationsComponent m_NotificationsComponent
void ~SCR_EditorManagerEntity()
void StartEvents(EEditorEventOperation type=EEditorEventOperation.NONE)
void AutoInit()
void SetCanCloseDebug(bool canClose, EEditorCanClose accessType=EEditorCanClose.SCRIPT)
void GetAllComponents(out array< SCR_BaseEditorComponent > outComponents)
void SetEditorModes(EEditorModeAccess access, EEditorMode modes, bool isInit=false)
EEditorMode GetDefaultMode()
bool ProcessAsyncEvent(bool toActivate, out bool instantContinue)
EEditorMode GetModes()
override ScriptInvoker GetOnDebug()
int GetModeEntities(out notnull array< SCR_EditorModeEntity > modeEntities)
override ScriptInvoker GetOnDeactivate()
void ToggleOwner(bool open)
ScriptInvoker GetOnCanClose()
void SetCanOpen(bool canOpen, EEditorCanOpen accessType)
void RequestAllAuthors()
override ScriptInvoker GetOnClosed()
bool IsInTransition()
void InitOwner(int playerID)
bool CanToggle()
void EnableCameraNwkSimulation(bool enable)
override ScriptInvoker GetOnOpenedServer()
void RecreateEditorModes()
void InitServer(int playerID)
ScriptInvoker GetOnCanEndGameChanged()
bool CanOpen()
void ProcessEvent()
This would be so much nicer as a flow chart.
override ScriptInvoker GetOnInit()
ScriptInvoker GetOnCanOpen()
void ShowDebug()
int GetOrder()
void Toggle()
Toggle hint. Hide it if it's shown, and open it again if it's hidden.
override void EOnFrame(IEntity owner, float timeSlice)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
void GetChildren(out array< SCR_ScenarioFrameworkLayerBase > children)
int Type
proto native void Close()
proto native bool Open(string path, FileMode mode=FileMode.READ)
enum EVehicleType IEntity
Definition DbgUI.c:66
Diagnostic and developer menu system.
Definition DiagMenu.c:18
void Rpc(func method, void p0=NULL, void p1=NULL, void p2=NULL, void p3=NULL, void p4=NULL, void p5=NULL, void p6=NULL, void p7=NULL)
proto external Managed FindComponent(typename typeName)
proto external IEntity GetSibling()
Input management system for user interactions.
Definition Math.c:13
Main replication API.
Definition Replication.c:14
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
static SCR_EditableEntityComponent GetFirstEntity(EEditableEntityState state)
sealed bool OnActivateAsyncBase(int attempt)
sealed bool OnDeactivateAsyncBase(int attempt)
SCR_EGameModeState GetState()
static SCR_ManualCamera GetCameraInstance()
void AddAuthorOnRequest(notnull SCR_EditableEntityAuthor newAuthor)
Do not call this function yourself, this has to be requested by server.
void DeleteAllEntitiesThatHaveBudgetOfType(EEditableEntityBudget budgetToFree)
set< SCR_EditableEntityAuthor > GetAllAuthorsServer()
Core component to manage SCR_EditorManagerEntity.
EEditorMode GetBaseModes(EEditorModeFlag flags=-1, bool coreOnly=false)
bool SetEditorManager(SCR_EditorManagerEntity entity)
SCR_EditorManagerEntity GetEditorManager()
int GetBaseModePrefabs(out notnull array< SCR_EditorModePrefab > outPrefabs, EEditorModeFlag flags=-1, bool coreOnly=false)
SCR_EditorModeUIInfo GetInfo()
ref SCR_EditorModeUIInfo m_ModeUIInfo
static bool IsAdmin(int playerID)
Definition Functions.c:1927
SCR_BaseManualCameraComponent FindCameraComponent(typename type)
static int GetLocalPlayerId()
Returns either a valid ID of local player or 0.
Teleport the camera to the cursor's world position.
void SetChannelTextOverwrite(string text)
void SetRadioEntry(notnull BaseTransceiver transceiver, int number, SCR_GadgetComponent gadgetComp)
void SetFrequencyTextOverwrite(string text)
Definition Types.c:486
void EntitySpawnParams()
Definition gameLib.c:130
override void EOnInit(IEntity owner)
BaseRadioComponentClass BaseTransceiver
bool IsOwner()
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
EEditableEntityState
SCR_FieldOfViewSettings Attribute
EEditorMode
Editor mode that defines overall functionality.
Definition EEditorMode.c:6
EEditorEvent
Editor event processed in components.
Definition EEditorEvent.c:6
EEditorCanClose
Layers allowing editor to be closed. All of them have to be activated.
EEditorEventOperation
Type of event-processing operation.
EEditorCanOpen
Layers allowing editor to be opened. All of them have to be activated (certain exceptions may apply w...
EntityEvent
Various entity events.
Definition EntityEvent.c:14
EntityFlags
Various entity flags.
Definition EntityFlags.c:14
SCR_EditorManagerCore m_iPlayerID
EActionTrigger
void RplRpc(RplChannel channel, RplRcver rcver, RplCondition condition=RplCondition.None, string customConditionName="")
Definition EnNetwork.c:95
RplRcver
Definition RplRcver.c:59
RplChannel
Communication channel. Reliable is guaranteed to be delivered. Unreliable not.
Definition RplChannel.c:14
ScriptInvokerBase< func > ScriptInvoker
Definition tools.c:134