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/mapitems/envelope.h>
15#include <game/editor/mapitems/layer.h>
16
17#include <functional>
18#include <memory>
19#include <vector>
20
21class CEditor;
22class CEditorImage;
23class CEditorSound;
24class CLayerFront;
25class CLayerGroup;
26class CLayerGame;
27class CLayerImage;
28class CLayerSound;
29class CLayerSpeedup;
30class CLayerSwitch;
31class CLayerTele;
32class CLayerTune;
33class CQuad;
34class IEditorEnvelopeReference;
35
36class CDataFileWriterFinishJob : public IJob
37{
38 char m_aRealFilename[IO_MAX_PATH_LENGTH];
39 char m_aTempFilename[IO_MAX_PATH_LENGTH];
40 CDataFileWriter m_Writer;
41
42 void Run() override;
43
44public:
45 CDataFileWriterFinishJob(const char *pRealFilename, const char *pTempFilename, CDataFileWriter &&Writer);
46 const char *GetRealFilename() const { return m_aRealFilename; }
47 const char *GetTempFilename() const { return m_aTempFilename; }
48};
49
50using FErrorHandler = std::function<void(const char *pErrorMessage)>;
51
52class CEditorMap
53{
54public:
55 explicit CEditorMap(CEditor *pEditor) :
56 m_EditorHistory(this),
57 m_ServerSettingsHistory(this),
58 m_EnvelopeEditorHistory(this),
59 m_QuadTracker(this),
60 m_EnvOpTracker(this),
61 m_LayerGroupPropTracker(this),
62 m_LayerPropTracker(this),
63 m_LayerTilesCommonPropTracker(this),
64 m_LayerTilesPropTracker(this),
65 m_LayerQuadPropTracker(this),
66 m_LayerSoundsPropTracker(this),
67 m_SoundSourceOperationTracker(this),
68 m_SoundSourcePropTracker(this),
69 m_SoundSourceRectShapePropTracker(this),
70 m_SoundSourceCircleShapePropTracker(this),
71 m_pEditor(pEditor)
72 {
73 }
74
75 const CEditor *Editor() const { return m_pEditor; }
76 CEditor *Editor() { return m_pEditor; }
77
78 char m_aFilename[IO_MAX_PATH_LENGTH];
79 bool m_ValidSaveFilename;
80 /**
81 * Map has unsaved changes for manual save.
82 */
83 bool m_Modified;
84 /**
85 * Map has unsaved changes for autosave.
86 */
87 bool m_ModifiedAuto;
88 float m_LastModifiedTime;
89 float m_LastSaveTime;
90 void OnModify();
91 void ResetModifiedState();
92
93 std::vector<std::shared_ptr<CLayerGroup>> m_vpGroups;
94 std::vector<std::shared_ptr<CEditorImage>> m_vpImages;
95 std::vector<std::shared_ptr<CEnvelope>> m_vpEnvelopes;
96 std::vector<std::shared_ptr<CEditorSound>> m_vpSounds;
97 std::vector<CEditorMapSetting> m_vSettings;
98
99 std::shared_ptr<CLayerGroup> m_pGameGroup;
100 std::shared_ptr<CLayerGame> m_pGameLayer;
101 std::shared_ptr<CLayerTele> m_pTeleLayer;
102 std::shared_ptr<CLayerSpeedup> m_pSpeedupLayer;
103 std::shared_ptr<CLayerFront> m_pFrontLayer;
104 std::shared_ptr<CLayerSwitch> m_pSwitchLayer;
105 std::shared_ptr<CLayerTune> m_pTuneLayer;
106
107 class CMapInfo
108 {
109 public:
110 char m_aAuthor[32];
111 char m_aVersion[16];
112 char m_aCredits[128];
113 char m_aLicense[32];
114
115 void Reset();
116 void Copy(const CMapInfo &Source);
117 };
118 CMapInfo m_MapInfo;
119 CMapInfo m_MapInfoTmp;
120
121 // Undo/Redo
122 CEditorHistory m_EditorHistory;
123 CEditorHistory m_ServerSettingsHistory;
124 CEditorHistory m_EnvelopeEditorHistory;
125 CQuadEditTracker m_QuadTracker;
126 CEnvelopeEditorOperationTracker m_EnvOpTracker;
127 CLayerGroupPropTracker m_LayerGroupPropTracker;
128 CLayerPropTracker m_LayerPropTracker;
129 CLayerTilesCommonPropTracker m_LayerTilesCommonPropTracker;
130 CLayerTilesPropTracker m_LayerTilesPropTracker;
131 CLayerQuadsPropTracker m_LayerQuadPropTracker;
132 CLayerSoundsPropTracker m_LayerSoundsPropTracker;
133 CSoundSourceOperationTracker m_SoundSourceOperationTracker;
134 CSoundSourcePropTracker m_SoundSourcePropTracker;
135 CSoundSourceRectShapePropTracker m_SoundSourceRectShapePropTracker;
136 CSoundSourceCircleShapePropTracker m_SoundSourceCircleShapePropTracker;
137
138 // Selections
139 int m_SelectedGroup;
140 std::vector<int> m_vSelectedLayers;
141 std::vector<int> m_vSelectedQuads;
142 int m_SelectedQuadPoints;
143 int m_SelectedQuadEnvelope;
144 int m_CurrentQuadIndex;
145 int m_SelectedEnvelope;
146 bool m_UpdateEnvPointInfo;
147 std::vector<std::pair<int, int>> m_vSelectedEnvelopePoints;
148 std::pair<int, int> m_SelectedTangentInPoint;
149 std::pair<int, int> m_SelectedTangentOutPoint;
150 int m_SelectedImage;
151 int m_SelectedSound;
152 int m_SelectedSoundSource;
153
154 int m_ShiftBy;
155
156 // Quad knife
157 class CQuadKnife
158 {
159 public:
160 bool m_Active;
161 int m_SelectedQuadIndex;
162 int m_Count;
163 vec2 m_aPoints[4];
164 };
165 CQuadKnife m_QuadKnife;
166
167 // Housekeeping
168 void Clean();
169 void CreateDefault();
170 void CheckIntegrity();
171
172 // Indices
173 void ModifyImageIndex(const FIndexModifyFunction &IndexModifyFunction);
174 void ModifyEnvelopeIndex(const FIndexModifyFunction &IndexModifyFunction);
175 void ModifySoundIndex(const FIndexModifyFunction &IndexModifyFunction);
176
177 // I/O
178 bool Save(const char *pFilename, const FErrorHandler &ErrorHandler);
179 bool PerformPreSaveSanityChecks(const FErrorHandler &ErrorHandler);
180 bool Load(const char *pFilename, int StorageType, const FErrorHandler &ErrorHandler);
181 void PerformSanityChecks(const FErrorHandler &ErrorHandler);
182 bool PerformAutosave(const FErrorHandler &ErrorHandler);
183
184 // Groups
185 std::shared_ptr<CLayerGroup> SelectedGroup() const;
186 std::shared_ptr<CLayerGroup> NewGroup();
187 int MoveGroup(int IndexFrom, int IndexTo);
188 void DeleteGroup(int Index);
189 void MakeGameGroup(std::shared_ptr<CLayerGroup> pGroup);
190
191 // Layers
192 std::shared_ptr<CLayer> SelectedLayer(int Index) const;
193 std::shared_ptr<CLayer> SelectedLayerType(int Index, int Type) const;
194 void SelectLayer(int LayerIndex, int GroupIndex = -1);
195 void AddSelectedLayer(int LayerIndex);
196 void SelectNextLayer();
197 void SelectPreviousLayer();
198 void SelectGameLayer();
199 void MakeGameLayer(const std::shared_ptr<CLayer> &pLayer);
200 void MakeTeleLayer(const std::shared_ptr<CLayer> &pLayer);
201 void MakeSpeedupLayer(const std::shared_ptr<CLayer> &pLayer);
202 void MakeFrontLayer(const std::shared_ptr<CLayer> &pLayer);
203 void MakeSwitchLayer(const std::shared_ptr<CLayer> &pLayer);
204 void MakeTuneLayer(const std::shared_ptr<CLayer> &pLayer);
205
206 // Quads
207 std::vector<CQuad *> SelectedQuads();
208 bool IsQuadSelected(int Index) const;
209 int FindSelectedQuadIndex(int Index) const;
210 void SelectQuad(int Index);
211 void ToggleSelectQuad(int Index);
212 void DeselectQuads();
213 bool IsQuadCornerSelected(int Index) const;
214 bool IsQuadPointSelected(int QuadIndex, int Index) const;
215 void SelectQuadPoint(int QuadIndex, int Index);
216 void ToggleSelectQuadPoint(int QuadIndex, int Index);
217 void DeselectQuadPoints();
218 void DeleteSelectedQuads();
219
220 // Envelopes
221 std::shared_ptr<CEnvelope> NewEnvelope(CEnvelope::EType Type);
222 void InsertEnvelope(int Index, std::shared_ptr<CEnvelope> &pEnvelope);
223 void UpdateEnvelopeReferences(int Index, std::shared_ptr<CEnvelope> &pEnvelope, std::vector<std::shared_ptr<IEditorEnvelopeReference>> &vpEditorObjectReferences);
224 std::vector<std::shared_ptr<IEditorEnvelopeReference>> DeleteEnvelope(int Index);
225 int MoveEnvelope(int IndexFrom, int IndexTo);
226 template<typename F>
227 std::vector<std::shared_ptr<IEditorEnvelopeReference>> VisitEnvelopeReferences(F &&Visitor);
228 bool IsEnvelopeUsed(int EnvelopeIndex) const;
229 void RemoveUnusedEnvelopes();
230
231 // Envelope points
232 int FindEnvPointIndex(int Index, int Channel) const;
233 void SelectEnvPoint(int Index);
234 void SelectEnvPoint(int Index, int Channel);
235 void ToggleEnvPoint(int Index, int Channel);
236 bool IsEnvPointSelected(int Index, int Channel) const;
237 bool IsEnvPointSelected(int Index) const;
238 void DeselectEnvPoints();
239 bool IsTangentSelected() const;
240 bool IsTangentOutPointSelected(int Index, int Channel) const;
241 bool IsTangentOutSelected() const;
242 void SelectTangentOutPoint(int Index, int Channel);
243 bool IsTangentInPointSelected(int Index, int Channel) const;
244 bool IsTangentInSelected() const;
245 void SelectTangentInPoint(int Index, int Channel);
246 std::pair<CFixedTime, int> SelectedEnvelopeTimeAndValue() const;
247
248 // Images
249 std::shared_ptr<CEditorImage> SelectedImage() const;
250 void SelectImage(const std::shared_ptr<CEditorImage> &pImage);
251 void SelectNextImage();
252 void SelectPreviousImage();
253 bool IsImageUsed(int ImageIndex) const;
254 std::vector<int> SortImages();
255
256 // Sounds
257 std::shared_ptr<CEditorSound> SelectedSound() const;
258 void SelectSound(const std::shared_ptr<CEditorSound> &pSound);
259 void SelectNextSound();
260 void SelectPreviousSound();
261 bool IsSoundUsed(int SoundIndex) const;
262 CSoundSource *SelectedSoundSource() const;
263
264private:
265 CEditor *m_pEditor;
266};
267
268#endif
269