close Warning: Can't synchronize with repository "(default)" (No changeset 184 in the repository). Look in the Trac log for more information.

source: trunk/UCore.pas

Last change on this file was 183, checked in by chronos, 6 years ago
  • Modified: Units move handling was moved from Core to FormClient as it is game client related functionality.
File size: 13.8 KB
Line 
1unit UCore;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, XMLConf, FileUtil, ActnList, Controls, Dialogs, Forms,
9 UGame, UApplicationInfo, UPersistentForm, UScaleDPI, UCoolTranslator,
10 URegistry, ULastOpenedList, Registry, Menus, UGeometry, Contnrs, UFormClient;
11
12type
13
14 { TCore }
15
16 TCore = class(TDataModule)
17 AAbout: TAction;
18 APlayersStats: TAction;
19 ANewSpectatorClient: TAction;
20 AShowUnitMoves: TAction;
21 AShowCharts: TAction;
22 AHelp: TAction;
23 AGameSave: TAction;
24 AGameLoad: TAction;
25 ApplicationInfo: TApplicationInfo;
26 ASettings: TAction;
27 ActionList1: TActionList;
28 AExit: TAction;
29 AGameEnd: TAction;
30 AGameEndTurn: TAction;
31 AGameNew: TAction;
32 AGameRestart: TAction;
33 CoolTranslator1: TCoolTranslator;
34 ImageListLarge: TImageList;
35 ImageListSmall: TImageList;
36 LastOpenedList1: TLastOpenedList;
37 OpenDialog1: TOpenDialog;
38 PersistentForm: TPersistentForm;
39 SaveDialog1: TSaveDialog;
40 ScaleDPI1: TScaleDPI;
41 XMLConfig1: TXMLConfig;
42 procedure AAboutExecute(Sender: TObject);
43 procedure AExitExecute(Sender: TObject);
44 procedure AGameEndExecute(Sender: TObject);
45 procedure AGameEndTurnExecute(Sender: TObject);
46 procedure AGameLoadExecute(Sender: TObject);
47 procedure AGameNewExecute(Sender: TObject);
48 procedure AGameRestartExecute(Sender: TObject);
49 procedure AGameSaveExecute(Sender: TObject);
50 procedure AHelpExecute(Sender: TObject);
51 procedure ANewSpectatorClientExecute(Sender: TObject);
52 procedure APlayersStatsExecute(Sender: TObject);
53 procedure ASettingsExecute(Sender: TObject);
54 procedure AShowChartsExecute(Sender: TObject);
55 procedure AShowUnitMovesExecute(Sender: TObject);
56 procedure CoolTranslator1Translate(Sender: TObject);
57 procedure DataModuleCreate(Sender: TObject);
58 procedure DataModuleDestroy(Sender: TObject);
59 procedure LastOpenedList1Change(Sender: TObject);
60 private
61 FInitialized: Boolean;
62 StoredDimension: TControlDimension;
63 RegistryContext: TRegistryContext;
64 procedure LoadRecentExecute(Sender: TObject);
65 procedure ProcessComputerTurns;
66 procedure StartNewGame;
67 procedure DoPlayerChange(Sender: TObject);
68 procedure DoMoveUpdated(UnitMove: TUnitMove);
69 procedure DoOnWin(Player: TPlayer);
70 procedure Delay(Time: Integer);
71 procedure GameNewTurnExecute(Sender: TObject);
72 procedure AutoSave;
73 procedure LoadConfig;
74 procedure SaveConfig;
75 procedure CommandLineParams;
76 procedure ScaleDPI;
77 procedure SelectClient;
78 procedure LoadGame(FileName: string);
79 procedure RedrawClients;
80 procedure UpdateOtherForms;
81 public
82 Game: TGame;
83 Server: TServer;
84 UseSingleView: Boolean;
85 DevelMode: Boolean;
86 AnimationSpeed: Integer;
87 AutoSaveEnabled: Boolean;
88 FormClients: TObjectList; // TFormClient
89 //CurrentClient: TClient;
90 LocalClients: TObjectList; // TClient
91 procedure Spectate(Player: TPlayer);
92 procedure UpdateActions;
93 procedure Init;
94 property Initialized: Boolean read FInitialized;
95 end;
96
97var
98 Core: TCore;
99
100
101implementation
102
103{$R *.lfm}
104
105uses
106 UFormMove, UFormMain, UFormNew, UFormSettings, UFormAbout,
107 UFormHelp, UFormCharts, UFormUnitMoves, UFormPlayersStats;
108
109const
110 DefaultRegKey = '\Software\Chronosoft\xTactics';
111
112resourcestring
113 SPlayerWins = 'Player %s wins';
114 SEndGame = 'End game?';
115 SEndGameQuestion = 'Do you want to end current game?';
116 SRestartGame = 'Restart game?';
117 SRestartGameQuestion = 'Do you want to restart current game?';
118 SPlayersNotInitialized = 'Not all players were initialized with start cell. Needed %d, initialized %d. Change map parameters to have more terrain cells.';
119 SFileDialogFilter = 'xTactics games (.xtg)|*.xtg|All files|*.*';
120
121
122{ TCore }
123
124procedure TCore.DoOnWin(Player: TPlayer);
125begin
126 RedrawClients;
127 ShowMessage(Format(SPlayerWins, [Player.Name]));
128end;
129
130procedure TCore.Delay(Time: Integer);
131const
132 Slice = 50; // ms
133begin
134 while Time > 0 do begin
135 Application.ProcessMessages;
136 if Time > Slice then Sleep(Slice) else Sleep(Time);
137 Dec(Time, Slice);
138 end;
139end;
140
141procedure TCore.GameNewTurnExecute(Sender: TObject);
142begin
143 if AutoSaveEnabled then AutoSave;
144end;
145
146procedure TCore.AutoSave;
147var
148 OldFileName: string;
149begin
150 OldFileName := Game.FileName;
151 Game.SaveToFile(GetAppConfigDir(False) + 'AutoSave.xtg');
152 Game.FileName := OldFileName;
153end;
154
155procedure TCore.LoadConfig;
156begin
157 RegistryContext := RegContext(HKEY_CURRENT_USER, DefaultRegKey);
158 PersistentForm.RegistryContext := RegistryContext;
159 XMLConfig1.Filename := GetAppConfigDir(False) + 'Config.xml';
160
161 LastOpenedList1.LoadFromXMLConfig(XMLConfig1, 'RecentFiles');
162 DevelMode := XMLConfig1.GetValue('DevelMode', false);
163 AnimationSpeed := XMLConfig1.GetValue('AnimationSpeed', 50);
164 AutoSaveEnabled := XMLConfig1.GetValue('AutoSave', True);
165 CoolTranslator1.Language := CoolTranslator1.Languages.SearchByCode(String(XMLConfig1.GetValue('Language', '')));
166 ScaleDPI1.DPI := Point(XMLConfig1.GetValue('DPIX', 96), XMLConfig1.GetValue('DPIY', 96));
167 ScaleDPI1.AutoDetect := XMLConfig1.GetValue('DPIAuto', True);
168end;
169
170procedure TCore.SaveConfig;
171begin
172 XMLConfig1.SetValue('Language', WideString(CoolTranslator1.Language.Code));
173 LastOpenedList1.SaveToXMLConfig(XMLConfig1, 'RecentFiles');
174 XMLConfig1.SetValue('DevelMode', DevelMode);
175 XMLConfig1.SetValue('AnimationSpeed', AnimationSpeed);
176 XMLConfig1.SetValue('AutoSave', AutoSaveEnabled);
177 XMLConfig1.SetValue('DPIX', ScaleDPI1.DPI.X);
178 XMLConfig1.SetValue('DPIY', ScaleDPI1.DPI.Y);
179 XMLConfig1.SetValue('DPIAuto', ScaleDPI1.AutoDetect);
180end;
181
182procedure TCore.CommandLineParams;
183var
184 FileName: string;
185begin
186 // Command line parameter handling
187 if (ParamCount > 0) then begin
188 FileName := UTF8Encode(ParamStr(1));
189 if FileExists(FileName) then LoadGame(FileName);
190 end;
191end;
192
193procedure TCore.ScaleDPI;
194var
195 I: Integer;
196begin
197 {$ifdef DEBUG}
198 with Core.ScaleDPI1 do begin
199 //DesignDPI := Point(144, 144);
200 if (DesignDPI.X <> DPI.X) or (DesignDPI.Y <> DPI.Y) then begin
201 //ApplyToAll(DesignDPI);
202 for I := 0 to Screen.FormCount - 1 do
203 if (Screen.Forms[I].WindowState = wsNormal) or
204 (Screen.Forms[I].WindowState = wsMinimized) then begin
205 StoreDimensions(Screen.Forms[I], StoredDimension);
206 ScaleDimensions(Screen.Forms[I], StoredDimension);
207 end;
208 ScaleImageList(Core.ImageListSmall, DesignDPI);
209 ScaleImageList(Core.ImageListLarge, DesignDPI);
210 end;
211 end;
212 {$endif}
213end;
214
215procedure TCore.SelectClient;
216var
217 FirstHuman: TPlayer;
218begin
219 FirstHuman := Game.Players.GetFirstHuman;
220 if Assigned(FirstHuman) then FormClient.Client := FirstHuman.Client
221 else FormClient.Client := TClient(Server.Clients.First);
222end;
223
224procedure TCore.UpdateActions;
225begin
226 Core.AGameEndTurn.Enabled := Core.Game.Running;
227 Core.AGameEnd.Enabled := Core.Game.Running;
228end;
229
230procedure TCore.AExitExecute(Sender: TObject);
231begin
232 Game.Running := False;
233 Application.Terminate;
234end;
235
236procedure TCore.AAboutExecute(Sender: TObject);
237begin
238 FormAbout := TFormAbout.Create(Self);
239 try
240 FormAbout.ShowModal;
241 finally
242 FreeAndNil(FormAbout);
243 end;
244end;
245
246procedure TCore.AGameEndExecute(Sender: TObject);
247begin
248 if MessageDlg(SEndGame, SEndGameQuestion, mtConfirmation, mbYesNo, 0) = mrYes then begin
249 Game.Running := False;
250 RedrawClients;
251 UpdateActions;
252 end;
253end;
254
255procedure TCore.ProcessComputerTurns;
256begin
257 while Game.Running and (Game.CurrentPlayer.Mode <> pmHuman) do begin
258 if Game.CurrentPlayer.Mode = pmComputer then begin
259 Game.CurrentPlayer.Computer.Process;
260 RedrawClients;
261 Delay(Trunc((100 - AnimationSpeed) / 100 * 2000));
262 end;
263 Game.NextTurn;
264 RedrawClients;
265 Application.ProcessMessages;
266 Sleep(1);
267 end;
268end;
269
270procedure TCore.AGameEndTurnExecute(Sender: TObject);
271begin
272 Game.NextTurn;
273 RedrawClients;
274 ProcessComputerTurns;
275 UpdateActions;
276end;
277
278procedure TCore.AGameLoadExecute(Sender: TObject);
279begin
280 OpenDialog1.Filter := SFileDialogFilter;
281 OpenDialog1.InitialDir := ExtractFileDir(Game.FileName);
282 OpenDialog1.FileName := ExtractFileName(Game.FileName);
283 if OpenDialog1.Execute then begin
284 LoadGame(OpenDialog1.FileName);
285 end;
286end;
287
288procedure TCore.AGameNewExecute(Sender: TObject);
289begin
290 FormNew := TFormNew.Create(nil);
291 try
292 FormNew.Load(Server);
293 if FormNew.ShowModal = mrOk then begin
294 FormNew.Save(Server);
295 StartNewGame;
296 end;
297 finally
298 FormNew.Free;
299 end;
300end;
301
302procedure TCore.AGameRestartExecute(Sender: TObject);
303begin
304 if MessageDlg(SRestartGame, SRestartGameQuestion, mtConfirmation, mbYesNo, 0) = mrYes then begin
305 StartNewGame;
306 end;
307end;
308
309procedure TCore.AGameSaveExecute(Sender: TObject);
310begin
311 SaveDialog1.Filter := SFileDialogFilter;
312 SaveDialog1.InitialDir := ExtractFileDir(Game.FileName);
313 SaveDialog1.FileName := ExtractFileName(Game.FileName);
314 if SaveDialog1.Execute then begin
315 Game.SaveToFile(SaveDialog1.FileName);
316 LastOpenedList1.AddItem(SaveDialog1.FileName);
317 end;
318end;
319
320procedure TCore.AHelpExecute(Sender: TObject);
321begin
322 FormHelp := TFormHelp.Create(Self);
323 try
324 FormHelp.ShowModal;
325 finally
326 FreeAndNil(FormHelp);
327 end;
328end;
329
330procedure TCore.ANewSpectatorClientExecute(Sender: TObject);
331begin
332 Spectate(nil);
333end;
334
335procedure TCore.APlayersStatsExecute(Sender: TObject);
336begin
337 if not Assigned(FormPlayersStats) then
338 FormPlayersStats := TFormPlayersStats.Create(nil);
339 FormPlayersStats.Show;
340end;
341
342procedure TCore.ASettingsExecute(Sender: TObject);
343begin
344 FormSettings := TFormSettings.Create(nil);
345 try
346 FormSettings.Load;
347 if FormSettings.ShowModal = mrOk then begin
348 FormSettings.Save;
349 Game.SaveConfig(XMLConfig1, 'Game');
350 Server.SaveConfig(XMLConfig1, 'Server');
351 end;
352 finally
353 FreeAndNil(FormSettings);
354 end;
355end;
356
357procedure TCore.AShowChartsExecute(Sender: TObject);
358begin
359 if not Assigned(FormCharts) then FormCharts := TFormCharts.Create(nil);
360 FormCharts.Show;
361end;
362
363procedure TCore.AShowUnitMovesExecute(Sender: TObject);
364begin
365 if not Assigned(FormUnitMoves) then FormUnitMoves := TFormUnitMoves.Create(nil);
366 FormUnitMoves.Show;
367end;
368
369procedure TCore.CoolTranslator1Translate(Sender: TObject);
370begin
371 UGame.InitStrings;
372end;
373
374procedure TCore.DataModuleCreate(Sender: TObject);
375begin
376 Server := TServer.Create;
377 Game := TGame.Create;
378 Game.OnMoveUpdated := DoMoveUpdated;
379 Game.OnWin := DoOnWin;
380 Game.OnNewTurn := GameNewTurnExecute;
381 Game.OnPlayerChange := DoPlayerChange;
382 Game.Server := Server;
383 Server.Game := Game;
384 StoredDimension := TControlDimension.Create;
385 XMLConfig1.Filename := GetAppConfigDir(False) + 'Config.xml';
386 ForceDirectories(GetAppConfigDir(False));
387 FormClients := TObjectList.Create;
388end;
389
390procedure TCore.DataModuleDestroy(Sender: TObject);
391begin
392 if Assigned(FormPlayersStats) then FreeAndNil(FormPlayersStats);
393 if Assigned(FormUnitMoves) then FreeAndNil(FormUnitMoves);
394 if Assigned(FormCharts) then FreeAndNil(FormCharts);
395 FreeAndNil(FormClients);
396 FreeAndNil(StoredDimension);
397 Game.SaveConfig(XMLConfig1, 'Game');
398 Server.SaveConfig(XMLConfig1, 'Server');
399 SaveConfig;
400 FreeAndNil(Server);
401 FreeAndNil(Game);
402end;
403
404procedure TCore.LastOpenedList1Change(Sender: TObject);
405begin
406 LastOpenedList1.LoadToMenuItem(FormMain.MenuItemLoadRecent, LoadRecentExecute);
407end;
408
409procedure TCore.LoadRecentExecute(Sender: TObject);
410begin
411 LoadGame((Sender as TMenuItem).Caption);
412end;
413
414procedure TCore.LoadGame(FileName: string);
415begin
416 Game.LoadFromFile(FileName);
417 Server.InitClients;
418 SelectClient;
419 LastOpenedList1.AddItem(FileName);
420 with FormClient.Client do
421 View.DestRect := TRect.CreateBounds(TPoint.Create(0, 0),
422 TPoint.Create(FormClient.PaintBox1.Width, FormClient.PaintBox1.Height));
423 FormClient.AZoomAll.Execute;
424 RedrawClients;
425 UpdateOtherForms;
426end;
427
428procedure TCore.RedrawClients;
429var
430 Form: TFormClient;
431begin
432 for Form in FormClients do
433 Form.Redraw;
434 FormClient.Redraw;
435end;
436
437procedure TCore.UpdateOtherForms;
438begin
439 if Assigned(FormCharts) and FormCharts.Visible then FormCharts.Redraw;
440 if Assigned(FormUnitMoves) and FormUnitMoves.Visible then FormUnitMoves.ReloadList;
441 if Assigned(FormPlayersStats) and FormPlayersStats.Visible then FormPlayersStats.ReloadList;
442end;
443
444procedure TCore.Spectate(Player: TPlayer);
445var
446 Form: TFormClient;
447begin
448 Form := TFormClient.Create(nil);
449 Form.Client := Game.Server.Clients.New(SSpectator);
450 //Form.Client.Form := Form;
451 //Form.Client.ControlPlayer := Player;
452 Form.AZoomAll.Execute;
453 Form.Show;
454 FormClients.Add(Form);
455end;
456
457procedure TCore.StartNewGame;
458begin
459 Game.New;
460 Server.InitClients;
461 Game.DevelMode := DevelMode;
462 SelectClient;
463 if Game.Players.GetAliveCount = Game.Players.Count then Game.Running := True
464 else ShowMessage(Format(SPlayersNotInitialized, [Game.Players.Count, Game.Players.GetAliveCount]));
465 RedrawClients;
466 UpdateOtherForms;
467 ProcessComputerTurns;
468 UpdateActions;
469end;
470
471procedure TCore.DoPlayerChange(Sender: TObject);
472begin
473 if Assigned(Game.CurrentPlayer) and Assigned(Game.CurrentPlayer.Client) then begin
474 FormClient.Client := Game.CurrentPlayer.Client;
475 end;
476 UpdateOtherForms;
477end;
478
479procedure TCore.DoMoveUpdated(UnitMove: TUnitMove);
480begin
481 if Assigned(FormUnitMoves) and FormUnitMoves.Visible then
482 FormUnitMoves.ReloadList;
483end;
484
485procedure TCore.Init;
486begin
487 if not Core.Initialized then begin
488 {$IFDEF Linux}
489 // If installed in Linux system then use installation directory for po files
490 if Application.ExeName = '/usr/bin/xtactics' then
491 CoolTranslator1.POFilesFolder := '/usr/share/xtactics/languages';
492 {$ENDIF}
493 FInitialized := True;
494
495 // Update translated default player names
496 TPlayer(Game.PlayersSetting[0]).Name := SPlayer + ' 1';
497 TPlayer(Game.PlayersSetting[1]).Name := SPlayer + ' 2';
498
499 LoadConfig;
500 Game.LoadConfig(XMLConfig1, 'Game');
501 Server.LoadConfig(XMLConfig1, 'Server');
502
503 CommandLineParams;
504 ScaleDPI;
505
506 if Game.FileName = '' then StartNewGame;
507 end;
508end;
509
510end.
511
Note: See TracBrowser for help on using the repository browser.