source: tags/1.3.6/LocalPlayer/UnitStat.pas

Last change on this file was 622, checked in by chronos, 2 months ago
  • Modified: Show windows by default on primary screen if multiple monitors present.
File size: 23.9 KB
Line 
1{$INCLUDE Switches.inc}
2unit UnitStat;
3
4interface
5
6uses
7 Protocol, ClientTools, ScreenTools, BaseWin, LCLIntf, LCLType, SysUtils,
8 Classes, ButtonB, ButtonC, IsoEngine,
9 {$IFDEF DPI}Dpi.Graphics, Dpi.Controls, Dpi.Forms{$ELSE}
10 Graphics, Controls, Forms{$ENDIF};
11
12type
13 TUnitStatDialogKind = (dkOwnModel, dkOwnUnit, dkEnemyModel, dkEnemyUnit,
14 dkEnemyCityDefense, dkEnemyCity);
15
16 TUnitStatDlg = class(TBufferedDrawDlg)
17 SwitchBtn: TButtonB;
18 CloseBtn: TButtonB;
19 ConscriptsBtn: TButtonB;
20 HelpBtn: TButtonC;
21 procedure FormShow(Sender: TObject);
22 procedure CloseBtnClick(Sender: TObject);
23 procedure FormCreate(Sender: TObject);
24 procedure ModelBoxChange(Sender: TObject);
25 procedure SwitchBtnClick(Sender: TObject);
26 procedure ConscriptsBtnClick(Sender: TObject);
27 procedure FormDestroy(Sender: TObject);
28 procedure FormClose(Sender: TObject; var Action: TCloseAction);
29 procedure HelpBtnClick(Sender: TObject);
30 private
31 NoMap: TIsoMap;
32 protected
33 mixShow, // for dkOwnModel
34 uixShow, euixShow, ecixShow, UnitLoc, AgePrepared: Integer;
35 // for dkEnemyUnit, euixShow=-1 ->
36 mox: ^TModelInfo; // for dkEnemyModel
37 Kind: TUnitStatDialogKind;
38 Back: TBitmap;
39 Template: TBitmap;
40 procedure OffscreenPaint; override;
41 public
42 procedure CheckAge;
43 procedure ShowNewContent_OwnModel(NewMode: TWindowMode; mix: Integer);
44 procedure ShowNewContent_OwnUnit(NewMode: TWindowMode; uix: Integer);
45 procedure ShowNewContent_EnemyUnit(NewMode: TWindowMode; euix: Integer);
46 procedure ShowNewContent_EnemyLoc(NewMode: TWindowMode; Loc: Integer);
47 procedure ShowNewContent_EnemyModel(NewMode: TWindowMode; emix: Integer);
48 procedure ShowNewContent_EnemyCity(NewMode: TWindowMode; Loc: Integer);
49 end;
50
51
52implementation
53
54uses
55 Term, Tribes, Help, Directories, Texture;
56
57{$R *.lfm}
58
59const
60 xView = 71;
61 xTotal = 20;
62 StatDown = 112;
63 yImp = 133;
64
65 // window size
66 wCommon = 208;
67 hOwnModel = 293;
68 hEnemyModel = 236;
69 hEnemyUnit = 212;
70 hEnemyCityDefense = 320;
71 hEnemyCity = 166;
72 hMax = 320;
73
74procedure TUnitStatDlg.FormCreate(Sender: TObject);
75begin
76 inherited;
77 NoMap := TIsoMap.Create;
78 AgePrepared := -2;
79 TitleHeight := Screen.PrimaryMonitor.Height;
80 InitButtons;
81
82 Back := TBitmap.Create;
83 Back.PixelFormat := TPixelFormat.pf24bit;
84 Back.SetSize(5 * wCommon, hMax);
85 Back.Canvas.FillRect(0, 0, Back.Width, Back.Height);
86 Template := TBitmap.Create;
87 Template.PixelFormat := TPixelFormat.pf24bit;
88 LoadGraphicFile(Template, GetGraphicsDir + DirectorySeparator + 'Unit.png',
89 [gfNoGamma]);
90end;
91
92procedure TUnitStatDlg.FormDestroy(Sender: TObject);
93begin
94 FreeAndNil(Template);
95 FreeAndNil(Back);
96 FreeAndNil(NoMap);
97end;
98
99procedure TUnitStatDlg.CheckAge;
100begin
101 if MainTexture.Age <> AgePrepared then begin
102 AgePrepared := MainTexture.Age;
103 BitBltBitmap(Back, 0, 0, wCommon, hOwnModel,
104 MainTexture.Image, (MainTexture.Width - wCommon) div 2,
105 (MainTexture.Height - hOwnModel) div 2);
106 BitBltBitmap(Back, wCommon, 0, wCommon, hEnemyModel,
107 MainTexture.Image, (MainTexture.Width - wCommon) div 2,
108 (MainTexture.Height - hEnemyModel) div 2);
109 BitBltBitmap(Back, 2 * wCommon, 0, wCommon, hEnemyUnit,
110 MainTexture.Image, (MainTexture.Width - wCommon) div 2,
111 (MainTexture.Height - hEnemyUnit) div 2);
112 BitBltBitmap(Back, 3 * wCommon, 0, wCommon, hEnemyCityDefense,
113 MainTexture.Image, (MainTexture.Width - wCommon) div 2,
114 (MainTexture.Height - hEnemyCityDefense) div 2);
115 BitBltBitmap(Back, 4 * wCommon, 0, wCommon, hEnemyCity,
116 MainTexture.Image, (MainTexture.Width - wCommon) div 2,
117 (MainTexture.Height - hEnemyCity) div 2);
118 ImageOp_B(Back, Template, 0, 0, 0, 0, 5 * wCommon, hMax);
119 end;
120end;
121
122procedure TUnitStatDlg.FormShow(Sender: TObject);
123var
124 Owner, mix: Integer;
125 IsSpecialUnit: Boolean;
126begin
127 if Kind in [dkEnemyUnit, dkEnemyCityDefense, dkEnemyCity] then
128 begin
129 if MyMap[UnitLoc] and fUnit <> 0 then
130 begin // find model
131 if euixShow < 0 then
132 begin
133 euixShow := MyRO.nEnemyUn - 1;
134 while (euixShow >= 0) and (MyRO.EnemyUn[euixShow].Loc <> UnitLoc) do
135 Dec(euixShow);
136 Assert(euixShow >= 0);
137 end;
138 with MyRO.EnemyUn[euixShow] do
139 begin
140 mox := @MyRO.EnemyModel[emix];
141 if not Assigned(Tribe[Owner].ModelPicture[mix].HGr) then
142 InitEnemyModel(emix);
143 end;
144 end
145 else
146 mox := nil;
147 if Kind in [dkEnemyCityDefense, dkEnemyCity] then
148 begin
149 ecixShow := MyRO.nEnemyCity - 1;
150 while (ecixShow >= 0) and (MyRO.EnemyCity[ecixShow].Loc <> UnitLoc) do
151 Dec(ecixShow);
152 Assert(ecixShow >= 0);
153 end;
154 end;
155 case Kind of
156 dkOwnModel: Height := hOwnModel;
157 dkOwnUnit: Height := hEnemyUnit;
158 dkEnemyModel: Height := hEnemyModel;
159 dkEnemyUnit: Height := hEnemyUnit;
160 dkEnemyCityDefense: Height := hEnemyCityDefense;
161 dkEnemyCity: Height := hEnemyCity;
162 end;
163
164 if Kind in [dkOwnModel, dkEnemyModel] then
165 begin
166 BoundsRect := Bounds(UserLeft, UserTop, Width, Height);
167 end else begin
168 BoundsRect := Bounds(Screen.PrimaryMonitor.Left + (Screen.PrimaryMonitor.Width - Width) div 2,
169 Screen.PrimaryMonitor.Top + (Screen.PrimaryMonitor.Height - Height) div 2,
170 Width, Height);
171 end;
172
173 SwitchBtn.Visible := not Supervising and (Kind = dkOwnModel);
174 ConscriptsBtn.Visible := not Supervising and (Kind = dkOwnModel) and
175 (MyRO.Tech[adConscription] >= tsApplicable) and
176 (MyModel[mixShow].Domain = dGround) and (MyModel[mixShow].Kind < mkScout);
177 IsSpecialUnit := False;
178 if Kind in [dkEnemyCity, dkEnemyCityDefense] then
179 Caption := CityName(MyRO.EnemyCity[ecixShow].ID)
180 else
181 begin
182 case Kind of
183 dkOwnModel: begin
184 Owner := Me;
185 mix := mixShow;
186 IsSpecialUnit := MyModel[mix].Kind >= $10;
187 end;
188 dkOwnUnit: begin
189 Owner := Me;
190 mix := MyUn[uixShow].mix;
191 IsSpecialUnit := MyModel[mix].Kind >= $10;
192 end;
193 else begin
194 Owner := mox.Owner;
195 mix := mox.mix;
196 IsSpecialUnit := mox.Kind >= $10;
197 end;
198 end;
199 if MainScreen.mNames.Checked then
200 Caption := Tribe[owner].ModelName[mix]
201 else
202 Caption := Format(Tribe[owner].TPhrase('GENMODEL'), [mix])
203 end;
204 if IsSpecialUnit then
205 HelpBtn.Hint := Phrases.Lookup('CONTROLS', 6);
206 HelpBtn.Visible := IsSpecialUnit;
207 OffscreenPaint;
208end;
209
210procedure TUnitStatDlg.ShowNewContent_OwnModel(NewMode: TWindowMode; mix: Integer);
211begin
212 Kind := dkOwnModel;
213 mixShow := mix;
214 inherited ShowNewContent(NewMode);
215end;
216
217procedure TUnitStatDlg.ShowNewContent_OwnUnit(NewMode: TWindowMode; uix: Integer);
218begin
219 Kind := dkOwnUnit;
220 uixShow := uix;
221 inherited ShowNewContent(NewMode);
222end;
223
224procedure TUnitStatDlg.ShowNewContent_EnemyUnit(NewMode: TWindowMode; euix: Integer);
225begin
226 Kind := dkEnemyUnit;
227 euixShow := euix;
228 UnitLoc := MyRO.EnemyUn[euix].Loc;
229 inherited ShowNewContent(NewMode);
230end;
231
232procedure TUnitStatDlg.ShowNewContent_EnemyLoc(NewMode: TWindowMode; Loc: Integer);
233begin
234 Kind := dkEnemyUnit;
235 UnitLoc := Loc;
236 euixShow := -1;
237 inherited ShowNewContent(NewMode);
238end;
239
240procedure TUnitStatDlg.ShowNewContent_EnemyModel(NewMode: TWindowMode; emix: Integer);
241begin
242 Kind := dkEnemyModel;
243 mox := @MyRO.EnemyModel[emix];
244 inherited ShowNewContent(NewMode);
245end;
246
247procedure TUnitStatDlg.ShowNewContent_EnemyCity(NewMode: TWindowMode; Loc: Integer);
248begin
249 if MyMap[Loc] and fUnit <> 0 then
250 Kind := dkEnemyCityDefense
251 else
252 Kind := dkEnemyCity;
253 UnitLoc := Loc;
254 euixShow := -1;
255 inherited ShowNewContent(NewMode);
256end;
257
258procedure TUnitStatDlg.FormClose(Sender: TObject; var Action: TCloseAction);
259begin
260 if Kind in [dkOwnModel, dkEnemyModel] then
261 begin
262 UserLeft := Left;
263 UserTop := Top;
264 end;
265 if OffscreenUser = Self then
266 OffscreenUser := nil;
267end;
268
269procedure TUnitStatDlg.CloseBtnClick(Sender: TObject);
270begin
271 Close;
272end;
273
274procedure TUnitStatDlg.OffscreenPaint;
275var
276 PPicture: ^TModelPicture;
277
278 function IsToCount(emix: Integer): Boolean;
279 var
280 PTestPicture: ^TModelPicture;
281 begin
282 if MainScreen.mNames.Checked then
283 begin
284 PTestPicture := @Tribe[MyRO.EnemyModel[emix].owner].ModelPicture
285 [MyRO.EnemyModel[emix].mix];
286 Result := (PPicture.HGr = PTestPicture.HGr) and
287 (PPicture.pix = PTestPicture.pix) and
288 (ModelHash(mox^) = ModelHash(MyRO.EnemyModel[emix]));
289 end
290 else
291 Result := (MyRO.EnemyModel[emix].owner = mox.owner) and
292 (MyRO.EnemyModel[emix].mix = mox.mix);
293 end;
294
295 procedure FeatureBar(Dst: TBitmap; X, Y: Integer; const mi: TModelInfo;
296 T: TTexture);
297 var
298 I, W, dx, Num: Integer;
299 S: string;
300 begin
301 DarkGradient(Dst.Canvas, X - 6, Y + 1, 180, 1);
302 with Dst.Canvas do
303 if mi.Kind >= $10 then
304 begin
305 S := Phrases.Lookup('UNITSPECIAL');
306 Font.Color := $000000;
307 TextOut(X - 1, Y + 1, S);
308 Font.Color := $B0B0B0;
309 TextOut(X - 2, Y, S);
310 end
311 else
312 begin
313 Font.Color := $000000;
314 dx := 2;
315 for I := 3 to nFeature - 1 do
316 begin
317 Num := 0;
318 case I of
319 mcSeaTrans:
320 if mi.Domain = dSea then
321 Num := mi.TTrans;
322 mcCarrier:
323 if mi.Domain = dSea then
324 Num := mi.ATrans_Fuel;
325 mcBombs:
326 Num := mi.Bombs;
327 mcFuel:
328 if mi.Domain = dAir then
329 Num := mi.ATrans_Fuel;
330 mcAirTrans:
331 if mi.Domain = dAir then
332 Num := mi.TTrans;
333 mcFirstNonCap .. nFeature - 1:
334 if mi.Cap and (1 shl (I - mcFirstNonCap)) <> 0 then
335 Num := 1;
336 end;
337 if (Num > 0) and
338 ((I <> mcSE) or (mi.Cap and (1 shl (mcNP - mcFirstNonCap)) = 0))
339 then
340 begin
341 if Num > 1 then
342 begin
343 S := IntToStr(Num);
344 W := TextWidth(S);
345 Brush.Color := $FFFFFF;
346 FillRect(Rect(X - 3 + dx, Y + 2, X + W - 1 + dx, Y + 16));
347 Brush.Style := TBrushStyle.bsClear;
348 TextOut(X - 3 + dx + 1, Y, S);
349 Inc(dx, W + 1);
350 end;
351 Brush.Color := $C0C0C0;
352 FrameRect(Rect(X - 3 + dx, Y + 2, X + 11 + dx, Y + 16));
353 Brush.Style := TBrushStyle.bsClear;
354 Sprite(Dst, HGrSystem, X - 1 + dx, Y + 4, 10, 10,
355 66 + I mod 11 * 11, 137 + I div 11 * 11);
356 Inc(dx, 15);
357 end;
358 end;
359 end;
360 end;
361
362 procedure NumberBarS(Dst: TBitmap; X, Y: Integer; Cap, S: string; T: TTexture);
363 begin
364 DLine(Dst.Canvas, X - 2, X + 170, Y + 16, T.ColorBevelShade, T.ColorBevelLight);
365 LoweredTextOut(Dst.Canvas, -1, T, X - 2, Y, Cap);
366 RisedTextOut(Dst.Canvas, X + 170 - BiColorTextWidth(Dst.Canvas, S), Y, S);
367 end;
368
369var
370 I, J, X, Y, cix, uix, emix, InProd, Available, Destroyed, Loc, Cnt, yView,
371 yTotal, yCaption: Integer;
372 S: string;
373 ui: TUnitInfo;
374 mi: TModelInfo;
375begin
376 inherited;
377
378 case Kind of
379 dkOwnModel: begin
380 BitBltBitmap(Offscreen, 0, 0, wCommon, hOwnModel, Back, 0, 0);
381 yView := 13;
382 yTotal := 92;
383 end;
384 dkEnemyModel: begin
385 BitBltBitmap(Offscreen, 0, 0, wCommon, hEnemyModel, Back, wCommon, 0);
386 yView := 13;
387 yTotal := 92;
388 end;
389 dkEnemyUnit, dkOwnUnit: begin
390 BitBltBitmap(Offscreen, 0, 0, wCommon, hEnemyUnit, Back, 2 * wCommon, 0);
391 yView := 13;
392 yTotal := 123;
393 end;
394 dkEnemyCityDefense: begin
395 BitBltBitmap(Offscreen, 0, 0, wCommon, hEnemyCityDefense, Back, 3 * wCommon, 0);
396 yView := 171;
397 yTotal := 231;
398 end;
399 dkEnemyCity: begin
400 BitBltBitmap(Offscreen, 0, 0, wCommon, hEnemyCity, Back, 4 * wCommon, 0);
401 yView := 171;
402 yTotal := 231;
403 end;
404 end;
405 MarkUsedOffscreen(ClientWidth, ClientHeight);
406 HelpBtn.Top := yTotal + 22;
407
408 if Kind in [dkEnemyCityDefense, dkEnemyCity] then
409 begin // show city defense facilities
410 Cnt := 0;
411 for I := 0 to 3 do
412 if MyRO.EnemyCity[ecixShow].Flags and (2 shl I) <> 0 then
413 Inc(Cnt);
414 X := (wCommon - Cnt * xSizeSmall) div 2 - (Cnt - 1) * 2;
415 for I := 0 to 3 do
416 if MyRO.EnemyCity[ecixShow].Flags and (2 shl I) <> 0 then
417 begin
418 case I of
419 0: J := imWalls;
420 1: J := imCoastalFort;
421 2: J := imMissileBat;
422 3: J := imBunker;
423 end;
424 Frame(Offscreen.Canvas, X - 1, yImp - 1, X + xSizeSmall,
425 yImp + ySizeSmall, MainTexture.ColorBevelLight,
426 MainTexture.ColorBevelShade);
427 BitBltBitmap(Offscreen, X, yImp, xSizeSmall, ySizeSmall,
428 SmallImp, J mod 7 * xSizeSmall,
429 (J + SystemIconLines * 7) div 7 * ySizeSmall);
430 Inc(X, xSizeSmall + 4);
431 end;
432 end;
433
434 if Kind = dkEnemyModel then
435 begin
436 PPicture := @Tribe[mox.owner].ModelPicture[mox.mix];
437 Available := 0;
438 if G.Difficulty[Me] = 0 then // supervisor -- count stacked units too
439 for Loc := 0 to G.lx * G.ly - 1 do
440 begin
441 if MyMap[Loc] and fUnit <> 0 then
442 begin
443 Server(sGetUnits, Me, Loc, Cnt);
444 for uix := 0 to Cnt - 1 do
445 if IsToCount(MyRO.EnemyUn[MyRO.nEnemyUn + uix].emix) then
446 Inc(Available);
447 end;
448 end
449 else // no supervisor -- can only count stack top units
450 for uix := 0 to MyRO.nEnemyUn - 1 do
451 if (MyRO.EnemyUn[uix].Loc >= 0) and IsToCount(MyRO.EnemyUn[uix].emix)
452 then
453 Inc(Available);
454 Destroyed := 0;
455 for emix := 0 to MyRO.nEnemyModel - 1 do
456 if IsToCount(emix) then
457 Inc(Destroyed, MyRO.EnemyModel[emix].Lost);
458 end
459 else
460 begin
461 Available := 0;
462 for uix := 0 to MyRO.nUn - 1 do
463 if (MyUn[uix].Loc >= 0) and (MyUn[uix].mix = mixShow) then
464 Inc(Available);
465 InProd := 0;
466 for cix := 0 to MyRO.nCity - 1 do
467 if (MyCity[cix].Loc >= 0) and
468 (MyCity[cix].Project and (cpImp + cpIndex) = mixShow) then
469 Inc(InProd);
470 end;
471
472 Offscreen.Canvas.Font.Assign(UniFont[ftSmall]);
473 if Kind in [dkEnemyCityDefense, dkEnemyCity] then
474 begin
475 NoMap.SetOutput(Offscreen);
476 NoMap.PaintCity(ClientWidth div 2, 53, MyRO.EnemyCity[ecixShow], False);
477
478 S := Tribe[MyRO.EnemyCity[ecixShow].owner].TPhrase('UNITOWNER');
479 LoweredTextOut(Offscreen.Canvas, -1, MainTexture,
480 (ClientWidth - BiColorTextWidth(Offscreen.Canvas, S)) div 2, 105, S);
481 end;
482
483 if Kind <> dkEnemyCity then
484 begin // show unit stats
485 if Kind = dkOwnModel then
486 MakeModelInfo(Me, mixShow, MyModel[mixShow], mi)
487 else if Kind = dkOwnUnit then
488 begin
489 MakeUnitInfo(Me, MyUn[uixShow], ui);
490 MakeModelInfo(Me, MyUn[uixShow].mix, MyModel[MyUn[uixShow].mix], mi);
491 end
492 else
493 begin
494 mi := mox^;
495 if Kind in [dkEnemyUnit, dkEnemyCityDefense] then
496 ui := MyRO.EnemyUn[euixShow];
497 end;
498
499 with Tribe[mi.owner].ModelPicture[mi.mix] do
500 begin
501 if Kind in [dkOwnUnit, dkEnemyUnit, dkEnemyCityDefense] then
502 with ui, NoMap do
503 begin
504 { Frame(offscreen.canvas,xView-1,yView-1,xView+64,yView+48,
505 MainTexture.ColorBevelShade,MainTexture.ColorBevelLight);
506 RFrame(Offscreen.Canvas,xView-2,yView-2,xView+65,yView+49,
507 MainTexture.ColorBevelShade,MainTexture.ColorBevelLight); }
508 with Offscreen.Canvas do
509 begin
510 Brush.Color := HGrSystem.Data.Canvas.Pixels[98, 67];
511 Offscreen.Canvas.FillRect(Rect(xView, yView, xView + 64,
512 yView + 16));
513 Brush.Style := TBrushStyle.bsClear;
514 end;
515
516 if MyMap[Loc] and fTerrain >= fForest then
517 begin
518 X := 1 + 2 * (xxt * 2 + 1);
519 Y := 1 + yyt + 2 * (yyt * 3 + 1);
520 end
521 else
522 begin
523 X := Integer(MyMap[Loc] and fTerrain) * (xxt * 2 + 1) + 1;
524 Y := 1 + yyt;
525 end;
526 for J := -1 to 1 do
527 for I := -1 to 1 do
528 if (I + J) and 1 = 0 then
529 begin
530 Sprite(Buffer, HGrTerrain, I * xxt, J * yyt, xxt * 2,
531 yyt * 2, X, Y);
532 if MyMap[Loc] and (fTerrain or fSpecial) = fGrass or fSpecial1
533 then
534 Sprite(Buffer, HGrTerrain, I * xxt, J * yyt, xxt * 2, yyt * 2,
535 1 + 2 * (xxt * 2 + 1), 1 + yyt + 1 * (yyt * 3 + 1))
536 else if (MyMap[Loc] and fTerrain = fForest) and
537 IsJungle(Loc div G.lx) then
538 Sprite(Buffer, HGrTerrain, I * xxt, J * yyt, xxt * 2, yyt * 2,
539 1 + 7 * (xxt * 2 + 1), 1 + yyt + 19 * (yyt * 3 + 1))
540 else if MyMap[Loc] and fTerrain >= fForest then
541 Sprite(Buffer, HGrTerrain, I * xxt, J * yyt, xxt * 2, yyt * 2,
542 1 + 7 * (xxt * 2 + 1),
543 1 + yyt + 2 * Integer(2 + MyMap[Loc] and fTerrain - fForest)
544 * (yyt * 3 + 1));
545 end;
546 BitBltBitmap(Offscreen, xView, yView + 16, 64, 32, Buffer, 1, 0);
547
548 // show unit, experience and health
549 Sprite(Offscreen, HGr, xView, yView, 64, 48, pix mod 10 * 65 + 1,
550 pix div 10 * 49 + 1);
551 if Flags and unFortified <> 0 then
552 Sprite(Offscreen, HGrStdUnits, xView, yView, xxu * 2, yyu * 2,
553 1 + 6 * (xxu * 2 + 1), 1);
554 FrameImage(Offscreen.Canvas, HGrSystem.Data, xView - 20,
555 yView + 5, 12, 14, 121 + Exp div ExpCost * 13, 28);
556 if Health < 100 then
557 begin
558 S := IntToStr(Health) + '%';
559 LightGradient(Offscreen.Canvas, xView - 45, yView + 24, 38,
560 (ColorOfHealth(Health) and $FEFEFE shr 2) * 3);
561 RisedTextOut(Offscreen.Canvas, xView - 45 + 20 -
562 BiColorTextWidth(Offscreen.Canvas, S) div 2, yView + 23, S);
563 end;
564
565 if Kind = dkEnemyUnit then
566 begin
567 S := Tribe[mox.owner].TPhrase('UNITOWNER');
568 LoweredTextOut(Offscreen.Canvas, -1, MainTexture,
569 (ClientWidth - BiColorTextWidth(Offscreen.Canvas, S)) div 2,
570 yView + 80, S);
571 end;
572 end
573 else
574 begin
575 FrameImage(Offscreen.Canvas, BigImp, xView + 4, yView, 56, 40, 0, 0);
576 Sprite(Offscreen, HGr, xView, yView - 4, 64, 44, pix mod 10 * 65 + 1,
577 pix div 10 * 49 + 1);
578 end;
579
580 DarkGradient(Offscreen.Canvas, xTotal - 6, yTotal + 1, 180, 2);
581 RisedTextOut(Offscreen.Canvas, xTotal - 2, yTotal,
582 Phrases.Lookup('UNITSTRENGTH'));
583 S := IntToStr(mi.Attack) + '/' + IntToStr(mi.Defense);
584 RisedTextOut(Offscreen.Canvas,
585 xTotal + 170 - BiColorTextWidth(Offscreen.Canvas, S), yTotal, S);
586 FeatureBar(Offscreen, xTotal, yTotal + 19, mi, MainTexture);
587 NumberBarS(Offscreen, xTotal, yTotal + 38, Phrases.Lookup('UNITSPEED'),
588 MovementToString(mi.Speed), MainTexture);
589 LoweredTextOut(Offscreen.Canvas, -1, MainTexture, xTotal - 2, yTotal + 57,
590 Phrases.Lookup('UNITCOST'));
591 DLine(Offscreen.Canvas, xTotal - 2, xTotal + 170, yTotal + 57 + 16,
592 MainTexture.ColorBevelShade, MainTexture.ColorBevelLight);
593 if G.Difficulty[Me] = 0 then
594 S := IntToStr(mi.cost)
595 else
596 S := IntToStr(mi.cost * BuildCostMod[G.Difficulty[Me]] div 12);
597 RisedTextOut(Offscreen.Canvas,
598 xTotal + 159 - BiColorTextWidth(Offscreen.Canvas, S), yTotal + 57, S);
599 Sprite(Offscreen, HGrSystem, xTotal + 160, yTotal + 57 + 5, 10,
600 10, 88, 115);
601
602 if Kind = dkOwnModel then
603 begin
604 if MyModel[mixShow].IntroTurn > 0 then
605 begin
606 if MyModel[mixShow].Kind = mkEnemyDeveloped then
607 LoweredTextOut(Offscreen.Canvas, -1, MainTexture, xTotal - 2,
608 (yTotal + StatDown - 19), Phrases.Lookup('UNITADOPT'))
609 else
610 LoweredTextOut(Offscreen.Canvas, -1, MainTexture, xTotal - 2,
611 (yTotal + StatDown - 19), Phrases.Lookup('UNITINTRO'));
612 DLine(Offscreen.Canvas, xTotal - 2, xTotal + 170,
613 (yTotal + StatDown - 19) + 16, MainTexture.ColorTextShade,
614 MainTexture.ColorTextLight);
615 S := TurnToString(MyModel[mixShow].IntroTurn);
616 RisedTextOut(Offscreen.Canvas,
617 xTotal + 170 - BiColorTextWidth(Offscreen.Canvas, S),
618 (yTotal + StatDown - 19), S);
619 end;
620
621 NumberBar(Offscreen, xTotal, yTotal + StatDown,
622 Phrases.Lookup('UNITBUILT'), MyModel[mixShow].Built, MainTexture);
623 if MyModel[mixShow].Lost > 0 then
624 NumberBar(Offscreen, xTotal, yTotal + StatDown + 19,
625 Phrases.Lookup('UNITLOST'), MyModel[mixShow].Lost, MainTexture);
626 if InProd > 0 then
627 NumberBar(Offscreen, xTotal, yTotal + StatDown + 57,
628 Phrases.Lookup('UNITINPROD'), InProd, MainTexture);
629 if Available > 0 then
630 NumberBar(Offscreen, xTotal, yTotal + StatDown + 38,
631 Phrases.Lookup('UNITAVAILABLE'), Available, MainTexture);
632
633 if MyModel[mixShow].Status and msObsolete <> 0 then
634 begin
635 SwitchBtn.ButtonIndex := 12;
636 SwitchBtn.Hint := Phrases.Lookup('BTN_OBSOLETE');
637 end
638 else
639 begin
640 SwitchBtn.ButtonIndex := 11;
641 SwitchBtn.Hint := Phrases.Lookup('BTN_NONOBSOLETE');
642 end;
643 if MyModel[mixShow].Status and msAllowConscripts = 0 then
644 begin
645 ConscriptsBtn.ButtonIndex := 30;
646 ConscriptsBtn.Hint := Phrases.Lookup('BTN_NOCONSCRIPTS');
647 end
648 else
649 begin
650 ConscriptsBtn.ButtonIndex := 29;
651 ConscriptsBtn.Hint := Phrases.Lookup('BTN_ALLOWCONSCRIPTS');
652 end;
653 end
654 else if Kind = dkEnemyModel then
655 begin
656 if Destroyed > 0 then
657 NumberBar(Offscreen, xTotal, yTotal + StatDown - 19,
658 Phrases.Lookup('UNITDESTROYED'), Destroyed, MainTexture);
659 if Available > 0 then
660 NumberBar(Offscreen, xTotal, yTotal + StatDown,
661 Phrases.Lookup('UNITKNOWN'), Available, MainTexture);
662 end;
663 end;
664 end;
665
666 Offscreen.Canvas.Font.Assign(UniFont[ftNormal]);
667 case Kind of
668 dkOwnModel, dkEnemyModel:
669 yCaption := yView + 46;
670 dkEnemyUnit, dkOwnUnit:
671 yCaption := yView + 54;
672 dkEnemyCityDefense, dkEnemyCity:
673 yCaption := 79;
674 end;
675 RisedTextOut(Offscreen.Canvas,
676 (ClientWidth - BiColorTextWidth(Offscreen.Canvas, Caption)) div 2,
677 yCaption, Caption);
678end;
679
680procedure TUnitStatDlg.ModelBoxChange(Sender: TObject);
681begin
682 SmartUpdateContent;
683end;
684
685procedure TUnitStatDlg.SwitchBtnClick(Sender: TObject);
686begin
687 MyModel[mixShow].Status := MyModel[mixShow].Status xor msObsolete;
688 if MyModel[mixShow].Status and msObsolete <> 0 then
689 begin
690 SwitchBtn.ButtonIndex := 12;
691 SwitchBtn.Hint := Phrases.Lookup('BTN_OBSOLETE');
692 end
693 else
694 begin
695 SwitchBtn.ButtonIndex := 11;
696 SwitchBtn.Hint := Phrases.Lookup('BTN_NONOBSOLETE');
697 end;
698end;
699
700procedure TUnitStatDlg.ConscriptsBtnClick(Sender: TObject);
701begin
702 MyModel[mixShow].Status := MyModel[mixShow].Status xor msAllowConscripts;
703 if MyModel[mixShow].Status and msAllowConscripts = 0 then
704 begin
705 ConscriptsBtn.ButtonIndex := 30;
706 ConscriptsBtn.Hint := Phrases.Lookup('BTN_NOCONSCRIPTS');
707 end
708 else
709 begin
710 ConscriptsBtn.ButtonIndex := 29;
711 ConscriptsBtn.Hint := Phrases.Lookup('BTN_ALLOWCONSCRIPTS');
712 end;
713end;
714
715procedure TUnitStatDlg.HelpBtnClick(Sender: TObject);
716begin
717 MainScreen.HelpDlg.ShowNewContent(wmPersistent, hkModel, 0);
718end;
719
720end.
Note: See TracBrowser for help on using the repository browser.