1#include "map_view.h"
2
3#include <engine/keys.h>
4#include <engine/shared/config.h>
5
6#include <game/client/render.h>
7#include <game/client/ui.h>
8
9#include "editor.h"
10
11void CMapView::Init(CEditor *pEditor)
12{
13 CEditorComponent::Init(pEditor);
14 RegisterSubComponent(Component&: m_MapGrid);
15 RegisterSubComponent(Component&: m_ProofMode);
16 InitSubComponents();
17}
18
19void CMapView::OnReset()
20{
21 m_Zoom = CSmoothValue(200.0f, 10.0f, 2000.0f);
22 m_Zoom.Init(pEditor: Editor());
23 m_WorldZoom = 1.0f;
24
25 SetWorldOffset({0, 0});
26 SetEditorOffset({0, 0});
27
28 m_ProofMode.OnReset();
29 m_MapGrid.OnReset();
30 m_ShowPicker = false;
31}
32
33void CMapView::OnMapLoad()
34{
35 m_ProofMode.OnMapLoad();
36}
37
38bool CMapView::IsFocused()
39{
40 if(m_ProofMode.m_ProofBorders == CProofMode::PROOF_BORDER_MENU)
41 return GetWorldOffset() == m_ProofMode.m_vMenuBackgroundPositions[m_ProofMode.m_CurrentMenuProofIndex];
42 else
43 return GetWorldOffset() == vec2(0, 0);
44}
45
46void CMapView::Focus()
47{
48 if(m_ProofMode.m_ProofBorders == CProofMode::PROOF_BORDER_MENU)
49 SetWorldOffset(m_ProofMode.m_vMenuBackgroundPositions[m_ProofMode.m_CurrentMenuProofIndex]);
50 else
51 SetWorldOffset({0, 0});
52}
53
54void CMapView::RenderGroupBorder()
55{
56 std::shared_ptr<CLayerGroup> pGroup = Editor()->GetSelectedGroup();
57 if(pGroup)
58 {
59 pGroup->MapScreen();
60
61 for(size_t i = 0; i < Editor()->m_vSelectedLayers.size(); i++)
62 {
63 std::shared_ptr<CLayer> pLayer = Editor()->GetSelectedLayerType(Index: i, Type: LAYERTYPE_TILES);
64 if(pLayer)
65 {
66 float w, h;
67 pLayer->GetSize(pWidth: &w, pHeight: &h);
68
69 IGraphics::CLineItem aArray[4] = {
70 IGraphics::CLineItem(0, 0, w, 0),
71 IGraphics::CLineItem(w, 0, w, h),
72 IGraphics::CLineItem(w, h, 0, h),
73 IGraphics::CLineItem(0, h, 0, 0)};
74 Graphics()->TextureClear();
75 Graphics()->LinesBegin();
76 Graphics()->LinesDraw(pArray: aArray, Num: std::size(aArray));
77 Graphics()->LinesEnd();
78 }
79 }
80 }
81}
82
83void CMapView::RenderMap()
84{
85 if(Editor()->m_Dialog == DIALOG_NONE && CLineInput::GetActiveInput() == nullptr && Input()->ShiftIsPressed() && !Input()->ModifierIsPressed() && Input()->KeyPress(Key: KEY_G))
86 {
87 const bool AnyHidden =
88 !Editor()->m_Map.m_pGameLayer->m_Visible ||
89 (Editor()->m_Map.m_pFrontLayer && !Editor()->m_Map.m_pFrontLayer->m_Visible) ||
90 (Editor()->m_Map.m_pTeleLayer && !Editor()->m_Map.m_pTeleLayer->m_Visible) ||
91 (Editor()->m_Map.m_pSpeedupLayer && !Editor()->m_Map.m_pSpeedupLayer->m_Visible) ||
92 (Editor()->m_Map.m_pTuneLayer && !Editor()->m_Map.m_pTuneLayer->m_Visible) ||
93 (Editor()->m_Map.m_pSwitchLayer && !Editor()->m_Map.m_pSwitchLayer->m_Visible);
94 Editor()->m_Map.m_pGameLayer->m_Visible = AnyHidden;
95 if(Editor()->m_Map.m_pFrontLayer)
96 Editor()->m_Map.m_pFrontLayer->m_Visible = AnyHidden;
97 if(Editor()->m_Map.m_pTeleLayer)
98 Editor()->m_Map.m_pTeleLayer->m_Visible = AnyHidden;
99 if(Editor()->m_Map.m_pSpeedupLayer)
100 Editor()->m_Map.m_pSpeedupLayer->m_Visible = AnyHidden;
101 if(Editor()->m_Map.m_pTuneLayer)
102 Editor()->m_Map.m_pTuneLayer->m_Visible = AnyHidden;
103 if(Editor()->m_Map.m_pSwitchLayer)
104 Editor()->m_Map.m_pSwitchLayer->m_Visible = AnyHidden;
105 }
106
107 for(auto &pGroup : Editor()->m_Map.m_vpGroups)
108 {
109 if(pGroup->m_Visible)
110 pGroup->Render();
111 }
112
113 // render the game, tele, speedup, front, tune and switch above everything else
114 if(Editor()->m_Map.m_pGameGroup->m_Visible)
115 {
116 Editor()->m_Map.m_pGameGroup->MapScreen();
117 for(auto &pLayer : Editor()->m_Map.m_pGameGroup->m_vpLayers)
118 {
119 if(pLayer->m_Visible && pLayer->IsEntitiesLayer())
120 pLayer->Render();
121 }
122 }
123
124 std::shared_ptr<CLayerTiles> pSelectedTilesLayer = std::static_pointer_cast<CLayerTiles>(r: Editor()->GetSelectedLayerType(Index: 0, Type: LAYERTYPE_TILES));
125 if(Editor()->m_ShowTileInfo != CEditor::SHOW_TILE_OFF && pSelectedTilesLayer && pSelectedTilesLayer->m_Visible && m_Zoom.GetValue() <= 300.0f)
126 {
127 Editor()->GetSelectedGroup()->MapScreen();
128 pSelectedTilesLayer->ShowInfo();
129 }
130}
131
132void CMapView::ResetZoom()
133{
134 SetEditorOffset({0, 0});
135 m_Zoom.SetValue(100.0f);
136}
137
138float CMapView::ScaleLength(float Value) const
139{
140 return m_WorldZoom * Value;
141}
142
143void CMapView::ZoomMouseTarget(float ZoomFactor)
144{
145 // zoom to the current mouse position
146 // get absolute mouse position
147 float aPoints[4];
148 RenderTools()->MapScreenToWorld(
149 CenterX: GetWorldOffset().x, CenterY: GetWorldOffset().y,
150 ParallaxX: 100.0f, ParallaxY: 100.0f, ParallaxZoom: 100.0f, OffsetX: 0.0f, OffsetY: 0.0f, Aspect: Graphics()->ScreenAspect(), Zoom: m_WorldZoom, pPoints: aPoints);
151
152 float WorldWidth = aPoints[2] - aPoints[0];
153 float WorldHeight = aPoints[3] - aPoints[1];
154
155 float Mwx = aPoints[0] + WorldWidth * (Ui()->MouseX() / Ui()->Screen()->w);
156 float Mwy = aPoints[1] + WorldHeight * (Ui()->MouseY() / Ui()->Screen()->h);
157
158 // adjust camera
159 OffsetWorld(Offset: (vec2(Mwx, Mwy) - GetWorldOffset()) * (1.0f - ZoomFactor));
160}
161
162void CMapView::UpdateZoom()
163{
164 float OldLevel = m_Zoom.GetValue();
165 bool UpdatedZoom = m_Zoom.UpdateValue();
166 m_Zoom.SetValueRange(MinValue: 10.0f, MaxValue: g_Config.m_EdLimitMaxZoomLevel ? 2000.0f : std::numeric_limits<float>::max());
167 float NewLevel = m_Zoom.GetValue();
168 if(UpdatedZoom && g_Config.m_EdZoomTarget)
169 ZoomMouseTarget(ZoomFactor: NewLevel / OldLevel);
170 m_WorldZoom = NewLevel / 100.0f;
171}
172
173CSmoothValue *CMapView::Zoom()
174{
175 return &m_Zoom;
176}
177
178const CSmoothValue *CMapView::Zoom() const
179{
180 return &m_Zoom;
181}
182
183CProofMode *CMapView::ProofMode()
184{
185 return &m_ProofMode;
186}
187
188const CProofMode *CMapView::ProofMode() const
189{
190 return &m_ProofMode;
191}
192
193CMapGrid *CMapView::MapGrid()
194{
195 return &m_MapGrid;
196}
197
198const CMapGrid *CMapView::MapGrid() const
199{
200 return &m_MapGrid;
201}
202
203void CMapView::OffsetWorld(vec2 Offset)
204{
205 m_WorldOffset += Offset;
206}
207
208void CMapView::OffsetEditor(vec2 Offset)
209{
210 m_EditorOffset += Offset;
211}
212
213void CMapView::SetWorldOffset(vec2 WorldOffset)
214{
215 m_WorldOffset = WorldOffset;
216}
217
218void CMapView::SetEditorOffset(vec2 EditorOffset)
219{
220 m_EditorOffset = EditorOffset;
221}
222
223vec2 CMapView::GetWorldOffset() const
224{
225 return m_WorldOffset;
226}
227
228vec2 CMapView::GetEditorOffset() const
229{
230 return m_EditorOffset;
231}
232
233float CMapView::GetWorldZoom() const
234{
235 return m_WorldZoom;
236}
237