source: tags/1.3.1/Start.pas

Last change on this file was 442, checked in by chronos, 2 years ago
  • Modified: Code cleanup.
File size: 66.3 KB
Line 
1{$INCLUDE Switches.inc}
2unit Start;
3
4interface
5
6uses
7 GameServer, Messg, ButtonBase, ButtonA, ButtonC, ButtonB, Area, Types,
8 LCLIntf, LCLType, SysUtils, Classes, Graphics, Controls, Forms, StdCtrls,
9 Menus, Registry, DrawDlg, Generics.Collections, Protocol, UMiniMap, UBrain,
10 UTranslator;
11
12type
13 { TPlayerSlot }
14
15 TPlayerSlot = class
16 DiffUpBtn: TButtonC;
17 DiffDownBtn: TButtonC;
18 MultiBtn: TButtonC;
19 OfferMultiple: Boolean;
20 Rect: TRect;
21 end;
22
23 TPlayerSlots = class(TObjectList<TPlayerSlot>)
24 end;
25
26 TStartPage = (
27 pgStartRandom,
28 pgStartMap,
29 pgNoLoad,
30 pgLoad,
31 pgEditRandom,
32 pgEditMap,
33 pgMain
34 );
35
36 TStartTab = (tbMain, tbMap, tbNew, tbPrevious);
37 TMainAction = (maConfig, maManual, maCredits, maAIDev, maWeb, maNone);
38 TMainActionSet = set of TMainAction;
39
40 { TStartDlg }
41
42 TStartDlg = class(TDrawDlg)
43 PopupMenu1: TPopupMenu;
44 StartBtn: TButtonA;
45 Down1Btn: TButtonC;
46 Up1Btn: TButtonC;
47 List: TListBox;
48 RenameBtn: TButtonB;
49 DeleteBtn: TButtonB;
50 Down2Btn: TButtonC;
51 Up2Btn: TButtonC;
52 QuitBtn: TButtonB;
53 CustomizeBtn: TButtonC;
54 AutoDiffUpBtn: TButtonC;
55 AutoDiffDownBtn: TButtonC;
56 AutoEnemyUpBtn: TButtonC;
57 AutoEnemyDownBtn: TButtonC;
58 ReplayBtn: TButtonB;
59 procedure ListKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
60 procedure ListKeyPress(Sender: TObject; var Key: char);
61 procedure StartBtnClick(Sender: TObject);
62 procedure FormPaint(Sender: TObject);
63 procedure FormShow(Sender: TObject);
64 procedure FormHide(Sender: TObject);
65 procedure FormClose(Sender: TObject; var Action: TCloseAction);
66 procedure FormCreate(Sender: TObject);
67 procedure FormDestroy(Sender: TObject);
68 procedure BrainClick(Sender: TObject);
69 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
70 procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
71 Shift: TShiftState; x, y: integer);
72 procedure FormMouseUp(Sender: TObject; Button: TMouseButton;
73 Shift: TShiftState; x, y: integer);
74 procedure FormMouseMove(Sender: TObject; Shift: TShiftState; x, y: integer);
75 procedure Up1BtnClick(Sender: TObject);
76 procedure Down1BtnClick(Sender: TObject);
77 procedure ListClick(Sender: TObject);
78 procedure RenameBtnClick(Sender: TObject);
79 procedure DeleteBtnClick(Sender: TObject);
80 procedure DiffBtnClick(Sender: TObject);
81 procedure MultiBtnClick(Sender: TObject);
82 procedure Up2BtnClick(Sender: TObject);
83 procedure Down2BtnClick(Sender: TObject);
84 procedure QuitBtnClick(Sender: TObject);
85 procedure CustomizeBtnClick(Sender: TObject);
86 procedure AutoDiffUpBtnClick(Sender: TObject);
87 procedure AutoDiffDownBtnClick(Sender: TObject);
88 procedure AutoEnemyUpBtnClick(Sender: TObject);
89 procedure AutoEnemyDownBtnClick(Sender: TObject);
90 procedure ReplayBtnClick(Sender: TObject);
91 private
92 WorldSize: Integer;
93 StartLandMass: Integer;
94 MaxTurn: Integer;
95 AutoEnemies: Integer;
96 AutoDiff: Integer;
97 MultiControl: Integer;
98 Page: TStartPage;
99 ShowTab: TStartTab;
100 Tab: TStartTab;
101 Diff0: Integer;
102 BrainDefault: TBrain;
103 nMapLandTiles: Integer;
104 nMapStartPositions: Integer;
105 LoadTurn: Integer;
106 LastTurn: Integer;
107 { last turn of selected former game }
108 SlotAvailable: Integer;
109 PlayerPopupIndex: Integer; { brain concerned by brain context menu }
110 ListIndex: array [TStartTab] of Integer;
111 MapFileName: string;
112 FormerGames: TStringList;
113 Maps: TStringList;
114 LogoBuffer: TBitmap;
115 // BookDate: string;
116 PlayerSlots: TPlayerSlots;
117 ActionsOffered: TMainActionSet;
118 SelectedAction: TMainAction;
119 TurnValid: Boolean;
120 Tracking: Boolean;
121 DefaultAI: string;
122 MiniMap: TMiniMap;
123 LastGame: string;
124 procedure DrawAction(y, IconIndex: integer; HeaderItem, TextItem: string);
125 procedure InitPopup(PlayerIndex: Integer);
126 procedure OfferBrain(Brain: TBrain; FixedLines: Integer);
127 procedure PaintInfo;
128 procedure ChangePage(NewPage: TStartPage);
129 procedure ChangeTab(NewTab: TStartTab);
130 procedure UnlistBackupFile(FileName: string);
131 procedure SmartInvalidate(x0, y0, x1, y1: integer;
132 invalidateTab0: boolean = false); overload;
133 procedure LoadConfig;
134 procedure SaveConfig;
135 procedure LoadLanguages;
136 procedure LoadAiBrainsPictures;
137 procedure UpdateInterface;
138 procedure ShowSettings;
139 public
140 EmptyPicture: TBitmap;
141 Translator: TTranslator;
142 procedure UpdateFormerGames;
143 procedure UpdateMaps;
144 end;
145
146var
147 StartDlg: TStartDlg;
148
149
150implementation
151
152uses
153 Global, Directories, Direct, ScreenTools, Inp, Back, Settings, UKeyBindings,
154 ULanguages;
155
156{$R *.lfm}
157
158const
159 // predefined world size
160 // attention: lx*ly+1 must be prime!
161 { MaxWorldSize=8;
162 lxpre: array[0..nWorldSize-1] of integer =(30,40,50,60,70,90,110,130);
163 lypre: array[0..nWorldSize-1] of integer =(46,52,60,70,84,94,110,130);
164 DefaultWorldTiles=4200; }
165 MaxWorldSize = 6;
166 WorldSizes: array [0 .. MaxWorldSize - 1] of TPoint = ((X: 30; Y: 46),
167 (X: 40; Y: 52), (X: 50; Y: 60), (X: 60; Y: 70), (X: 75; Y: 82),
168 (X: 100; Y: 96));
169 DefaultWorldTiles = 4150;
170 DefaultWorldSize = 3;
171 DefaultLandMass = 30;
172
173 nPlOffered = 9;
174 yMain = 14;
175 xActionIcon = 55;
176 xAction = 111;
177 yAction = 60;
178 ActionPitch = 56;
179 ActionSideBorder = 24;
180 ActionBottomBorder = 10;
181 wBuffer = 91;
182 x0Mini = 437;
183 y0Mini = 178;
184 xTurnSlider = 346;
185 yTurnSlider = 262;
186 wTurnSlider = 168;
187 yLogo = 74;
188 xDefault = 234;
189 yDefault = 148;
190 x0Brain = 146;
191 y0Brain = 148;
192 dxBrain = 104;
193 dyBrain = 80;
194 xBrain: array [0 .. nPlOffered - 1] of integer = (x0Brain, x0Brain,
195 x0Brain + dxBrain, x0Brain + dxBrain, x0Brain + dxBrain, x0Brain,
196 x0Brain - dxBrain, x0Brain - dxBrain, x0Brain - dxBrain);
197 yBrain: array [0 .. nPlOffered - 1] of integer = (y0Brain, y0Brain - dyBrain,
198 y0Brain - dyBrain, y0Brain, y0Brain + dyBrain, y0Brain + dyBrain,
199 y0Brain + dyBrain, y0Brain, y0Brain - dyBrain);
200 TabOffset = -115;
201 TabSize = 159;
202 TabHeight = 40;
203
204 InitAlive: array [1 .. nPl] of integer = (1, 1 + 2, 1 + 2 + 32,
205 1 + 2 + 8 + 128, 1 + 2 + 8 + 32 + 128, 1 + 2 + 8 + 16 + 64 + 128,
206 1 + 2 + 4 + 16 + 32 + 64 + 256, 511 - 32, 511, 511 - 32, 511, 511 - 32, 511,
207 511 - 32, 511);
208 InitMulti: array [nPlOffered + 1 .. nPl] of integer = (256, 256, 256 + 128,
209 256 + 128, 256 + 128 + 64, 256 + 128 + 64);
210
211 PlayerAutoDiff: array [1 .. 5] of integer = (1, 1, 2, 2, 3);
212 EnemyAutoDiff: array [1 .. 5] of integer = (4, 3, 2, 1, 1);
213
214{ TStartDlg }
215
216procedure TStartDlg.FormCreate(Sender: TObject);
217var
218 x, i: Integer;
219 PlayerSlot: TPlayerSlot;
220 AIBrains: TBrains;
221begin
222 PlayerSlots := TPlayerSlots.Create;
223 PlayerSlots.Count := nPlOffered;
224 for I := 0 to PlayerSlots.Count - 1 do begin
225 PlayerSlot := TPlayerSlot.Create;
226 PlayerSlot.Rect := Bounds(xBrain[I], YBrain[I], 0, 0);
227 PlayerSlots[I] := PlayerSlot;
228 end;
229 LoadConfig;
230 LoadAssets;
231 LoadLanguages;
232
233 ActionsOffered := [maConfig, maManual, maCredits, maWeb];
234 if FileExists(HomeDir + AITemplateFileName) then
235 Include(ActionsOffered, maAIDev);
236
237 BrainDefault := nil;
238 for i := Brains.IndexOf(BrainRandom) to Brains.Count - 1 do
239 if AnsiCompareFileName(DefaultAI, Brains[i].FileName) = 0 then
240 BrainDefault := Brains[i];
241 if (BrainDefault = BrainRandom) and (Brains.GetKindCount(btAI) < 2) then
242 BrainDefault := nil;
243 if (not Assigned(BrainDefault)) and (Brains.GetKindCount(btAI) > 0) then
244 begin
245 AIBrains := TBrains.Create(False);
246 Brains.GetByKind(btAI, AIBrains);
247 BrainDefault := Brains[0];
248 FreeAndNil(AIBrains);
249 end; // default AI not found, use any
250
251 DirectDlg.Left := (Screen.Width - DirectDlg.Width) div 2;
252 DirectDlg.Top := (Screen.Height - DirectDlg.Height) div 2;
253
254 UpdateInterface;
255
256 Canvas.Font.Assign(UniFont[ftNormal]);
257 Canvas.Brush.Style := bsClear;
258
259 QuitBtn.Hint := Phrases.Lookup('STARTCONTROLS', 0);
260 ReplayBtn.Hint := Phrases.Lookup('BTN_REPLAY');
261 PlayerSlots.Count := nPlOffered;
262 for i := 0 to PlayerSlots.Count - 1 do
263 with PlayerSlots[i] do begin
264 DiffUpBtn := TButtonC.Create(self);
265 DiffUpBtn.Graphic := HGrSystem.Data;
266 DiffUpBtn.left := xBrain[i] - 18;
267 DiffUpBtn.top := yBrain[i] + 39;
268 DiffUpBtn.ButtonIndex := 1;
269 DiffUpBtn.Parent := self;
270 DiffUpBtn.OnClick := DiffBtnClick;
271 DiffDownBtn := TButtonC.Create(self);
272 DiffDownBtn.Graphic := HGrSystem.Data;
273 DiffDownBtn.left := xBrain[i] - 18;
274 DiffDownBtn.top := yBrain[i] + 51;
275 DiffDownBtn.ButtonIndex := 0;
276 DiffDownBtn.Parent := self;
277 DiffDownBtn.OnClick := DiffBtnClick;
278 end;
279 for i := 6 to 8 do
280 with PlayerSlots[i] do begin
281 MultiBtn := TButtonC.Create(self);
282 MultiBtn.Graphic := HGrSystem.Data;
283 MultiBtn.left := xBrain[i] - 18;
284 MultiBtn.top := yBrain[i];
285 MultiBtn.Parent := self;
286 MultiBtn.OnClick := MultiBtnClick;
287 OfferMultiple := True;
288 end;
289
290 x := BiColorTextWidth(Canvas, Phrases.Lookup('STARTCONTROLS', 7)) div 2;
291 CustomizeBtn.left := x0Brain + 32 - 16 - x;
292 if AutoDiff < 0 then
293 CustomizeBtn.ButtonIndex := 3
294 else
295 CustomizeBtn.ButtonIndex := 2;
296
297 BitBltBitmap(BrainNoTerm.Picture, 0, 0, 64, 64, HGrSystem2.Data, GBrainNoTerm.Left, GBrainNoTerm.Top);
298 BitBltBitmap(BrainSuperVirtual.Picture, 0, 0, 64, 64, HGrSystem2.Data, GBrainSuperVirtual.Left, GBrainSuperVirtual.Top);
299 BitBltBitmap(BrainTerm.Picture, 0, 0, 64, 64, HGrSystem2.Data, GBrainTerm.Left, GBrainTerm.Top);
300 BitBltBitmap(BrainRandom.Picture, 0, 0, 64, 64, HGrSystem2.Data, GBrainRandom.Left, GBrainRandom.Top);
301
302 LoadAiBrainsPictures;
303
304 EmptyPicture := TBitmap.Create;
305 EmptyPicture.PixelFormat := pf24bit;
306 EmptyPicture.SetSize(64, 64);
307 EmptyPicture.Canvas.FillRect(0, 0, EmptyPicture.Width, EmptyPicture.Height);
308 LogoBuffer := TBitmap.Create;
309 LogoBuffer.PixelFormat := pf24bit;
310 LogoBuffer.SetSize(wBuffer, 56);
311 LogoBuffer.Canvas.FillRect(0, 0, LogoBuffer.Width, LogoBuffer.Height);
312
313 MiniMap := TMiniMap.Create;
314 InitButtons;
315
316 PlayersBrain[0] := BrainTerm;
317 SlotAvailable := -1;
318 Tab := tbNew;
319 Diff0 := 2;
320 TurnValid := False;
321 Tracking := False;
322 FormerGames := TStringList.Create;
323 UpdateFormerGames;
324 MapFileName := '';
325 Maps := TStringList.Create;
326 UpdateMaps;
327end;
328
329procedure TStartDlg.FormDestroy(Sender: TObject);
330begin
331 SaveConfig;
332 FreeAndNil(Translator);
333 FreeAndNil(FormerGames);
334 FreeAndNil(Maps);
335 FreeAndNil(EmptyPicture);
336 FreeAndNil(LogoBuffer);
337 FreeAndNil(PlayerSlots);
338 FreeAndNil(MiniMap);
339end;
340
341procedure TStartDlg.SmartInvalidate(x0, y0, x1, y1: integer;
342 invalidateTab0: boolean);
343var
344 i: integer;
345 r0, r1: HRgn;
346begin
347 r0 := CreateRectRgn(x0, y0, x1, y1);
348 for i := 0 to ControlCount - 1 do
349 if not (Controls[i] is TArea) and Controls[i].Visible then
350 begin
351 with Controls[i].BoundsRect do
352 r1 := CreateRectRgn(left, top, Right, Bottom);
353 CombineRgn(r0, r0, r1, RGN_DIFF);
354 DeleteObject(r1);
355 end;
356 if not invalidateTab0 then begin
357 r1 := CreateRectRgn(0, 0, 6 + 36, 3 + 38); // tab 0 icon
358 CombineRgn(r0, r0, r1, RGN_DIFF);
359 DeleteObject(r1);
360 end;
361 InvalidateRgn(Handle, r0, false);
362 DeleteObject(r0);
363end;
364
365procedure TStartDlg.LoadConfig;
366var
367 Reg: TRegistry;
368 I: Integer;
369 S: string;
370 {$IFDEF WINDOWS}
371 ResolutionX, ResolutionY, ResolutionBPP, ResolutionFreq: Integer;
372 {$ENDIF}
373 ScreenMode: Integer;
374begin
375 Reg := TRegistry.Create;
376 with Reg do try
377 // Initialize AI assignment
378 OpenKey(AppRegistryKey + '\AI', True);
379 for I := 0 to nPlOffered - 1 do begin
380 if I = 0 then S := ':StdIntf'
381 else S := 'StdAI';
382 if not ValueExists('Control' + IntToStr(I)) then
383 WriteString('Control' + IntToStr(I), S);
384 if not ValueExists('Diff' + IntToStr(I)) then
385 WriteInteger('Diff' + IntToStr(I), 2);
386 end;
387
388 OpenKey(AppRegistryKey, True);
389 if ValueExists('Gamma') then Gamma := ReadInteger('Gamma')
390 else Gamma := 100;
391 if Gamma <> 100 then InitGammaLookupTable;
392 if ValueExists('Locale') then LocaleCode := ReadString('Locale')
393 else LocaleCode := '';
394 if ValueExists('WorldSize') then WorldSize := Reg.ReadInteger('WorldSize')
395 else WorldSize := DefaultWorldSize;
396 if ValueExists('LandMass') then StartLandMass := Reg.ReadInteger('LandMass')
397 else StartLandMass := DefaultLandMass;
398 if ValueExists('MaxTurn') then MaxTurn := Reg.ReadInteger('MaxTurn')
399 else MaxTurn := 800;
400 if ValueExists('DefaultAI') then DefaultAI := Reg.ReadString('DefaultAI')
401 else DefaultAI := 'StdAI';
402 if ValueExists('AutoEnemies') then AutoEnemies := Reg.ReadInteger('AutoEnemies')
403 else AutoEnemies := 8;
404 if ValueExists('AutoDiff') then AutoDiff := Reg.ReadInteger('AutoDiff')
405 else AutoDiff := 1;
406 if ValueExists('StartTab') then ShowTab := TStartTab(Reg.ReadInteger('StartTab'))
407 else ShowTab := tbNew;
408 if ValueExists('LastGame') then LastGame := Reg.ReadString('LastGame')
409 else LastGame := '';
410 if ValueExists('NetworkEnabled') then NetworkEnabled := Reg.ReadBool('NetworkEnabled')
411 else NetworkEnabled := False;
412
413 if ValueExists('ScreenMode') then
414 ScreenMode := ReadInteger('ScreenMode')
415 else ScreenMode := 1;
416 FullScreen := ScreenMode > 0;
417 if ValueExists('MultiControl') then
418 MultiControl := ReadInteger('MultiControl')
419 else MultiControl := 0;
420 {$IFDEF WINDOWS}
421 if ValueExists('ResolutionX') then
422 ResolutionX := ReadInteger('ResolutionX');
423 if ValueExists('ResolutionY') then
424 ResolutionY := ReadInteger('ResolutionY');
425 if ValueExists('ResolutionBPP') then
426 ResolutionBPP := ReadInteger('ResolutionBPP');
427 if ValueExists('ResolutionFreq') then
428 ResolutionFreq := ReadInteger('ResolutionFreq');
429 if ScreenMode = 2 then
430 ChangeResolution(ResolutionX, ResolutionY, ResolutionBPP,
431 ResolutionFreq);
432 {$ENDIF}
433 finally
434 Free;
435 end;
436
437 KeyBindings.LoadFromRegistry(HKEY_CURRENT_USER, AppRegistryKey + '\KeyBindings');
438end;
439
440procedure TStartDlg.SaveConfig;
441var
442 Reg: TRegistry;
443begin
444 Reg := TRegistry.Create;
445 with Reg do try
446 OpenKey(AppRegistryKey, True);
447 WriteInteger('WorldSize', WorldSize);
448 WriteInteger('LandMass', StartLandMass);
449 WriteString('Locale', LocaleCode);
450 WriteInteger('Gamma', Gamma);
451 if FullScreen then WriteInteger('ScreenMode', 1)
452 else WriteInteger('ScreenMode', 0);
453 WriteInteger('MultiControl', MultiControl);
454 WriteInteger('StartTab', Integer(ShowTab));
455 WriteString('LastGame', LastGame);
456 WriteBool('NetworkEnabled', NetworkEnabled);
457 finally
458 Free;
459 end;
460
461 KeyBindings.SaveToRegistry(HKEY_CURRENT_USER, AppRegistryKey + '\KeyBindings');
462end;
463
464procedure TStartDlg.LoadLanguages;
465var
466 I: Integer;
467begin
468 Translator := TTranslator.Create(nil);
469 with Translator, Languages do begin
470 AddNew('zh-Hant', 'Traditional Chinese');
471 AddNew('zh-Hans', 'Simplified Chinese');
472 SearchByCode('').Available := True;
473
474 for I := 1 to Languages.Count - 1 do
475 with Languages[I] do begin
476 Available := DirectoryExists(HomeDir + 'Localization' + DirectorySeparator + Code) or (Code = 'en');
477 end;
478 end;
479end;
480
481procedure TStartDlg.LoadAiBrainsPictures;
482var
483 AiBrains: TBrains;
484begin
485 AiBrains := TBrains.Create(False);
486 try
487 Brains.GetByKind(btAI, AiBrains);
488 AiBrains.LoadPictures;
489 finally
490 FreeAndNil(AiBrains);
491 end;
492end;
493
494procedure TStartDlg.UpdateInterface;
495var
496 r0, r1: HRgn;
497 Location: TPoint;
498begin
499 if FullScreen then begin
500 Location := Point((Screen.Width - 800) * 3 div 8,
501 Screen.Height - Height - (Screen.Height - 600) div 3);
502 BoundsRect := Bounds(Location.X, Location.Y, Width, Height);
503
504 r0 := CreateRectRgn(0, 0, Width, Height);
505 r1 := CreateRectRgn(TabOffset + 4 * TabSize + 2, 0, Width, TabHeight);
506 CombineRgn(r0, r0, r1, RGN_DIFF);
507 DeleteObject(r1);
508 r1 := CreateRectRgn(QuitBtn.Left, QuitBtn.Top, QuitBtn.Left + QuitBtn.Width,
509 QuitBtn.top + QuitBtn.Height);
510 CombineRgn(r0, r0, r1, RGN_OR);
511 DeleteObject(r1);
512 SetWindowRgn(Handle, r0, False);
513 DeleteObject(r0); // causes crash with Windows 95
514 end else begin
515 BoundsRect := Bounds((Screen.Width - Width) div 2,
516 (Screen.Height - Height) div 2, Width, Height)
517 end;
518end;
519
520procedure TStartDlg.ShowSettings;
521begin
522 SettingsDlg := TSettingsDlg.Create(nil);
523 if SettingsDlg.ShowModal = mrOk then begin
524 LoadAssets;
525 Invalidate;
526 UpdateInterface;
527 Background.UpdateInterface;
528 end;
529 FreeAndNil(SettingsDlg);
530end;
531
532procedure TStartDlg.DrawAction(y, IconIndex: integer; HeaderItem, TextItem: string);
533begin
534 Canvas.Font.Assign(UniFont[ftCaption]);
535 Canvas.Font.Style := Canvas.Font.Style + [fsUnderline];
536 RisedTextOut(Canvas, xAction, y - 3, Phrases2.Lookup(HeaderItem));
537 Canvas.Font.Assign(UniFont[ftNormal]);
538 BiColorTextOut(Canvas, Colors.Canvas.Pixels[clkAge0 - 1, cliDimmedText],
539 $000000, xAction, y + 21, Phrases2.Lookup(TextItem));
540
541 UnshareBitmap(LogoBuffer);
542 BitBltCanvas(LogoBuffer.Canvas, 0, 0, 50, 50, Canvas,
543 xActionIcon - 2, y - 2);
544 GlowFrame(LogoBuffer, 8, 8, 34, 34, $202020);
545 BitBltCanvas(Canvas, xActionIcon - 2, y - 2, 50, 50,
546 LogoBuffer.Canvas, 0, 0);
547 BitBltCanvas(Canvas, xActionIcon, y, 40, 40, BigImp.Canvas,
548 (IconIndex mod 7) * xSizeBig + 8, (IconIndex div 7) * ySizeBig);
549 RFrame(Canvas, xActionIcon - 1, y - 1, xActionIcon + 40, y + 40,
550 $000000, $000000);
551end;
552
553procedure TStartDlg.FormPaint(Sender: TObject);
554const
555 TabNames: array[TStartTab] of Integer = (0, 11, 3, 4);
556var
557 i, w, h, xMini, yMini, y: integer;
558 s: string;
559 Tab2: TStartTab;
560 MainAction: TMainAction;
561begin
562 PaintBackground(self, 3, 3, TabOffset + 4 * TabSize - 4, TabHeight - 3);
563 PaintBackground(self, 3, TabHeight + 3, ClientWidth - 6,
564 ClientHeight - TabHeight - 6);
565 with Canvas do
566 begin
567 Brush.Color := $000000;
568 FillRect(Rect(0, 1, ClientWidth, 3));
569 FillRect(Rect(TabOffset + 4 * TabSize + 2, 0, ClientWidth, TabHeight));
570 Brush.Style := bsClear;
571 end;
572 if Page in [pgStartRandom, pgStartMap] then
573 begin
574 Frame(Canvas, 328, yMain + 112 - 15, ClientWidth, Up2Btn.top + 38,
575 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
576 if AutoDiff > 0 then
577 begin
578 Frame(Canvas, -1 { x0Brain-dxBrain } ,
579 yMain + 112 - 15 { Up1Btn.Top-12 }{ y0Brain-dyBrain } ,
580 x0Brain + dxBrain + 64, Up2Btn.top + 38 { y0Brain+dyBrain+64 } ,
581 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
582 end;
583 end
584 else if Page <> pgMain then
585 Frame(Canvas, 328, Up1Btn.top - 15, ClientWidth, Up2Btn.top + 38,
586 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
587 Frame(Canvas, 0, 0, ClientWidth - 1, ClientHeight - 1, 0, 0);
588
589 // draw tabs
590 Frame(Canvas, 2, 2 + 2 * integer(Tab <> tbMain), TabOffset + (0 + 1) * TabSize - 1,
591 TabHeight, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
592 Frame(Canvas, 1, 1 + 2 * integer(Tab <> tbMain), TabOffset + (0 + 1) * TabSize,
593 TabHeight, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
594 Canvas.Pixels[1, 1 + 2 * integer(Tab <> tbMain)] := MainTexture.ColorBevelShade;
595 for Tab2 := tbMap to tbPrevious do
596 begin
597 Frame(Canvas, TabOffset + Integer(Tab2) * TabSize + 2, 2 + 2 * integer(Tab <> Tab2),
598 TabOffset + (Integer(Tab2) + 1) * TabSize - 1, TabHeight, MainTexture.ColorBevelLight,
599 MainTexture.ColorBevelShade);
600 Frame(Canvas, TabOffset + Integer(Tab2) * TabSize + 1, 1 + 2 * integer(Tab <> Tab2),
601 TabOffset + (Integer(Tab2) + 1) * TabSize, TabHeight, MainTexture.ColorBevelLight,
602 MainTexture.ColorBevelShade);
603 Canvas.Pixels[TabOffset + Integer(Tab2) * TabSize + 1, 1 + 2 * integer(Tab <> Tab2)] :=
604 MainTexture.ColorBevelShade;
605 end;
606 Canvas.Font.Assign(UniFont[ftNormal]);
607 for Tab2 := tbMap to tbPrevious do
608 begin
609 s := Phrases.Lookup('STARTCONTROLS', TabNames[Tab2]);
610 RisedTextOut(Canvas, TabOffset + Integer(Tab2) * TabSize + 1 +
611 (TabSize - BiColorTextWidth(Canvas, s)) div 2,
612 10 + 2 * integer(Tab <> Tab2), s);
613 end;
614 Frame(Canvas, TabOffset + 4 * TabSize + 1, -1, ClientWidth, TabHeight,
615 $000000, $000000);
616 Frame(Canvas, 1, TabHeight + 1, ClientWidth - 2, ClientHeight - 2,
617 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
618 Frame(Canvas, 2, TabHeight + 2, ClientWidth - 3, ClientHeight - 3,
619 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
620 if Tab = tbMain then
621 begin
622 PaintBackground(self, 3, TabHeight - 1, TabSize - 4 - 3 + TabOffset + 3, 4);
623 Canvas.Pixels[2, TabHeight] := MainTexture.ColorBevelLight;
624 end
625 else
626 begin
627 PaintBackground(self, TabOffset + 3 + Integer(Tab) * TabSize, TabHeight - 1,
628 TabSize - 4, 4);
629 Canvas.Pixels[TabOffset + Integer(Tab) * TabSize + 2, TabHeight] :=
630 MainTexture.ColorBevelLight;
631 end;
632 Canvas.Pixels[TabOffset + (Integer(Tab) + 1) * TabSize - 1, TabHeight + 1] :=
633 MainTexture.ColorBevelShade;
634 if Tab < tbPrevious then
635 Frame(Canvas, TabOffset + (Integer(Tab) + 1) * TabSize + 1, 3,
636 TabOffset + (Integer(Tab) + 1) * TabSize + 2, TabHeight, MainTexture.ColorBevelShade,
637 MainTexture.ColorBevelShade); // Tab shadow
638
639 // Paint menu logo
640 UnshareBitmap(LogoBuffer);
641 BitBltCanvas(LogoBuffer.Canvas, 0, 0, MenuLogo.Width, MenuLogo.Height, Canvas, 6,
642 3 + 2 * integer(Tab <> tbMain));
643
644 ImageOp_BCC(LogoBuffer, Templates.Data, 0, 0, MenuLogo.Left, MenuLogo.Top,
645 MenuLogo.Width, MenuLogo.Height - 9, $BFBF20, $4040DF); // logo part 1
646 ImageOp_BCC(LogoBuffer, Templates.Data, 10, 27, MenuLogo.Left + 10,
647 MenuLogo.Top + 27, MenuLogo.Width - 10, 9, $BFBF20, $4040DF); // logo part 2
648 BitBltCanvas(Canvas, 6, 3 + 2 * integer(Tab <> tbMain), MenuLogo.Width, MenuLogo.Height,
649 LogoBuffer.Canvas, 0, 0);
650
651 if Page = pgMain then begin
652 if SelectedAction <> maNone then // mark selected action
653 for i := 0 to (ClientWidth - 2 * ActionSideBorder) div wBuffer + 1 do
654 begin
655 w := ClientWidth - 2 * ActionSideBorder - i * wBuffer;
656 if w > wBuffer then
657 w := wBuffer;
658 h := ActionPitch;
659 if yAction + Integer(SelectedAction) * ActionPitch - 8 + h > ClientHeight - ActionBottomBorder
660 then
661 h := ClientHeight - ActionBottomBorder -
662 (yAction + Integer(SelectedAction) * ActionPitch - 8);
663
664 UnshareBitmap(LogoBuffer);
665 BitBltCanvas(LogoBuffer.Canvas, 0, 0, w, h, Canvas,
666 ActionSideBorder + i * wBuffer, yAction + Integer(SelectedAction) * ActionPitch
667 - 8);
668 MakeBlue(LogoBuffer, 0, 0, w, h);
669 BitBltCanvas(Canvas, ActionSideBorder + i * wBuffer,
670 yAction + Integer(SelectedAction) * ActionPitch - 8, w, h,
671 LogoBuffer.Canvas, 0, 0);
672 end;
673 y := yAction;
674 for MainAction := Low(TMainActionSet) to High(TMainActionSet) do
675 begin
676 if MainAction in ActionsOffered then
677 case MainAction of
678 maConfig: DrawAction(y, 25, 'ACTIONHEADER_CONFIG', 'ACTION_CONFIG');
679 maManual: DrawAction(y, 19, 'ACTIONHEADER_MANUAL', 'ACTION_MANUAL');
680 maCredits: DrawAction(y, 22, 'ACTIONHEADER_CREDITS', 'ACTION_CREDITS');
681 maAIDev: DrawAction(y, 24, 'ACTIONHEADER_AIDEV', 'ACTION_AIDEV');
682 maWeb:
683 begin
684 Canvas.Font.Assign(UniFont[ftCaption]);
685 // Canvas.Font.Style:=Canvas.Font.Style+[fsUnderline];
686 RisedTextOut(Canvas, xActionIcon + 99, y,
687 Format(Phrases2.Lookup('ACTIONHEADER_WEB'), [CevoHomepageShort]));
688 Canvas.Font.Assign(UniFont[ftNormal]);
689
690 UnshareBitmap(LogoBuffer);
691 BitBltCanvas(LogoBuffer.Canvas, 0, 0, LinkArrows.Width, LinkArrows.Height, Canvas,
692 xActionIcon, y + 2);
693 ImageOp_BCC(LogoBuffer, Templates.Data, Point(0, 0), LinkArrows.BoundsRect, 0,
694 Colors.Canvas.Pixels[clkAge0 - 1, cliDimmedText]);
695 BitBltCanvas(Canvas, xActionIcon, y + 2, LinkArrows.Width, LinkArrows.Height,
696 LogoBuffer.Canvas, 0, 0);
697 end;
698 end;
699 Inc(y, ActionPitch);
700 end;
701 end
702 else if Page in [pgStartRandom, pgStartMap] then
703 begin
704 UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 10),
705 TurnToString(MaxTurn), 344, y0Mini + 61, 170);
706
707 s := Phrases.Lookup('STARTCONTROLS', 7);
708 w := Canvas.TextWidth(s);
709 LoweredTextOut(Canvas, -2, MainTexture, x0Brain + 32 - w div 2,
710 y0Brain + dyBrain + 69, s);
711
712 InitOrnament;
713 if AutoDiff < 0 then
714 begin
715 for i := 12 to 19 do
716 if (i < 13) or (i > 17) then begin
717 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
718 HGrSystem2.Mask.Canvas, Ornament.Left, Ornament.Top, SRCAND);
719 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
720 HGrSystem2.Data.Canvas, Ornament.Left, Ornament.Top, SRCPAINT);
721 end;
722 PaintLogo(Canvas, 69 + 11 * 27, yLogo, MainTexture.ColorBevelLight,
723 MainTexture.ColorBevelShade);
724
725 for i := 0 to nPlOffered - 1 do
726 if 1 shl i and SlotAvailable <> 0 then
727 begin
728 if Assigned(PlayersBrain[i]) then
729 FrameImage(Canvas, PlayersBrain[i].Picture, xBrain[i], yBrain[i],
730 64, 64, 0, 0, true)
731 else
732 FrameImage(Canvas, EmptyPicture, xBrain[i], yBrain[i], 64, 64,
733 0, 0, true);
734 if Assigned(PlayersBrain[I]) and (PlayersBrain[i].Kind in [btTerm, btRandom, btAI]) then
735 begin
736 BitBltCanvas(Canvas, xBrain[i] - 18, yBrain[i] + 19, 12, 14,
737 HGrSystem.Data.Canvas, 134 + (Difficulty[i] - 1) *
738 13, 28);
739 Frame(Canvas, xBrain[i] - 19, yBrain[i] + 18, xBrain[i] - 18 + 12,
740 yBrain[i] + (19 + 14), $000000, $000000);
741 RFrame(Canvas, PlayerSlots[i].DiffUpBtn.left - 1, PlayerSlots[i].DiffUpBtn.top - 1,
742 PlayerSlots[i].DiffUpBtn.left + 12, PlayerSlots[i].DiffUpBtn.top + 24,
743 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
744 with Canvas do
745 begin
746 Brush.Color := $000000;
747 FillRect(Rect(xBrain[i] - 5, yBrain[i] + 25, xBrain[i] - 2,
748 yBrain[i] + 27));
749 Brush.Style := bsClear;
750 end;
751 if PlayerSlots[I].OfferMultiple then
752 begin
753 RFrame(Canvas, PlayerSlots[I].MultiBtn.left - 1, PlayerSlots[I].MultiBtn.top - 1,
754 PlayerSlots[I].MultiBtn.left + 12, PlayerSlots[I].MultiBtn.top + 12,
755 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
756 BitBltCanvas(Canvas, xBrain[i] - 31, yBrain[i], 13, 12,
757 HGrSystem.Data.Canvas, 88, 47);
758 end;
759 end;
760 if Assigned(PlayersBrain[i]) then
761 begin
762 PlayerSlots[i].DiffUpBtn.Hint := Format(Phrases.Lookup('STARTCONTROLS', 9),
763 [PlayersBrain[i].Name]);
764 PlayerSlots[i].DiffDownBtn.Hint := PlayerSlots[i].DiffUpBtn.Hint;
765 end;
766 end;
767 end
768 else
769 begin
770 DLine(Canvas, 24, 198, yMain + 140 + 19, MainTexture.ColorBevelLight,
771 MainTexture.ColorBevelShade);
772 RisedTextOut(Canvas, 24 { x0Brain+32-BiColorTextWidth(Canvas,s) div 2 } ,
773 yMain + 140 { y0Mini-77 } , Phrases.Lookup('STARTCONTROLS', 15));
774 if Page = pgStartRandom then
775 s := IntToStr(AutoEnemies)
776 else if nMapStartPositions = 0 then
777 s := '0'
778 else
779 s := IntToStr(nMapStartPositions - 1);
780 RisedTextOut(Canvas, 198 - BiColorTextWidth(Canvas, s), yMain + 140, s);
781
782 DLine(Canvas, 24, xDefault - 6, yMain + 164 + 19,
783 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
784 RisedTextOut(Canvas, 24 { x0Brain+32-BiColorTextWidth(Canvas,s) div 2 } ,
785 yMain + 164 { y0Mini-77 } , Phrases.Lookup('STARTCONTROLS', 16));
786 if AutoDiff = 1 then
787 FrameImage(Canvas, Brains.GetBeginner.Picture, xDefault, yDefault, 64,
788 64, 0, 0, false)
789 else
790 FrameImage(Canvas, BrainDefault.Picture, xDefault, yDefault, 64, 64,
791 0, 0, true);
792 DLine(Canvas, 56, 272, y0Mini + 61 + 19, MainTexture.ColorBevelLight,
793 MainTexture.ColorBevelShade);
794
795 RisedTextOut(Canvas, 56, y0Mini + 61,
796 Phrases.Lookup('STARTCONTROLS', 14));
797 s := Phrases.Lookup('AUTODIFF', AutoDiff - 1);
798 RisedTextOut(Canvas, 272 - BiColorTextWidth(Canvas, s), y0Mini + 61, s);
799
800 for i := 0 to 19 do
801 if (i < 2) or (i > 6) then begin
802 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
803 HGrSystem2.Mask.Canvas, Ornament.Left, Ornament.Top, SRCAND);
804 BitBltCanvas(Canvas, 9 + i * 27, yLogo - 2, Ornament.Width, Ornament.Height,
805 HGrSystem2.Data.Canvas, Ornament.Left, Ornament.Top, SRCPAINT);
806 end;
807 PaintLogo(Canvas, 69, yLogo, MainTexture.ColorBevelLight,
808 MainTexture.ColorBevelShade);
809 end;
810 end
811 else if Page = pgLoad then
812 begin
813 // RisedTextOut(Canvas,x0Mini+2-BiColorTextWidth(Canvas,BookDate) div 2,y0Mini-73,BookDate);
814 if LastTurn > 0 then
815 begin
816 PaintProgressBar(Canvas, 6, xTurnSlider, yTurnSlider, 0,
817 LoadTurn * wTurnSlider div LastTurn, wTurnSlider, MainTexture);
818 Frame(Canvas, xTurnSlider - 2, yTurnSlider - 2, xTurnSlider + wTurnSlider
819 + 1, yTurnSlider + 8, $B0B0B0, $FFFFFF);
820 RFrame(Canvas, xTurnSlider - 3, yTurnSlider - 3, xTurnSlider + wTurnSlider
821 + 2, yTurnSlider + 9, $FFFFFF, $B0B0B0);
822 end
823 else
824 DLine(Canvas, 344, 514, y0Mini + 61 + 19, MainTexture.ColorBevelLight,
825 MainTexture.ColorBevelShade);
826 RisedTextOut(Canvas, 344, y0Mini + 61, Phrases.Lookup('STARTCONTROLS', 8));
827 s := TurnToString(LoadTurn);
828 RisedTextOut(Canvas, 514 - BiColorTextWidth(Canvas, s), y0Mini + 61, s);
829 end
830 else if Page = pgEditRandom then
831 begin
832 UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 5),
833 IntToStr((WorldSizes[WorldSize].X * WorldSizes[WorldSize].Y * 20 +
834 DefaultWorldTiles div 2) div DefaultWorldTiles * 5) + '%',
835 344, y0Mini - 77, 170);
836 UnderlinedTitleValue(Canvas, Phrases.Lookup('STARTCONTROLS', 6),
837 IntToStr(StartLandMass) + '%', 344, y0Mini + 61, 170);
838 end
839 else if Page = pgEditMap then
840 begin
841 // DLine(Canvas,344,514,y0Mini+61+19,MainTexture.ColorBevelLight,MainTexture.ColorBevelShade);
842 s := Format(Phrases2.Lookup('MAPPROP'),
843 [(nMapLandTiles * 100 + 556) div 1112,
844 // 1112 is typical for world with 100% size and default land mass
845 nMapStartPositions]);
846 RisedTextOut(Canvas, x0Mini - BiColorTextWidth(Canvas, s) div 2,
847 y0Mini + 61, s);
848 end;
849
850 if StartBtn.Visible then
851 BtnFrame(Canvas, StartBtn.BoundsRect, MainTexture);
852 if Up2Btn.Visible then
853 RFrame(Canvas, Up2Btn.left - 1, Up2Btn.top - 1, Up2Btn.left + 12,
854 Up2Btn.top + 24, MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
855 if Up1Btn.Visible then
856 RFrame(Canvas, Up1Btn.left - 1, Up1Btn.top - 1, Up1Btn.left + 12,
857 Up1Btn.top + 24, MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
858 if AutoDiffUpBtn.Visible then
859 RFrame(Canvas, AutoDiffUpBtn.left - 1, AutoDiffUpBtn.top - 1,
860 AutoDiffUpBtn.left + 12, AutoDiffUpBtn.top + 24, MainTexture.ColorBevelShade,
861 MainTexture.ColorBevelLight);
862 if AutoEnemyUpBtn.Visible then
863 RFrame(Canvas, AutoEnemyUpBtn.left - 1, AutoEnemyUpBtn.top - 1,
864 AutoEnemyUpBtn.left + 12, AutoEnemyUpBtn.top + 24,
865 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
866 if CustomizeBtn.Visible then
867 RFrame(Canvas, CustomizeBtn.left - 1, CustomizeBtn.top - 1,
868 CustomizeBtn.left + 12, CustomizeBtn.top + 12, MainTexture.ColorBevelShade,
869 MainTexture.ColorBevelLight);
870 if List.Visible then
871 EditFrame(Canvas, List.BoundsRect, MainTexture);
872 if RenameBtn.Visible then
873 BtnFrame(Canvas, RenameBtn.BoundsRect, MainTexture);
874 if DeleteBtn.Visible then
875 BtnFrame(Canvas, DeleteBtn.BoundsRect, MainTexture);
876 if Page = pgLoad then
877 BtnFrame(Canvas, ReplayBtn.BoundsRect, MainTexture);
878
879 if not (Page in [pgMain, pgNoLoad]) then
880 begin
881 xMini := x0Mini - MiniMap.Size.X;
882 yMini := y0Mini - MiniMap.Size.Y div 2;
883 Frame(Canvas, xMini, yMini, xMini + 3 + MiniMap.Size.X * 2,
884 yMini + 3 + MiniMap.Size.Y, MainTexture.ColorBevelLight,
885 MainTexture.ColorBevelShade);
886 Frame(Canvas, xMini + 1, yMini + 1, xMini + 2 + MiniMap.Size.X * 2,
887 yMini + 2 + MiniMap.Size.Y, MainTexture.ColorBevelShade,
888 MainTexture.ColorBevelLight);
889
890 s := '';
891 if MiniMap.Mode = mmPicture then
892 begin
893 BitBltCanvas(Canvas, xMini + 2, yMini + 2, MiniMap.Size.X * 2, MiniMap.Size.Y,
894 MiniMap.Bitmap.Canvas, 0, 0);
895 if Page = pgStartRandom then
896 s := Phrases.Lookup('RANMAP')
897 end
898 else if MiniMap.Mode = mmMultiPlayer then
899 s := Phrases.Lookup('MPMAP')
900 else if Page = pgStartMap then
901 s := Copy(MapFileName, 1, Length(MapFileName) - Length(CevoMapExt))
902 else if Page = pgEditMap then
903 s := List.Items[List.ItemIndex]
904 else if Page = pgNoLoad then
905 s := Phrases.Lookup('NOGAMES');
906 if s <> '' then
907 RisedTextOut(Canvas, x0Mini + 2 - BiColorTextWidth(Canvas, s) div 2,
908 y0Mini - 8, s);
909 end;
910end;
911
912procedure TStartDlg.FormShow(Sender: TObject);
913begin
914 {$IFDEF UNIX}
915 ShowInTaskBar := stAlways;
916 {$ENDIF}
917 MainTexture.Age := -1;
918 List.Font.Color := MainTexture.ColorMark;
919
920 Fill(EmptyPicture.Canvas, Bounds(0, 0, 64, 64),
921 Point((Maintexture.Width - 64) div 2, (Maintexture.Height - 64) div 2));
922
923 DarkenImage(EmptyPicture, 28);
924
925 Difficulty[0] := Diff0;
926
927 SelectedAction := maNone;
928 if ShowTab = tbPrevious then
929 PreviewMap(StartLandMass); // avoid delay on first TabX change
930 ChangeTab(ShowTab);
931 Background.Enabled := False;
932end;
933
934procedure TStartDlg.UnlistBackupFile(FileName: string);
935var
936 I: Integer;
937begin
938 if FileName[1] <> '~' then
939 FileName := '~' + FileName;
940 I := FormerGames.Count - 1;
941 while (I >= 0) and (AnsiCompareFileName(FormerGames[I], FileName) <> 0) do
942 Dec(I);
943 if I >= 0 then
944 begin
945 FormerGames.Delete(I);
946 if ListIndex[tbNew] = I then
947 ListIndex[tbNew] := 0;
948 end;
949end;
950
951procedure TStartDlg.StartBtnClick(Sender: TObject);
952var
953 I, GameCount, MapCount: Integer;
954 FileName: string;
955 Reg: TRegistry;
956begin
957 case Page of
958 pgLoad:
959 begin // load
960 FileName := List.Items[List.ItemIndex];
961 if LoadGame(GetSavedDir + DirectorySeparator, FileName + CevoExt, LoadTurn, false)
962 then
963 UnlistBackupFile(FileName)
964 else
965 SimpleMessage(Phrases.Lookup('LOADERR'));
966 SlotAvailable := -1;
967 end;
968 pgStartRandom, pgStartMap:
969 if Assigned(PlayersBrain[0]) then
970 begin
971 if (Page = pgStartMap) and (nMapStartPositions = 0) and (AutoDiff > 0)
972 then
973 begin
974 SimpleMessage(Phrases.Lookup('NOSTARTPOS'));
975 Exit;
976 end;
977
978 Reg := TRegistry.Create;
979 with Reg do
980 try
981 OpenKey(AppRegistryKey, true);
982 if ValueExists('GameCount') then GameCount := ReadInteger('GameCount')
983 else GameCount := 0;
984
985 if (AutoDiff < 0) and (PlayersBrain[0].Kind = btNoTerm) then
986 FileName := 'Round' + IntToStr(GetProcessID())
987 else begin
988 Inc(GameCount);
989 FileName := Format(Phrases.Lookup('GAME'), [GameCount]);
990 end;
991
992 // Save settings and AI assignment
993 if Page = pgStartRandom then begin
994 SaveConfig;
995 OpenKey(AppRegistryKey + '\AI', True);
996 if AutoDiff < 0 then
997 for I := 0 to nPlOffered - 1 do begin
998 if not Assigned(PlayersBrain[I]) then
999 Reg.WriteString('Control' + IntToStr(I), '')
1000 else Reg.WriteString('Control' + IntToStr(I),
1001 PlayersBrain[I].FileName);
1002 WriteInteger('Diff' + IntToStr(I), Difficulty[I]);
1003 end;
1004 end;
1005
1006 OpenKey(AppRegistryKey, True);
1007 if BrainDefault.Kind <> btNetworkClient then begin
1008 if AutoDiff > 0 then begin
1009 WriteString('DefaultAI', BrainDefault.FileName);
1010 SlotAvailable := 0; // PlayerSlot will be invalid hereafter
1011 PlayersBrain[0] := BrainTerm;
1012 Difficulty[0] := PlayerAutoDiff[AutoDiff];
1013 for I := 1 to nPl - 1 do
1014 if (Page = pgStartRandom) and (I <= AutoEnemies) or
1015 (Page = pgStartMap) and (I < nMapStartPositions) then begin
1016 if AutoDiff = 1 then PlayersBrain[I] := Brains.GetBeginner
1017 else PlayersBrain[I] := BrainDefault;
1018 Difficulty[I] := EnemyAutoDiff[AutoDiff];
1019 end else PlayersBrain[I] := nil;
1020 end else begin
1021 for I := 6 to 8 do
1022 if (PlayersBrain[0].Kind <> btNoTerm) and (MultiControl and (1 shl I) <> 0)
1023 then begin
1024 PlayersBrain[I + 3] := PlayersBrain[I];
1025 Difficulty[I + 3] := Difficulty[I];
1026 PlayersBrain[I + 6] := PlayersBrain[I];
1027 Difficulty[I + 6] := Difficulty[I];
1028 end else begin
1029 PlayersBrain[I + 3] := nil;
1030 PlayersBrain[I + 6] := nil;
1031 end;
1032 end;
1033 end;
1034
1035 WriteInteger('AutoDiff', AutoDiff);
1036 WriteInteger('AutoEnemies', AutoEnemies);
1037 WriteInteger('MaxTurn', MaxTurn);
1038 WriteInteger('GameCount', GameCount);
1039 finally
1040 Free;
1041 end;
1042
1043 StartNewGame(GetSavedDir + DirectorySeparator, FileName + CevoExt, MapFileName,
1044 WorldSizes[WorldSize].X, WorldSizes[WorldSize].Y, StartLandMass, MaxTurn);
1045 UnlistBackupFile(FileName);
1046 end;
1047 pgEditMap:
1048 EditMap(GetMapsDir + DirectorySeparator + MapFileName, lxmax, lymax, StartLandMass);
1049 pgEditRandom: // new map
1050 begin
1051 Reg := TRegistry.Create;
1052 with Reg do
1053 try
1054 OpenKey(AppRegistryKey, True);
1055 if ValueExists('MapCount') then MapCount := ReadInteger('MapCount')
1056 else MapCount := 0;
1057 Inc(MapCount);
1058 WriteInteger('MapCount', MapCount);
1059 finally
1060 Free;
1061 end;
1062 MapFileName := Format(Phrases.Lookup('MAP'), [MapCount]) + CevoMapExt;
1063 EditMap(GetMapsDir + DirectorySeparator + MapFileName,
1064 WorldSizes[WorldSize].X, WorldSizes[WorldSize].Y, StartLandMass);
1065 end;
1066 end;
1067end;
1068
1069procedure TStartDlg.ListKeyPress(Sender: TObject; var Key: char);
1070begin
1071 if Key = #13 then StartBtnClick(Sender);
1072end;
1073
1074procedure TStartDlg.ListKeyDown(Sender: TObject; var Key: Word;
1075 Shift: TShiftState);
1076const
1077 DelKey = 46;
1078begin
1079 if Key = DelKey then DeleteBtnClick(Sender)
1080 else FormKeyDown(Sender, Key, Shift);
1081end;
1082
1083procedure TStartDlg.PaintInfo;
1084begin
1085 case Page of
1086 pgStartRandom: begin
1087 MiniMap.Mode := mmPicture;
1088 MiniMap.PaintRandom(3, StartLandMass, WorldSizes[WorldSize]);
1089 end;
1090 pgNoLoad: begin
1091 MiniMap.Mode := mmNone;
1092 MiniMap.Size := WorldSizes[DefaultWorldSize];
1093 end;
1094 pgLoad: begin
1095 MiniMap.LoadFromLogFile(GetSavedDir + DirectorySeparator +
1096 List.Items[List.ItemIndex] + CevoExt, LastTurn, WorldSizes[DefaultWorldSize]);
1097 // BookDate:=DateToStr(FileDateToDateTime(FileAge(FileName)));
1098 if not TurnValid then begin
1099 LoadTurn := LastTurn;
1100 SmartInvalidate(xTurnSlider - 2, y0Mini + 61,
1101 xTurnSlider + wTurnSlider + 2, yTurnSlider + 9);
1102 end;
1103 TurnValid := True;
1104 end;
1105 pgEditRandom: begin
1106 MapFileName := '';
1107 MiniMap.Mode := mmPicture;
1108 MiniMap.PaintRandom(4, StartLandMass, WorldSizes[WorldSize]);
1109 end;
1110 pgStartMap, pgEditMap:
1111 begin
1112 if Page = pgEditMap then
1113 MapFileName := List.Items[List.ItemIndex] + CevoMapExt;
1114 MiniMap.LoadFromMapFile(GetMapsDir + DirectorySeparator + MapFileName,
1115 nMapLandTiles, nMapStartPositions);
1116 if Page = pgEditMap then
1117 SmartInvalidate(x0Mini - 112, y0Mini + 61, x0Mini + 112, y0Mini + 91);
1118 end;
1119 end;
1120 SmartInvalidate(x0Mini - lxmax, y0Mini - lymax div 2,
1121 x0Mini - lxmax + 2 * lxmax + 4, y0Mini - lymax div 2 + lymax + 4);
1122end;
1123
1124procedure TStartDlg.BrainClick(Sender: TObject);
1125var
1126 I: Integer;
1127begin
1128 // Play('BUTTON_UP');
1129 if PlayerPopupIndex < 0 then
1130 begin // change default AI
1131 BrainDefault := Brains[TMenuItem(Sender).Tag];
1132 SmartInvalidate(xDefault, yDefault, xDefault + 64, yDefault + 64);
1133 end
1134 else
1135 begin
1136 if Assigned(PlayersBrain[PlayerPopupIndex]) then
1137 PlayersBrain[PlayerPopupIndex].Flags := PlayersBrain[PlayerPopupIndex].Flags and not fUsed;
1138 if TMenuItem(Sender).Tag = -1 then begin
1139 PlayersBrain[PlayerPopupIndex] := nil;
1140 PlayerSlots[PlayerPopupIndex].DiffUpBtn.Visible := False;
1141 PlayerSlots[PlayerPopupIndex].DiffDownBtn.Visible := False;
1142 if PlayerSlots[PlayerPopupIndex].OfferMultiple then begin
1143 PlayerSlots[PlayerPopupIndex].MultiBtn.Visible := False;
1144 PlayerSlots[PlayerPopupIndex].MultiBtn.ButtonIndex := 2 + (MultiControl shr PlayerPopupIndex) and 1;
1145 end;
1146 MultiControl := MultiControl and not (1 shl PlayerPopupIndex);
1147 end else begin
1148 PlayersBrain[PlayerPopupIndex] := Brains[TMenuItem(Sender).Tag];
1149 PlayerSlots[PlayerPopupIndex].DiffUpBtn.Visible := PlayersBrain[PlayerPopupIndex].Kind in [btTerm, btRandom, btAI];
1150 PlayerSlots[PlayerPopupIndex].DiffDownBtn.Visible := PlayersBrain[PlayerPopupIndex].Kind in [btTerm, btRandom, btAI];
1151 if PlayerSlots[PlayerPopupIndex].OfferMultiple then begin
1152 PlayerSlots[PlayerPopupIndex].MultiBtn.Visible := PlayersBrain[PlayerPopupIndex].Kind in [btTerm, btRandom, btAI];
1153 PlayerSlots[PlayerPopupIndex].MultiBtn.ButtonIndex := 2 + (MultiControl shr PlayerPopupIndex) and 1;
1154 end;
1155 PlayersBrain[PlayerPopupIndex].Flags := PlayersBrain[PlayerPopupIndex].Flags or fUsed;
1156 if PlayersBrain[PlayerPopupIndex].Kind in [btNoTerm, btSuperVirtual] then
1157 Difficulty[PlayerPopupIndex] := 0 { supervisor }
1158 else
1159 Difficulty[PlayerPopupIndex] := 2;
1160 if (Page = pgStartRandom) and (PlayerSlots[PlayerPopupIndex].OfferMultiple) and
1161 (not Assigned(PlayersBrain[PlayerPopupIndex])) then
1162 MultiControl := MultiControl and not (1 shl PlayerPopupIndex);
1163 if (PlayerPopupIndex = 0) and (MapFileName <> '') then
1164 ChangePage(Page);
1165 if PlayersBrain[PlayerPopupIndex].Kind = btNoTerm then
1166 begin // turn all local players off
1167 for I := 1 to PlayerSlots.Count - 1 do
1168 if Assigned(PlayersBrain[I]) and (PlayersBrain[I].Kind = btTerm) then begin
1169 PlayersBrain[I] := nil;
1170 PlayerSlots[I].DiffUpBtn.Visible := false;
1171 PlayerSlots[I].DiffUpBtn.Tag := 0;
1172 PlayerSlots[I].DiffDownBtn.Visible := false;
1173 PlayerSlots[I].DiffDownBtn.Tag := 0;
1174 if PlayerSlots[I].OfferMultiple then begin
1175 PlayerSlots[I].MultiBtn.Visible := false;
1176 PlayerSlots[I].MultiBtn.Tag := 0;
1177 end;
1178 SmartInvalidate(xBrain[I] - 31, yBrain[I] - 1, xBrain[I] + 64,
1179 PlayerSlots[I].DiffUpBtn.top + 25);
1180 end;
1181 BrainTerm.Flags := BrainTerm.Flags and not fUsed;
1182 end;
1183 end;
1184 SmartInvalidate(xBrain[PlayerPopupIndex] - 31, yBrain[PlayerPopupIndex] - 1,
1185 xBrain[PlayerPopupIndex] + 64, PlayerSlots[PlayerPopupIndex].DiffUpBtn.top + 25);
1186 end;
1187end;
1188
1189procedure TStartDlg.OfferBrain(Brain: TBrain; FixedLines: Integer);
1190var
1191 J: Integer;
1192 MenuItem: TMenuItem;
1193begin
1194 MenuItem := TMenuItem.Create(PopupMenu1);
1195 if not Assigned(Brain) then MenuItem.Caption := Phrases.Lookup('NOMOD')
1196 else MenuItem.Caption := Brain.Name;
1197 MenuItem.Tag := Brains.IndexOf(Brain);
1198 MenuItem.OnClick := BrainClick;
1199 J := FixedLines;
1200 while (J < PopupMenu1.Items.Count) and
1201 (StrIComp(pchar(MenuItem.Caption), pchar(PopupMenu1.Items[J].Caption)) > 0) do
1202 Inc(J);
1203 MenuItem.RadioItem := True;
1204 if (PlayerPopupIndex < 0) then MenuItem.Checked := BrainDefault = Brain
1205 else MenuItem.Checked := PlayersBrain[PlayerPopupIndex] = Brain;
1206 PopupMenu1.Items.Insert(J, MenuItem);
1207end;
1208
1209procedure TStartDlg.InitPopup(PlayerIndex: Integer);
1210var
1211 I: Integer;
1212 FixedLines: integer;
1213 MenuItem: TMenuItem;
1214 AIBrains: TBrains;
1215begin
1216 FixedLines := 0;
1217 PlayerPopupIndex := PlayerIndex;
1218 EmptyMenu(PopupMenu1.Items);
1219 if PlayerPopupIndex < 0 then begin // select default AI
1220 if NetworkEnabled then begin
1221 OfferBrain(BrainNetworkClient, FixedLines);
1222 Inc(FixedLines);
1223 end;
1224
1225 MenuItem := TMenuItem.Create(PopupMenu1);
1226 MenuItem.Caption := '-';
1227 PopupMenu1.Items.Add(MenuItem);
1228
1229 Inc(FixedLines);
1230 if Brains.GetKindCount(btAI) >= 2 then begin
1231 OfferBrain(BrainRandom, FixedLines);
1232 Inc(FixedLines);
1233 end;
1234 AIBrains := TBrains.Create(False);
1235 Brains.GetByKind(btAI, AIBrains);
1236 for I := 0 to AIBrains.Count - 1 do // offer available AIs
1237 if AIBrains[I].Flags and fMultiple <> 0 then
1238 OfferBrain(AIBrains[I], FixedLines);
1239 FreeAndNil(AIBrains);
1240 end else begin
1241 if PlayerPopupIndex > 0 then begin
1242 OfferBrain(nil, FixedLines);
1243 Inc(FixedLines);
1244 end;
1245 for I := Brains.IndexOf(BrainTerm) downto 0 do // offer game interfaces
1246 if (PlayerPopupIndex = 0) or (Brains[i].Kind = btTerm) and
1247 (PlayersBrain[0].Kind <> btNoTerm) then begin
1248 OfferBrain(Brains[I], FixedLines);
1249 Inc(FixedLines);
1250 end;
1251 if PlayerPopupIndex > 0 then begin
1252 if NetworkEnabled then begin
1253 OfferBrain(BrainNetworkServer, FixedLines);
1254 Inc(FixedLines);
1255 end;
1256
1257 MenuItem := TMenuItem.Create(PopupMenu1);
1258 MenuItem.Caption := '-';
1259 PopupMenu1.Items.Add(MenuItem);
1260 Inc(FixedLines);
1261 if Brains.GetKindCount(btAI) >= 2 then begin
1262 OfferBrain(BrainRandom, FixedLines);
1263 Inc(FixedLines);
1264 end;
1265 AIBrains := TBrains.Create(False);
1266 Brains.GetByKind(btAI, AIBrains);
1267 for I := 0 to AIBrains.Count - 1 do // offer available AIs
1268 if (AIBrains[I].Flags and fMultiple <> 0) or (AIBrains[I].Flags and fUsed = 0)
1269 or (Brains[I] = PlayersBrain[PlayerPopupIndex]) then
1270 OfferBrain(AIBrains[i], FixedLines);
1271 FreeAndNil(AIBrains);
1272 end;
1273 end;
1274end;
1275
1276procedure TStartDlg.UpdateFormerGames;
1277var
1278 I: Integer;
1279 F: TSearchRec;
1280begin
1281 FormerGames.Clear;
1282 if FindFirst(GetSavedDir + DirectorySeparator + '*' + CevoExt, $21, F) = 0 then
1283 repeat
1284 I := FormerGames.Count;
1285 while (I > 0) and (F.Time < integer(FormerGames.Objects[I - 1])) do
1286 Dec(I);
1287 FormerGames.InsertObject(I, Copy(F.Name, 1, Length(F.Name) - 5),
1288 TObject(F.Time));
1289 until FindNext(F) <> 0;
1290 FindClose(F);
1291 I := FormerGames.IndexOf(LastGame);
1292 if I >= 0 then ListIndex[tbPrevious] := I
1293 else ListIndex[tbPrevious] := FormerGames.Count - 1;
1294 TurnValid := False;
1295end;
1296
1297procedure TStartDlg.UpdateMaps;
1298var
1299 f: TSearchRec;
1300begin
1301 Maps.Clear;
1302 if FindFirst(GetMapsDir + DirectorySeparator + '*' + CevoMapExt, $21, f) = 0 then
1303 repeat
1304 Maps.Add(Copy(f.Name, 1, Length(f.Name) - Length(CevoMapExt)));
1305 until FindNext(f) <> 0;
1306 FindClose(F);
1307 Maps.Sort;
1308 Maps.Insert(0, Phrases.Lookup('RANMAP'));
1309 ListIndex[tbMain] := Maps.IndexOf(Copy(MapFileName, 1, Length(MapFileName) - Length(CevoMapExt)));
1310 if ListIndex[tbMain] < 0 then
1311 ListIndex[tbMain] := 0;
1312end;
1313
1314procedure TStartDlg.ChangePage(NewPage: TStartPage);
1315var
1316 i, j, p1: integer;
1317 s: string;
1318 Reg: TRegistry;
1319 InvalidateTab0: boolean;
1320begin
1321 InvalidateTab0 := (Page = pgMain) or (NewPage = pgMain);
1322 Page := NewPage;
1323 case Page of
1324 pgStartRandom, pgStartMap:
1325 begin
1326 StartBtn.Caption := Phrases.Lookup('STARTCONTROLS', 1);
1327 if Page = pgStartRandom then
1328 i := nPlOffered
1329 else
1330 begin
1331 i := nMapStartPositions;
1332 if i = 0 then
1333 begin
1334 PlayersBrain[0] := BrainSuperVirtual;
1335 Difficulty[0] := 0;
1336 end;
1337 if PlayersBrain[0].Kind in [btNoTerm, btSuperVirtual] then
1338 inc(i);
1339 if i > nPl then
1340 i := nPl;
1341 if i <= nPlOffered then
1342 MultiControl := 0
1343 else
1344 MultiControl := InitMulti[i];
1345 end;
1346 if InitAlive[i] <> SlotAvailable then
1347 if Page = pgStartRandom then
1348 begin // restore AI assignment of last start
1349 Reg := TRegistry.Create;
1350 with Reg do
1351 try
1352 OpenKey(AppRegistryKey + '\AI', True);
1353 for p1 := 0 to nPlOffered - 1 do begin
1354 PlayersBrain[p1] := nil;
1355 s := ReadString('Control' + IntToStr(p1));
1356 Difficulty[p1] := ReadInteger('Diff' + IntToStr(p1));
1357 if s <> '' then
1358 for j := 0 to Brains.Count - 1 do
1359 if AnsiCompareFileName(s, Brains[j].FileName) = 0 then
1360 PlayersBrain[p1] := Brains[j];
1361 end;
1362 finally
1363 Free;
1364 end;
1365 end
1366 else
1367 for p1 := 1 to nPl - 1 do
1368 if 1 shl p1 and InitAlive[i] <> 0 then
1369 begin
1370 PlayersBrain[p1] := BrainDefault;
1371 Difficulty[p1] := 2;
1372 end
1373 else
1374 PlayersBrain[p1] := nil;
1375 SlotAvailable := InitAlive[i];
1376 for i := 0 to nPlOffered - 1 do
1377 if (AutoDiff < 0) and Assigned(PlayersBrain[i]) and
1378 (PlayersBrain[i].Kind in [btTerm, btRandom, btAI]) then
1379 begin
1380 PlayerSlots[i].DiffUpBtn.Tag := 768;
1381 PlayerSlots[i].DiffDownBtn.Tag := 768;
1382 end
1383 else
1384 begin
1385 PlayerSlots[i].DiffUpBtn.Tag := 0;
1386 PlayerSlots[i].DiffDownBtn.Tag := 0;
1387 end;
1388 for i := 6 to 8 do
1389 if (AutoDiff < 0) and Assigned(PlayersBrain[i]) and
1390 (PlayersBrain[i].Kind in [btTerm, btRandom, btAI]) then
1391 begin
1392 PlayerSlots[i].MultiBtn.Tag := 768;
1393 PlayerSlots[i].MultiBtn.ButtonIndex := 2 + (MultiControl shr i) and 1;
1394 PlayerSlots[i].MultiBtn.Enabled := Page = pgStartRandom
1395 end
1396 else
1397 PlayerSlots[i].MultiBtn.Tag := 0;
1398 if (AutoDiff > 0) and (Page <> pgStartMap) then
1399 begin
1400 AutoEnemyUpBtn.Tag := 768;
1401 AutoEnemyDownBtn.Tag := 768;
1402 end
1403 else
1404 begin
1405 AutoEnemyUpBtn.Tag := 0;
1406 AutoEnemyDownBtn.Tag := 0;
1407 end;
1408 if AutoDiff > 0 then
1409 begin
1410 AutoDiffUpBtn.Tag := 768;
1411 AutoDiffDownBtn.Tag := 768;
1412 end
1413 else
1414 begin
1415 AutoDiffUpBtn.Tag := 0;
1416 AutoDiffDownBtn.Tag := 0;
1417 end;
1418 end;
1419
1420 pgNoLoad, pgLoad:
1421 begin
1422 StartBtn.Caption := Phrases.Lookup('STARTCONTROLS', 2);
1423 RenameBtn.Hint := Phrases.Lookup('BTN_RENGAME');
1424 DeleteBtn.Hint := Phrases.Lookup('BTN_DELGAME');
1425 end;
1426
1427 pgEditRandom, pgEditMap:
1428 begin
1429 StartBtn.Caption := Phrases.Lookup('STARTCONTROLS', 12);
1430 RenameBtn.Hint := Phrases.Lookup('BTN_RENMAP');
1431 DeleteBtn.Hint := Phrases.Lookup('BTN_DELMAP');
1432 end;
1433 end;
1434
1435 PaintInfo;
1436 for i := 0 to ControlCount - 1 do
1437 Controls[i].Visible := Controls[i].Tag and (256 shl Integer(Page)) <> 0;
1438 if Page = pgLoad then
1439 ReplayBtn.Visible := MiniMap.Mode <> mmMultiPlayer;
1440 List.Invalidate;
1441 SmartInvalidate(0, 0, ClientWidth, ClientHeight, invalidateTab0);
1442end;
1443
1444procedure TStartDlg.ChangeTab(NewTab: TStartTab);
1445begin
1446 Tab := NewTab;
1447 case Tab of
1448 tbMap:
1449 List.Items.Assign(Maps);
1450 tbPrevious:
1451 List.Items.Assign(FormerGames);
1452 end;
1453 if Tab <> tbNew then
1454 if List.Count > 0 then begin
1455 if (ListIndex[Tab] < List.Count) and (ListIndex[Tab] >= 0) then begin
1456 List.ItemIndex := ListIndex[Tab];
1457 end else List.ItemIndex := 0;
1458 end else List.ItemIndex := -1;
1459 case Tab of
1460 tbMain:
1461 ChangePage(pgMain);
1462 tbMap:
1463 if List.ItemIndex = 0 then
1464 ChangePage(pgEditRandom)
1465 else
1466 ChangePage(pgEditMap);
1467 tbNew:
1468 if MapFileName = '' then
1469 ChangePage(pgStartRandom)
1470 else
1471 ChangePage(pgStartMap);
1472 tbPrevious:
1473 if FormerGames.Count = 0 then
1474 ChangePage(pgNoLoad)
1475 else
1476 ChangePage(pgLoad);
1477 end;
1478end;
1479
1480procedure TStartDlg.FormMouseDown(Sender: TObject; Button: TMouseButton;
1481 Shift: TShiftState; x, y: integer);
1482var
1483 I: Integer;
1484begin
1485 if (y < TabHeight + 1) and (x - TabOffset < TabSize * 4) and
1486 ((x - TabOffset) div TabSize <> Integer(Tab)) then
1487 begin
1488 // Play('BUTTON_DOWN');
1489 ListIndex[Tab] := List.ItemIndex;
1490 ChangeTab(TStartTab((x - TabOffset) div TabSize));
1491 end
1492 else if Page = pgMain then begin
1493 case SelectedAction of
1494 maConfig: ShowSettings;
1495 maManual: DirectHelp(cStartHelp);
1496 maCredits: DirectHelp(cStartCredits);
1497 maAIDev: OpenDocument(HomeDir + AITemplateFileName);
1498 maWeb: OpenURL(CevoHomepage);
1499 end;
1500 end
1501 else if (AutoDiff < 0) and ((Page = pgStartRandom) or (Page = pgStartMap) and
1502 (nMapStartPositions > 0)) then
1503 begin
1504 for I := 0 to nPlOffered - 1 do
1505 if (1 shl I and SlotAvailable <> 0) and (x >= xBrain[I]) and
1506 (y >= yBrain[I]) and (x < xBrain[I] + 64) and (y < yBrain[I] + 64) then
1507 begin
1508 InitPopup(I);
1509 if yBrain[I] > y0Brain then
1510 PopupMenu1.Popup(left + xBrain[I] + 4, top + yBrain[I] + 60)
1511 else
1512 PopupMenu1.Popup(left + xBrain[I] + 4, top + yBrain[I] + 4);
1513 end;
1514 end
1515 else if (AutoDiff > 1) and ((Page = pgStartRandom) or (Page = pgStartMap)) and
1516 (x >= xDefault) and (y >= yDefault) and (x < xDefault + 64) and
1517 (y < yDefault + 64) then
1518 if Brains.GetKindCount(btAI) < 2 then
1519 SimpleMessage(Phrases.Lookup('NOALTAI'))
1520 else
1521 begin
1522 InitPopup(-1);
1523 PopupMenu1.Popup(left + xDefault + 4, top + yDefault + 4);
1524 end
1525 else if (Page = pgLoad) and (LastTurn > 0) and (y >= yTurnSlider) and
1526 (y < yTurnSlider + 7) and (x >= xTurnSlider) and
1527 (x <= xTurnSlider + wTurnSlider) then
1528 begin
1529 LoadTurn := LastTurn * (x - xTurnSlider) div wTurnSlider;
1530 SmartInvalidate(xTurnSlider - 2, y0Mini + 61, xTurnSlider + wTurnSlider + 2,
1531 yTurnSlider + 9);
1532 Tracking := True;
1533 end;
1534end;
1535
1536procedure TStartDlg.Up2BtnClick(Sender: TObject);
1537begin
1538 case Page of
1539 pgStartRandom, pgStartMap:
1540 if MaxTurn < 1400 then
1541 begin
1542 inc(MaxTurn, 200);
1543 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1544 end;
1545 pgLoad:
1546 if LoadTurn < LastTurn then
1547 begin
1548 inc(LoadTurn);
1549 SmartInvalidate(xTurnSlider - 2, y0Mini + 61, xTurnSlider + wTurnSlider
1550 + 2, yTurnSlider + 9);
1551 end;
1552 pgEditRandom:
1553 if StartLandMass < 96 then
1554 begin
1555 inc(StartLandMass, 5);
1556 PaintInfo;
1557 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 61 + 21);
1558 end;
1559 end;
1560end;
1561
1562procedure TStartDlg.Down2BtnClick(Sender: TObject);
1563begin
1564 case Page of
1565 pgStartRandom, pgStartMap:
1566 if MaxTurn > 400 then
1567 begin
1568 dec(MaxTurn, 200);
1569 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1570 end;
1571 pgLoad:
1572 if LoadTurn > 0 then
1573 begin
1574 dec(LoadTurn);
1575 SmartInvalidate(xTurnSlider - 2, y0Mini + 61, xTurnSlider + wTurnSlider
1576 + 2, yTurnSlider + 9);
1577 end;
1578 pgEditRandom:
1579 if StartLandMass > 10 then
1580 begin
1581 dec(StartLandMass, 5);
1582 PaintInfo;
1583 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 61 + 21);
1584 end;
1585 end;
1586end;
1587
1588procedure TStartDlg.Up1BtnClick(Sender: TObject);
1589begin
1590 if WorldSize < MaxWorldSize - 1 then
1591 begin
1592 Inc(WorldSize);
1593 PaintInfo;
1594 SmartInvalidate(344, y0Mini - 77, 510, y0Mini - 77 + 21);
1595 end;
1596end;
1597
1598procedure TStartDlg.Down1BtnClick(Sender: TObject);
1599begin
1600 if WorldSize > 0 then
1601 begin
1602 Dec(WorldSize);
1603 PaintInfo;
1604 SmartInvalidate(344, y0Mini - 77, 510, y0Mini - 77 + 21);
1605 end;
1606end;
1607
1608procedure TStartDlg.FormClose(Sender: TObject; var Action: TCloseAction);
1609begin
1610 DirectDlg.Close;
1611end;
1612
1613procedure TStartDlg.ListClick(Sender: TObject);
1614var
1615 I: Integer;
1616begin
1617 if (Tab = tbMap) and ((List.ItemIndex = 0) <> (Page = pgEditRandom)) then
1618 begin
1619 if List.ItemIndex = 0 then
1620 Page := pgEditRandom
1621 else
1622 Page := pgEditMap;
1623 for I := 0 to ControlCount - 1 do
1624 Controls[I].Visible := Controls[I].Tag and (256 shl Integer(Page)) <> 0;
1625 SmartInvalidate(328, Up1Btn.top - 12, ClientWidth, Up2Btn.top + 35);
1626 end;
1627 if Page = pgLoad then
1628 TurnValid := False;
1629 PaintInfo;
1630 if Page = pgLoad then
1631 ReplayBtn.Visible := MiniMap.Mode <> mmMultiPlayer;
1632end;
1633
1634procedure TStartDlg.RenameBtnClick(Sender: TObject);
1635var
1636 i: integer;
1637 NewName: string;
1638 f: file;
1639 ok: boolean;
1640 MapPictureFileName: string;
1641begin
1642 if List.ItemIndex >= 0 then
1643 begin
1644 if Page = pgLoad then
1645 InputDlg.Caption := Phrases.Lookup('TITLE_BOOKNAME')
1646 else
1647 InputDlg.Caption := Phrases.Lookup('TITLE_MAPNAME');
1648 InputDlg.EInput.Text := List.Items[List.ItemIndex];
1649 InputDlg.CenterToRect(BoundsRect);
1650 InputDlg.ShowModal;
1651 NewName := InputDlg.EInput.Text;
1652 while (NewName <> '') and (NewName[1] = '~') do
1653 Delete(NewName, 1, 1);
1654 if (InputDlg.ModalResult = mrOK) and (NewName <> '') and
1655 (NewName <> List.Items[List.ItemIndex]) then
1656 begin
1657 for i := 1 to Length(NewName) do
1658 if NewName[i] in ['\', '/', ':', '*', '?', '"', '<', '>', '|'] then
1659 begin
1660 SimpleMessage(Format(Phrases.Lookup('NOFILENAME'), [NewName[i]]));
1661 Exit;
1662 end;
1663 if Page = pgLoad then
1664 AssignFile(f, GetSavedDir + DirectorySeparator + List.Items[List.ItemIndex] + CevoExt)
1665 else
1666 AssignFile(f, GetMapsDir + DirectorySeparator + List.Items[List.ItemIndex] +
1667 CevoMapExt);
1668 ok := true;
1669 try
1670 if Page = pgLoad then
1671 Rename(f, GetSavedDir + DirectorySeparator + NewName + CevoExt)
1672 else
1673 Rename(f, GetMapsDir + DirectorySeparator + NewName + CevoMapExt);
1674 except
1675 // Play('INVALID');
1676 ok := False;
1677 end;
1678 if Page <> pgLoad then begin
1679 // Rename map picture
1680 MapPictureFileName := GetMapsDir + DirectorySeparator +
1681 List.Items[List.ItemIndex] + CevoMapPictureExt;
1682 if FileExists(MapPictureFileName) then
1683 try
1684 AssignFile(f, GetMapsDir + DirectorySeparator + List.Items[List.ItemIndex]
1685 + CevoMapPictureExt);
1686 Rename(f, GetMapsDir + DirectorySeparator + NewName + CevoMapPictureExt);
1687 except
1688 end;
1689 end;
1690 if ok then begin
1691 if Page = pgLoad then
1692 FormerGames[List.ItemIndex] := NewName
1693 else
1694 Maps[List.ItemIndex] := NewName;
1695 List.Items[List.ItemIndex] := NewName;
1696 if Page = pgEditMap then
1697 PaintInfo;
1698 List.Invalidate;
1699 end;
1700 end;
1701 end;
1702end;
1703
1704procedure TStartDlg.DeleteBtnClick(Sender: TObject);
1705var
1706 iDel: integer;
1707 f: file;
1708begin
1709 if List.ItemIndex >= 0 then
1710 begin
1711 if Page = pgLoad then
1712 MessgDlg.MessgText := Phrases.Lookup('DELETEQUERY')
1713 else
1714 MessgDlg.MessgText := Phrases.Lookup('MAPDELETEQUERY');
1715 MessgDlg.Kind := mkOKCancel;
1716 MessgDlg.ShowModal;
1717 if MessgDlg.ModalResult = mrOK then
1718 begin
1719 if Page = pgLoad then
1720 AssignFile(f, GetSavedDir + DirectorySeparator + List.Items[List.ItemIndex] + CevoExt)
1721 else
1722 AssignFile(f, GetMapsDir + DirectorySeparator + List.Items[List.ItemIndex] +
1723 CevoMapExt);
1724 Erase(f);
1725 iDel := List.ItemIndex;
1726 if Page = pgLoad then
1727 FormerGames.Delete(iDel)
1728 else
1729 Maps.Delete(iDel);
1730 List.Items.Delete(iDel);
1731 if List.Items.Count = 0 then
1732 ChangePage(pgNoLoad)
1733 else
1734 begin
1735 if iDel = 0 then
1736 List.ItemIndex := 0
1737 else
1738 List.ItemIndex := iDel - 1;
1739 if (Page = pgEditMap) and (List.ItemIndex = 0) then
1740 ChangePage(pgEditRandom)
1741 else
1742 begin
1743 List.Invalidate;
1744 if Page = pgLoad then
1745 TurnValid := false;
1746 PaintInfo;
1747 if Page = pgLoad then
1748 ReplayBtn.Visible := MiniMap.Mode <> mmMultiPlayer;
1749 end;
1750 end;
1751 end;
1752 end;
1753end;
1754
1755procedure TStartDlg.DiffBtnClick(Sender: TObject);
1756var
1757 I: Integer;
1758begin
1759 for I := 0 to nPlOffered - 1 do
1760 if (Sender = PlayerSlots[I].DiffUpBtn) and (Difficulty[I] < 3) or
1761 (Sender = PlayerSlots[I].DiffDownBtn) and (Difficulty[I] > 1) then
1762 begin
1763 if Sender = PlayerSlots[I].DiffUpBtn then
1764 Inc(Difficulty[I])
1765 else
1766 Dec(Difficulty[I]);
1767 SmartInvalidate(xBrain[I] - 18, yBrain[I] + 19, xBrain[I] - 18 + 12,
1768 yBrain[I] + (19 + 14));
1769 end;
1770end;
1771
1772procedure TStartDlg.MultiBtnClick(Sender: TObject);
1773var
1774 I: Integer;
1775begin
1776 for I := 6 to 8 do
1777 if Sender = PlayerSlots[I].MultiBtn then
1778 begin
1779 MultiControl := MultiControl xor (1 shl I);
1780 TButtonC(Sender).ButtonIndex := 2 + (MultiControl shr I) and 1;
1781 end;
1782end;
1783
1784procedure TStartDlg.FormHide(Sender: TObject);
1785begin
1786 Diff0 := Difficulty[0];
1787 ListIndex[Tab] := List.ItemIndex;
1788 ShowTab := Tab;
1789 Background.Enabled := True;
1790 LastGame := FormerGames[ListIndex[tbPrevious]];
1791end;
1792
1793procedure TStartDlg.QuitBtnClick(Sender: TObject);
1794begin
1795 Close;
1796end;
1797
1798procedure TStartDlg.FormKeyDown(Sender: TObject; var Key: Word;
1799 Shift: TShiftState);
1800var
1801 ShortCut: TShortCut;
1802begin
1803 ShortCut := KeyToShortCut(Key, Shift);
1804 if BFullScreen.Test(ShortCut) then begin
1805 FullScreen := not FullScreen;
1806 UpdateInterface;
1807 Background.UpdateInterface;
1808 SetFocus;
1809 end else
1810 if BHelp.Test(ShortCut) then
1811 DirectHelp(cStartHelp);
1812end;
1813
1814procedure TStartDlg.CustomizeBtnClick(Sender: TObject);
1815begin
1816 AutoDiff := -AutoDiff;
1817 CustomizeBtn.ButtonIndex := CustomizeBtn.ButtonIndex xor 1;
1818 ChangePage(Page);
1819end;
1820
1821procedure TStartDlg.AutoDiffUpBtnClick(Sender: TObject);
1822begin
1823 if AutoDiff < 5 then
1824 begin
1825 Inc(AutoDiff);
1826 SmartInvalidate(120, y0Mini + 61, 272, y0Mini + 61 + 21);
1827 SmartInvalidate(xDefault - 2, yDefault - 2, xDefault + 64 + 2,
1828 yDefault + 64 + 2);
1829 end;
1830end;
1831
1832procedure TStartDlg.AutoDiffDownBtnClick(Sender: TObject);
1833begin
1834 if AutoDiff > 1 then
1835 begin
1836 Dec(AutoDiff);
1837 SmartInvalidate(120, y0Mini + 61, 272, y0Mini + 61 + 21);
1838 SmartInvalidate(xDefault - 2, yDefault - 2, xDefault + 64 + 2,
1839 yDefault + 64 + 2);
1840 end;
1841end;
1842
1843procedure TStartDlg.FormMouseUp(Sender: TObject; Button: TMouseButton;
1844 Shift: TShiftState; x, y: integer);
1845begin
1846 Tracking := False;
1847end;
1848
1849procedure TStartDlg.FormMouseMove(Sender: TObject; Shift: TShiftState;
1850 x, y: integer);
1851var
1852 OldLoadTurn: Integer;
1853 NewSelectedAction: TMainAction;
1854begin
1855 if Tracking then
1856 begin
1857 x := x - xTurnSlider;
1858 if x < 0 then
1859 x := 0
1860 else if x > wTurnSlider then
1861 x := wTurnSlider;
1862 OldLoadTurn := LoadTurn;
1863 LoadTurn := LastTurn * x div wTurnSlider;
1864 if LoadTurn < OldLoadTurn then
1865 begin
1866 SmartInvalidate(xTurnSlider + LoadTurn * wTurnSlider div LastTurn,
1867 yTurnSlider, xTurnSlider + OldLoadTurn * wTurnSlider div LastTurn + 1,
1868 yTurnSlider + 7);
1869 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1870 end
1871 else if LoadTurn > OldLoadTurn then
1872 begin
1873 SmartInvalidate(xTurnSlider + OldLoadTurn * wTurnSlider div LastTurn,
1874 yTurnSlider, xTurnSlider + LoadTurn * wTurnSlider div LastTurn + 1,
1875 yTurnSlider + 7);
1876 SmartInvalidate(344, y0Mini + 61, 514, y0Mini + 82);
1877 end;
1878 end
1879 else if Page = pgMain then
1880 begin
1881 if (x >= ActionSideBorder) and (x < ClientWidth - ActionSideBorder) and
1882 (y >= yAction - 8) and (y < ClientHeight - ActionBottomBorder) then
1883 begin
1884 NewSelectedAction := TMainAction((y - (yAction - 8)) div ActionPitch);
1885 if not (NewSelectedAction in ActionsOffered) then
1886 NewSelectedAction := maNone;
1887 end
1888 else
1889 NewSelectedAction := maNone;
1890 if NewSelectedAction <> SelectedAction then
1891 begin
1892 if SelectedAction <> maNone then
1893 SmartInvalidate(ActionSideBorder, yAction + Integer(SelectedAction) * ActionPitch
1894 - 8, ClientWidth - ActionSideBorder, yAction + (Integer(SelectedAction) + 1) *
1895 ActionPitch - 8);
1896 SelectedAction := NewSelectedAction;
1897 if SelectedAction <> maNone then
1898 SmartInvalidate(ActionSideBorder, yAction + Integer(SelectedAction) * ActionPitch
1899 - 8, ClientWidth - ActionSideBorder, yAction + (Integer(SelectedAction) + 1) *
1900 ActionPitch - 8);
1901 end;
1902 end;
1903end;
1904
1905procedure TStartDlg.AutoEnemyUpBtnClick(Sender: TObject);
1906begin
1907 if AutoEnemies < nPl - 1 then
1908 begin
1909 Inc(AutoEnemies);
1910 SmartInvalidate(160, yMain + 140, 198, yMain + 140 + 21);
1911 end;
1912end;
1913
1914procedure TStartDlg.AutoEnemyDownBtnClick(Sender: TObject);
1915begin
1916 if AutoEnemies > 0 then
1917 begin
1918 Dec(AutoEnemies);
1919 SmartInvalidate(160, yMain + 140, 198, yMain + 140 + 21);
1920 end;
1921end;
1922
1923procedure TStartDlg.ReplayBtnClick(Sender: TObject);
1924begin
1925 LoadGame(GetSavedDir + DirectorySeparator, List.Items[List.ItemIndex] + CevoExt,
1926 LastTurn, True);
1927 SlotAvailable := -1;
1928end;
1929
1930end.
Note: See TracBrowser for help on using the repository browser.