1 | #include "editor_trackers.h" |
2 | |
3 | #include <game/editor/mapitems/layer_group.h> |
4 | #include <game/editor/mapitems/layer_tiles.h> |
5 | |
6 | #include "editor.h" |
7 | #include "editor_actions.h" |
8 | |
9 | CQuadEditTracker::CQuadEditTracker() : |
10 | m_pEditor(nullptr), m_TrackedProp(EQuadProp::PROP_NONE) {} |
11 | |
12 | CQuadEditTracker::~CQuadEditTracker() |
13 | { |
14 | m_InitalPoints.clear(); |
15 | m_vSelectedQuads.clear(); |
16 | } |
17 | |
18 | void CQuadEditTracker::BeginQuadTrack(const std::shared_ptr<CLayerQuads> &pLayer, const std::vector<int> &vSelectedQuads, int GroupIndex, int LayerIndex) |
19 | { |
20 | if(m_Tracking) |
21 | return; |
22 | m_Tracking = true; |
23 | m_vSelectedQuads.clear(); |
24 | m_pLayer = pLayer; |
25 | m_GroupIndex = GroupIndex < 0 ? m_pEditor->m_SelectedGroup : GroupIndex; |
26 | m_LayerIndex = LayerIndex < 0 ? m_pEditor->m_vSelectedLayers[0] : LayerIndex; |
27 | // Init all points |
28 | for(auto QuadIndex : vSelectedQuads) |
29 | { |
30 | auto &pQuad = pLayer->m_vQuads[QuadIndex]; |
31 | m_InitalPoints[QuadIndex] = std::vector<CPoint>(pQuad.m_aPoints, pQuad.m_aPoints + 5); |
32 | m_vSelectedQuads.push_back(x: QuadIndex); |
33 | } |
34 | } |
35 | |
36 | void CQuadEditTracker::EndQuadTrack() |
37 | { |
38 | if(!m_Tracking) |
39 | return; |
40 | m_Tracking = false; |
41 | |
42 | // Record all moved stuff |
43 | std::vector<std::shared_ptr<IEditorAction>> vpActions; |
44 | for(auto QuadIndex : m_vSelectedQuads) |
45 | { |
46 | auto &pQuad = m_pLayer->m_vQuads[QuadIndex]; |
47 | auto vCurrentPoints = std::vector<CPoint>(pQuad.m_aPoints, pQuad.m_aPoints + 5); |
48 | vpActions.push_back(x: std::make_shared<CEditorActionEditQuadPoint>(args&: m_pEditor, args&: m_GroupIndex, args&: m_LayerIndex, args&: QuadIndex, args&: m_InitalPoints[QuadIndex], args&: vCurrentPoints)); |
49 | } |
50 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionBulk>(args&: m_pEditor, args&: vpActions)); |
51 | } |
52 | |
53 | void CQuadEditTracker::BeginQuadPropTrack(const std::shared_ptr<CLayerQuads> &pLayer, const std::vector<int> &vSelectedQuads, EQuadProp Prop, int GroupIndex, int LayerIndex) |
54 | { |
55 | if(m_TrackedProp != EQuadProp::PROP_NONE) |
56 | return; |
57 | m_TrackedProp = Prop; |
58 | m_pLayer = pLayer; |
59 | m_GroupIndex = GroupIndex < 0 ? m_pEditor->m_SelectedGroup : GroupIndex; |
60 | m_LayerIndex = LayerIndex < 0 ? m_pEditor->m_vSelectedLayers[0] : LayerIndex; |
61 | m_vSelectedQuads = vSelectedQuads; |
62 | m_PreviousValues.clear(); |
63 | |
64 | for(auto QuadIndex : vSelectedQuads) |
65 | { |
66 | auto &Quad = pLayer->m_vQuads[QuadIndex]; |
67 | if(Prop == EQuadProp::PROP_POS_X || Prop == EQuadProp::PROP_POS_Y) |
68 | m_InitalPoints[QuadIndex] = std::vector<CPoint>(Quad.m_aPoints, Quad.m_aPoints + 5); |
69 | else if(Prop == EQuadProp::PROP_POS_ENV) |
70 | m_PreviousValues[QuadIndex] = Quad.m_PosEnv; |
71 | else if(Prop == EQuadProp::PROP_POS_ENV_OFFSET) |
72 | m_PreviousValues[QuadIndex] = Quad.m_PosEnvOffset; |
73 | else if(Prop == EQuadProp::PROP_COLOR_ENV) |
74 | m_PreviousValues[QuadIndex] = Quad.m_ColorEnv; |
75 | else if(Prop == EQuadProp::PROP_COLOR_ENV_OFFSET) |
76 | m_PreviousValues[QuadIndex] = Quad.m_ColorEnvOffset; |
77 | } |
78 | } |
79 | void CQuadEditTracker::EndQuadPropTrack(EQuadProp Prop) |
80 | { |
81 | if(m_TrackedProp != Prop) |
82 | return; |
83 | m_TrackedProp = EQuadProp::PROP_NONE; |
84 | |
85 | std::vector<std::shared_ptr<IEditorAction>> vpActions; |
86 | |
87 | for(auto QuadIndex : m_vSelectedQuads) |
88 | { |
89 | auto &Quad = m_pLayer->m_vQuads[QuadIndex]; |
90 | if(Prop == EQuadProp::PROP_POS_X || Prop == EQuadProp::PROP_POS_Y) |
91 | { |
92 | auto vCurrentPoints = std::vector<CPoint>(Quad.m_aPoints, Quad.m_aPoints + 5); |
93 | vpActions.push_back(x: std::make_shared<CEditorActionEditQuadPoint>(args&: m_pEditor, args&: m_GroupIndex, args&: m_LayerIndex, args&: QuadIndex, args&: m_InitalPoints[QuadIndex], args&: vCurrentPoints)); |
94 | } |
95 | else |
96 | { |
97 | int Value = 0; |
98 | if(Prop == EQuadProp::PROP_POS_ENV) |
99 | Value = Quad.m_PosEnv; |
100 | else if(Prop == EQuadProp::PROP_POS_ENV_OFFSET) |
101 | Value = Quad.m_PosEnvOffset; |
102 | else if(Prop == EQuadProp::PROP_COLOR_ENV) |
103 | Value = Quad.m_ColorEnv; |
104 | else if(Prop == EQuadProp::PROP_COLOR_ENV_OFFSET) |
105 | Value = Quad.m_ColorEnvOffset; |
106 | |
107 | if(Value != m_PreviousValues[QuadIndex]) |
108 | vpActions.push_back(x: std::make_shared<CEditorActionEditQuadProp>(args&: m_pEditor, args&: m_GroupIndex, args&: m_LayerIndex, args&: QuadIndex, args&: Prop, args&: m_PreviousValues[QuadIndex], args&: Value)); |
109 | } |
110 | } |
111 | |
112 | if(!vpActions.empty()) |
113 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionBulk>(args&: m_pEditor, args&: vpActions)); |
114 | } |
115 | |
116 | void CQuadEditTracker::BeginQuadPointPropTrack(const std::shared_ptr<CLayerQuads> &pLayer, const std::vector<int> &vSelectedQuads, int SelectedQuadPoints, int GroupIndex, int LayerIndex) |
117 | { |
118 | if(!m_vTrackedProps.empty()) |
119 | return; |
120 | |
121 | m_pLayer = pLayer; |
122 | m_GroupIndex = GroupIndex < 0 ? m_pEditor->m_SelectedGroup : GroupIndex; |
123 | m_LayerIndex = LayerIndex < 0 ? m_pEditor->m_vSelectedLayers[0] : LayerIndex; |
124 | m_SelectedQuadPoints = SelectedQuadPoints; |
125 | m_vSelectedQuads = vSelectedQuads; |
126 | m_PreviousValuesPoint.clear(); |
127 | |
128 | for(auto QuadIndex : vSelectedQuads) |
129 | { |
130 | m_PreviousValuesPoint[QuadIndex] = std::vector<std::map<EQuadPointProp, int>>(4); |
131 | } |
132 | } |
133 | |
134 | void CQuadEditTracker::AddQuadPointPropTrack(EQuadPointProp Prop) |
135 | { |
136 | if(std::find(first: m_vTrackedProps.begin(), last: m_vTrackedProps.end(), val: Prop) != m_vTrackedProps.end()) |
137 | return; |
138 | |
139 | m_vTrackedProps.push_back(x: Prop); |
140 | |
141 | for(auto QuadIndex : m_vSelectedQuads) |
142 | { |
143 | auto &Quad = m_pLayer->m_vQuads[QuadIndex]; |
144 | if(Prop == EQuadPointProp::PROP_POS_X || Prop == EQuadPointProp::PROP_POS_Y) |
145 | m_InitalPoints[QuadIndex] = std::vector<CPoint>(Quad.m_aPoints, Quad.m_aPoints + 5); |
146 | else if(Prop == EQuadPointProp::PROP_COLOR) |
147 | { |
148 | for(int v = 0; v < 4; v++) |
149 | { |
150 | if(m_SelectedQuadPoints & (1 << v)) |
151 | { |
152 | int Color = PackColor(Color: Quad.m_aColors[v]); |
153 | m_PreviousValuesPoint[QuadIndex][v][Prop] = Color; |
154 | } |
155 | } |
156 | } |
157 | else if(Prop == EQuadPointProp::PROP_TEX_U) |
158 | { |
159 | for(int v = 0; v < 4; v++) |
160 | { |
161 | if(m_SelectedQuadPoints & (1 << v)) |
162 | { |
163 | m_PreviousValuesPoint[QuadIndex][v][Prop] = Quad.m_aTexcoords[v].x; |
164 | } |
165 | } |
166 | } |
167 | else if(Prop == EQuadPointProp::PROP_TEX_V) |
168 | { |
169 | for(int v = 0; v < 4; v++) |
170 | { |
171 | if(m_SelectedQuadPoints & (1 << v)) |
172 | { |
173 | m_PreviousValuesPoint[QuadIndex][v][Prop] = Quad.m_aTexcoords[v].y; |
174 | } |
175 | } |
176 | } |
177 | } |
178 | } |
179 | |
180 | void CQuadEditTracker::EndQuadPointPropTrack(EQuadPointProp Prop) |
181 | { |
182 | auto It = std::find(first: m_vTrackedProps.begin(), last: m_vTrackedProps.end(), val: Prop); |
183 | if(It == m_vTrackedProps.end()) |
184 | return; |
185 | |
186 | m_vTrackedProps.erase(position: It); |
187 | |
188 | std::vector<std::shared_ptr<IEditorAction>> vpActions; |
189 | |
190 | for(auto QuadIndex : m_vSelectedQuads) |
191 | { |
192 | auto &Quad = m_pLayer->m_vQuads[QuadIndex]; |
193 | if(Prop == EQuadPointProp::PROP_POS_X || Prop == EQuadPointProp::PROP_POS_Y) |
194 | { |
195 | auto vCurrentPoints = std::vector<CPoint>(Quad.m_aPoints, Quad.m_aPoints + 5); |
196 | vpActions.push_back(x: std::make_shared<CEditorActionEditQuadPoint>(args&: m_pEditor, args&: m_GroupIndex, args&: m_LayerIndex, args&: QuadIndex, args&: m_InitalPoints[QuadIndex], args&: vCurrentPoints)); |
197 | } |
198 | else |
199 | { |
200 | int Value = 0; |
201 | for(int v = 0; v < 4; v++) |
202 | { |
203 | if(m_SelectedQuadPoints & (1 << v)) |
204 | { |
205 | if(Prop == EQuadPointProp::PROP_COLOR) |
206 | { |
207 | Value = PackColor(Color: Quad.m_aColors[v]); |
208 | } |
209 | else if(Prop == EQuadPointProp::PROP_TEX_U) |
210 | { |
211 | Value = Quad.m_aTexcoords[v].x; |
212 | } |
213 | else if(Prop == EQuadPointProp::PROP_TEX_V) |
214 | { |
215 | Value = Quad.m_aTexcoords[v].y; |
216 | } |
217 | |
218 | if(Value != m_PreviousValuesPoint[QuadIndex][v][Prop]) |
219 | vpActions.push_back(x: std::make_shared<CEditorActionEditQuadPointProp>(args&: m_pEditor, args&: m_GroupIndex, args&: m_LayerIndex, args&: QuadIndex, args&: v, args&: Prop, args&: m_PreviousValuesPoint[QuadIndex][v][Prop], args&: Value)); |
220 | } |
221 | } |
222 | } |
223 | } |
224 | |
225 | if(!vpActions.empty()) |
226 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionBulk>(args&: m_pEditor, args&: vpActions)); |
227 | } |
228 | |
229 | void CQuadEditTracker::EndQuadPointPropTrackAll() |
230 | { |
231 | std::vector<std::shared_ptr<IEditorAction>> vpActions; |
232 | for(auto &Prop : m_vTrackedProps) |
233 | { |
234 | for(auto QuadIndex : m_vSelectedQuads) |
235 | { |
236 | auto &Quad = m_pLayer->m_vQuads[QuadIndex]; |
237 | if(Prop == EQuadPointProp::PROP_POS_X || Prop == EQuadPointProp::PROP_POS_Y) |
238 | { |
239 | auto vCurrentPoints = std::vector<CPoint>(Quad.m_aPoints, Quad.m_aPoints + 5); |
240 | vpActions.push_back(x: std::make_shared<CEditorActionEditQuadPoint>(args&: m_pEditor, args&: m_GroupIndex, args&: m_LayerIndex, args&: QuadIndex, args&: m_InitalPoints[QuadIndex], args&: vCurrentPoints)); |
241 | } |
242 | else |
243 | { |
244 | int Value = 0; |
245 | for(int v = 0; v < 4; v++) |
246 | { |
247 | if(m_SelectedQuadPoints & (1 << v)) |
248 | { |
249 | if(Prop == EQuadPointProp::PROP_COLOR) |
250 | { |
251 | Value = PackColor(Color: Quad.m_aColors[v]); |
252 | } |
253 | else if(Prop == EQuadPointProp::PROP_TEX_U) |
254 | { |
255 | Value = Quad.m_aTexcoords[v].x; |
256 | } |
257 | else if(Prop == EQuadPointProp::PROP_TEX_V) |
258 | { |
259 | Value = Quad.m_aTexcoords[v].y; |
260 | } |
261 | |
262 | if(Value != m_PreviousValuesPoint[QuadIndex][v][Prop]) |
263 | vpActions.push_back(x: std::make_shared<CEditorActionEditQuadPointProp>(args&: m_pEditor, args&: m_GroupIndex, args&: m_LayerIndex, args&: QuadIndex, args&: v, args&: Prop, args&: m_PreviousValuesPoint[QuadIndex][v][Prop], args&: Value)); |
264 | } |
265 | } |
266 | } |
267 | } |
268 | } |
269 | |
270 | if(!vpActions.empty()) |
271 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionBulk>(args&: m_pEditor, args&: vpActions)); |
272 | |
273 | m_vTrackedProps.clear(); |
274 | } |
275 | |
276 | // ----------------------------- |
277 | |
278 | void CEnvelopeEditorOperationTracker::Begin(EEnvelopeEditorOp Operation) |
279 | { |
280 | if(m_TrackedOp == Operation) |
281 | return; |
282 | |
283 | if(m_TrackedOp != EEnvelopeEditorOp::OP_NONE) |
284 | { |
285 | Stop(Switch: true); |
286 | } |
287 | |
288 | m_TrackedOp = Operation; |
289 | |
290 | if(Operation == EEnvelopeEditorOp::OP_DRAG_POINT || Operation == EEnvelopeEditorOp::OP_DRAG_POINT_X || Operation == EEnvelopeEditorOp::OP_DRAG_POINT_Y || Operation == EEnvelopeEditorOp::OP_SCALE) |
291 | { |
292 | HandlePointDragStart(); |
293 | } |
294 | } |
295 | |
296 | void CEnvelopeEditorOperationTracker::Stop(bool Switch) |
297 | { |
298 | if(m_TrackedOp == EEnvelopeEditorOp::OP_NONE) |
299 | return; |
300 | |
301 | if(m_TrackedOp == EEnvelopeEditorOp::OP_DRAG_POINT || m_TrackedOp == EEnvelopeEditorOp::OP_DRAG_POINT_X || m_TrackedOp == EEnvelopeEditorOp::OP_DRAG_POINT_Y || m_TrackedOp == EEnvelopeEditorOp::OP_SCALE) |
302 | { |
303 | HandlePointDragEnd(Switch); |
304 | } |
305 | |
306 | m_TrackedOp = EEnvelopeEditorOp::OP_NONE; |
307 | } |
308 | |
309 | void CEnvelopeEditorOperationTracker::HandlePointDragStart() |
310 | { |
311 | // Figure out which points are selected and which channels |
312 | // Save their X and Y position (time and value) |
313 | auto pEnv = m_pEditor->m_Map.m_vpEnvelopes[m_pEditor->m_SelectedEnvelope]; |
314 | |
315 | for(auto [PointIndex, Channel] : m_pEditor->m_vSelectedEnvelopePoints) |
316 | { |
317 | auto &Point = pEnv->m_vPoints[PointIndex]; |
318 | auto &Data = m_SavedValues[PointIndex]; |
319 | Data.m_Values[Channel] = Point.m_aValues[Channel]; |
320 | if(Data.m_Used) |
321 | continue; |
322 | Data.m_Time = Point.m_Time; |
323 | Data.m_Used = true; |
324 | } |
325 | } |
326 | |
327 | void CEnvelopeEditorOperationTracker::HandlePointDragEnd(bool Switch) |
328 | { |
329 | if(Switch && m_TrackedOp != EEnvelopeEditorOp::OP_SCALE) |
330 | return; |
331 | |
332 | int EnvIndex = m_pEditor->m_SelectedEnvelope; |
333 | auto pEnv = m_pEditor->m_Map.m_vpEnvelopes[EnvIndex]; |
334 | std::vector<std::shared_ptr<IEditorAction>> vpActions; |
335 | |
336 | for(auto const &Entry : m_SavedValues) |
337 | { |
338 | int PointIndex = Entry.first; |
339 | auto &Point = pEnv->m_vPoints[PointIndex]; |
340 | const auto &Data = Entry.second; |
341 | |
342 | if(Data.m_Time != Point.m_Time) |
343 | { // Save time |
344 | vpActions.push_back(x: std::make_shared<CEditorActionEnvelopeEditPoint>(args&: m_pEditor, args&: EnvIndex, args&: PointIndex, args: 0, args: CEditorActionEnvelopeEditPoint::EEditType::TIME, args: Data.m_Time, args&: Point.m_Time)); |
345 | } |
346 | |
347 | for(auto Value : Data.m_Values) |
348 | { |
349 | // Value.second is the saved value, Value.first is the channel |
350 | int Channel = Value.first; |
351 | if(Value.second != Point.m_aValues[Channel]) |
352 | { // Save value |
353 | vpActions.push_back(x: std::make_shared<CEditorActionEnvelopeEditPoint>(args&: m_pEditor, args&: EnvIndex, args&: PointIndex, args&: Channel, args: CEditorActionEnvelopeEditPoint::EEditType::VALUE, args&: Value.second, args&: Point.m_aValues[Channel])); |
354 | } |
355 | } |
356 | } |
357 | |
358 | if(!vpActions.empty()) |
359 | { |
360 | m_pEditor->m_EnvelopeEditorHistory.RecordAction(pAction: std::make_shared<CEditorActionBulk>(args&: m_pEditor, args&: vpActions, args: "Envelope point drag" )); |
361 | } |
362 | |
363 | m_SavedValues.clear(); |
364 | } |
365 | |
366 | // ----------------------------------------------------------------------- |
367 | CSoundSourceOperationTracker::CSoundSourceOperationTracker(CEditor *pEditor) : |
368 | m_pEditor(pEditor), m_pSource(nullptr), m_TrackedOp(ESoundSourceOp::OP_NONE), m_LayerIndex(-1) |
369 | { |
370 | } |
371 | |
372 | void CSoundSourceOperationTracker::Begin(CSoundSource *pSource, ESoundSourceOp Operation, int LayerIndex) |
373 | { |
374 | if(m_TrackedOp == Operation || m_TrackedOp != ESoundSourceOp::OP_NONE) |
375 | return; |
376 | |
377 | m_TrackedOp = Operation; |
378 | m_pSource = pSource; |
379 | m_LayerIndex = LayerIndex; |
380 | |
381 | if(m_TrackedOp == ESoundSourceOp::OP_MOVE) |
382 | HandlePointMove(State: EState::STATE_BEGIN); |
383 | } |
384 | |
385 | void CSoundSourceOperationTracker::End() |
386 | { |
387 | if(m_TrackedOp == ESoundSourceOp::OP_NONE) |
388 | return; |
389 | |
390 | if(m_TrackedOp == ESoundSourceOp::OP_MOVE) |
391 | HandlePointMove(State: EState::STATE_END); |
392 | |
393 | m_TrackedOp = ESoundSourceOp::OP_NONE; |
394 | } |
395 | |
396 | void CSoundSourceOperationTracker::HandlePointMove(EState State) |
397 | { |
398 | if(State == EState::STATE_BEGIN) |
399 | { |
400 | m_Data.m_OriginalPoint = m_pSource->m_Position; |
401 | } |
402 | else if(State == EState::STATE_END) |
403 | { |
404 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionMoveSoundSource>(args&: m_pEditor, args&: m_pEditor->m_SelectedGroup, args&: m_LayerIndex, args&: m_pEditor->m_SelectedSource, args&: m_Data.m_OriginalPoint, args&: m_pSource->m_Position)); |
405 | } |
406 | } |
407 | |
408 | // ----------------------------------------------------------------------- |
409 | |
410 | int SPropTrackerHelper::GetDefaultGroupIndex(CEditor *pEditor) |
411 | { |
412 | return pEditor->m_SelectedGroup; |
413 | } |
414 | |
415 | int SPropTrackerHelper::GetDefaultLayerIndex(CEditor *pEditor) |
416 | { |
417 | return pEditor->m_vSelectedLayers[0]; |
418 | } |
419 | |
420 | // ----------------------------------------------------------------------- |
421 | |
422 | void CLayerPropTracker::OnEnd(ELayerProp Prop, int Value) |
423 | { |
424 | if(Prop == ELayerProp::PROP_GROUP) |
425 | { |
426 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionEditLayersGroupAndOrder>(args&: m_pEditor, args&: m_OriginalGroupIndex, args: std::vector<int>{m_OriginalLayerIndex}, args&: m_CurrentGroupIndex, args: std::vector<int>{m_CurrentLayerIndex})); |
427 | } |
428 | else |
429 | { |
430 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionEditLayerProp>(args&: m_pEditor, args&: m_CurrentGroupIndex, args&: m_CurrentLayerIndex, args&: Prop, args&: m_OriginalValue, args&: Value)); |
431 | } |
432 | } |
433 | |
434 | int CLayerPropTracker::PropToValue(ELayerProp Prop) |
435 | { |
436 | switch(Prop) |
437 | { |
438 | case ELayerProp::PROP_GROUP: return m_CurrentGroupIndex; |
439 | case ELayerProp::PROP_HQ: return m_pObject->m_Flags; |
440 | case ELayerProp::PROP_ORDER: return m_CurrentLayerIndex; |
441 | default: return 0; |
442 | } |
443 | } |
444 | |
445 | // ----------------------------------------------------------------------- |
446 | |
447 | bool CLayerTilesPropTracker::EndChecker(ETilesProp Prop, EEditState State, int Value) |
448 | { |
449 | return (State == EEditState::END || State == EEditState::ONE_GO) && (Value != m_OriginalValue || Prop == ETilesProp::PROP_SHIFT); |
450 | } |
451 | |
452 | void CLayerTilesPropTracker::OnStart(ETilesProp Prop) |
453 | { |
454 | if(Prop == ETilesProp::PROP_WIDTH || Prop == ETilesProp::PROP_HEIGHT) |
455 | { |
456 | m_SavedLayers[LAYERTYPE_TILES] = m_pObject->Duplicate(); |
457 | if(m_pObject->m_Game || m_pObject->m_Front || m_pObject->m_Switch || m_pObject->m_Speedup || m_pObject->m_Tune || m_pObject->m_Tele) |
458 | { // Need to save all entities layers when any entity layer |
459 | if(m_pEditor->m_Map.m_pFrontLayer && !m_pObject->m_Front) |
460 | m_SavedLayers[LAYERTYPE_FRONT] = m_pEditor->m_Map.m_pFrontLayer->Duplicate(); |
461 | if(m_pEditor->m_Map.m_pTeleLayer && !m_pObject->m_Tele) |
462 | m_SavedLayers[LAYERTYPE_TELE] = m_pEditor->m_Map.m_pTeleLayer->Duplicate(); |
463 | if(m_pEditor->m_Map.m_pSwitchLayer && !m_pObject->m_Switch) |
464 | m_SavedLayers[LAYERTYPE_SWITCH] = m_pEditor->m_Map.m_pSwitchLayer->Duplicate(); |
465 | if(m_pEditor->m_Map.m_pSpeedupLayer && !m_pObject->m_Speedup) |
466 | m_SavedLayers[LAYERTYPE_SPEEDUP] = m_pEditor->m_Map.m_pSpeedupLayer->Duplicate(); |
467 | if(m_pEditor->m_Map.m_pTuneLayer && !m_pObject->m_Tune) |
468 | m_SavedLayers[LAYERTYPE_TUNE] = m_pEditor->m_Map.m_pTuneLayer->Duplicate(); |
469 | if(!m_pObject->m_Game) |
470 | m_SavedLayers[LAYERTYPE_GAME] = m_pEditor->m_Map.m_pGameLayer->Duplicate(); |
471 | } |
472 | } |
473 | else if(Prop == ETilesProp::PROP_SHIFT) |
474 | { |
475 | m_SavedLayers[LAYERTYPE_TILES] = m_pObject->Duplicate(); |
476 | } |
477 | } |
478 | |
479 | void CLayerTilesPropTracker::OnEnd(ETilesProp Prop, int Value) |
480 | { |
481 | auto pAction = std::make_shared<CEditorActionEditLayerTilesProp>(args&: m_pEditor, args&: m_OriginalGroupIndex, args&: m_OriginalLayerIndex, args&: Prop, args&: m_OriginalValue, args&: Value); |
482 | |
483 | pAction->SetSavedLayers(m_SavedLayers); |
484 | m_SavedLayers.clear(); |
485 | |
486 | m_pEditor->m_EditorHistory.RecordAction(pAction); |
487 | } |
488 | |
489 | int CLayerTilesPropTracker::PropToValue(ETilesProp Prop) |
490 | { |
491 | switch(Prop) |
492 | { |
493 | case ETilesProp::PROP_AUTOMAPPER: return m_pObject->m_AutoMapperConfig; |
494 | case ETilesProp::PROP_COLOR: return PackColor(Color: m_pObject->m_Color); |
495 | case ETilesProp::PROP_COLOR_ENV: return m_pObject->m_ColorEnv; |
496 | case ETilesProp::PROP_COLOR_ENV_OFFSET: return m_pObject->m_ColorEnvOffset; |
497 | case ETilesProp::PROP_HEIGHT: return m_pObject->m_Height; |
498 | case ETilesProp::PROP_WIDTH: return m_pObject->m_Width; |
499 | case ETilesProp::PROP_IMAGE: return m_pObject->m_Image; |
500 | case ETilesProp::PROP_SEED: return m_pObject->m_Seed; |
501 | case ETilesProp::PROP_SHIFT_BY: return m_pEditor->m_ShiftBy; |
502 | default: return 0; |
503 | } |
504 | } |
505 | |
506 | // ------------------------------ |
507 | |
508 | void CLayerTilesCommonPropTracker::OnStart(ETilesCommonProp Prop) |
509 | { |
510 | for(auto &pLayer : m_vpLayers) |
511 | { |
512 | if(Prop == ETilesCommonProp::PROP_SHIFT) |
513 | { |
514 | m_SavedLayers[pLayer][LAYERTYPE_TILES] = pLayer->Duplicate(); |
515 | } |
516 | } |
517 | } |
518 | |
519 | void CLayerTilesCommonPropTracker::OnEnd(ETilesCommonProp Prop, int Value) |
520 | { |
521 | std::vector<std::shared_ptr<IEditorAction>> vpActions; |
522 | |
523 | static std::map<ETilesCommonProp, ETilesProp> s_PropMap{ |
524 | {ETilesCommonProp::PROP_COLOR, ETilesProp::PROP_COLOR}, |
525 | {ETilesCommonProp::PROP_SHIFT, ETilesProp::PROP_SHIFT}, |
526 | {ETilesCommonProp::PROP_SHIFT_BY, ETilesProp::PROP_SHIFT_BY}}; |
527 | |
528 | int j = 0; |
529 | for(auto &pLayer : m_vpLayers) |
530 | { |
531 | int LayerIndex = m_vLayerIndices[j++]; |
532 | auto pAction = std::make_shared<CEditorActionEditLayerTilesProp>(args&: m_pEditor, args&: m_OriginalGroupIndex, args&: LayerIndex, args&: s_PropMap[Prop], args&: m_OriginalValue, args&: Value); |
533 | pAction->SetSavedLayers(m_SavedLayers[pLayer]); |
534 | vpActions.push_back(x: pAction); |
535 | } |
536 | |
537 | char aDisplay[256]; |
538 | static const char *s_apNames[] = { |
539 | "width" , |
540 | "height" , |
541 | "shift" , |
542 | "shift by" , |
543 | "color" , |
544 | }; |
545 | |
546 | str_format(buffer: aDisplay, buffer_size: sizeof(aDisplay), format: "Edit %d layers common property: %s" , (int)m_vpLayers.size(), s_apNames[(int)Prop]); |
547 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionBulk>(args&: m_pEditor, args&: vpActions, args&: aDisplay)); |
548 | } |
549 | |
550 | bool CLayerTilesCommonPropTracker::EndChecker(ETilesCommonProp Prop, EEditState State, int Value) |
551 | { |
552 | return (State == EEditState::END || State == EEditState::ONE_GO) && (Value != m_OriginalValue || Prop == ETilesCommonProp::PROP_SHIFT); |
553 | } |
554 | |
555 | int CLayerTilesCommonPropTracker::PropToValue(ETilesCommonProp Prop) |
556 | { |
557 | if(Prop == ETilesCommonProp::PROP_SHIFT_BY) |
558 | return m_pEditor->m_ShiftBy; |
559 | return 0; |
560 | } |
561 | |
562 | // ------------------------------ |
563 | |
564 | void CLayerGroupPropTracker::OnEnd(EGroupProp Prop, int Value) |
565 | { |
566 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionEditGroupProp>(args&: m_pEditor, args&: m_pEditor->m_SelectedGroup, args&: Prop, args&: m_OriginalValue, args&: Value)); |
567 | } |
568 | |
569 | int CLayerGroupPropTracker::PropToValue(EGroupProp Prop) |
570 | { |
571 | switch(Prop) |
572 | { |
573 | case EGroupProp::PROP_ORDER: return m_pEditor->m_SelectedGroup; |
574 | case EGroupProp::PROP_POS_X: return m_pObject->m_OffsetX; |
575 | case EGroupProp::PROP_POS_Y: return m_pObject->m_OffsetY; |
576 | case EGroupProp::PROP_PARA_X: return m_pObject->m_ParallaxX; |
577 | case EGroupProp::PROP_PARA_Y: return m_pObject->m_ParallaxY; |
578 | case EGroupProp::PROP_USE_CLIPPING: return m_pObject->m_UseClipping; |
579 | case EGroupProp::PROP_CLIP_X: return m_pObject->m_ClipX; |
580 | case EGroupProp::PROP_CLIP_Y: return m_pObject->m_ClipY; |
581 | case EGroupProp::PROP_CLIP_W: return m_pObject->m_ClipW; |
582 | case EGroupProp::PROP_CLIP_H: return m_pObject->m_ClipH; |
583 | default: return 0; |
584 | } |
585 | } |
586 | |
587 | // ------------------------------------------------------------------ |
588 | |
589 | void CLayerQuadsPropTracker::OnEnd(ELayerQuadsProp Prop, int Value) |
590 | { |
591 | auto pAction = std::make_shared<CEditorActionEditLayerQuadsProp>(args&: m_pEditor, args&: m_OriginalGroupIndex, args&: m_OriginalLayerIndex, args&: Prop, args&: m_OriginalValue, args&: Value); |
592 | m_pEditor->m_EditorHistory.RecordAction(pAction); |
593 | } |
594 | |
595 | int CLayerQuadsPropTracker::PropToValue(ELayerQuadsProp Prop) |
596 | { |
597 | if(Prop == ELayerQuadsProp::PROP_IMAGE) |
598 | return m_pObject->m_Image; |
599 | return 0; |
600 | } |
601 | |
602 | // ------------------------------------------------------------------- |
603 | |
604 | void CLayerSoundsPropTracker::OnEnd(ELayerSoundsProp Prop, int Value) |
605 | { |
606 | auto pAction = std::make_shared<CEditorActionEditLayerSoundsProp>(args&: m_pEditor, args&: m_OriginalGroupIndex, args&: m_OriginalLayerIndex, args&: Prop, args&: m_OriginalValue, args&: Value); |
607 | m_pEditor->m_EditorHistory.RecordAction(pAction); |
608 | } |
609 | |
610 | int CLayerSoundsPropTracker::PropToValue(ELayerSoundsProp Prop) |
611 | { |
612 | if(Prop == ELayerSoundsProp::PROP_SOUND) |
613 | return m_pObject->m_Sound; |
614 | return 0; |
615 | } |
616 | |
617 | // ---- |
618 | |
619 | void CSoundSourcePropTracker::OnEnd(ESoundProp Prop, int Value) |
620 | { |
621 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionEditSoundSourceProp>(args&: m_pEditor, args&: m_OriginalGroupIndex, args&: m_OriginalLayerIndex, args&: m_pEditor->m_SelectedSource, args&: Prop, args&: m_OriginalValue, args&: Value)); |
622 | } |
623 | |
624 | int CSoundSourcePropTracker::PropToValue(ESoundProp Prop) |
625 | { |
626 | switch(Prop) |
627 | { |
628 | case ESoundProp::PROP_POS_X: return m_pObject->m_Position.x; |
629 | case ESoundProp::PROP_POS_Y: return m_pObject->m_Position.y; |
630 | case ESoundProp::PROP_LOOP: return m_pObject->m_Loop; |
631 | case ESoundProp::PROP_PAN: return m_pObject->m_Pan; |
632 | case ESoundProp::PROP_TIME_DELAY: return m_pObject->m_TimeDelay; |
633 | case ESoundProp::PROP_FALLOFF: return m_pObject->m_Falloff; |
634 | case ESoundProp::PROP_POS_ENV: return m_pObject->m_PosEnv; |
635 | case ESoundProp::PROP_POS_ENV_OFFSET: return m_pObject->m_PosEnvOffset; |
636 | case ESoundProp::PROP_SOUND_ENV: return m_pObject->m_SoundEnv; |
637 | case ESoundProp::PROP_SOUND_ENV_OFFSET: return m_pObject->m_SoundEnvOffset; |
638 | default: return 0; |
639 | } |
640 | } |
641 | |
642 | // ---- |
643 | |
644 | void CSoundSourceRectShapePropTracker::OnEnd(ERectangleShapeProp Prop, int Value) |
645 | { |
646 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionEditRectSoundSourceShapeProp>(args&: m_pEditor, args&: m_OriginalGroupIndex, args&: m_OriginalLayerIndex, args&: m_pEditor->m_SelectedSource, args&: Prop, args&: m_OriginalValue, args&: Value)); |
647 | } |
648 | |
649 | int CSoundSourceRectShapePropTracker::PropToValue(ERectangleShapeProp Prop) |
650 | { |
651 | switch(Prop) |
652 | { |
653 | case ERectangleShapeProp::PROP_RECTANGLE_WIDTH: return m_pObject->m_Shape.m_Rectangle.m_Width; |
654 | case ERectangleShapeProp::PROP_RECTANGLE_HEIGHT: return m_pObject->m_Shape.m_Rectangle.m_Height; |
655 | default: return 0; |
656 | } |
657 | } |
658 | |
659 | void CSoundSourceCircleShapePropTracker::OnEnd(ECircleShapeProp Prop, int Value) |
660 | { |
661 | m_pEditor->m_EditorHistory.RecordAction(pAction: std::make_shared<CEditorActionEditCircleSoundSourceShapeProp>(args&: m_pEditor, args&: m_OriginalGroupIndex, args&: m_OriginalLayerIndex, args&: m_pEditor->m_SelectedSource, args&: Prop, args&: m_OriginalValue, args&: Value)); |
662 | } |
663 | |
664 | int CSoundSourceCircleShapePropTracker::PropToValue(ECircleShapeProp Prop) |
665 | { |
666 | switch(Prop) |
667 | { |
668 | case ECircleShapeProp::PROP_CIRCLE_RADIUS: return m_pObject->m_Shape.m_Circle.m_Radius; |
669 | default: return 0; |
670 | } |
671 | } |
672 | |