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 | |
11 | void CMapView::Init(CEditor *pEditor) |
12 | { |
13 | CEditorComponent::Init(pEditor); |
14 | RegisterSubComponent(Component&: m_MapGrid); |
15 | RegisterSubComponent(Component&: m_ProofMode); |
16 | InitSubComponents(); |
17 | } |
18 | |
19 | void 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 | |
33 | void CMapView::OnMapLoad() |
34 | { |
35 | m_ProofMode.OnMapLoad(); |
36 | } |
37 | |
38 | bool 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 | |
46 | void 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 | |
54 | void 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 | |
83 | void 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 | |
132 | void CMapView::ResetZoom() |
133 | { |
134 | SetEditorOffset({0, 0}); |
135 | m_Zoom.SetValue(100.0f); |
136 | } |
137 | |
138 | float CMapView::ScaleLength(float Value) const |
139 | { |
140 | return m_WorldZoom * Value; |
141 | } |
142 | |
143 | void 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 | |
162 | void 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 | |
173 | CSmoothValue *CMapView::Zoom() |
174 | { |
175 | return &m_Zoom; |
176 | } |
177 | |
178 | const CSmoothValue *CMapView::Zoom() const |
179 | { |
180 | return &m_Zoom; |
181 | } |
182 | |
183 | CProofMode *CMapView::ProofMode() |
184 | { |
185 | return &m_ProofMode; |
186 | } |
187 | |
188 | const CProofMode *CMapView::ProofMode() const |
189 | { |
190 | return &m_ProofMode; |
191 | } |
192 | |
193 | CMapGrid *CMapView::MapGrid() |
194 | { |
195 | return &m_MapGrid; |
196 | } |
197 | |
198 | const CMapGrid *CMapView::MapGrid() const |
199 | { |
200 | return &m_MapGrid; |
201 | } |
202 | |
203 | void CMapView::OffsetWorld(vec2 Offset) |
204 | { |
205 | m_WorldOffset += Offset; |
206 | } |
207 | |
208 | void CMapView::OffsetEditor(vec2 Offset) |
209 | { |
210 | m_EditorOffset += Offset; |
211 | } |
212 | |
213 | void CMapView::SetWorldOffset(vec2 WorldOffset) |
214 | { |
215 | m_WorldOffset = WorldOffset; |
216 | } |
217 | |
218 | void CMapView::SetEditorOffset(vec2 EditorOffset) |
219 | { |
220 | m_EditorOffset = EditorOffset; |
221 | } |
222 | |
223 | vec2 CMapView::GetWorldOffset() const |
224 | { |
225 | return m_WorldOffset; |
226 | } |
227 | |
228 | vec2 CMapView::GetEditorOffset() const |
229 | { |
230 | return m_EditorOffset; |
231 | } |
232 | |
233 | float CMapView::GetWorldZoom() const |
234 | { |
235 | return m_WorldZoom; |
236 | } |
237 | |