DEADSOFTWARE

56eb889402ed087291951f9f6398828488d02dd4
[d2df-editor.git] / src / editor / f_mapoptimization.pas
1 unit f_mapoptimization;
3 {$MODE Delphi}
5 interface
7 uses
8 LCLIntf, LCLType, LMessages, Messages, SysUtils, Variants, Classes,
9 Graphics, Controls, Forms, Dialogs, StdCtrls,
10 ComCtrls, ExtCtrls;
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 g_DeleteTexture(MainForm.lbTextureList.Items[a]);
125 MainForm.lbTextureList.Items.Delete(a);
126 end
127 else
128 a := a + 1;
129 end;
131 with mOptimizationResult.Lines do
132 begin
133 Add(#13#10+_lc[I_OPT_TOTAL_TEXTURES]+' '+#9+IntToStr(c));
134 Add(_lc[I_OPT_TEX_DELETED]+#9+IntToStr(c-MainForm.lbTextureList.Count));
135 end;
136 end;
138 procedure TMapOptimizationForm.bBeginPanelsOptimizationClick(
139 Sender: TObject);
141 function OptimizePanels(PanelsType: Word): Integer;
142 var
143 a, c: Boolean;
144 i, n, b: Integer;
145 list: Array of DWORD;
147 begin
148 Result := 0;
150 // Составляем список переключаемых лифтов:
151 list := nil;
152 if WordBool(PanelsType and (PANEL_LIFTUP or PANEL_LIFTDOWN or PANEL_LIFTLEFT or PANEL_LIFTRIGHT)) then
153 begin
154 SetLength(list, 32);
155 n := 0;
157 if gTriggers <> nil then
158 for i := 0 to High(gTriggers) do
159 if (gTriggers[i].Data.PanelID <> -1) and
160 ((gTriggers[i].TriggerType = TRIGGER_LIFT) or
161 (gTriggers[i].TriggerType = TRIGGER_LIFTUP) or
162 (gTriggers[i].TriggerType = TRIGGER_LIFTDOWN)) then
163 begin
164 if n > High(list) then
165 SetLength(list, Length(list)+32);
166 list[n] := gTriggers[i].Data.PanelID;
167 n := n + 1;
168 end;
170 SetLength(list, n);
171 end;
173 // Оптимизация:
174 a := True;
175 while a do
176 begin
177 a := False;
179 for i := 0 to High(gPanels) do
180 if gPanels[i].PanelType <> PANEL_NONE then
181 begin
182 c := False;
183 if list <> nil then
184 for b := 0 to High(list) do
185 if list[b] = DWORD(i) then
186 begin
187 c := True;
188 Break;
189 end;
191 // Это переключаемый лифт:
192 if c then
193 Continue;
195 for n := 0 to High(gPanels) do
196 if gPanels[i].PanelType <> PANEL_NONE then
197 begin
198 c := False;
199 if list <> nil then
200 for b := 0 to High(list) do
201 if list[b] = DWORD(n) then
202 begin
203 c := True;
204 Break;
205 end;
207 // Это тоже переключаемый лифт:
208 if c then
209 Continue;
211 // Если можно - объединяем панели:
212 if (gPanels[i].PanelType <> 0) and
213 (gPanels[n].PanelType <> 0) then
214 begin
215 if (i <> n) and
216 (gPanels[i].Width <> 0) and
217 (gPanels[n].Width <> 0) and
218 (gPanels[n].TextureID = gPanels[i].TextureID) and
219 (gPanels[n].PanelType = gPanels[i].PanelType) and
220 (gPanels[n].PanelType = PanelsType) and
221 (gPanels[n].Alpha = gPanels[i].Alpha) and
222 (gPanels[n].Blending = gPanels[i].Blending) and
223 (gPanels[n].TextureName = gPanels[i].TextureName) then
224 begin
225 // Рядом по-горизонтали:
226 if (gPanels[n].X = gPanels[i].X + gPanels[i].Width) and
227 (gPanels[n].Y = gPanels[i].Y) and
228 (gPanels[n].Height = gPanels[i].Height) then
229 begin
230 gPanels[i].Width := gPanels[i].Width+gPanels[n].Width;
231 RemoveObject(n, OBJECT_PANEL);
232 a := True;
233 Inc(Result);
234 Continue;
235 end;
237 // Рядом по-вертикали:
238 if (gPanels[n].Y = gPanels[i].Y + gPanels[i].Height) and
239 (gPanels[n].X = gPanels[i].X) and
240 (gPanels[n].Width = gPanels[i].Width) then
241 begin
242 gPanels[i].Height := gPanels[i].Height+gPanels[n].Height;
243 RemoveObject(n, OBJECT_PANEL);
244 a := True;
245 Inc(Result);
246 Continue;
247 end;
248 end;
249 end;
250 end;
251 end;
252 end;
253 end;
255 var
256 count: Integer;
257 panelcount1, panelcount2: Integer;
258 a: Integer;
260 begin
261 mOptimizationResult.Clear();
263 if gPanels = nil then
264 Exit;
266 panelcount1 := 0;
267 for a := 0 to High(gPanels) do
268 if gPanels[a].PanelType <> 0 then
269 panelcount1 := panelcount1 + 1;
271 if panelcount1 = 0 then
272 Exit;
274 if cbOptimizeWalls.Checked then
275 begin
276 mOptimizationResult.Lines.Add(_lc[I_OPT_WALLS]);
277 count := OptimizePanels(PANEL_WALL);
278 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
279 end;
281 if cbOptimizeForeGround.Checked then
282 begin
283 mOptimizationResult.Lines.Add(_lc[I_OPT_FORES]);
284 count := OptimizePanels(PANEL_FORE);
285 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
286 end;
288 if cbOptimizeBackGround.Checked then
289 begin
290 mOptimizationResult.Lines.Add(_lc[I_OPT_BACKS]);
291 count := OptimizePanels(PANEL_BACK);
292 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
293 end;
295 if cbOptimizeSteps.Checked then
296 begin
297 mOptimizationResult.Lines.Add(_lc[I_OPT_STAIRS]);
298 count := OptimizePanels(PANEL_STEP);
299 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
300 end;
302 if cbOptimizeWater.Checked then
303 begin
304 mOptimizationResult.Lines.Add(_lc[I_OPT_WATER]);
305 count := OptimizePanels(PANEL_WATER);
306 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
307 end;
309 if cbOptimizeAcid1.Checked then
310 begin
311 mOptimizationResult.Lines.Add(_lc[I_OPT_ACID1]);
312 count := OptimizePanels(PANEL_ACID1);
313 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
314 end;
316 if cbOptimizeAcid2.Checked then
317 begin
318 mOptimizationResult.Lines.Add(_lc[I_OPT_ACID2]);
319 count := OptimizePanels(PANEL_ACID2);
320 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
321 end;
323 if cbOptimizeLift.Checked then
324 begin
325 mOptimizationResult.Lines.Add(_lc[I_OPT_LIFTS]);
326 count := OptimizePanels(PANEL_LIFTUP)+OptimizePanels(PANEL_LIFTDOWN)+OptimizePanels(PANEL_LIFTLEFT)+OptimizePanels(PANEL_LIFTRIGHT);
327 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
328 end;
330 if cbOptimizeBlockMon.Checked then
331 begin
332 mOptimizationResult.Lines.Add(_lc[I_OPT_BLOCKMON]);
333 count := OptimizePanels(PANEL_BLOCKMON);
334 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(count)+#13#10);
335 end;
337 panelcount2 := 0;
338 for a := 0 to High(gPanels) do
339 if gPanels[a].PanelType <> 0 then
340 panelcount2 := panelcount2 + 1;
342 mOptimizationResult.Lines.Add('-----------------------');
343 mOptimizationResult.Lines.Add(_lc[I_OPT_TOTAL_PANELS]+' '+IntToStr(panelcount1));
344 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_AFTER]+' '+IntToStr(panelcount2));
345 mOptimizationResult.Lines.Add(_lc[I_OPT_PANELS_OPT]+' '+IntToStr(panelcount1-panelcount2));
346 end;
348 end.