DayZ 1.30
DayZ Explorer by KGB
 
Загрузка...
Поиск...
Не найдено
PluginUndergroundTriggerManager.c
См. документацию.
1#ifdef DIAG_DEVELOPER
2class PluginUndergroundTriggerManager : PluginBase
3{
4 private static PluginUndergroundTriggerManager m_Instance;
5
6 private static const float RAYCAST_LENGTH = 1000.0;
7 private static const string DATETIME_FORMAT = "%1%2%3T%4%5%6Z";
8 private static const float SORT_RESORT_THRESHOLD = 10.0;
9 private static const int MAX_DEBUG_DRAW_COUNT = 100;
10 private static const float MAX_DEBUG_DRAW_DISTANCE = 300.0;
11
12 private bool m_IsOpen;
13
14 private vector m_LastSortCameraPosition;
15
16 private bool m_BreadcrumbEditMode;
17 private int m_BreadcrumbEditOriginalCount;
18 private bool m_BreadcrumbsDirty;
19 private bool m_TriggersDirty;
20
21 private ref array<UndergroundTriggerHandle> m_TriggerHandles;
22 private ref array<UndergroundBreadcrumbHandle> m_BreadcrumbHandles;
23
24 private ref ArrayBoxDraw m_TriggerVisuals;
25 private ref BoxDraw m_TriggerVisualsSelected;
26
27 private ref ArrayBreadcrumbDraw m_BreadcrumbVisuals;
28 private ref BreadcrumbDraw m_BreadcrumbVisualsSelected;
29
30 private ref ScriptInvoker m_OnUpdateData;
31
32 private ref ScriptInvoker m_OnSelectTrigger;
33 private ref ScriptInvoker m_OnDeleteTrigger;
34
35 private ref ScriptInvoker m_OnSelectBreadcrumb;
36 private ref ScriptInvoker m_OnDeleteBreadcrumb;
37
38 private ref ScriptInvoker m_OnBreadcrumbEditModeChanged;
39
40 void PluginUndergroundTriggerManager()
41 {
42 if (m_Instance == null)
43 m_Instance = this;
44 }
45
46 // --------------------------------------------------------------------------------
47
48 static PluginUndergroundTriggerManager GetInstance()
49 {
50 return PluginUndergroundTriggerManager.Cast(GetPlugin(PluginUndergroundTriggerManager));
51 }
52
53 // --------------------------------------------------------------------------------
54
55 ScriptInvoker Event_OnUpdateData()
56 {
57 if (!m_OnUpdateData)
58 m_OnUpdateData = new ScriptInvoker();
59
60 return m_OnUpdateData;
61 }
62
63 // --------------------------------------------------------------------------------
64
65 ScriptInvoker Event_OnSelectTrigger()
66 {
67 if (!m_OnSelectTrigger)
68 m_OnSelectTrigger = new ScriptInvoker();
69
70 return m_OnSelectTrigger;
71 }
72
73 // --------------------------------------------------------------------------------
74
75 ScriptInvoker Event_OnDeleteTrigger()
76 {
77 if (!m_OnDeleteTrigger)
78 m_OnDeleteTrigger = new ScriptInvoker();
79
80 return m_OnDeleteTrigger;
81 }
82
83 // --------------------------------------------------------------------------------
84
85 ScriptInvoker Event_OnSelectBreadcrumb()
86 {
87 if (!m_OnSelectBreadcrumb)
88 m_OnSelectBreadcrumb = new ScriptInvoker();
89
90 return m_OnSelectBreadcrumb;
91 }
92
93 // --------------------------------------------------------------------------------
94
95 ScriptInvoker Event_OnDeleteBreadcrumb()
96 {
97 if (!m_OnDeleteBreadcrumb)
98 m_OnDeleteBreadcrumb = new ScriptInvoker();
99
100 return m_OnDeleteBreadcrumb;
101 }
102
103 // --------------------------------------------------------------------------------
104
105 ScriptInvoker Event_OnBreadcrumbEditModeChanged()
106 {
107 if (!m_OnBreadcrumbEditModeChanged)
108 m_OnBreadcrumbEditModeChanged = new ScriptInvoker();
109
110 return m_OnBreadcrumbEditModeChanged;
111 }
112
113 // --------------------------------------------------------------------------------
114
115 override void OnUpdate(float delta_time)
116 {
117 if (m_IsOpen)
118 {
119 vector cameraPos = FreeDebugCamera.GetInstance().GetPosition();
120
121 if (vector.Distance(cameraPos, m_LastSortCameraPosition) > SORT_RESORT_THRESHOLD)
122 {
123 m_LastSortCameraPosition = cameraPos;
124
125 if (m_TriggerVisuals.Count() > 1)
126 SortBoxDrawsByDistance(m_TriggerVisuals);
127
128 if (m_BreadcrumbVisuals.Count() > 1)
129 SortBreadcrumbDrawsByDistance(m_BreadcrumbVisuals);
130 }
131
132 UpdateTriggers(cameraPos);
133 UpdateBreadcrumbs(cameraPos);
134 }
135 }
136
137 private void UpdateTriggers(vector cameraPos)
138 {
139 int limit = Math.Min(m_TriggerVisuals.Count(), MAX_DEBUG_DRAW_COUNT);
140 bool selectedWasDrawn = false;
141
142 for (int i = 0; i < limit; ++i)
143 {
144 BoxDraw triggerVisual = m_TriggerVisuals.Get(i);
145
146 if (vector.Distance(cameraPos, triggerVisual.GetCenter()) > MAX_DEBUG_DRAW_DISTANCE)
147 break;
148
149 if (triggerVisual == m_TriggerVisualsSelected)
150 selectedWasDrawn = true;
151
152 triggerVisual.SetAllowTransform(triggerVisual == m_TriggerVisualsSelected && !m_BreadcrumbEditMode);
153 triggerVisual.Update();
154 }
155
156 if (m_TriggerVisualsSelected && !selectedWasDrawn)
157 {
158 m_TriggerVisualsSelected.SetAllowTransform(!m_BreadcrumbEditMode);
159 m_TriggerVisualsSelected.Update();
160 }
161 }
162
163 private void UpdateBreadcrumbs(vector cameraPos)
164 {
165 int limit = Math.Min(m_BreadcrumbVisuals.Count(), MAX_DEBUG_DRAW_COUNT);
166 bool selectedWasDrawn = false;
167
168 for (int i = 0; i < limit; ++i)
169 {
170 BreadcrumbDraw breadCrumbVisual = m_BreadcrumbVisuals.Get(i);
171
172 if (vector.Distance(cameraPos, breadCrumbVisual.GetCenter()) > MAX_DEBUG_DRAW_DISTANCE)
173 break;
174
175 if (breadCrumbVisual == m_BreadcrumbVisualsSelected)
176 selectedWasDrawn = true;
177
178 if (m_BreadcrumbEditMode)
179 breadCrumbVisual.SetAllowTransform(breadCrumbVisual == m_BreadcrumbVisualsSelected);
180 else
181 breadCrumbVisual.SetAllowTransform(false);
182 breadCrumbVisual.Update();
183 }
184
185 if (m_BreadcrumbVisualsSelected && !selectedWasDrawn)
186 {
187 m_BreadcrumbVisualsSelected.SetAllowTransform(true);
188 m_BreadcrumbVisualsSelected.Update();
189 }
190 }
191
192 // --------------------------------------------------------------------------------
193
194 override void OnInit()
195 {
196 m_TriggerHandles = new array<UndergroundTriggerHandle>();
197 m_BreadcrumbHandles = new array<UndergroundBreadcrumbHandle>();
198 m_TriggerVisuals = new ArrayBoxDraw();
199 m_BreadcrumbVisuals = new ArrayBreadcrumbDraw();
200
201 LoadDataFromFile();
202 }
203
204 // --------------------------------------------------------------------------------
205
206 void OnMouseWheel(int wheel)
207 {
208 if (!IsMouseInScene())
209 return;
210
211 Event_OnUpdateData().Invoke();
212 }
213
214 // --------------------------------------------------------------------------------
215
216 void OnUIEditorOpened()
217 {
218 m_IsOpen = true;
219
220 //OnInit(); // leaves the data untouched during runtime
221 if (!DeveloperFreeCamera.IsFreeCameraEnabled())
222 DeveloperFreeCamera.EnableFreeCameraSceneEditor(PlayerBase.Cast(g_Game.GetPlayer()));
223
224 DiagMenu.SetEngineValue(EDiagMenuGame.ENF_DIAG_GAME_FREECAM_NOCLIP, true);
225 Event_OnUpdateData().Invoke();
226 }
227
228 // --------------------------------------------------------------------------------
229
230 void OnUIEditorClosed()
231 {
232 m_IsOpen = false;
233
234 DeveloperFreeCamera.FreeCameraToggle(PlayerBase.Cast(g_Game.GetPlayer()));
235 DiagMenu.SetEngineValue(EDiagMenuGame.ENF_DIAG_GAME_FREECAM_NOCLIP, false);
236 Event_OnUpdateData().Invoke();
237 m_TriggerVisuals.Update();
238 m_BreadcrumbVisuals.Update();
239 }
240
241 // --------------------------------------------------------------------------------
242
243 void Event_OnClick()
244 {
245 if (!IsMouseInScene() || !m_IsOpen)
246 return;
247
248 vector dir = g_Game.GetPointerDirection();
249 vector from = FreeDebugCamera.GetInstance().GetPosition();
250 vector to = from + (dir * RAYCAST_LENGTH);
251
252 RaycastRVParams params = new RaycastRVParams(from, to, null);
253 params.type = ObjIntersectGeom;
254
255 array<ref RaycastRVResult> results = new array<ref RaycastRVResult>();
256 array<Object> excluded = new array<Object>();
257 if (DayZPhysics.RaycastRVProxy(params, results, excluded))
258 {
259 if (results.Count() == 0)
260 return;
261
262 UndergroundTriggerHandle triggerHandle;
263 UndergroundBreadcrumbHandle breadcrumbHandle;
264 if (Class.CastTo(triggerHandle, results[0].obj))
265 {
266 if (!m_BreadcrumbEditMode)
267 SelectTrigger(triggerHandle);
268 }
269 else if (Class.CastTo(breadcrumbHandle, results[0].obj))
270 {
271 if (m_BreadcrumbEditMode)
272 SelectBreadcrumb(breadcrumbHandle);
273 }
274 else
275 {
276 if (!m_BreadcrumbEditMode)
277 {
278 SelectTrigger(null);
279 SelectBreadcrumb(null);
280 }
281 else
282 {
283 SelectBreadcrumb(null);
284 }
285 }
286 }
287 else
288 {
289 if (!m_BreadcrumbEditMode)
290 {
291 SelectTrigger(null);
292 SelectBreadcrumb(null);
293 }
294 else
295 {
296 SelectBreadcrumb(null);
297 }
298 }
299
300 Event_OnUpdateData().Invoke();
301 }
302
303 // --------------------------------------------------------------------------------
304
305 void Event_OnDoubleClick()
306 {
307 if (!IsMouseInScene() || !m_IsOpen)
308 return;
309
310 vector dir = g_Game.GetPointerDirection();
311 vector from = FreeDebugCamera.GetInstance().GetPosition();
312 vector to = from + (dir * RAYCAST_LENGTH);
313
314 RaycastRVParams params = new RaycastRVParams(from, to, null);
315 params.type = ObjIntersectGeom;
316
317 array<ref RaycastRVResult> results = new array<ref RaycastRVResult>();
318 array<Object> excluded = new array<Object>();
319 if (DayZPhysics.RaycastRVProxy(params, results, excluded))
320 {
321 if (m_BreadcrumbEditMode)
322 {
323 AddBreadcrumb(results[0].pos);
324 }
325 else
326 {
327 BoxDraw box = new BoxDraw(results[0].pos);
328 m_TriggerVisuals.Insert(box);
329 UndergroundTriggerHandle handle = box.GetTriggerHandle();
330 handle.SetHandleName(string.Format("trigger-%1", g_Game.GetTime()));
331 box.Event_OnTransformChanged().Insert(MarkTriggersDirtyOnTransform);
332 m_TriggerHandles.Insert(handle);
333
334 MarkTriggersDirty();
335 SelectTrigger(handle);
336 }
337 }
338
339 Event_OnUpdateData().Invoke();
340 }
341
342 // --------------------------------------------------------------------------------
343
344 array<UndergroundTriggerHandle> GetTriggersList()
345 {
346 return m_TriggerHandles;
347 }
348
349 // --------------------------------------------------------------------------------
350
351 array<UndergroundBreadcrumbHandle> GetBreadcrumbsList()
352 {
353 return m_BreadcrumbHandles;
354 }
355
356 // --------------------------------------------------------------------------------
357
358 void EditorToggle()
359 {
360 if (g_Game.IsMultiplayer())
361 return;
362
363 if (IsOpened())
364 g_Game.GetUIManager().Back();
365 else
366 {
367 g_Game.GetUIManager().EnterScriptedMenu(MENU_UNDERGROUND_TRIGGER_EDITOR, null);
368 Event_OnUpdateData().Invoke();
369 }
370 }
371
372 // --------------------------------------------------------------------------------
373
374 bool IsOpened()
375 {
376 return m_IsOpen;
377 }
378
379 // --------------------------------------------------------------------------------
380
381 bool IsBreadcrumbEditMode()
382 {
383 return m_BreadcrumbEditMode;
384 }
385
386 // --------------------------------------------------------------------------------
387
388 bool IsBreadcrumbsDirty()
389 {
390 return m_BreadcrumbsDirty;
391 }
392
393 // --------------------------------------------------------------------------------
394
395 bool IsTriggersDirty()
396 {
397 return m_TriggersDirty;
398 }
399
400 // --------------------------------------------------------------------------------
401
402 // Marks unexported trigger changes; refreshes UI only on the false->true edge
403 void MarkTriggersDirty()
404 {
405 if (m_TriggersDirty)
406 return;
407
408 m_TriggersDirty = true;
409 Event_OnUpdateData().Invoke();
410 }
411
412 // --------------------------------------------------------------------------------
413
414 // ScriptInvoker-compatible hook for BoxDraw.Event_OnTransformChanged.
415 // Ignores no-op re-emits (gizmo selection / init) that pass an unchanged transform.
416 void MarkTriggersDirtyOnTransform(vector oldTransform[4], vector newTransform[4])
417 {
418 if (IsTransformUnchanged(oldTransform, newTransform))
419 return;
420
421 MarkTriggersDirty();
422 }
423
424 // --------------------------------------------------------------------------------
425
426 // ScriptInvoker-compatible hook for BreadcrumbDraw.Event_OnTransformChanged.
427 // Ignores no-op re-emits (gizmo selection / init) that pass an unchanged transform.
428 void MarkBreadcrumbsDirtyOnTransform(vector oldTransform[4], vector newTransform[4])
429 {
430 if (IsTransformUnchanged(oldTransform, newTransform))
431 return;
432
433 MarkBreadcrumbsDirty();
434 }
435
436 // --------------------------------------------------------------------------------
437
438 // Marks unsaved breadcrumb changes; refreshes UI only on the false->true edge
439 void MarkBreadcrumbsDirty()
440 {
441 if (!m_BreadcrumbEditMode || m_BreadcrumbsDirty)
442 return;
443
444 m_BreadcrumbsDirty = true;
445 Event_OnUpdateData().Invoke();
446 }
447
448 // --------------------------------------------------------------------------------
449
450 void EnterBreadcrumbEditMode()
451 {
452 UndergroundTriggerHandle triggerHandle = GetSelectedTrigger();
453 if (!triggerHandle)
454 return;
455
456 if (!triggerHandle.m_Data.Breadcrumbs)
457 triggerHandle.m_Data.Breadcrumbs = new array<ref JsonUndergroundAreaBreadcrumb>();
458
459 m_BreadcrumbEditMode = true;
460 m_BreadcrumbEditOriginalCount = triggerHandle.m_Data.Breadcrumbs.Count();
461 m_BreadcrumbsDirty = false;
462
463 Event_OnBreadcrumbEditModeChanged().Invoke(true);
464 Event_OnUpdateData().Invoke();
465 }
466
467 // --------------------------------------------------------------------------------
468
469 void SaveBreadcrumbs()
470 {
471 UndergroundTriggerHandle triggerHandle = GetSelectedTrigger();
472 if (!triggerHandle || !triggerHandle.m_Data.Breadcrumbs)
473 return;
474
475 // Sync visual positions back to the data model
476 foreach (int index, UndergroundBreadcrumbHandle breadcrumbHandle : m_BreadcrumbHandles)
477 {
478 if (index >= triggerHandle.m_Data.Breadcrumbs.Count())
479 break;
480
481 vector pos = breadcrumbHandle.m_Reference.GetCenter();
482 JsonUndergroundAreaBreadcrumb breadcrumbData = triggerHandle.m_Data.Breadcrumbs[index];
483 breadcrumbData.Position = new TFloatArray();
484 breadcrumbData.Position.Insert(pos[0]);
485 breadcrumbData.Position.Insert(pos[1]);
486 breadcrumbData.Position.Insert(pos[2]);
487
488 breadcrumbData.EyeAccommodation = breadcrumbHandle.m_Data.EyeAccommodation;
489 breadcrumbData.Radius = breadcrumbHandle.m_Data.Radius;
490 breadcrumbData.LightLerp = breadcrumbHandle.m_Data.LightLerp;
491 breadcrumbData.UseRaycast = breadcrumbHandle.m_Data.UseRaycast;
492 }
493
494 // Advance snapshot so Cancel from this point only undoes post-save changes
495 m_BreadcrumbEditOriginalCount = triggerHandle.m_Data.Breadcrumbs.Count();
496 m_BreadcrumbsDirty = false;
497 m_TriggersDirty = true;
498 Event_OnUpdateData().Invoke();
499 }
500
501 // --------------------------------------------------------------------------------
502
503 void ExitBreadcrumbEditMode(bool save)
504 {
505 UndergroundTriggerHandle triggerHandle = GetSelectedTrigger();
506
507 m_BreadcrumbEditMode = false;
508 m_BreadcrumbsDirty = false;
509
510 if (!save && triggerHandle && triggerHandle.m_Data.Breadcrumbs)
511 {
512 // Remove breadcrumbs added since last save from the data model
513 for (int i = triggerHandle.m_Data.Breadcrumbs.Count() - 1; i >= m_BreadcrumbEditOriginalCount; i--)
514 triggerHandle.m_Data.Breadcrumbs.Remove(i);
515
516 // Re-select trigger to reload breadcrumb visuals from the unmodified m_Data
517 SelectTrigger(triggerHandle);
518 }
519
520 if (m_BreadcrumbVisualsSelected)
521 {
522 m_BreadcrumbVisualsSelected.SetAllowTransform(false);
523 m_BreadcrumbVisualsSelected = null;
524 }
525
526 Event_OnBreadcrumbEditModeChanged().Invoke(false);
527 Event_OnUpdateData().Invoke();
528 }
529
530 // --------------------------------------------------------------------------------
531
532 void SelectTrigger(UndergroundTriggerHandle handle)
533 {
534 if (m_BreadcrumbEditMode)
535 return;
536
537 if (m_TriggerVisualsSelected)
538 {
539 m_TriggerVisualsSelected.SetAllowTransform(false);
540 m_TriggerVisualsSelected = null;
541 DeleteAllBreadcrumbs();
542 }
543
545
546 if (handle)
547 {
548 if (m_TriggerHandles.Find(handle) > INDEX_NOT_FOUND)
549 {
550 m_TriggerVisualsSelected = handle.m_Reference;
551 m_TriggerVisualsSelected.SetAllowTransform(true);
552 m_TriggerVisualsSelected.Select();
553
554 Event_OnSelectTrigger().Invoke(handle);
555 Event_OnUpdateData().Invoke();
556
557 if (handle.m_Data.Breadcrumbs && handle.m_Data.Breadcrumbs.Count() > 0)
558 {
559 m_BreadcrumbVisuals = new ArrayBreadcrumbDraw();
560 foreach (int index, JsonUndergroundAreaBreadcrumb breadcrumbData : handle.m_Data.Breadcrumbs)
561 {
562 BreadcrumbDraw breadcrumb = new BreadcrumbDraw(breadcrumbData.GetPosition());
563 UndergroundBreadcrumbHandle breadcrumbHandle = breadcrumb.GetBreadcrumbHandle();
564
565 handle.m_Reference.Event_OnTransformChanged().Insert(breadcrumbHandle.m_Reference.ApplyTransformation);
566 breadcrumb.Event_OnTransformChanged().Insert(MarkBreadcrumbsDirtyOnTransform);
567
568 breadcrumbHandle.m_ParentTrigger = handle;
569 if (!breadcrumbData.Comment)
570 {
571 breadcrumbHandle.SetHandleName(string.Format("Breadcrumb #%1", index));
572 m_BreadcrumbHandles.Insert(breadcrumbHandle);
573
574 breadcrumbHandle.m_Data.EyeAccommodation = breadcrumbData.EyeAccommodation;
575 breadcrumbHandle.m_Data.Radius = breadcrumbData.Radius;
576 breadcrumbHandle.m_Data.LightLerp = breadcrumbData.LightLerp;
577 breadcrumbHandle.m_Data.UseRaycast = breadcrumbData.UseRaycast;
578 }
579
580 m_BreadcrumbVisuals.Insert(breadcrumb);
581 }
582 }
583 }
584 }
585 else
586 {
587 Event_OnSelectTrigger().Invoke(null);
588 Event_OnUpdateData().Invoke();
589 }
590 }
591
592 // --------------------------------------------------------------------------------
593
594 void SelectBreadcrumb(UndergroundBreadcrumbHandle handle)
595 {
596 if (m_BreadcrumbVisualsSelected)
597 {
598 m_BreadcrumbVisualsSelected.SetAllowTransform(false);
599 m_BreadcrumbVisualsSelected = null;
600 }
601
603
604 if (handle)
605 {
606 if (m_BreadcrumbHandles.Find(handle) > INDEX_NOT_FOUND)
607 {
608 m_BreadcrumbVisualsSelected = handle.m_Reference;
609 m_BreadcrumbVisualsSelected.SetAllowTransform(true);
610 m_BreadcrumbVisualsSelected.Select();
611
612 Event_OnSelectBreadcrumb().Invoke(handle);
613 Event_OnUpdateData().Invoke();
614 }
615 }
616 else
617 {
618 Event_OnSelectBreadcrumb().Invoke(null);
619 Event_OnUpdateData().Invoke();
620 }
621 }
622
623 // --------------------------------------------------------------------------------
624
625 UndergroundTriggerHandle GetSelectedTrigger()
626 {
627 if (m_TriggerVisualsSelected)
628 return m_TriggerVisualsSelected.GetTriggerHandle();
629
630 return null;
631 }
632
633 // --------------------------------------------------------------------------------
634
635 UndergroundBreadcrumbHandle GetSelectedBreadcrumb()
636 {
637 if (m_BreadcrumbVisualsSelected)
638 return m_BreadcrumbVisualsSelected.GetBreadcrumbHandle();
639
640 return null;
641 }
642
643 // --------------------------------------------------------------------------------
644
645 void AddBreadcrumb(vector position)
646 {
647 UndergroundTriggerHandle triggerHandle = GetSelectedTrigger();
648 if (!triggerHandle || !triggerHandle.m_Data)
649 return;
650
651 if (!triggerHandle.m_Data.Breadcrumbs)
652 triggerHandle.m_Data.Breadcrumbs = new array<ref JsonUndergroundAreaBreadcrumb>();
653
654 // Add to data model
655 JsonUndergroundAreaBreadcrumb breadcrumbData = new JsonUndergroundAreaBreadcrumb();
656 breadcrumbData.Position = new TFloatArray();
657 breadcrumbData.Position.Insert(position[0]);
658 breadcrumbData.Position.Insert(position[1]);
659 breadcrumbData.Position.Insert(position[2]);
660 triggerHandle.m_Data.Breadcrumbs.Insert(breadcrumbData);
661
662 // Create visual
663 BreadcrumbDraw breadcrumb = new BreadcrumbDraw(position);
664 UndergroundBreadcrumbHandle breadcrumbHandle = breadcrumb.GetBreadcrumbHandle();
665
666 triggerHandle.m_Reference.Event_OnTransformChanged().Insert(breadcrumbHandle.m_Reference.ApplyTransformation);
667 breadcrumb.Event_OnTransformChanged().Insert(MarkBreadcrumbsDirtyOnTransform);
668
669 breadcrumbHandle.m_ParentTrigger = triggerHandle;
670 breadcrumbHandle.SetHandleName(string.Format("Breadcrumb #%1", m_BreadcrumbHandles.Count()));
671
672 m_BreadcrumbHandles.Insert(breadcrumbHandle);
673 m_BreadcrumbVisuals.Insert(breadcrumb);
674
675 m_BreadcrumbsDirty = true;
676
677 SelectBreadcrumb(breadcrumbHandle);
678 Event_OnUpdateData().Invoke();
679 }
680
681 // --------------------------------------------------------------------------------
682
683 void DeleteBreadcrumb(UndergroundBreadcrumbHandle handle)
684 {
685 int index = m_BreadcrumbHandles.Find(handle);
686 if (index == INDEX_NOT_FOUND)
687 return;
688
689 // Remove from parent trigger data model at the matching index
690 UndergroundTriggerHandle triggerHandle = handle.m_ParentTrigger;
691 if (triggerHandle && index < triggerHandle.m_Data.Breadcrumbs.Count())
692 triggerHandle.m_Data.Breadcrumbs.Remove(index);
693
694 if (m_BreadcrumbVisualsSelected == handle.m_Reference)
695 {
696 m_BreadcrumbVisualsSelected.SetAllowTransform(false);
697 m_BreadcrumbVisualsSelected = null;
698 }
699
700 m_BreadcrumbVisuals.RemoveItem(handle.m_Reference);
701 m_BreadcrumbHandles.Remove(index);
702
703 if (m_BreadcrumbEditMode)
704 m_BreadcrumbsDirty = true;
705
706 Event_OnDeleteBreadcrumb().Invoke(handle);
707 Event_OnUpdateData().Invoke();
708 }
709
710 // --------------------------------------------------------------------------------
711
712 void DeleteTrigger(UndergroundTriggerHandle handle)
713 {
715
716 if (handle)
717 {
718 if (m_TriggerHandles.Find(handle) > INDEX_NOT_FOUND)
719 {
720 m_TriggerVisualsSelected = null;
721
722 m_TriggerVisuals.RemoveItem(handle.m_Reference);
723 m_TriggerHandles.RemoveItem(handle);
724
725 m_TriggersDirty = true;
726
727 Event_OnDeleteTrigger().Invoke(handle);
728 DeleteAllBreadcrumbs();
729 Event_OnUpdateData().Invoke();
730 }
731 }
732 }
733
734 // --------------------------------------------------------------------------------
735
736 void DeleteAllTrigers()
737 {
738 int count = m_TriggerHandles.Count();
739 if (count > 0)
740 {
741 m_TriggerVisualsSelected = null;
742
743 m_TriggerVisuals.Clear();
744 m_TriggerHandles.Clear();
745
746 DeleteAllBreadcrumbs();
747
748 Event_OnUpdateData().Invoke();
749 }
750 }
751
752 // --------------------------------------------------------------------------------
753
754 void DeleteAllBreadcrumbs()
755 {
756 int count = m_BreadcrumbHandles.Count();
757 if (count > 0)
758 {
759 m_BreadcrumbVisualsSelected = null;
760
761 m_BreadcrumbHandles.Clear();
762 m_BreadcrumbVisuals.Clear();
763
764 Event_OnUpdateData().Invoke();
765 }
766 }
767
768 // --------------------------------------------------------------------------------
769
770 void ExportData()
771 {
772 JsonUndergroundTriggers jsonData = new JsonUndergroundTriggers();
773 jsonData.Triggers = new array<ref JsonUndergroundAreaTriggerData>();
774
775 foreach (UndergroundTriggerHandle triggerHandle : m_TriggerHandles)
776 {
777 vector size = triggerHandle.m_Reference.GetSize();
778 triggerHandle.m_Data.Size = new TFloatArray();
779 triggerHandle.m_Data.Size.Insert(size[0]);
780 triggerHandle.m_Data.Size.Insert(size[1]);
781 triggerHandle.m_Data.Size.Insert(size[2]);
782
783 vector center = triggerHandle.m_Reference.GetCenter();
784 triggerHandle.m_Data.Position = new TFloatArray();
785 triggerHandle.m_Data.Position.Insert(center[0]);
786 triggerHandle.m_Data.Position.Insert(center[1]);
787 triggerHandle.m_Data.Position.Insert(center[2]);
788
789 vector orientation = triggerHandle.m_Reference.GetOrientation();
790 triggerHandle.m_Data.Orientation = new TFloatArray();
791 triggerHandle.m_Data.Orientation.Insert(orientation[0]);
792 triggerHandle.m_Data.Orientation.Insert(orientation[1]);
793 triggerHandle.m_Data.Orientation.Insert(orientation[2]);
794
795 foreach (int index, UndergroundBreadcrumbHandle breadcrumbHandle : m_BreadcrumbHandles)
796 {
797 if (breadcrumbHandle.m_ParentTrigger && triggerHandle != breadcrumbHandle.m_ParentTrigger)
798 continue;
799
800 vector breadcrumbPosition = breadcrumbHandle.m_Reference.GetCenter();
801 breadcrumbHandle.m_Data.Position = new TFloatArray();
802 breadcrumbHandle.m_Data.Position.Insert(breadcrumbPosition[0]);
803 breadcrumbHandle.m_Data.Position.Insert(breadcrumbPosition[1]);
804 breadcrumbHandle.m_Data.Position.Insert(breadcrumbPosition[2]);
805
806 JsonUndergroundAreaBreadcrumb originalBreadcrumb = JsonUndergroundAreaBreadcrumb.Cast(triggerHandle.m_Data.Breadcrumbs[index]);
807 originalBreadcrumb.Position = breadcrumbHandle.m_Data.Position;
808 originalBreadcrumb.EyeAccommodation = breadcrumbHandle.m_Data.EyeAccommodation;
809 originalBreadcrumb.Radius = breadcrumbHandle.m_Data.Radius;
810 originalBreadcrumb.LightLerp = breadcrumbHandle.m_Data.LightLerp;
811 originalBreadcrumb.UseRaycast = breadcrumbHandle.m_Data.UseRaycast;
812 }
813
814 JsonUndergroundAreaTriggerData triggerData = new JsonUndergroundAreaTriggerData();
815 triggerData = triggerHandle.m_Data;
816
817 jsonData.Triggers.Insert(triggerData);
818 }
819
820 string errorMessage;
821 if (!JsonFileLoader<JsonUndergroundTriggers>.SaveFile("$mission:cfgundergroundtriggers.json", jsonData, errorMessage))
822 {
823 ErrorEx(errorMessage);
824 return;
825 }
826
827 m_TriggersDirty = false;
828 Event_OnUpdateData().Invoke();
829
830 OnExport();
831 }
832
833 // --------------------------------------------------------------------------------
834
835 void FocusOnObject()
836 {
837 if (m_TriggerVisualsSelected)
838 FocusCameraOn(m_TriggerVisualsSelected.GetCenter(), m_TriggerVisualsSelected.GetSize());
839 else if (m_BreadcrumbVisualsSelected)
840 // Breadcrumbs have no real size, use an artificial 2m distance
841 FocusCameraOn(m_BreadcrumbVisualsSelected.GetCenter(), Vector(1, 1, 1), 2.0);
842 }
843
844 // --------------------------------------------------------------------------------
845
846 private void FocusCameraOn(vector position, vector size, float maxDistance = 0)
847 {
848 vector cameraPosition = position;
849 cameraPosition[0] = cameraPosition[0] + size[0] * 2;
850 cameraPosition[1] = cameraPosition[1] + size[1] + 0.5;
851 cameraPosition[2] = cameraPosition[2] + size[2] * 2;
852
853 // Clamp the camera offset to maxDistance while preserving the viewing angle.
854 // Triggers pass the default (0) and are unaffected.
855 if (maxDistance > 0)
856 {
857 vector offset = cameraPosition - position;
858 if (offset.Length() > maxDistance)
859 cameraPosition = position + (offset.Normalized() * maxDistance);
860 }
861
862 vector viewTarget = position;
863 viewTarget[1] = viewTarget[1] + size[1] * 0.5;
864
865 vector cameraDirection = viewTarget - cameraPosition;
866 cameraDirection.Normalize();
867
868 FreeDebugCamera.GetInstance().SetPosition(cameraPosition);
869 FreeDebugCamera.GetInstance().SetDirection(cameraDirection);
870 }
871
872 // --------------------------------------------------------------------------------
873
874 // Bound in PluginKeybings directly
875 void FreeCameraControlEnable()
876 {
877 if (g_Game.GetUIManager().GetMenu())
878 g_Game.GetUIManager().GetMenu().OnHide();
879 }
880
881 // --------------------------------------------------------------------------------
882
883 // Bound in PluginKeybings directly
884 void FreeCameraControlDisable()
885 {
886 if (g_Game.GetUIManager().GetMenu())
887 g_Game.GetUIManager().GetMenu().OnShow();
888 }
889
890 // --------------------------------------------------------------------------------
891
892 void LoadDataFromFile()
893 {
894 // preload data from cfgundergoundtriggers.json
895 JsonUndergroundTriggers jsonData = UndergroundAreaLoader.GetData();
896 if (jsonData && jsonData.Triggers)
897 {
898 foreach (int index, JsonUndergroundAreaTriggerData data : jsonData.Triggers)
899 {
900 BoxDraw box = new BoxDraw(data.GetPosition(), data.GetOrientation(), data.GetSize());
901 m_TriggerVisuals.Insert(box);
902 UndergroundTriggerHandle handle = box.GetTriggerHandle();
903 handle.m_Data = data;
904 if (!handle.m_Data.Comment)
905 handle.m_Data.Comment = string.Format("trigger %1", index);
906 box.Event_OnTransformChanged().Insert(MarkTriggersDirtyOnTransform);
907 m_TriggerHandles.Insert(handle);
908 }
909
910 m_TriggersDirty = false;
911 Event_OnUpdateData().Invoke();
912 }
913 }
914
915 private void OnExport()
916 {
917 //backup original file
918 int year, month, day, hour, minute, second;
919 GetYearMonthDayUTC(year, month, day);
920 GetHourMinuteSecondUTC(hour, minute, second);
921 string datetimeUTC = string.Format(DATETIME_FORMAT, year, month.ToStringLen(2), day.ToStringLen(2), hour.ToStringLen(2), minute.ToStringLen(2), second.ToStringLen(2));
922 string backupFilename = string.Format("$mission:cfgundergroundtriggers.json.backup-%1", datetimeUTC);
923 CopyFile("$mission:cfgundergroundtriggers.json", backupFilename);
924 }
925
926 // --------------------------------------------------------------------------------
927
928 private bool IsTransformUnchanged(vector oldTransform[4], vector newTransform[4])
929 {
930 const float eps = 0.0001;
931 return vector.Distance(oldTransform[3], newTransform[3]) < eps && vector.Distance(oldTransform[0], newTransform[0]) < eps && vector.Distance(oldTransform[1], newTransform[1]) < eps && vector.Distance(oldTransform[2], newTransform[2]) < eps;
932 }
933
934 // --------------------------------------------------------------------------------
935
936 private bool IsMouseInScene()
937 {
938 Widget widgetUnder = GetWidgetUnderCursor();
939
940 if (widgetUnder != null && widgetUnder.GetName() == "panel_scene")
941 return true;
942
943 return false;
944 }
945
946 // --------------------------------------------------------------------------------
947
948 private void SortBoxDrawsByDistance(ArrayBoxDraw arr)
949 {
950 int n = arr.Count();
951 for (int i = 1; i < n; i++)
952 {
953 BoxDraw key = arr.Get(i);
954 float keyDist = vector.Distance(m_LastSortCameraPosition, key.GetCenter());
955 int j = i - 1;
956 while (j >= 0 && vector.Distance(m_LastSortCameraPosition, arr.Get(j).GetCenter()) > keyDist)
957 {
958 arr.Set(j + 1, arr.Get(j));
959 j--;
960 }
961 arr.Set(j + 1, key);
962 }
963 }
964
965 // --------------------------------------------------------------------------------
966
967 private void SortBreadcrumbDrawsByDistance(ArrayBreadcrumbDraw arr)
968 {
969 int n = arr.Count();
970 for (int i = 1; i < n; i++)
971 {
972 BreadcrumbDraw key = arr.Get(i);
973 float keyDist = vector.Distance(m_LastSortCameraPosition, key.GetCenter());
974 int j = i - 1;
975 while (j >= 0 && vector.Distance(m_LastSortCameraPosition, arr.Get(j).GetCenter()) > keyDist)
976 {
977 arr.Set(j + 1, arr.Get(j));
978 j--;
979 }
980 arr.Set(j + 1, key);
981 }
982 }
983}
984#endif
bool IsOpened()
Определения BaseBuildingBase.c:1647
static AnimSoundObjectBuilderBank GetInstance()
Определения DayZAnimEventMaps.c:186
DayZGame g_Game
Определения DayZGame.c:4074
vector position
Определения DustKickupEffects.c:20
vector orientation
Определения DustKickupEffects.c:21
proto GizmoApi GetGizmoApi()
void Event_OnClick()
Определения PluginDayZCreatureAIDebug.c:595
PluginBase GetPlugin(typename plugin_type)
Определения PluginManager.c:326
static ref RadialMenu m_Instance
Определения RadialMenu.c:55
void DeleteTrigger()
Определения TrapBase.c:487
proto void DeselectAll()
ref array< ref JsonUndergroundAreaTriggerData > Triggers
Определения UndergroundAreaLoader.c:3
Plugin interface for controlling of agent pool system.
Определения PluginBase.c:2
proto vector Normalized()
return normalized vector (keeps orginal vector untouched)
proto native float Length()
Returns length of vector (magnitude)
proto float Normalize()
Normalizes vector. Returns length.
const int INDEX_NOT_FOUND
Определения gameplay.c:13
enum ShapeType ErrorEx
array< float > TFloatArray
Определения EnScript.c:732
proto native bool CopyFile(string sourceName, string destName)
copy file. destName must be "$profile:" or "$saves:" location
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
const int MENU_UNDERGROUND_TRIGGER_EDITOR
Определения 3_Game/DayZ/constants.c:223
void OnInit()
Callback for user defined initialization. Called for all suites during TestHarness....
Определения FreezeState.c:81
proto void Insert(int index, string input)
Inserts a string into the n-th index, increasing the string length by the size of the input.
static proto string Format(string fmt, void param1=NULL, void param2=NULL, void param3=NULL, void param4=NULL, void param5=NULL, void param6=NULL, void param7=NULL, void param8=NULL, void param9=NULL)
Gets n-th character from string.
proto void GetYearMonthDayUTC(out int year, out int month, out int day)
Returns UTC system date.
proto void GetHourMinuteSecondUTC(out int hour, out int minute, out int second)
Returns UTC system time.
proto native void OnUpdate()
Определения 3_Game/DayZ/tools/tools.c:349
WorkspaceWidget Widget
Defined in code.
proto native Widget GetWidgetUnderCursor()