Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_MapEntity.c
Go to the documentation of this file.
4
5//------------------------------------------------------------------------------------------------
6// invoker typedefs
9
10void MapItemInvoker(MapItem mapItem);
12
13void ScriptInvokerFloat2Bool(float f1, float f2, bool b1);
15
16[EntityEditorProps(category: "GameScripted/Map", description: "Map entity, handles displaying of map etc", sizeMin: "-5 -5 -5", sizeMax: "5 5 5", color: "255 255 200 0", dynamicBox: true)]
17class SCR_MapEntity: MapEntity
18{
19 const int FRAME_DELAY = 1;
20 protected int m_iDelayCounter = FRAME_DELAY; // used to delay the map logic by set amount of frames to give the map widget time to properly init
21
22 // generic
23 protected bool m_bIsOpen; // is open flag
24 protected bool m_bDoReload; // mark whether map config changed in order to reload modules/components
25 protected bool m_bDoUpdate; // mark whether user setting changed, update zoom & position
26 protected bool m_bIsDebugMode; // variable debug mode
27 protected int m_iMapSizeX; // map size X in meters/units
28 protected int m_iMapSizeY; // map size Y in meters/units
29 protected int m_iMapOffsetX; // map offset X in meters/units
30 protected int m_iMapOffsetY; // map offset Y in meters/units
31 protected vector m_vVisibleFrameMin; // cache visible frame min point for use elsewhere
32 protected vector m_vVisibleFrameMax; // cache visible frame max point for use elsewhere
33 protected EMapEntityMode m_eLastMapMode; // cached mode of last map for reload check
34 protected Widget m_wMapRoot; // map menu root widget
35 protected CanvasWidget m_MapWidget; // map widget
37 protected ref MapConfiguration m_ActiveMapCfg; // map config
38 protected static SCR_MapEntity s_MapInstance; // map entity instance
39
40 protected MapItem m_HoveredMapItem; // currently hovered map item
41
42 // zoom
43 protected bool m_bIsZoomInterp; // is currently zoom animating
44 protected float m_fZoomPPU = 1; // current zoom PixelPerUnit value
45 protected float m_fStartPPU; // zoom start PixelPerUnit
46 protected float m_fTargetPPU = 1; // zoom target PixelPerUnit
47 protected float m_fZoomTimeModif; // zoom anim speed modifier
48 protected float m_fZoomSlice; // zoom anim timeslce
49 protected float m_fMinZoom = 1; // minimal zoom PixelPerUnit
50 protected float m_fMaxZoom; // maximal zoom PixelPerUnit
51
52 // pan
53 protected bool m_bIsPanInterp; // is currently pan animating
54 protected int m_iPanX = 0; // current horizontal pan offset - UNSCALED value in px
55 protected int m_iPanY = 0; // current vertical pan offset - UNSCALED value in px
56 protected int m_aStartPan[2]; // pan start coords - UNSCALED value in px
57 protected int m_aTargetPan[2]; // pan target coords - UNSCALED value in px
58 protected float m_fPanTimeModif; // pan anim speed modifier
59 protected float m_fPanSlice; // pan anim timeslce
60
61 // modules & components
62 protected ref array<ref SCR_MapModuleBase> m_aActiveModules = {};
63 protected ref array<ref SCR_MapModuleBase> m_aLoadedModules = {};
64 protected ref array<ref SCR_MapUIBaseComponent> m_aActiveComponents = {};
65 protected ref array<ref SCR_MapUIBaseComponent> m_aLoadedComponents = {};
66
67 // invokers
68 protected static ref ScriptInvokerBase<MapConfigurationInvoker> s_OnMapInit = new ScriptInvokerBase<MapConfigurationInvoker>(); // map init, called straight after opening the map
69 protected static ref ScriptInvokerBase<MapConfigurationInvoker> s_OnMapOpen = new ScriptInvokerBase<MapConfigurationInvoker>(); // map open, called after map is properly initialized
70 protected static ref ScriptInvokerBase<MapConfigurationInvoker> s_OnMapOpenComplete = new ScriptInvokerBase<MapConfigurationInvoker>(); //map fully opened, called after the OnMapOpen invoker, after everything has been set up
71 protected static ref ScriptInvokerBase<MapConfigurationInvoker> s_OnMapClose = new ScriptInvokerBase<MapConfigurationInvoker>();// map close
72 protected static ref ScriptInvokerBase<ScriptInvokerFloat2Bool> s_OnMapPan = new ScriptInvokerBase<ScriptInvokerFloat2Bool>; // map pan, passes UNSCALED x & y
73 protected static ref ScriptInvokerFloat2 s_OnMapPanEnd = new ScriptInvokerFloat2(); // map pan interpolated end
74 protected static ref ScriptInvokerFloat s_OnMapZoom = new ScriptInvokerFloat(); // map zoom
75 protected static ref ScriptInvokerFloat s_OnMapZoomEnd = new ScriptInvokerFloat(); // map zoom interpolated end
76 protected static ref ScriptInvokerVector s_OnSelection = new ScriptInvokerVector(); // any click/selection on map
77 protected static ref ScriptInvokerInt s_OnLayerChanged = new ScriptInvokerInt(); // map layer changed
78 protected static ref ScriptInvokerBase<MapItemInvoker> s_OnSelectionChanged = new ScriptInvokerBase<MapItemInvoker>(); // map items de/selected
79 protected static ref ScriptInvokerBase<MapItemInvoker> s_OnHoverItem = new ScriptInvokerBase<MapItemInvoker>(); // map item hovered
80 protected static ref ScriptInvokerBase<MapItemInvoker> s_OnHoverEnd = new ScriptInvokerBase<MapItemInvoker>(); // map item hover end
81
82 //------------------------------------------------------------------------------------------------
83 // GETTERS / SETTERS
84 //------------------------------------------------------------------------------------------------
86 static ScriptInvokerBase<MapConfigurationInvoker> GetOnMapInit() { return s_OnMapInit; }
88 static ScriptInvokerBase<MapConfigurationInvoker> GetOnMapOpen() { return s_OnMapOpen; }
90 static ScriptInvokerBase<MapConfigurationInvoker> GetOnMapOpenComplete() { return s_OnMapOpenComplete; }
92 static ScriptInvokerBase<MapConfigurationInvoker> GetOnMapClose() { return s_OnMapClose; }
94 static ScriptInvokerBase<ScriptInvokerFloat2Bool> GetOnMapPan() { return s_OnMapPan; }
102 static ScriptInvokerBase<MapItemInvoker> GetOnSelectionChanged() { return s_OnSelectionChanged; }
106 static ScriptInvokerBase<MapItemInvoker> GetOnHoverItem() { return s_OnHoverItem; }
108 static ScriptInvokerBase<MapItemInvoker> GetOnHoverEnd() { return s_OnHoverEnd; }
113
114 //------------------------------------------------------------------------------------------------
120
121 //------------------------------------------------------------------------------------------------
123 bool IsOpen()
124 {
125 return m_bIsOpen;
126 }
127
128 //------------------------------------------------------------------------------------------------
131 {
132 return m_iMapSizeX;
133 }
134
135 //------------------------------------------------------------------------------------------------
138 {
139 return m_iMapSizeY;
140 }
141
142 //------------------------------------------------------------------------------------------------
144 float GetMaxZoom()
145 {
146 return m_fMaxZoom;
147 }
148
149 //------------------------------------------------------------------------------------------------
151 float GetMinZoom()
152 {
153 return m_fMinZoom;
154 }
155
156 //------------------------------------------------------------------------------------------------
159 {
160 return m_fTargetPPU;
161 }
162
163 //------------------------------------------------------------------------------------------------
165 bool IsZooming()
166 {
167 return m_bIsZoomInterp;
168 }
169
170 //------------------------------------------------------------------------------------------------
173 {
174 return { m_Workspace.DPIScale(m_iPanX), m_Workspace.DPIScale(m_iPanY), 0 };
175 }
176
177 //------------------------------------------------------------------------------------------------
180 {
181 return m_MapWidget;
182 }
183
184 //------------------------------------------------------------------------------------------------
187 {
188 return m_wMapRoot;
189 }
190
191 //------------------------------------------------------------------------------------------------
194 {
195 m_MapWidget = CanvasWidget.Cast(mapW);
196 }
197
198 //------------------------------------------------------------------------------------------------
201 {
202 return m_HoveredMapItem;
203 }
204
205 //------------------------------------------------------------------------------------------------
207 void GetMapVisibleFrame(out vector min, out vector max)
208 {
209 min = m_vVisibleFrameMin;
210 max = m_vVisibleFrameMax;
211 }
212
213 //------------------------------------------------------------------------------------------------
217 {
218 return m_fZoomPPU;
219 }
220
221 //------------------------------------------------------------------------------------------------
225 void GetMapCursorWorldPosition(out float worldX, out float worldY)
226 {
227 ScreenToWorld(m_Workspace.DPIScale(SCR_MapCursorInfo.x), m_Workspace.DPIScale(SCR_MapCursorInfo.y), worldX, worldY);
228 }
229
230 //------------------------------------------------------------------------------------------------
234 void GetMapCenterWorldPosition(out float worldX, out float worldY)
235 {
236 float screenX, screenY;
237 m_MapWidget.GetScreenSize(screenX, screenY);
238
239 ScreenToWorld(screenX/2, screenY/2, worldX, worldY);
240 }
241
242 //------------------------------------------------------------------------------------------------
246 SCR_MapModuleBase GetMapModule(typename moduleType)
247 {
248 foreach ( SCR_MapModuleBase module : m_aActiveModules )
249 {
250 if ( module.IsInherited(moduleType) )
251 return module;
252 }
253
254 return null;
255 }
256
257 //------------------------------------------------------------------------------------------------
262 {
264 {
265 if ( comp.IsInherited(componentType) )
266 return comp;
267 }
268
269 return null;
270 }
271
272 //------------------------------------------------------------------------------------------------
273 // OPEN / CLOSE
274 //------------------------------------------------------------------------------------------------
278 {
279 if (!config)
280 return;
281
282 if (m_bIsOpen)
283 {
284 Print("SCR_MapEntity: Attempted opening a map while it is already open", LogLevel.WARNING);
285 CloseMap();
286 }
287
288 if (config.MapEntityMode != m_eLastMapMode)
289 m_bDoReload = true;
290
291 m_eLastMapMode = config.MapEntityMode;
292 m_ActiveMapCfg = config;
293 m_Workspace = GetGame().GetWorkspace();
294 m_wMapRoot = config.RootWidgetRef;
295
296 SetMapWidget(config.RootWidgetRef.FindAnyWidget(SCR_MapConstants.MAP_WIDGET_NAME));
297
298 if (config.MapEntityMode == EMapEntityMode.FULLSCREEN)
299 {
301 if (char)
303
305 if (gameMode)
306 gameMode.GetOnPlayerDeleted().Insert(OnPlayerDeleted);
307 }
308
309 InitLayers(config);
310
311 SetFrame(Vector(0, 0, 0), Vector(0, 0, 0)); // Gamecode starts rendering stuff like descriptors straight away instead of waiting a frame - this is a hack to display nothing, avoiding the "blink" of icons
312
313 m_bIsOpen = true;
314
315 s_OnMapInit.Invoke(config);
316
317 PlayerController plc = GetGame().GetPlayerController();
318 if (plc && GetGame().GetCameraManager().CurrentCamera() == plc.GetPlayerCamera())
319 plc.SetCharacterCameraRenderActive(false);
320 }
321
322 //------------------------------------------------------------------------------------------------
324 void CloseMap()
325 {
326 if (!m_bIsOpen)
327 return;
328
329 OnMapClose();
330
331 m_bIsOpen = false;
332 m_iDelayCounter = FRAME_DELAY;
333 auto plc = GetGame().GetPlayerController();
334 if (plc)
335 plc.SetCharacterCameraRenderActive(true);
336 }
337
338 //------------------------------------------------------------------------------------------------
341 protected void OnMapOpen(MapConfiguration config)
342 {
343 // init zoom & layers
344 m_MapWidget.SetSizeInUnits(Vector(m_iMapSizeX, m_iMapSizeY, 0)); // unit size to meters
346 AssignViewLayer(true);
347
348 if (m_bDoUpdate) // when resolution changes, zoom to the same PPU to update zoom and pos
349 {
350 ZoomSmooth(m_fZoomPPU, reinitZoom: true);
351 m_bDoUpdate = false;
352 }
353
354 // activate modules & components
355 ActivateModules(config.Modules);
356 ActivateComponents(config.Components);
357 ActivateOtherComponents(config.OtherComponents);
358
359 m_bDoReload = false;
360
361 if (s_OnMapOpen)
362 s_OnMapOpen.Invoke(config);
363
364 if (config.MapEntityMode == EMapEntityMode.FULLSCREEN)
365 SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_HUD_MAP_OPEN);
366
367 //calling methods that are dependent on setup done by methods called by the OnMapOpen invoker
369 s_OnMapOpenComplete.Invoke(config);
370
372 }
373
374 //------------------------------------------------------------------------------------------------
376 protected void OnMapClose()
377 {
378 if (s_OnMapClose)
380
381 if (m_ActiveMapCfg.MapEntityMode == EMapEntityMode.FULLSCREEN)
382 {
383 SCR_UISoundEntity.SoundEvent(SCR_SoundEvent.SOUND_HUD_MAP_CLOSE);
384
385 PlayerController controller = GetGame().GetPlayerController();
386 if (controller)
387 {
388 ChimeraCharacter char = ChimeraCharacter.Cast(controller.GetControlledEntity());
389 if (char)
391 }
392
394 if (gameMode)
395 gameMode.GetOnPlayerDeleted().Remove(OnPlayerDeleted);
396 }
397
398 if ( m_ActiveMapCfg.OtherComponents & EMapOtherComponents.LEGEND_SCALE)
399 EnableLegend(false);
400
401 EnableVisualisation(false);
402
403 Cleanup();
404 }
405
406 //------------------------------------------------------------------------------------------------
409 protected void OnLifeStateChanged(ECharacterLifeState previousLifeState, ECharacterLifeState newLifeState)
410 {
411 if (newLifeState == ECharacterLifeState.ALIVE)
412 return;
413
415 if (!gadgetMgr)
416 return;
417
418 IEntity mapGadget = gadgetMgr.GetGadgetByType(EGadgetType.MAP);
419 if (!mapGadget)
420 return;
421
422 SCR_MapGadgetComponent mapComp = SCR_MapGadgetComponent.Cast(mapGadget.FindComponent(SCR_MapGadgetComponent));
423 mapComp.SetMapMode(false);
424 }
425
426 //------------------------------------------------------------------------------------------------
429 protected void OnPlayerDeleted(int playerId, IEntity player)
430 {
431 if (playerId != GetGame().GetPlayerController().GetPlayerId())
432 return;
433
434 MenuManager menuManager = g_Game.GetMenuManager();
435 menuManager.CloseMenuByPreset(ChimeraMenuPreset.MapMenu);
436 }
437
438 //------------------------------------------------------------------------------------------------
440 protected void OnUserSettingsChanged()
441 {
442 UpdateTexts();
443
444 if (m_bIsOpen)
445 {
447 ZoomSmooth(m_fZoomPPU, reinitZoom: true);
448 }
449 else
450 {
451 m_bDoUpdate = true;
452 }
453 }
454
455 //------------------------------------------------------------------------------------------------
457 protected void OnWindowResized(int width, int height, bool windowed)
458 {
460 }
461
462 //------------------------------------------------------------------------------------------------
463 // MAP SETUP
464 //------------------------------------------------------------------------------------------------
470 {
471 if (mapMode == m_eLastMapMode)
472 {
473 m_ActiveMapCfg.RootWidgetRef = rootWidget;
474 return m_ActiveMapCfg;
475 }
476
477 // clear loaded compas and modules
478 m_aLoadedComponents.Clear();
479 m_aLoadedModules.Clear();
480
481 // Load config
482 Resource container = BaseContainerTools.LoadContainer(configPath);
483 if (!container)
484 return null;
485
486 SCR_MapConfig mapConfig = SCR_MapConfig.Cast( BaseContainerTools.CreateInstanceFromContainer( container.GetResource().ToBaseContainer() ) );
487 MapConfiguration configObject = new MapConfiguration();
488
489 // basic
490 configObject.RootWidgetRef = rootWidget;
491 configObject.MapEntityMode = mapConfig.m_iMapMode;
492
493 // modules & componentss
494 configObject.Modules = mapConfig.m_aModules;
495 configObject.Components = mapConfig.m_aUIComponents;
496
497 if (mapConfig.m_bEnableLegendScale == true)
498 configObject.OtherComponents |= EMapOtherComponents.LEGEND_SCALE;
499
500 if (mapConfig.m_bEnableGrid == true)
501 configObject.OtherComponents |= EMapOtherComponents.GRID;
502
503 SetupLayersAndProps(configObject, mapConfig);
504 SetupDescriptorTypes(mapConfig.m_DescriptorDefaultsConfig);
505
506 return configObject;
507 }
508
509 //------------------------------------------------------------------------------------------------
513 protected void SetupLayersAndProps(inout MapConfiguration configObject, SCR_MapConfig mapCfg)
514 {
515 SCR_MapLayersBase layersCfg = mapCfg.m_LayersConfig; // layers
516 if (!layersCfg) // use default if above fails
517 {
518 Resource containerDefs = BaseContainerTools.LoadContainer(SCR_MapConstants.CFG_LAYERS_DEFAULT);
519 layersCfg = SCR_MapLayersBase.Cast( BaseContainerTools.CreateInstanceFromContainer( containerDefs.GetResource().ToBaseContainer() ) );
520 }
521
522 configObject.LayerConfig = layersCfg;
523
524 if (layersCfg.m_aLayers.IsEmpty())
525 configObject.LayerCount = 0;
526 else
527 configObject.LayerCount = layersCfg.m_aLayers.Count();
528
529 SCR_MapPropsBase propsCfg = mapCfg.m_MapPropsConfig; // map properties
530 if (!propsCfg) // use default if above fails
531 {
532 Resource containerDefs = BaseContainerTools.LoadContainer(SCR_MapConstants.CFG_PROPS_DEFAULT);
533 propsCfg = SCR_MapPropsBase.Cast( BaseContainerTools.CreateInstanceFromContainer( containerDefs.GetResource().ToBaseContainer() ) );
534 }
535
536 configObject.MapPropsConfig = propsCfg;
537
538 SCR_MapDescriptorVisibilityBase descriptorViewCfg = mapCfg.m_DescriptorVisibilityConfig; // descriptors visibility within layers
539 if (!descriptorViewCfg) // use default if above fails
540 {
541 Resource containerDefs = BaseContainerTools.LoadContainer(SCR_MapConstants.CFG_DESCVIEW_DEFAULT);
542 descriptorViewCfg = SCR_MapDescriptorVisibilityBase.Cast( BaseContainerTools.CreateInstanceFromContainer( containerDefs.GetResource().ToBaseContainer() ) );
543 }
544
545 configObject.DescriptorVisibilityConfig = descriptorViewCfg;
546
547 SCR_MapDescriptorDefaults descriptorDefaults = mapCfg.m_DescriptorDefaultsConfig;
548 if (!descriptorDefaults)
549 {
550 Resource containerDefs = BaseContainerTools.LoadContainer(SCR_MapConstants.CFG_DESCTYPES_DEFAULT);
551 descriptorDefaults = SCR_MapDescriptorDefaults.Cast( BaseContainerTools.CreateInstanceFromContainer( containerDefs.GetResource().ToBaseContainer() ) );
552 }
553
554 configObject.DescriptorDefsConfig = descriptorDefaults;
555 }
556
557 //------------------------------------------------------------------------------------------------
561 protected void SetupDescriptorTypes(SCR_MapDescriptorDefaults descriptorDefaultsConfig)
562 {
563 array<int> imagesetIndices = {};
564
565 if (!descriptorDefaultsConfig.m_aDescriptorDefaults.IsEmpty())
566 {
567 for (int i = 0; i < EMapDescriptorType.MDT_COUNT; ++i)
568 {
569 imagesetIndices.Insert(-1);
570 }
571
572 foreach (SCR_DescriptorDefaultsBase descriptorDefs : descriptorDefaultsConfig.m_aDescriptorDefaults)
573 {
574 imagesetIndices[descriptorDefs.m_iDescriptorType] = descriptorDefs.m_iImageSetIndex;
575 }
576
577 SetImagesetMapping(imagesetIndices);
578 }
579 }
580
581 //------------------------------------------------------------------------------------------------
582 // MAP CONTROL METHODS
583 //------------------------------------------------------------------------------------------------
586 {
587 if (m_iDelayCounter > 0)
588 {
589 Print("SCR_MapEntity: Attempt to call CenterMap before map init is completed", LogLevel.WARNING);
590 return;
591 }
592
594 int x, y;
596
597 SetPan(x, y);
598 }
599
600 //------------------------------------------------------------------------------------------------
602 void ZoomOut()
603 {
604 SetZoom(m_fMinZoom, true);
605 CenterMap();
606 }
607
608 //------------------------------------------------------------------------------------------------
614
615 //------------------------------------------------------------------------------------------------
619 void SetZoom(float targetPPU, bool instant = false)
620 {
621 if (m_iDelayCounter > 0)
622 {
623 Print("SCR_MapEntity: Attempt to call SetZoom before map init is completed", LogLevel.NORMAL);
624 return;
625 }
626
627 targetPPU = Math.Clamp(targetPPU, m_fMinZoom, m_fMaxZoom);
628
629 m_fZoomPPU = targetPPU;
630 AssignViewLayer(false);
631 ZoomChange(targetPPU / m_MapWidget.PixelPerUnit()); // contours
632
633 if (instant)
635
636 s_OnMapZoom.Invoke(targetPPU);
637 }
638
639 //------------------------------------------------------------------------------------------------
645 void ZoomSmooth(float targetPixPerUnit, float zoomTime = 0.25, bool zoomToCenter = true, bool reinitZoom = false)
646 {
647 if (m_iDelayCounter > 0)
648 {
649 Print("SCR_MapEntity: Attempt to call ZoomSmooth before map init is completed", LogLevel.NORMAL);
650 return;
651 }
652
653 if (zoomTime <= 0)
654 zoomTime = 0.1;
655
656 targetPixPerUnit = Math.Clamp(targetPixPerUnit, m_fMinZoom, m_fMaxZoom);
657 if (!reinitZoom && targetPixPerUnit == m_fZoomPPU)
658 return;
659
661 m_fTargetPPU = targetPixPerUnit;
662 m_fZoomTimeModif = 1/zoomTime;
663 m_fZoomSlice = 1.0;
664 m_bIsZoomInterp = true;
665
666 float screenX, screenY, worldX, worldY, targetScreenX, targetScreenY;
667 m_MapWidget.GetScreenSize(screenX, screenY);
668
669 if (zoomToCenter)
670 {
671 // zoom according to the current screen center
672 GetMapCenterWorldPosition(worldX, worldY);
673 WorldToScreenCustom( worldX, worldY, targetScreenX, targetScreenY, targetPixPerUnit, false );
674 PanSmooth( targetScreenX, targetScreenY, zoomTime );
675 }
676 else
677 {
678 // Calculate target pan position in a way which makes cursor stay on the same world pos while zooming
679 float diffX = screenX/2 - m_Workspace.DPIScale(SCR_MapCursorInfo.x); // difference in pixels between screen center and cursor
680 float diffY = screenY/2 - m_Workspace.DPIScale(SCR_MapCursorInfo.y);
681
682 GetMapCursorWorldPosition(worldX, worldY); // current cursor world pos, relative anchor of zoom
683 WorldToScreenCustom( worldX, worldY, targetScreenX, targetScreenY, targetPixPerUnit, false ); // target screen pos of cursor with zoom applied
684 PanSmooth( targetScreenX + diffX, targetScreenY + diffY, zoomTime ); // offset the target position by the pix diference from screen center
685 }
686 }
687
688 //------------------------------------------------------------------------------------------------
694 void ZoomPanSmooth(float targetPixPerUnit, float worldX, float worldY, float zoomTime = 0.25)
695 {
696 if (m_iDelayCounter > 0)
697 {
698 Print("SCR_MapEntity: Attempt to call ZoomPanSmooth before map init is completed", LogLevel.NORMAL);
699 return;
700 }
701
702 if (zoomTime <= 0)
703 zoomTime = 0.1;
704
705 if (targetPixPerUnit > m_fMaxZoom)
706 targetPixPerUnit = m_fMaxZoom;
707 else if (targetPixPerUnit < m_fMinZoom)
708 targetPixPerUnit = m_fMinZoom;
709
711 m_fTargetPPU = targetPixPerUnit;
712 m_fZoomTimeModif = 1/zoomTime;
713 m_fZoomSlice = 1.0;
714 m_bIsZoomInterp = true;
715
716 float screenX, screenY, targetScreenX, targetScreenY;
717 m_MapWidget.GetScreenSize(screenX, screenY);
718
719 WorldToScreenCustom( worldX, worldY, targetScreenX, targetScreenY, targetPixPerUnit, false ); // target pos with zoom applied
720 PanSmooth( targetScreenX, targetScreenY, zoomTime );
721 }
722
723 //------------------------------------------------------------------------------------------------
729 void SetPan(float x, float y, bool isPanEnd = true, bool center = true, bool updatingPan = false)
730 {
731 if (m_iDelayCounter > 0)
732 {
733 Print("SCR_MapEntity: Attempt to call SetPan before map init is completed", LogLevel.NORMAL);
734 return;
735 }
736
737 bool adjustedPan = false;
738
739 // test bounds
740 if (!FitPanBounds(x, y, center))
741 adjustedPan = true;
742
743 if (m_bIsPanInterp && !updatingPan)
744 {
745 float diffX = x - m_iPanX;
746 float diffY = y - m_iPanY;
747
748 m_aStartPan[0] = m_aStartPan[0] - diffX;
749 m_aStartPan[1] = m_aStartPan[1] - diffY;
750
751 m_aTargetPan[0] = m_aTargetPan[0] - diffX;
752 m_aTargetPan[1] = m_aTargetPan[1] - diffY;
753 }
754
755 // save current pan
756 m_iPanX = x;
757 m_iPanY = y;
758
759 PosChange(m_Workspace.DPIScale(m_iPanX), m_Workspace.DPIScale(m_iPanY));
760
761 if (isPanEnd)
762 SCR_MapCursorInfo.startPos = {0, 0};
763
764 s_OnMapPan.Invoke(m_iPanX, m_iPanY, adjustedPan);
765 }
766
767 //------------------------------------------------------------------------------------------------
771 void Pan(EMapPanMode panMode, float panValue = 0)
772 {
773 if (m_iDelayCounter > 0)
774 {
775 Print("SCR_MapEntity: Attempt to call Pan before map init is completed", LogLevel.NORMAL);
776 return;
777 }
778
779 float panX, panY;
780
781 // panning mode
782 if (panMode == EMapPanMode.DRAG)
783 {
784 // begin drag
785 if (SCR_MapCursorInfo.startPos[0] == 0 && SCR_MapCursorInfo.startPos[1] == 0)
787
788 // mouse position difference
789 int diffX = SCR_MapCursorInfo.x - SCR_MapCursorInfo.startPos[0];
790 int diffY = SCR_MapCursorInfo.y - SCR_MapCursorInfo.startPos[1];
791
792 panX = m_iPanX + diffX;
793 panY = m_iPanY + diffY;
794
795 SCR_MapCursorInfo.startPos[0] = SCR_MapCursorInfo.x;
796 SCR_MapCursorInfo.startPos[1] = SCR_MapCursorInfo.y;
797 }
798 else if (panMode == EMapPanMode.HORIZONTAL)
799 {
800 panX = m_iPanX + panValue;
801 panY = m_iPanY;
802 }
803 else if (panMode == EMapPanMode.VERTICAL)
804 {
805 panX = m_iPanX;
806 panY = m_iPanY + panValue;
807 }
808
809 // Pan
810 SetPan(panX, panY, false, false);
811 s_OnMapPanEnd.Invoke(panX, panY);
812 }
813
814 //------------------------------------------------------------------------------------------------
819 void PanSmooth(float panX, float panY, float panTime = 0.25)
820 {
821 if (m_iDelayCounter > 0)
822 {
823 Print("SCR_MapEntity: Attempt to call PanSmooth before map init is completed", LogLevel.NORMAL);
824 return;
825 }
826
827 float screenWidth, screenHeight;
828 m_MapWidget.GetScreenSize(screenWidth, screenHeight);
829
830 if (panTime <= 0)
831 panTime = 0.1;
832
833 // un-center to get direct pan pos
834 m_aStartPan = { m_Workspace.DPIUnscale(screenWidth/2) - m_iPanX, m_Workspace.DPIUnscale(screenHeight/2) - m_iPanY };
835 m_aTargetPan = { m_Workspace.DPIUnscale(panX), m_Workspace.DPIUnscale(panY)};
836 m_fPanTimeModif = 1/panTime;
837 m_fPanSlice = 1.0;
838 m_bIsPanInterp = true;
839 }
840
841 //------------------------------------------------------------------------------------------------
844 void InvokeOnSelect(vector selectionPos)
845 {
846 s_OnSelection.Invoke(selectionPos);
847 }
848
852 {
853 item.Select(true);
854 item.SetHighlighted(true);
855
856 s_OnSelectionChanged.Invoke(item);
857 }
858
859 //------------------------------------------------------------------------------------------------
863 {
864 item.SetHovering(true);
865 m_HoveredMapItem = item;
866
867 s_OnHoverItem.Invoke(item);
868 }
869
870 //------------------------------------------------------------------------------------------------
873 {
876
877 s_OnSelectionChanged.Invoke(null);
878 }
879
880 //------------------------------------------------------------------------------------------------
883 {
885
887 m_HoveredMapItem = null;
888 }
889
890 //------------------------------------------------------------------------------------------------
891 // CONVERSION METHODS
892 //------------------------------------------------------------------------------------------------
894 // \param worldX is world x
895 // \param worldY is world y
896 // \param screenPosX is screen x
897 // \param screenPosY is screen y
898 // \param withPan determines whether current pan is added to the result
899 void WorldToScreen(float worldX, float worldY, out int screenPosX, out int screenPosY, bool withPan = false)
900 {
901 worldY = m_iMapSizeY - worldY; // fix Y axis which is reversed between screen and world
902
903 if (withPan)
904 {
905 screenPosX = ((worldX - m_iMapOffsetX) * m_fZoomPPU) + m_Workspace.DPIScale(m_iPanX);
906 screenPosY = ((worldY + m_iMapOffsetY) * m_fZoomPPU) + m_Workspace.DPIScale(m_iPanY);
907 }
908 else
909 {
910 screenPosX = (worldX - m_iMapOffsetX) * m_fZoomPPU;
911 screenPosY = (worldY + m_iMapOffsetY) * m_fZoomPPU;
912 }
913 }
914
915 //------------------------------------------------------------------------------------------------
917 // \param worldX is world x
918 // \param worldY is world y
919 // \param screenPosX is screen x
920 // \param screenPosY is screen y
921 // \param withPan determines whether current pan is added to the result
922 // \param targetPPU sets PixelPerUnit used for the calculation (useful for precalculating)
923 void WorldToScreenCustom(float worldX, float worldY, out int screenPosX, out int screenPosY, float targetPPU, bool withPan = false)
924 {
925 worldY = m_iMapSizeY - worldY;
926
927 if (withPan)
928 {
929 screenPosX = ((worldX - m_iMapOffsetX) * targetPPU) + m_Workspace.DPIScale(m_iPanX);
930 screenPosY = ((worldY + m_iMapOffsetY) * targetPPU) + m_Workspace.DPIScale(m_iPanY);
931 }
932 else
933 {
934 screenPosX = (worldX - m_iMapOffsetX) * targetPPU;
935 screenPosY = (worldY + m_iMapOffsetY) * targetPPU;
936 }
937 }
938
939 //------------------------------------------------------------------------------------------------
941 // \param screenPosX is screen x
942 // \param screenPosY is screen y
943 // \param worldX is world x
944 // \param worldY is world y
945 void ScreenToWorld(int screenPosX, int screenPosY, out float worldX, out float worldY)
946 {
947 worldX = (screenPosX - m_Workspace.DPIScale(m_iPanX)) / m_fZoomPPU + m_iMapOffsetX;
948 worldY = (screenPosY - m_Workspace.DPIScale(m_iPanY)) / m_fZoomPPU - m_iMapOffsetY;
949 worldY = m_iMapSizeY - worldY; // fix Y axis which is reversed between screen and world
950 }
951
952 //------------------------------------------------------------------------------------------------
954 // \param screenPosX is screen x
955 // \param screenPosY is screen y
956 // \param worldX is world x
957 // \param worldY is world y
958 void ScreenToWorldNoFlip(int screenPosX, int screenPosY, out float worldX, out float worldY)
959 {
960 worldX = (screenPosX - m_Workspace.DPIScale(m_iPanX)) / m_fZoomPPU + m_iMapOffsetX;
961 worldY = (screenPosY - m_Workspace.DPIScale(m_iPanY)) / m_fZoomPPU + m_iMapOffsetY;
962 }
963
972 //--- ToDo: Use grid sizes configured in layers in case someone will define non-metric grid
973 static string GetGridLabel(vector pos, int resMin = 2, int resMax = 4, string delimiter = " ")
974 {
975 int gridX, gridZ;
976 GetGridPos(pos, gridX, gridZ, resMin, resMax);
977 return gridX.ToString() + delimiter + gridZ.ToString();
978 }
979
987 static void GetGridPos(vector pos, out int gridX, out int gridZ, int resMin = 2, int resMax = 4)
988 {
989 //--- Convert to int so we can use native mod operator %
990 int posX = pos[0];
991 int posZ = pos[2];
992
993 for (int i = resMax; i >= resMin; i--)
994 {
995 int mod = Math.Pow(10, i);
996 int modX = posX - posX % mod;
997 int modZ = posZ - posZ % mod;
998 gridX = gridX * 10 + (modX / mod);
999 gridZ = gridZ * 10 + (modZ / mod);
1000 posX -= modX;
1001 posZ -= modZ;
1002 }
1003 }
1004
1005 //------------------------------------------------------------------------------------------------
1006 // SUPPORT METHODS
1007 //------------------------------------------------------------------------------------------------
1012 protected bool FitPanBounds(inout float panX, inout float panY, bool center)
1013 {
1014 float windowWidth, windowHeight;
1015 m_MapWidget.GetScreenSize(windowWidth, windowHeight);
1016
1017 windowWidth = m_Workspace.DPIUnscale(windowWidth);
1018 windowHeight = m_Workspace.DPIUnscale(windowHeight);
1019
1020 // center to coords
1021 if (center)
1022 {
1023 panX = windowWidth/2 - panX;
1024 panY = windowHeight/2 - panY;
1025 }
1026
1027 int width = m_iMapSizeX * m_fZoomPPU;
1028 int height = m_iMapSizeY * m_fZoomPPU;
1029
1030 // center of the screen can travel everywhere within map
1031 int minCoordX = windowWidth/2 - m_Workspace.DPIUnscale(width);
1032 int minCoordY = windowHeight/2 - m_Workspace.DPIUnscale(height);
1033 int maxCoordX = windowWidth/2;
1034 int maxCoordY = windowHeight/2;
1035
1036 // cannot pan outside of map bounds
1037 /*int minCoordX = windowWidth - width;
1038 int minCoordY = windowHeight - height;
1039 int maxCoordX = 0;
1040 int maxCoordY = 0;*/
1041
1042 bool adjusted = false;
1043
1044 // stop when over min/max
1045 if (panX < minCoordX)
1046 {
1047 panX = minCoordX;
1048 adjusted = true;
1049 }
1050
1051 if (panX > maxCoordX)
1052 {
1053 panX = maxCoordX;
1054 adjusted = true;
1055 }
1056
1057 if (panY < minCoordY)
1058 {
1059 panY = minCoordY;
1060 adjusted = true;
1061 }
1062
1063 if (panY > maxCoordY)
1064 {
1065 panY = maxCoordY;
1066 adjusted = true;
1067 }
1068
1069 if (adjusted)
1070 return false;
1071
1072 return true;
1073 }
1074
1075 //------------------------------------------------------------------------------------------------
1079 {
1080 float screenWidth, screenHeight;
1081 m_MapWidget.GetScreenSize(screenWidth, screenHeight);
1082
1083 float maxUnitsPerScreen = screenHeight / m_MapWidget.PixelPerUnit();
1084 m_fMinZoom = (maxUnitsPerScreen / m_iMapSizeY) * m_MapWidget.PixelPerUnit();
1085 m_fMaxZoom = SCR_MapConstants.MAX_PIX_PER_METER;
1086
1087 return true;
1088 }
1089
1090 //------------------------------------------------------------------------------------------------
1092 protected void AssignViewLayer(bool isInit)
1093 {
1094 int count = LayerCount();
1095 if (count == 0) // No layers to change to
1096 return;
1097
1098 for ( int layerID = 0; layerID < count; layerID++ )
1099 {
1100 if ( GetCurrentZoom() >= GetLayer(layerID).GetCeiling() )
1101 {
1102 if (isInit || layerID != GetLayerIndex())
1103 {
1104 SetLayer(layerID);
1105 s_OnLayerChanged.Invoke(layerID);
1106 }
1107
1108 break;
1109 }
1110 }
1111 }
1112
1113 //------------------------------------------------------------------------------------------------
1114 // INIT / CLEANUP METHODS
1115 //------------------------------------------------------------------------------------------------
1117 protected void InitLayers(MapConfiguration mapConfig)
1118 {
1119 SCR_MapLayersBase layerConfig = mapConfig.LayerConfig;
1120
1121 int layerCount = mapConfig.LayerCount;
1122 InitializeLayers(layerCount);
1123
1124 if (layerCount < 1)
1125 return;
1126
1127 for (int i = 0; i < layerCount; i++) // per layer configuration
1128 {
1129 MapLayer layer = GetLayer(i);
1130 if (layer)
1131 {
1132 // setr ceiling vals
1133 layerConfig.m_aLayers[i].SetLayerProps(layer);
1134
1135 // props configs
1136 foreach ( SCR_MapPropsConfig propsCfg : mapConfig.MapPropsConfig.m_aMapPropConfigs)
1137 {
1138 propsCfg.SetDefaults(layer);
1139 }
1140
1141 // descriptor configuration init
1142 InitDescriptors(i, layer, layerConfig.m_aLayers[i], mapConfig);
1143 }
1144 }
1145 }
1146
1147 //------------------------------------------------------------------------------------------------
1152 protected void InitDescriptors(int layerID, MapLayer layer, SCR_LayerConfiguration layerConfig, MapConfiguration mapConfig)
1153 {
1154 // create descriptor visiiblity map
1155 map<int, int> descriptorVisibility = new map<int, int>;
1156
1157 // descriptor visibility configuration
1158 foreach (SCR_DescriptorViewLayer descConfig : mapConfig.DescriptorVisibilityConfig.m_aDescriptorViewLayers)
1159 {
1160 if (descConfig.m_iViewLayer >= layerID + 1)
1161 descriptorVisibility.Set(descConfig.m_iDescriptorType, layerID); // match descriptor type with visibility
1162 }
1163
1164 foreach (SCR_DescriptorDefaultsBase descriptorType : mapConfig.DescriptorDefsConfig.m_aDescriptorDefaults)
1165 {
1166 // visible in the current layer
1167 if ( descriptorVisibility.Get(descriptorType.m_iDescriptorType) >= layerID )
1168 {
1169 MapDescriptorProps props;
1170
1171 // is using faction based configuration
1172 if (descriptorType.m_bUseFactionColors)
1173 {
1174 foreach (SCR_FactionColorDefaults factionDefaults : mapConfig.DescriptorDefsConfig.m_aFactionColors)
1175 {
1176 props = layer.GetPropsFor(factionDefaults.m_iFaction, descriptorType.m_iDescriptorType);
1177 if (props)
1178 {
1179 descriptorType.SetDefaults(props);
1180 factionDefaults.SetColors(props);
1181 }
1182 }
1183 }
1184 else
1185 {
1186 props = layer.GetPropsFor(EFactionMapID.UNKNOWN, descriptorType.m_iDescriptorType);
1187 if (props)
1188 {
1189 descriptorType.SetDefaults(props);
1190 descriptorType.SetColors(props);
1191 }
1192 }
1193 }
1194 // not visible in the current layer
1195 else
1196 {
1197 MapDescriptorProps props;
1198
1199 // is using faction based configuration
1200 if (descriptorType.m_bUseFactionColors)
1201 {
1202 foreach (SCR_FactionColorDefaults factionDefaults : mapConfig.DescriptorDefsConfig.m_aFactionColors)
1203 {
1204 props = layer.GetPropsFor(factionDefaults.m_iFaction, descriptorType.m_iDescriptorType);
1205 if (props)
1206 props.SetVisible(false);
1207 }
1208 }
1209 else
1210 {
1211 props = layer.GetPropsFor(EFactionMapID.UNKNOWN, descriptorType.m_iDescriptorType);
1212 if (props)
1213 props.SetVisible(false);
1214 }
1215 }
1216 }
1217 }
1218
1219 //------------------------------------------------------------------------------------------------
1222 //------------------------------------------------------------------------------------------------
1223 protected void ActivateModules( array<ref SCR_MapModuleBase> modules )
1224 {
1225 if (modules.IsEmpty())
1226 return;
1227
1228 array<SCR_MapModuleBase> modulesToInit = new array<SCR_MapModuleBase>();
1229
1230 foreach ( SCR_MapModuleBase module : modules )
1231 {
1232 // load new module
1233 if (m_bDoReload)
1234 {
1235 if (module.IsConfigDisabled())
1236 continue;
1237
1238 m_aLoadedModules.Insert(module);
1239 modulesToInit.Insert(module);
1240 m_aActiveModules.Insert(module);
1241 module.SetActive(true);
1242 }
1243 // activate modules
1244 else
1245 {
1246 int count = m_aLoadedModules.Count();
1247 for (int i = 0; i < count; i++)
1248 {
1249 if (!m_aLoadedModules[i].IsInherited(module.Type()))
1250 continue;
1251
1252 // is module active
1253 if (m_aActiveModules.Find(m_aLoadedModules[i]) == -1)
1254 {
1256 m_aLoadedModules[i].SetActive(true);
1257 break;
1258 }
1259 }
1260 }
1261 }
1262
1263 foreach ( SCR_MapModuleBase module : modulesToInit )
1264 {
1265 module.Init();
1266 }
1267 }
1268
1269 //------------------------------------------------------------------------------------------------
1272 protected void ActivateComponents( array<ref SCR_MapUIBaseComponent> components )
1273 {
1274 if (components.IsEmpty())
1275 return;
1276
1277 array<SCR_MapUIBaseComponent> componentsToInit = new array<SCR_MapUIBaseComponent>();
1278
1279 foreach ( SCR_MapUIBaseComponent component : components )
1280 {
1281 // load new component
1282 if (m_bDoReload)
1283 {
1284 if (component.IsConfigDisabled())
1285 continue;
1286
1287 m_aLoadedComponents.Insert(component);
1288 componentsToInit.Insert(component);
1289 m_aActiveComponents.Insert(component);
1290 component.SetActive(true);
1291 }
1292 // activate components
1293 else
1294 {
1295 int count = m_aLoadedComponents.Count();
1296 for (int i = 0; i < count; i++)
1297 {
1298 if (!m_aLoadedComponents[i].IsInherited(component.Type()))
1299 continue;
1300
1301 // is component active
1302 if (m_aActiveComponents.Find(m_aLoadedComponents[i]) == -1)
1303 {
1305 m_aLoadedComponents[i].SetActive(true);
1306 break;
1307 }
1308 }
1309 }
1310 }
1311
1312 foreach ( SCR_MapUIBaseComponent component : componentsToInit )
1313 {
1314 component.Init();
1315 }
1316
1317 }
1318
1319 //------------------------------------------------------------------------------------------------
1322 protected void ActivateOtherComponents(EMapOtherComponents componentFlags)
1323 {
1324 if (componentFlags & EMapOtherComponents.LEGEND_SCALE)
1325 EnableLegend(true);
1326 else
1327 EnableLegend(false);
1328
1329 if (componentFlags & EMapOtherComponents.GRID)
1330 EnableGrid(true);
1331 else
1332 EnableGrid(false);
1333
1334 }
1335
1336 //------------------------------------------------------------------------------------------------
1339 {
1340 m_aActiveModules.RemoveItem(module);
1341 m_aLoadedModules.RemoveItem(module);
1342 }
1343
1344 //------------------------------------------------------------------------------------------------
1347 {
1348 m_aActiveComponents.RemoveItem(component);
1349 m_aLoadedComponents.RemoveItem(component);
1350 }
1351
1352 //------------------------------------------------------------------------------------------------
1354 protected void Cleanup()
1355 {
1356 // deactivate components & modules
1357 foreach (SCR_MapUIBaseComponent component : m_aActiveComponents )
1358 {
1359 component.SetActive(false, true);
1360 }
1361
1362 m_aActiveComponents.Clear();
1363
1364 foreach (SCR_MapModuleBase module : m_aActiveModules )
1365 {
1366 module.SetActive(false, true);
1367 }
1368
1369 m_aActiveModules.Clear();
1370 m_bIsDebugMode = false;
1371 }
1372
1373 //------------------------------------------------------------------------------------------------
1374 // UPDATE METHODS
1375 //------------------------------------------------------------------------------------------------
1378 {
1379 float screenWidth, screenHeight;
1380 m_MapWidget.GetScreenSize(screenWidth, screenHeight);
1381
1382 float minCoordX, minCoordY, maxCoordX, maxCoordY;
1383
1384 ScreenToWorld(screenWidth, 0, maxCoordX, maxCoordY);
1385 ScreenToWorld(0, screenHeight, minCoordX, minCoordY);
1386
1387 m_vVisibleFrameMin = Vector(minCoordX, 0, minCoordY);
1388 m_vVisibleFrameMax = Vector(maxCoordX, 0, maxCoordY);
1390 }
1391
1392 //------------------------------------------------------------------------------------------------
1395 protected void PanUpdate(float timeSlice)
1396 {
1397 m_fPanSlice -= timeSlice * m_fPanTimeModif;
1398
1399 // End interpolation
1400 if (m_fPanSlice <= 0)
1401 {
1402 m_bIsPanInterp = false;
1403 SetPan(m_aTargetPan[0], m_aTargetPan[1], true, true, true);
1405 }
1406 else
1407 {
1408 int panX = Math.Lerp(m_aStartPan[0], m_aTargetPan[0], 1 - m_fPanSlice);
1409 int panY = Math.Lerp(m_aStartPan[1], m_aTargetPan[1], 1 - m_fPanSlice);
1410 SetPan(panX, panY, false, true, true);
1411 }
1412 }
1413
1414 //------------------------------------------------------------------------------------------------
1417 protected void ZoomUpdate(float timeSlice)
1418 {
1419 m_fZoomSlice -= timeSlice * m_fZoomTimeModif;
1420
1421 // End interpolation
1422 if (m_fZoomSlice <= 0)
1423 {
1426 m_bIsZoomInterp = false;
1427 }
1428 else
1429 {
1430 float zoom = Math.Lerp(m_fStartPPU, m_fTargetPPU, 1 - m_fZoomSlice);
1431 SetZoom(zoom);
1432 }
1433 }
1434
1435 //------------------------------------------------------------------------------------------------
1437 protected void UpdateDebug()
1438 {
1439 float wX, wY;
1440 float x = m_Workspace.DPIScale(SCR_MapCursorInfo.x);
1441 float y = m_Workspace.DPIScale(SCR_MapCursorInfo.y);
1442 ScreenToWorld(x, y, wX, wY);
1443
1444 vector pan = GetCurrentPan();
1445 array<MapItem> outItems = {};
1446 GetSelected(outItems);
1447
1448 DbgUI.Begin("Map debug");
1449 const string dbg1 = "CURSOR SCREEN POS: x: %1 y: %2";
1450 DbgUI.Text( string.Format( dbg1, x, y ) );
1451 const string dbg2 = "CURSOR WORLD POS: x: %1 y: %2";
1452 DbgUI.Text( string.Format( dbg2, wX, wY ) );
1453 const string dbg3 = "PAN OFFSET: x: %1 y: %2 ";
1454 DbgUI.Text( string.Format( dbg3, pan[0], pan[1] ) );
1455 const string dbg4 = "ZOOM: min: %1 max: %2 | pixPerUnit: %3";
1456 DbgUI.Text( string.Format( dbg4, GetMinZoom(), GetMaxZoom(), GetCurrentZoom() ) );
1457 const string dbg5 = "LAYER: current: %1 | pixPerUnit ceiling: %2";
1458 DbgUI.Text( string.Format( dbg5, GetLayerIndex(), GetLayer(GetLayerIndex()).GetCeiling() ) );
1459 const string dbg6 = "MODULES: loaded: %1 | active: %2 | list: %3 ";
1460 DbgUI.Text( string.Format( dbg6, m_aLoadedModules.Count(), m_aActiveModules.Count(), m_aActiveModules ) );
1461 const string dbg7 = "COMPONENTS: loaded: %1 | active: %2 | list: %3 ";
1462 DbgUI.Text( string.Format( dbg7, m_aLoadedComponents.Count(), m_aActiveComponents.Count(), m_aActiveComponents ) );
1463 const string dbg8 = "MAPITEMS: selected: %1 | hovered: %2 ";
1464 DbgUI.Text( string.Format( dbg8, outItems, m_HoveredMapItem ) );
1465 DbgUI.End();
1466 }
1467
1468 //------------------------------------------------------------------------------------------------
1471 protected void UpdateMap(float timeSlice)
1472 {
1473 // update modules
1474 foreach ( SCR_MapModuleBase module : m_aActiveModules)
1475 {
1476 module.Update(timeSlice);
1477 }
1478
1479 //update components
1480 foreach ( SCR_MapUIBaseComponent component : m_aActiveComponents)
1481 {
1482 component.Update(timeSlice);
1483 }
1484
1485 // interpolation update
1486 if (m_bIsZoomInterp)
1487 ZoomUpdate(timeSlice);
1488
1489 if (m_bIsPanInterp)
1490 PanUpdate(timeSlice);
1491 }
1492
1493#ifndef DISABLE_GADGETS
1494 //------------------------------------------------------------------------------------------------
1495 override void EOnFrame(IEntity owner, float timeSlice)
1496 {
1497 if (IsOpen())
1498 {
1499 // delayed init -> This is here so the MapWidget has time to initiate its size & PixelPerUnit calculation
1500 if (m_iDelayCounter >= 0)
1501 {
1502 if (m_iDelayCounter == 0)
1503 {
1506 }
1507 else
1508 {
1510 return;
1511 }
1512 }
1513
1514 UpdateMap(timeSlice);
1515
1516 if (m_bIsDebugMode)
1517 UpdateDebug();
1518
1520 }
1521 }
1522
1523 //------------------------------------------------------------------------------------------------
1524 override void EOnInit(IEntity owner)
1525 {
1526 vector size = Size();
1527 m_iMapSizeX = size[0];
1528 m_iMapSizeY = size[2];
1529 vector offset = Offset();
1530 m_iMapOffsetX = offset[0];
1531 m_iMapOffsetY = offset[2];
1532
1533 if (m_iMapSizeX == 0 || m_iMapSizeY == 0)
1534 {
1535 Print("SCR_MapEntity: Cannot get the size from terrain. Using default.", LogLevel.WARNING);
1536 m_iMapSizeX = 1024;
1537 m_iMapSizeY = 1024;
1538 }
1539
1540 ChimeraWorld world = GetGame().GetWorld();
1541 if (world)
1542 world.RegisterEntityToBeUpdatedWhileGameIsPaused(this);
1543 }
1544
1545 //------------------------------------------------------------------------------------------------
1547 {
1548 SetEventMask(EntityEvent.INIT | EntityEvent.FRAME);
1549
1550 s_MapInstance = this;
1551
1552 DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_UI_MAP_DEBUG_OPTIONS, "", "Enable map debug menu", "UI");
1553
1554 GetGame().OnUserSettingsChangedInvoker().Insert(OnUserSettingsChanged);
1555 GetGame().OnWindowResizeInvoker().Insert(OnWindowResized);
1556 }
1557
1558 //------------------------------------------------------------------------------------------------
1560 {
1561 if (m_bIsOpen)
1562 CloseMap();
1563
1564 ChimeraWorld world = GetGame().GetWorld();
1565 if (world)
1566 world.UnregisterEntityToBeUpdatedWhileGameIsPaused(this);
1567
1568 s_OnMapInit.Clear();
1569 s_OnMapOpen.Clear();
1570 s_OnMapOpenComplete.Clear();
1571 s_OnMapClose.Clear();
1572 s_OnMapPan.Clear();
1573 s_OnMapPanEnd.Clear();
1574 s_OnMapZoom.Clear();
1575 s_OnMapZoomEnd.Clear();
1576 s_OnSelectionChanged.Clear();
1577 s_OnSelection.Clear();
1578 s_OnHoverItem.Clear();
1579 s_OnHoverEnd.Clear();
1580 s_OnLayerChanged.Clear();
1581
1582 DiagMenu.Unregister(SCR_DebugMenuID.DEBUGUI_UI_MAP_DEBUG_OPTIONS);
1583
1584 s_MapInstance = null;
1585 }
1586
1587#endif
1588};
ChimeraMenuPreset
Menu presets.
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
ArmaReforgerScripted GetGame()
Definition game.c:1398
LayerPresets layer
int size
SCR_CharacterControllerComponent GetCharacterController()
SCR_BaseGameMode GetGameMode()
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
EMapPanMode
Panning modes.
EMapEntityMode
Mode of the map.
EMapOtherComponents
Map components which are not part of the component system.
func MapItemInvoker
func ScriptInvokerFloat2Bool
func MapConfigurationInvoker
ScriptInvokerBase< ScriptInvokerFloatMethod > ScriptInvokerFloat
ScriptInvokerBase< ScriptInvokerIntMethod > ScriptInvokerInt
ScriptInvokerBase< ScriptInvokerVectorMethod > ScriptInvokerVector
ScriptInvokerBase< ScriptInvokerFloat2Method > ScriptInvokerFloat2
proto native external bool IsInherited(typename type)
Definition DbgUI.c:66
Diagnostic and developer menu system.
Definition DiagMenu.c:18
proto external Managed FindComponent(typename typeName)
Definition Math.c:13
proto external bool CloseMenuByPreset(ScriptMenuPresetEnum preset)
Put menu with given iPresetId into queue for closing (which is processed during next MenuManeger upda...
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
ScriptInvokerBase< SCR_BaseGameMode_PlayerIdAndEntity > GetOnPlayerDeleted()
ref OnLifeStateChangedInvoker m_OnLifeStateChanged
Configuration of descriptor defaults.
Configuration of visibility in layers per descriptor type.
Configuration of descriptor defaults.
IEntity GetGadgetByType(EGadgetType type)
static SCR_GadgetManagerComponent GetGadgetManager(IEntity entity)
Map config root.
Config for default values set per descriptor type.
Descriptor visibility config root.
void OnUserSettingsChanged()
Game event.
static SCR_MapEntity s_MapInstance
ref array< ref SCR_MapUIBaseComponent > m_aActiveComponents
SCR_MapModuleBase GetMapModule(typename moduleType)
void GetMapCenterWorldPosition(out float worldX, out float worldY)
void Pan(EMapPanMode panMode, float panValue=0)
static ScriptInvokerBase< MapConfigurationInvoker > GetOnMapClose()
Get on map close invoker.
ref array< ref SCR_MapModuleBase > m_aActiveModules
static ref ScriptInvokerBase< MapItemInvoker > s_OnHoverItem
static ref ScriptInvokerBase< ScriptInvokerFloat2Bool > s_OnMapPan
MapItem m_HoveredMapItem
CanvasWidget GetMapWidget()
Get map widget.
CanvasWidget m_MapWidget
bool UpdateZoomBounds()
ref array< ref SCR_MapUIBaseComponent > m_aLoadedComponents
int GetMapSizeX()
Get map sizeX in meters.
vector m_vVisibleFrameMin
static ref ScriptInvokerInt s_OnLayerChanged
void InvokeOnSelect(vector selectionPos)
float GetMinZoom()
Get minimal zoom.
void SetMapWidget(Widget mapW)
Set map widget.
static ScriptInvokerBase< MapConfigurationInvoker > GetOnMapOpenComplete()
Get on map open complete invoker.
Widget GetMapMenuRoot()
Get map menu root widget.
static void GetGridPos(vector pos, out int gridX, out int gridZ, int resMin=2, int resMax=4)
void SetupLayersAndProps(inout MapConfiguration configObject, SCR_MapConfig mapCfg)
MapConfiguration GetMapConfig()
Get map config.
static ref ScriptInvokerBase< MapItemInvoker > s_OnHoverEnd
void ZoomUpdate(float timeSlice)
MapItem GetHoveredItem()
Get hovered item.
vector GetCurrentPan()
Get current DPIScaled pan offsets.
static ScriptInvokerVector GetOnSelection()
Get on selection invoker.
void ShowScriptDebug()
Show/hide debug info table.
bool IsZooming()
Get whether zoom interpolation is ongoing.
void CloseMap()
Close the map.
void ZoomSmooth(float targetPixPerUnit, float zoomTime=0.25, bool zoomToCenter=true, bool reinitZoom=false)
bool FitPanBounds(inout float panX, inout float panY, bool center)
EMapEntityMode m_eLastMapMode
static ScriptInvokerBase< MapItemInvoker > GetOnHoverItem()
Get on hover item invoker.
static ScriptInvokerInt GetOnLayerChanged()
Get on layer changed invoker.
void SetupDescriptorTypes(SCR_MapDescriptorDefaults descriptorDefaultsConfig)
ref array< ref SCR_MapModuleBase > m_aLoadedModules
void OpenMap(MapConfiguration config)
void GetMapCursorWorldPosition(out float worldX, out float worldY)
void InitDescriptors(int layerID, MapLayer layer, SCR_LayerConfiguration layerConfig, MapConfiguration mapConfig)
void ScreenToWorld(int screenPosX, int screenPosY, out float worldX, out float worldY)
Use scaled screen coords to get canvas world coords, flips the y-axis.
static ScriptInvokerBase< MapItemInvoker > GetOnHoverEnd()
Get on hover end invoker.
static ref ScriptInvokerBase< MapConfigurationInvoker > s_OnMapOpen
SCR_MapUIBaseComponent GetMapUIComponent(typename componentType)
void AssignViewLayer(bool isInit)
Checks whether layer should change based on current zoom.
float m_fZoomTimeModif
static ref ScriptInvokerFloat s_OnMapZoom
void WorldToScreen(float worldX, float worldY, out int screenPosX, out int screenPosY, bool withPan=false)
Use canvas world coords to get DPIscaled screen coords, flips the y-axis.
static ref ScriptInvokerBase< MapConfigurationInvoker > s_OnMapClose
void SetPan(float x, float y, bool isPanEnd=true, bool center=true, bool updatingPan=false)
void OnPlayerDeleted(int playerId, IEntity player)
static string GetGridLabel(vector pos, int resMin=2, int resMax=4, string delimiter=" ")
void PanSmooth(float panX, float panY, float panTime=0.25)
static ref ScriptInvokerBase< MapConfigurationInvoker > s_OnMapOpenComplete
ref MapConfiguration m_ActiveMapCfg
override void EOnInit(IEntity owner)
void UpdateMap(float timeSlice)
void OnMapClose()
Map close event.
static ref ScriptInvokerVector s_OnSelection
void DeactivateModule(SCR_MapModuleBase module)
Deactivate module, removing it from loadable list until config is reloaded.
void ActivateModules(array< ref SCR_MapModuleBase > modules)
bool IsOpen()
Check if the map is opened.
void ZoomOut()
Set minimal zoom and center the map.
void OnLifeStateChanged(ECharacterLifeState previousLifeState, ECharacterLifeState newLifeState)
float GetTargetZoomPPU()
Get target zoom in the form of PixelPerUnit value, which is different from current zoom if interpolat...
static ref ScriptInvokerFloat2 s_OnMapPanEnd
static ref ScriptInvokerBase< MapConfigurationInvoker > s_OnMapInit
static ScriptInvokerFloat GetOnMapZoomEnd()
Get on map zoom interpolated end invoker.
void SelectItem(MapItem item)
void InitLayers(MapConfiguration mapConfig)
Initialize layers from config.
void UpdateDebug()
Update map debug table.
void DeactivateComponent(SCR_MapUIBaseComponent component)
Deactivate UI component, removing it from loadable list until config is reloaded.
float GetMaxZoom()
Get maximal zoom.
static ScriptInvokerBase< MapConfigurationInvoker > GetOnMapInit()
Get on map init invoker, caution: called during the first frame of opening the map when widget relate...
vector m_vVisibleFrameMax
static ScriptInvokerBase< MapItemInvoker > GetOnSelectionChanged()
Get on selection changed invoker.
void CenterMap()
Center the map.
void ActivateComponents(array< ref SCR_MapUIBaseComponent > components)
WorkspaceWidget m_Workspace
static ScriptInvokerFloat2 GetOnMapPanEnd()
Get on map pan interpolated end invoker.
void HoverItem(MapItem item)
void ActivateOtherComponents(EMapOtherComponents componentFlags)
float GetCurrentZoom()
void PanUpdate(float timeSlice)
static ScriptInvokerBase< ScriptInvokerFloat2Bool > GetOnMapPan()
Get on map pan invoker.
void OnWindowResized(int width, int height, bool windowed)
Game event.
static ScriptInvokerFloat GetOnMapZoom()
Get on map zoom invoker.
void GetMapVisibleFrame(out vector min, out vector max)
Return visible frame in the form of min and max point, used to ignore update of f....
void OnMapOpen(MapConfiguration config)
void SCR_MapEntity(IEntitySource src, IEntity parent)
static ScriptInvokerBase< MapConfigurationInvoker > GetOnMapOpen()
Get on map open invoker.
void UpdateViewPort()
Updates view port.
void ZoomPanSmooth(float targetPixPerUnit, float worldX, float worldY, float zoomTime=0.25)
float m_fPanTimeModif
void ScreenToWorldNoFlip(int screenPosX, int screenPosY, out float worldX, out float worldY)
Use scaled screen coords to get canvas world coords without flipping the y-axis.
MapConfiguration SetupMapConfig(EMapEntityMode mapMode, ResourceName configPath, Widget rootWidget)
void Cleanup()
Map close cleanup.
void SetZoom(float targetPPU, bool instant=false)
static ref ScriptInvokerBase< MapItemInvoker > s_OnSelectionChanged
static SCR_MapEntity GetMapInstance()
Get map entity instance.
int GetMapSizeY()
Get map sizeY in meters.
void ClearHover()
Clear hover state.
void ClearSelection()
Clear selected items.
override void EOnFrame(IEntity owner, float timeSlice)
static ref ScriptInvokerFloat s_OnMapZoomEnd
int m_aTargetPan[2]
void WorldToScreenCustom(float worldX, float worldY, out int screenPosX, out int screenPosY, float targetPPU, bool withPan=false)
Use canvas world coords and defined pixel per unit to get DPIscaled screen coords,...
Layer config root.
Map module base class.
Map props root.
Property type base.
Definition Types.c:486
Game g_Game
Game singleton instance.
Definition gameLib.c:13
SCR_EditableEntityComponent GetControlledEntity()
CameraManagerClass GenericEntityClass CurrentCamera()
Returns the current camera.
ECharacterLifeState
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
EntityEvent
Various entity events.
Definition EntityEvent.c:14
proto external PlayerController GetPlayerController()
proto external void EnableGrid(bool bValue)
Enable/ Disable grid visibility.
proto external void InitializeLayers(int count, int factionSize=4)
Clear layer setup + set new layer count.
proto external vector Size()
Terrain dimensions (x, height = maxElevation-minElevation, z).
EMapDescriptorType
proto external int GetSelected(out notnull array< MapItem > outItems)
Get all selected entities.
void EnableLegend(bool bValue)
Enable/ Disable legend.
proto external void PosChange(float x, float y)
Set new pos of map.
proto external void ResetSelected()
Reset all entity selection.
proto external void SetLayer(int index)
Set active layer.
proto external vector Offset()
Starting offset of the map.
proto external int GetLayerIndex()
Returns -1 if no valid index previously set.
proto external void SetImagesetMapping(notnull array< int > values)
Sets corresponding multiple imageset indices for MapDescriptors usage.
proto external void SetFrame(vector start, vector end)
Set frame to visualise (from -> to).
proto external MapLayer GetLayer(int index)
Get layer by Index.
proto external void ZoomChange(float level)
Set new zoom.
proto external int LayerCount()
Get layer count.
proto external void EnableVisualisation(bool bValue)
Enable/ Disable visualisation.
MapEntityClass GenericEntityClass UpdateTexts()
proto external void ResetHighlighted()
Reset all entity highlighted tag.
proto external void ResetHovering()
Reset all entity hovering tag.
proto external int GetPlayerId()
proto native vector Vector(float x, float y, float z)