1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3#ifndef GAME_EDITOR_MAPITEMS_MAP_H
4#define GAME_EDITOR_MAPITEMS_MAP_H
5
6#include <base/types.h>
7
8#include <engine/shared/datafile.h>
9#include <engine/shared/jobs.h>
10
11#include <game/editor/editor_history.h>
12#include <game/editor/editor_server_settings.h>
13#include <game/editor/editor_trackers.h>
14#include <game/editor/editor_ui.h>
15#include <game/editor/envelope_editor.h>
16#include <game/editor/font_typer.h>
17#include <game/editor/map_grid.h>
18#include <game/editor/map_view.h>
19#include <game/editor/mapitems/envelope.h>
20#include <game/editor/mapitems/envelope_evaluator.h>
21#include <game/editor/mapitems/layer.h>
22#include <game/editor/proof_mode.h>
23#include <game/editor/quad_art.h>
24#include <game/editor/quad_knife.h>
25
26#include <functional>
27#include <memory>
28#include <vector>
29
30class CEditor;
31class CEditorImage;
32class CEditorSound;
33class CLayerFront;
34class CLayerGroup;
35class CLayerGame;
36class CLayerImage;
37class CLayerSound;
38class CLayerSpeedup;
39class CLayerSwitch;
40class CLayerTele;
41class CLayerTune;
42class CQuad;
43class IEditorEnvelopeReference;
44
45class CDataFileWriterFinishJob : public IJob
46{
47 IStorage *m_pStorage;
48 char m_aRealFilename[IO_MAX_PATH_LENGTH];
49 char m_aTempFilename[IO_MAX_PATH_LENGTH];
50 char m_aErrorMessage[2 * IO_MAX_PATH_LENGTH + 128];
51 CDataFileWriter m_Writer;
52
53 void Run() override;
54
55public:
56 CDataFileWriterFinishJob(IStorage *pStorage, const char *pRealFilename, const char *pTempFilename, CDataFileWriter &&Writer);
57 const char *RealFilename() const { return m_aRealFilename; }
58 const char *ErrorMessage() const { return m_aErrorMessage; }
59};
60
61using FErrorHandler = std::function<void(const char *pErrorMessage)>;
62
63class CEditorMap
64{
65public:
66 explicit CEditorMap(CEditor *pEditor);
67
68 const CEditor *Editor() const { return m_pEditor; }
69 CEditor *Editor() { return m_pEditor; }
70
71 /**
72 * Path and filename including extension within the storage system.
73 */
74 char m_aFilename[IO_MAX_PATH_LENGTH];
75 /**
76 * Unique name for displaying. Updated by the editor when open maps are changed to ensure it is unique.
77 */
78 char m_aDisplayName[IO_MAX_PATH_LENGTH];
79 /**
80 * Unique name for autosaving. Updated by the editor when open maps are changed to ensure it is unique.
81 */
82 char m_aAutosaveName[IO_MAX_PATH_LENGTH];
83 bool m_ValidSaveFilename;
84 bool m_CloseOnSave;
85 /**
86 * Map has unsaved changes for manual save.
87 */
88 bool m_Modified;
89 /**
90 * Map has unsaved changes for autosave.
91 */
92 bool m_ModifiedAuto;
93 float m_LastModifiedTime;
94 float m_LastSaveTime;
95 void OnModify();
96 void ResetModifiedState();
97
98 // UI elements
99 char m_TabSelectButtonId;
100 char m_TabCloseButtonId;
101
102 std::vector<std::shared_ptr<CLayerGroup>> m_vpGroups;
103 std::vector<std::shared_ptr<CEditorImage>> m_vpImages;
104 std::vector<std::shared_ptr<CEnvelope>> m_vpEnvelopes;
105 std::vector<std::shared_ptr<CEditorSound>> m_vpSounds;
106 std::vector<CEditorMapSetting> m_vSettings;
107
108 std::shared_ptr<CLayerGroup> m_pGameGroup;
109 std::shared_ptr<CLayerGame> m_pGameLayer;
110 std::shared_ptr<CLayerTele> m_pTeleLayer;
111 std::shared_ptr<CLayerSpeedup> m_pSpeedupLayer;
112 std::shared_ptr<CLayerFront> m_pFrontLayer;
113 std::shared_ptr<CLayerSwitch> m_pSwitchLayer;
114 std::shared_ptr<CLayerTune> m_pTuneLayer;
115
116 class CMapInfo
117 {
118 public:
119 char m_aAuthor[32];
120 char m_aVersion[16];
121 char m_aCredits[128];
122 char m_aLicense[32];
123
124 void Reset();
125 void Copy(const CMapInfo &Source);
126 };
127 CMapInfo m_MapInfo;
128 CMapInfo m_MapInfoTmp;
129
130 // Undo/Redo
131 CEditorHistory m_EditorHistory;
132 CEditorHistory m_ServerSettingsHistory;
133 CEditorHistory m_EnvelopeEditorHistory;
134 CQuadEditTracker m_QuadTracker;
135 CEnvelopeEditorOperationTracker m_EnvOpTracker;
136 CLayerGroupPropTracker m_LayerGroupPropTracker;
137 CLayerPropTracker m_LayerPropTracker;
138 CLayerTilesCommonPropTracker m_LayerTilesCommonPropTracker;
139 CLayerTilesPropTracker m_LayerTilesPropTracker;
140 CLayerQuadsPropTracker m_LayerQuadPropTracker;
141 CLayerSoundsPropTracker m_LayerSoundsPropTracker;
142 CSoundSourceOperationTracker m_SoundSourceOperationTracker;
143 CSoundSourcePropTracker m_SoundSourcePropTracker;
144 CSoundSourceRectShapePropTracker m_SoundSourceRectShapePropTracker;
145 CSoundSourceCircleShapePropTracker m_SoundSourceCircleShapePropTracker;
146
147 // Selections
148 int m_SelectedGroup;
149 std::vector<int> m_vSelectedLayers;
150 std::vector<int> m_vSelectedQuads;
151 int m_SelectedQuadPoints;
152 int m_SelectedQuadEnvelope;
153 int m_CurrentQuadIndex;
154 int m_SelectedEnvelope;
155 bool m_UpdateEnvPointInfo;
156 std::vector<std::pair<int, int>> m_vSelectedEnvelopePoints;
157 std::pair<int, int> m_SelectedTangentInPoint;
158 std::pair<int, int> m_SelectedTangentOutPoint;
159 int m_SelectedImage;
160 int m_SelectedSound;
161 int m_SelectedSoundSource;
162
163 int m_ShiftBy;
164 bool m_ShowDetail;
165 bool m_PreviewZoom;
166
167 // Component states
168 CMapView::CState m_MapViewState;
169 CMapGrid::CState m_MapGridState;
170 CProofMode::CState m_ProofModeState;
171 CQuadKnife::CState m_QuadKnifeState;
172 CMapEnvelopeEvaluator m_EnvelopeEvaluator;
173 CEnvelopeEditor::CState m_EnvelopeEditorState;
174 CMapSettingsBackend::CContextWithInput m_MapSettingsCommandContext;
175 CFontTyper::CState m_FontTyperState;
176 CEditorUiElements m_EditorUiElements;
177 CEditorHistoryUiState m_EditorHistoryUiState;
178
179 // Housekeeping
180 void CreateDefault();
181 void CheckIntegrity();
182
183 // Indices
184 void ModifyImageIndex(const FIndexModifyFunction &IndexModifyFunction);
185 void ModifyEnvelopeIndex(const FIndexModifyFunction &IndexModifyFunction);
186 void ModifySoundIndex(const FIndexModifyFunction &IndexModifyFunction);
187
188 // I/O
189 bool Save(const char *pFilename, const FErrorHandler &ErrorHandler);
190 bool PerformPreSaveSanityChecks(const FErrorHandler &ErrorHandler);
191 bool Load(const char *pFilename, int StorageType, const FErrorHandler &ErrorHandler);
192 bool Append(const char *pFilename, int StorageType, bool IgnoreHistory, const FErrorHandler &ErrorHandler);
193 void PerformSanityChecks(const FErrorHandler &ErrorHandler);
194 bool PerformAutosave(const FErrorHandler &ErrorHandler);
195
196 // Groups
197 std::shared_ptr<CLayerGroup> SelectedGroup() const;
198 std::shared_ptr<CLayerGroup> NewGroup();
199 int MoveGroup(int IndexFrom, int IndexTo);
200 void DeleteGroup(int Index);
201 void MakeGameGroup(std::shared_ptr<CLayerGroup> pGroup);
202
203 // Layers
204 std::shared_ptr<CLayer> SelectedLayer(int Index) const;
205 std::shared_ptr<CLayer> SelectedLayerType(int Index, int Type) const;
206 void SelectLayer(int LayerIndex, int GroupIndex = -1);
207 void AddSelectedLayer(int LayerIndex);
208 void SelectNextLayer();
209 void SelectPreviousLayer();
210 void SelectGameLayer();
211 void MakeGameLayer(const std::shared_ptr<CLayer> &pLayer);
212 void MakeTeleLayer(const std::shared_ptr<CLayer> &pLayer);
213 void MakeSpeedupLayer(const std::shared_ptr<CLayer> &pLayer);
214 void MakeFrontLayer(const std::shared_ptr<CLayer> &pLayer);
215 void MakeSwitchLayer(const std::shared_ptr<CLayer> &pLayer);
216 void MakeTuneLayer(const std::shared_ptr<CLayer> &pLayer);
217
218 // Quads
219 std::vector<CQuad *> SelectedQuads();
220 bool IsQuadSelected(int Index) const;
221 int FindSelectedQuadIndex(int Index) const;
222 void SelectQuad(int Index);
223 void ToggleSelectQuad(int Index);
224 void DeselectQuads();
225 bool IsQuadCornerSelected(int Index) const;
226 bool IsQuadPointSelected(int QuadIndex, int Index) const;
227 void SelectQuadPoint(int QuadIndex, int Index);
228 void ToggleSelectQuadPoint(int QuadIndex, int Index);
229 void DeselectQuadPoints();
230 void DeleteSelectedQuads();
231
232 // Envelopes
233 std::shared_ptr<CEnvelope> NewEnvelope(CEnvelope::EType Type);
234 void InsertEnvelope(int Index, std::shared_ptr<CEnvelope> &pEnvelope);
235 void UpdateEnvelopeReferences(int Index, std::shared_ptr<CEnvelope> &pEnvelope, std::vector<std::shared_ptr<IEditorEnvelopeReference>> &vpEditorObjectReferences);
236 std::vector<std::shared_ptr<IEditorEnvelopeReference>> DeleteEnvelope(int Index);
237 int MoveEnvelope(int IndexFrom, int IndexTo);
238 template<typename F>
239 std::vector<std::shared_ptr<IEditorEnvelopeReference>> VisitEnvelopeReferences(F &&Visitor);
240 bool IsEnvelopeUsed(int EnvelopeIndex) const;
241 void RemoveUnusedEnvelopes();
242
243 // Envelope points
244 int FindEnvPointIndex(int Index, int Channel) const;
245 void SelectEnvPoint(int Index);
246 void SelectEnvPoint(int Index, int Channel);
247 void ToggleEnvPoint(int Index, int Channel);
248 bool IsEnvPointSelected(int Index, int Channel) const;
249 bool IsEnvPointSelected(int Index) const;
250 void DeselectEnvPoints();
251 bool IsTangentSelected() const;
252 bool IsTangentOutPointSelected(int Index, int Channel) const;
253 bool IsTangentOutSelected() const;
254 void SelectTangentOutPoint(int Index, int Channel);
255 bool IsTangentInPointSelected(int Index, int Channel) const;
256 bool IsTangentInSelected() const;
257 void SelectTangentInPoint(int Index, int Channel);
258 std::pair<CFixedTime, int> SelectedEnvelopeTimeAndValue() const;
259
260 // Images
261 std::shared_ptr<CEditorImage> SelectedImage() const;
262 void SelectImage(const std::shared_ptr<CEditorImage> &pImage);
263 void SelectNextImage();
264 void SelectPreviousImage();
265 bool IsImageUsed(int ImageIndex) const;
266 std::vector<int> SortImages();
267
268 // Sounds
269 std::shared_ptr<CEditorSound> SelectedSound() const;
270 void SelectSound(const std::shared_ptr<CEditorSound> &pSound);
271 void SelectNextSound();
272 void SelectPreviousSound();
273 bool IsSoundUsed(int SoundIndex) const;
274 CSoundSource *SelectedSoundSource() const;
275
276 void PlaceBorderTiles();
277
278 void AddTileArt(CImageInfo &&Image, const char *pFilename, bool IgnoreHistory);
279
280 void AddQuadArt(CImageInfo &&Image, const CQuadArtParameters &Parameters, bool IgnoreHistory);
281
282private:
283 CEditor *m_pEditor;
284};
285
286#endif
287