DEADSOFTWARE

Movement: Implement WASD move/resize
[d2df-editor.git] / src / editor / f_mapoptimization.pas
1 unit f_mapoptimization;
3 {$INCLUDE ../shared/a_modes.inc}
5 interface
7 uses
8 LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes,
9 Graphics, Controls, Forms, Dialogs, StdCtrls,
10 ComCtrls, ExtCtrls, utils;
12 type
13 TMapOptimizationForm = class (TForm)
14 // Выбор оптимизации:
15 GroupBoxOpt: TGroupBox;
16 Bevel1: TBevel;
17 lOptimizationDescription: TLabel;
18 rbTexturesOptimization: TRadioButton;
19 rbPanelsOptimization: TRadioButton;
20 // Результаты:
21 mOptimizationResult: TMemo;
22 // Настройки:
23 pcOptimizationOptions: TPageControl;
24 // Оптимизация текстур:
25 tsTextureOptimization: TTabSheet;
26 bBeginTextureOptimization: TButton;
27 // Оптимизация панелей:
28 tsPanelOptimization: TTabSheet;
29 cbOptimizeWalls: TCheckBox;
30 cbOptimizeForeGround: TCheckBox;
31 cbOptimizeBackGround: TCheckBox;
32 cbOptimizeSteps: TCheckBox;
33 cbOptimizeWater: TCheckBox;
34 cbOptimizeAcid1: TCheckBox;
35 cbOptimizeAcid2: TCheckBox;
36 cbOptimizeLift: TCheckBox;
37 cbOptimizeBlockMon: TCheckBox;
38 bBeginPanelsOptimization: TButton;
40 procedure FormActivate(Sender: TObject);
41 procedure rbTexturesOptimizationClick(Sender: TObject);
42 procedure rbPanelsOptimizationClick(Sender: TObject);
43 procedure bBeginTextureOptimizationClick(Sender: TObject);
44 procedure bBeginPanelsOptimizationClick(Sender: TObject);
46 private
47 { Private declarations }
48 public
49 { Public declarations }
50 end;
52 var
53 MapOptimizationForm: TMapOptimizationForm;
55 implementation
57 uses
58 f_main, g_map, g_textures, MAPDEF, g_language;
60 {$R *.lfm}
62 procedure TMapOptimizationForm.FormActivate(Sender: TObject);
63 begin
64 rbTexturesOptimization.Checked := True;
65 mOptimizationResult.Clear();
66 end;
68 procedure TMapOptimizationForm.rbTexturesOptimizationClick(Sender: TObject);
69 begin
70 pcOptimizationOptions.ActivePage := tsTextureOptimization;
71 lOptimizationDescription.Caption := _lc[I_CTRL_OPT_DESC_TEXTURE];
72 end;
74 procedure TMapOptimizationForm.rbPanelsOptimizationClick(Sender: TObject);
75 begin
76 pcOptimizationOptions.ActivePage := tsPanelOptimization;
77 lOptimizationDescription.Caption := _lc[I_CTRL_OPT_DESC_PANEL];
78 end;
80 procedure TMapOptimizationForm.bBeginTextureOptimizationClick(
81 Sender: TObject);
82 var
83 i: Integer;
84 a: Integer;
85 ok: Boolean;
86 b: Boolean;
87 c: Integer;
89 begin
90 mOptimizationResult.Clear();
91 b := False;
93 if MainForm.lbTextureList.Count = 0 then
94 begin
95 mOptimizationResult.Lines.Add(_lc[I_OPT_NO_TEXTURES]);
96 Exit;
97 end;
99 c := MainForm.lbTextureList.Count;
100 a := 0;
102 while a <= MainForm.lbTextureList.Count-1 do
103 begin
104 ok := True;
106 for i := 0 to High(gPanels) do
107 if (gPanels[i].PanelType <> 0) and
108 (gPanels[i].TextureName = MainForm.lbTextureList.Items[a]) then
109 begin
110 ok := False;
111 Break;
112 end;
114 // Нашли неиспользуемую текстуру:
115 if ok then
116 begin
117 g_DeleteTexture(MainForm.lbTextureList.Items[a]);
118 if not b then
119 begin
120 mOptimizationResult.Lines.Add(_lc[I_OPT_DELETED_TEXTURES]);
121 b := True;
122 end;
123 mOptimizationResult.Lines.Add(' '+MainForm.lbTextureList.Items[a]);
124 MainForm.lbTextureList.Items.Delete(a);
125 end
126 else
127 a := a + 1;
128 end;
130 with mOptimizationResult.Lines do
131 begin
132 Add(#13#10+_lc[I_OPT_TOTAL_TEXTURES]+' '+#9+IntToStr(c));
133 Add(_lc[I_OPT_TEX_DELETED]+#9+IntToStr(c-MainForm.lbTextureList.Count));
134 end;
135 end;
137 procedure TMapOptimizationForm.bBeginPanelsOptimizationClick(
138 Sender: TObject);
140 function OptimizePanels(PanelsType: Word): Integer;
141 var
142 a, c: Boolean;
143 i, n, b: Integer;
144 list: Array of DWORD;
146 begin
147 Result := 0;
149 // Составляем список переключаемых лифтов:
150 list := nil;
151 if WordBool(PanelsType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) then
152 begin
153 SetLength(list, 32);
154 n := 0;
156 if gTriggers <> nil then
157 for i := 0 to High(gTriggers) do
158 if (gTriggers[i].Data.PanelID <> -1) and
159 ((gTriggers[i].TriggerType = TRIGGER_LIFT) or
160 (gTriggers[i].TriggerType = TRIGGER_LIFTUP) or
161 (gTriggers[i].TriggerType = TRIGGER_LIFTDOWN)) then
162 begin
163 if n > High(list) then
164 SetLength(list, Length(list)+32);
165 list[n] := gTriggers[i].Data.PanelID;
166 n := n + 1;
167 end;
169 SetLength(list, n);
170 end;
172 // Оптимизация:
173 a := True;
174 while a do
175 begin
176 a := False;
178 for i := 0 to High(gPanels) do
179 if gPanels[i].PanelType <> PANEL_NONE then
180 begin
181 c := False;
182 if list <> nil then
183 for b := 0 to High(list) do
184 if list[b] = DWORD(i) then
185 begin
186 c := True;
187 Break;
188 end;
190 // Это переключаемый лифт:
191 if c then
192 Continue;
194 for n := 0 to High(gPanels) do
195 if gPanels[i].PanelType <> PANEL_NONE then
196 begin
197 c := False;
198 if list <> nil then
199 for b := 0 to High(list) do
200 if list[b] = DWORD(n) then
201 begin
202 c := True;
203 Break;
204 end;
206 // Это тоже переключаемый лифт:
207 if c then
208 Continue;
210 // Если можно - объединяем панели:
211 if (gPanels[i].PanelType <> 0) and
212 (gPanels[n].PanelType <> 0) then
213 begin
214 if (i <> n) and
215 (gPanels[i].Width <> 0) and
216 (gPanels[n].Width <> 0) and
217 (gPanels[n].TextureID = gPanels[i].TextureID) and
218 (gPanels[n].PanelType = gPanels[i].PanelType) and
219 (gPanels[n].PanelType = PanelsType) and
220 (gPanels[n].Alpha = gPanels[i].Alpha) and
221 (gPanels[n].Blending = gPanels[i].Blending) and
222 (gPanels[n].TextureName = gPanels[i].TextureName) then
223 begin
224 // Рядом по-горизонтали:
225 if (gPanels[n].X = gPanels[i].X + gPanels[i].Width) and
226 (gPanels[n].Y = gPanels[i].Y) and
227 (gPanels[n].Height = gPanels[i].Height) then
228 begin
229 gPanels[i].Width := gPanels[i].Width+gPanels[n].Width;
230 RemoveObject(n, OBJECT_PANEL);
231 a := True;
232 Inc(Result);
233 Continue;
234 end;
236 // Рядом по-вертикали:
237 if (gPanels[n].Y = gPanels[i].Y + gPanels[i].Height) and
238 (gPanels[n].X = gPanels[i].X) and
239 (gPanels[n].Width = gPanels[i].Width) then
240 begin
241 gPanels[i].Height := gPanels[i].Height+gPanels[n].Height;
242 RemoveObject(n, OBJECT_PANEL);
243 a := True;
244 Inc(Result);
245 Continue;
246 end;
247 end;
248 end;
249 end;
250 end;
251 end;
252 end;
254 var
255 count: Integer;
256 panelcount1, panelcount2: Integer;
257 a: Integer;
259 begin
260 mOptimizationResult.Clear();
262 if gPanels = nil then
263 Exit;
265 panelcount1 := 0;
266 for a := 0 to High(gPanels) do
267 if gPanels[a].PanelType <> 0 then
268 panelcount1 := panelcount1 + 1;
270 if panelcount1 = 0 then
271 Exit;
273 if cbOptimizeWalls.Checked then
274 begin
275 mOptimizationResult.Lines.Add(_lc[I_OPT_WALLS]);
276 count := OptimizePanels(PANEL_WALL);
277 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
278 end;
280 if cbOptimizeForeGround.Checked then
281 begin
282 mOptimizationResult.Lines.Add(_lc[I_OPT_FORES]);
283 count := OptimizePanels(PANEL_FORE);
284 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
285 end;
287 if cbOptimizeBackGround.Checked then
288 begin
289 mOptimizationResult.Lines.Add(_lc[I_OPT_BACKS]);
290 count := OptimizePanels(PANEL_BACK);
291 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
292 end;
294 if cbOptimizeSteps.Checked then
295 begin
296 mOptimizationResult.Lines.Add(_lc[I_OPT_STAIRS]);
297 count := OptimizePanels(PANEL_STEP);
298 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
299 end;
301 if cbOptimizeWater.Checked then
302 begin
303 mOptimizationResult.Lines.Add(_lc[I_OPT_WATER]);
304 count := OptimizePanels(PANEL_WATER);
305 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
306 end;
308 if cbOptimizeAcid1.Checked then
309 begin
310 mOptimizationResult.Lines.Add(_lc[I_OPT_ACID1]);
311 count := OptimizePanels(PANEL_ACID1);
312 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
313 end;
315 if cbOptimizeAcid2.Checked then
316 begin
317 mOptimizationResult.Lines.Add(_lc[I_OPT_ACID2]);
318 count := OptimizePanels(PANEL_ACID2);
319 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
320 end;
322 if cbOptimizeLift.Checked then
323 begin
324 mOptimizationResult.Lines.Add(_lc[I_OPT_LIFTS]);
325 count := OptimizePanels(PANEL_LIFTUP)+OptimizePanels(PANEL_LIFTDOWN)+OptimizePanels(PANEL_LIFTLEFT)+OptimizePanels(PANEL_LIFTRIGHT);
326 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
327 end;
329 if cbOptimizeBlockMon.Checked then
330 begin
331 mOptimizationResult.Lines.Add(_lc[I_OPT_BLOCKMON]);
332 count := OptimizePanels(PANEL_BLOCKMON);
333 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
334 end;
336 panelcount2 := 0;
337 for a := 0 to High(gPanels) do
338 if gPanels[a].PanelType <> 0 then
339 panelcount2 := panelcount2 + 1;
341 mOptimizationResult.Lines.Add('-----------------------');
342 mOptimizationResult.Lines.Add(_lc[I_OPT_TOTAL_PANELS]+' '+IntToStr(panelcount1));
343 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_AFTER]+' '+IntToStr(panelcount2));
344 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(panelcount1-panelcount2));
345 end;
347 end.