source: tags/1.3.9/LocalPlayer/Select.pas

Last change on this file was 725, checked in by chronos, 3 weeks ago
File size: 69.3 KB
Line 
1{$INCLUDE Switches.inc}
2unit Select;
3
4interface
5
6uses
7 Protocol, ClientTools, ScreenTools, PVSB, BaseWin, LCLIntf, LCLType, Messages,
8 SysUtils, Classes, ButtonB, ButtonBase, Types, Math, Generics.Collections,
9 {$IFDEF DPI}Dpi.Graphics, Dpi.Controls, Dpi.Forms, Dpi.ExtCtrls, Dpi.Menus,
10 Dpi.Common, System.UITypes{$ELSE}
11 Graphics, Controls, Forms, ExtCtrls, Menus{$ENDIF};
12
13type
14 TListKind = (kProject, kAdvance, kFarAdvance, kCities, kCityEvents, kModels,
15 kEnemyModels, kAllEnemyModels, kTribe, kScience, kShipPart, kEnemyShipPart,
16 kChooseTech, kChooseEnemyTech, kChooseModel, kChooseEnemyModel, kChooseCity,
17 kChooseEnemyCity, kStealTech, kGovernment, kMission);
18
19 TLayerIndex = (laImprovements, laWonders, laClasses);
20
21 { TLine }
22
23 TLine = class
24 Code: Integer;
25 Model: Integer;
26 ModelSortValue: Integer;
27 procedure Assign(Source: TLine);
28 end;
29
30 { TLayer }
31
32 TLayer = class
33 Index: TLayerIndex;
34 FirstShrinkedLine: Integer;
35 Lines: TObjectList<TLine>;
36 procedure AddLine(Code: Integer; Model: Integer = 0; ModelSortValue: Integer = 0);
37 procedure SwapLine(I, J: Integer);
38 procedure SortModels;
39 procedure SortCities;
40 procedure SortTechs;
41 constructor Create(AIndex: TLayerIndex);
42 destructor Destroy; override;
43 end;
44
45 { TListDlg }
46
47 TListDlg = class(TFramedDlg)
48 CloseBtn: TButtonB;
49 LayerClassesButton: TButtonB;
50 LayerWondersButton: TButtonB;
51 LayerImprovementsButton: TButtonB;
52 ToggleBtn: TButtonB;
53 Popup: TPopupMenu;
54 procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
55 procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
56 WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
57 procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
58 X, Y: Integer);
59 procedure FormCreate(Sender: TObject);
60 procedure FormDestroy(Sender: TObject);
61 procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
62 Shift: TShiftState; X, Y: Integer);
63 procedure FormPaint(Sender: TObject);
64 procedure CloseBtnClick(Sender: TObject);
65 procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
66 procedure FormShow(Sender: TObject);
67 procedure ModeBtnClick(Sender: TObject);
68 procedure ToggleBtnClick(Sender: TObject);
69 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
70 procedure PlayerClick(Sender: TObject);
71 private
72 Kind: TListKind;
73 LineDistance: Integer;
74 MaxLines: Integer;
75 cixProject: Integer;
76 PlayerView: Integer;
77 Selected: Integer;
78 DispLines: Integer;
79 Layer: TLayer;
80 nColumn: Integer;
81 TechNameSpace: Integer;
82 ScienceNation: Integer;
83 ScrollBar: TPVScrollbar;
84 Layers: array [TLayerIndex] of TLayer;
85 Column: array [0 .. nPl - 1] of Integer;
86 Closable: Boolean;
87 MultiPage: Boolean;
88 ScienceNationDotBuffer: TBitmap;
89 function GetSelectionIndex: Integer;
90 procedure ScrollBarUpdate(Sender: TObject);
91 procedure InitLines;
92 procedure PaintLine(ca: TCanvas; L: Integer; NonText, Lit: Boolean);
93 function RenameModel(mix: Integer): Boolean;
94 procedure OnScroll(var Msg: TMessage); message WM_VSCROLL;
95 procedure OnMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
96 procedure SetSelectionIndex(Index: Integer);
97 protected
98 procedure DoOnResize; override;
99 public
100 Result: Integer;
101 function RenameCity(cix: Integer): Boolean;
102 function OnlyChoice(TestKind: TListKind): Integer;
103 // -2=empty, -1=ambiguous, other=only choice
104 procedure OffscreenPaint; override;
105 procedure ShowNewContent(NewMode: TWindowMode; ListKind: TListKind);
106 procedure ShowNewContent_CityProject(NewMode: TWindowMode; cix: Integer);
107 procedure ShowNewContent_MilReport(NewMode: TWindowMode; Player: Integer);
108 procedure EcoChange;
109 procedure TechChange;
110 procedure AddCity;
111 procedure RemoveUnit;
112 end;
113
114 TModalSelectDlg = TListDlg;
115
116const
117 cpType = $10000;
118 mixAll = $10000;
119 adAll = $10000;
120
121
122implementation
123
124uses
125 Term, CityScreen, Help, UnitStat, Tribes, Inp, CmdList;
126
127{$R *.lfm}
128
129const
130 CityNameSpace = 127;
131
132 MustChooseKind = [kTribe, kStealTech, kGovernment];
133
134{ TLine }
135
136procedure TLine.Assign(Source: TLine);
137begin
138 Code := Source.Code;
139 Model := Source.Model;
140 ModelSortValue := Source.ModelSortValue;
141end;
142
143{ TLayer }
144
145procedure TLayer.AddLine(Code: Integer; Model: Integer = 0; ModelSortValue: Integer = 0);
146var
147 NewLine: TLine;
148begin
149 NewLine := TLine.Create;
150 NewLine.Code := Code;
151 NewLine.Model := Model;
152 NewLine.ModelSortValue := ModelSortValue;
153 Lines.Add(NewLine);
154end;
155
156procedure TLayer.SwapLine(I, J: Integer);
157var
158 Temp: TLine;
159begin
160 Temp := TLine.Create;
161 Temp.Assign(Lines[I]);
162 Lines[I].Assign(Lines[J]);
163 Lines[J].Assign(Temp);
164 Temp.Free;
165end;
166
167procedure TLayer.SortModels;
168var
169 I, J: Integer;
170begin
171 for I := 0 to Lines.Count - 2 do
172 for J := I + 1 to Lines.Count - 1 do
173 if Lines[I].ModelSortValue > Lines[J].ModelSortValue then
174 begin
175 SwapLine(I, J);
176 end;
177end;
178
179procedure TLayer.SortTechs;
180var
181 I, J: Integer;
182begin // sort by advancedness
183 for I := 0 to Lines.Count - 2 do
184 if Lines[I].Code < adMilitary then
185 for J := I + 1 to Lines.Count - 1 do
186 if AdvValue[Lines[I].Code] * nAdv + Lines[I].Code < AdvValue[Lines[J].Code] *
187 nAdv + Lines[J].Code then
188 begin
189 SwapLine(I, J);
190 end;
191end;
192
193procedure TLayer.SortCities;
194var
195 I, J: Integer;
196begin
197 for I := 0 to Lines.Count - 2 do
198 for J := I + 1 to Lines.Count - 1 do
199 if CityName(MyCity[Lines[I].Code].ID) > CityName(MyCity[Lines[J].Code].ID) then
200 begin
201 SwapLine(I, J);
202 end;
203end;
204
205constructor TLayer.Create(AIndex: TLayerIndex);
206begin
207 Lines := TObjectList<TLine>.Create;
208 Index := AIndex;
209end;
210
211destructor TLayer.Destroy;
212begin
213 FreeAndNil(Lines);
214 inherited;
215end;
216
217procedure TListDlg.FormCreate(Sender: TObject);
218begin
219 inherited;
220 Layers[laImprovements] := TLayer.Create(laImprovements);
221 Layers[laWonders] := TLayer.Create(laWonders);
222 Layers[laClasses] := TLayer.Create(laClasses);
223 Canvas.Font.Assign(UniFont[ftNormal]);
224 ScrollBar := TPVScrollbar.Create(Self);
225 ScrollBar.SetBorderSpacing(36, 10, 36);
226 ScrollBar.OnUpdate := ScrollBarUpdate;
227 InitButtons;
228 Kind := kMission;
229 LayerImprovementsButton.Hint := Phrases.Lookup('BTN_IMPRS');
230 LayerWondersButton.Hint := Phrases.Lookup('BTN_WONDERS');
231 LayerClassesButton.Hint := Phrases.Lookup('BTN_CLASSES');
232 ScienceNationDotBuffer := TBitmap.Create;
233 ScienceNationDotBuffer.PixelFormat := TPixelFormat.pf24bit;
234 ScienceNationDotBuffer.SetSize(17, 17);
235 ScienceNationDotBuffer.Canvas.FillRect(0, 0, ScienceNationDotBuffer.Width, ScienceNationDotBuffer.Height);
236end;
237
238procedure TListDlg.FormDestroy(Sender: TObject);
239begin
240 FreeAndNil(ScrollBar);
241 FreeAndNil(ScienceNationDotBuffer);
242 FreeAndNil(Layers[laImprovements]);
243 FreeAndNil(Layers[laWonders]);
244 FreeAndNil(Layers[laClasses]);
245end;
246
247procedure TListDlg.CloseBtnClick(Sender: TObject);
248begin
249 Closable := True;
250 Close;
251end;
252
253procedure TListDlg.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
254begin
255 CanClose := Closable or not (Kind in MustChooseKind);
256end;
257
258procedure TListDlg.OnScroll(var Msg: TMessage);
259begin
260 { TODO: Handled by MouseWheel event
261 if ScrollBar.Process(Msg) then begin
262 Selected := -2;
263 SmartUpdateContent(True);
264 end;
265 }
266end;
267
268procedure TListDlg.OnMouseLeave(var Msg: TMessage);
269begin
270 if not Closable and (Selected <> -2) then
271 begin
272 PaintLine(Canvas, Selected, False, False);
273 Selected := -2;
274 end;
275end;
276
277procedure TListDlg.FormPaint(Sender: TObject);
278var
279 S: string;
280begin
281 inherited;
282 Canvas.Font.Assign(UniFont[ftNormal]);
283 if Selected <> -2 then
284 PaintLine(Canvas, Selected, False, True);
285 S := '';
286 if (Kind = kAdvance) and (MyData.FarTech <> adNone) then
287 S := Format(Phrases.Lookup('TECHFOCUS'),
288 [Phrases.Lookup('ADVANCES', MyData.FarTech)])
289 else if Kind = kModels then
290 S := Tribe[Me].TPhrase('SHORTNAME')
291 else if Kind = kEnemyModels then
292 S := Tribe[PlayerView].TPhrase('SHORTNAME') + ' (' +
293 TurnToString(MyRO.EnemyReport[PlayerView].TurnOfMilReport) + ')';
294 if S <> '' then
295 LoweredTextOut(Canvas, -1, MainTexture,
296 (Width - BiColorTextWidth(Canvas, S)) div 2, 31, S);
297 if not MultiPage and (Kind in [kProject, kAdvance, kFarAdvance]) and
298 not Phrases2FallenBackToEnglish then begin
299 S := Phrases2.Lookup('SHIFTCLICK');
300 LoweredTextOut(Canvas, -2, MainTexture,
301 (Width - BiColorTextWidth(Canvas, S)) div 2, Height - 29, S);
302 end;
303end;
304
305procedure TListDlg.PaintLine(ca: TCanvas; L: Integer; NonText, Lit: Boolean);
306// paint a line
307
308 procedure DisplayProject(X, Y, pix: Integer);
309 begin
310 if pix and (cpType or cpImp) = 0 then
311 with Tribe[Me].ModelPicture[pix and cpIndex] do
312 Sprite(Offscreen, HGr, X, Y, 64, 48, pix mod 10 * 65 + 1,
313 pix div 10 * 49 + 1)
314 else
315 begin
316 Frame(Offscreen.Canvas, X + (16 - 1), Y + (16 - 2), X + (16 + xSizeSmall),
317 Y + (16 - 1 + ySizeSmall), MainTexture.ColorBevelLight,
318 MainTexture.ColorBevelShade);
319 if pix and cpType = 0 then
320 if (pix and cpIndex = imPalace) and (MyRO.Government <> gAnarchy) then
321 BitBltBitmap(Offscreen, X + 16, Y + (16 - 1), xSizeSmall,
322 ySizeSmall, SmallImp, (MyRO.Government - 1) *
323 xSizeSmall, ySizeSmall)
324 else
325 BitBltBitmap(Offscreen, X + 16, Y + (16 - 1), xSizeSmall,
326 ySizeSmall, SmallImp, pix and cpIndex mod 7 *
327 xSizeSmall, (pix and cpIndex + SystemIconLines * 7) div 7 *
328 ySizeSmall)
329 else
330 BitBltBitmap(Offscreen, X + 16, Y + (16 - 1), xSizeSmall,
331 ySizeSmall, SmallImp, (3 + pix and cpIndex) *
332 xSizeSmall, 0);
333 end;
334 end;
335
336 procedure ReplaceText(X, Y, Color: Integer; S: string);
337 var
338 TextSize: TSize;
339 begin
340 if ca = Canvas then
341 begin
342 TextSize.cx := BiColorTextWidth(ca, S);
343 TextSize.cy := ca.TextHeight(S);
344 if Y + TextSize.cy >= TitleHeight + InnerHeight then
345 TextSize.cy := TitleHeight + InnerHeight - Y;
346 Fill(ca, X, Y, TextSize.cx, TextSize.cy, (Maintexture.Width - Width)
347 div 2, (Maintexture.Height - Height) div 2);
348 end;
349 LoweredTextOut(ca, Color, MainTexture, X, Y, S);
350 end;
351
352var
353 Icon, ofs, X, Y, y0, lix, I, J, TextColor, Available, First, Test,
354 FutureCount, Growth, TrueFood, TrueProd: Integer;
355 CityReport: TCityReportNew;
356 mox: ^TModelInfo;
357 S, Number: string;
358 CanGrow: Boolean;
359begin
360 lix := Layer.Lines[ScrollBar.Position + L].Code;
361 y0 := 2 + (L + 1) * LineDistance;
362
363 if ScrollBar.Position + L >= Layer.FirstShrinkedLine then
364 ofs := (ScrollBar.Position + L - Layer.FirstShrinkedLine) and 1 * 33
365 else { if Layers[Layer].FirstShrinkedLine < Layers[Layer].Lines.Count then }
366 ofs := 33;
367
368 if Kind in [kCities, kCityEvents] then
369 with TCity(MyCity[lix]) do
370 begin
371 X := 104 - 76;
372 Y := y0;
373 if ca = Canvas then
374 begin
375 X := X + SideFrame;
376 Y := Y + TitleHeight;
377 end;
378 if Lit then
379 TextColor := MainTexture.ColorLitText
380 else
381 TextColor := -1;
382 S := CityName(ID);
383 while BiColorTextWidth(ca, S) > CityNameSpace do
384 Delete(S, Length(S), 1);
385 ReplaceText(X + 15, Y, TextColor, S);
386
387 if NonText then
388 with Offscreen.Canvas do
389 begin // city size
390 Brush.Color := $000000;
391 FillRect(Rect(X - 4 - 11, Y + 1, X - 4 + 13, Y + 21));
392 Brush.Color := $FFFFFF;
393 FillRect(Rect(X - 4 - 12, Y, X - 4 + 12, Y + 20));
394 Brush.Style := TBrushStyle.bsClear;
395 Font.Color := $000000;
396 S := IntToStr(MyCity[lix].Size);
397 TextOut(X - 4 - TextWidth(S) div 2, Y, S);
398 end;
399
400 if Kind = kCityEvents then
401 begin
402 First := -1;
403 for J := 0 to nCityEventPriority - 1 do
404 if (Flags and CityRepMask and CityEventPriority[J] <> 0) then
405 begin
406 First := J;
407 Break;
408 end;
409 if First >= 0 then
410 begin
411 I := 0;
412 Test := 1;
413 while Test < CityEventPriority[First] do
414 begin
415 Inc(I);
416 Inc(Test, Test);
417 end;
418 S := CityEventName(I);
419 { if CityEventPriority[First] = chNoGrowthWarning then
420 if Built[imAqueduct] = 0 then
421 S := Format(S, [Phrases.Lookup('IMPROVEMENTS', imAqueduct)])
422 else begin S := Format(S, [Phrases.Lookup('IMPROVEMENTS', imSewer)]); I := 17 end; }
423 ReplaceText(X + (CityNameSpace + 4 + 40 + 18 + 8), Y, TextColor, S);
424 if NonText then
425 begin
426 Sprite(Offscreen, HGrSystem, 105 - 76 + CityNameSpace + 4 + 40,
427 y0 + 1, 18, 18, 1 + I mod 3 * 19, 1 + I div 3 * 19);
428 X := InnerWidth - 26;
429 for J := nCityEventPriority - 1 downto First + 1 do
430 if (Flags and CityRepMask and CityEventPriority[J] <> 0) then
431 begin
432 I := 0;
433 Test := 1;
434 while Test < CityEventPriority[J] do
435 begin
436 Inc(I);
437 Inc(Test, Test);
438 end;
439 if (CityEventPriority[J] = chNoGrowthWarning) and
440 (Built[imAqueduct] > 0) then
441 I := 17;
442 Sprite(Offscreen, HGrSystem, X, y0 + 1, 18, 18,
443 1 + I mod 3 * 19, 1 + I div 3 * 19);
444 Dec(X, 20);
445 end;
446 end;
447 end;
448 end
449 else
450 begin
451 CityReport.HypoTiles := -1;
452 CityReport.HypoTaxRate := -1;
453 CityReport.HypoLuxuryRate := -1;
454 Server(sGetCityReportNew, Me, lix, CityReport);
455 TrueFood := Food;
456 TrueProd := Prod;
457 if Supervising then
458 begin // normalize city from after-turn state
459 Dec(TrueFood, CityReport.FoodSurplus);
460 if TrueFood < 0 then
461 TrueFood := 0; // shouldn't happen
462 Dec(TrueProd, CityReport.Production);
463 if TrueProd < 0 then
464 TrueProd := 0; // shouldn't happen
465 end;
466
467 S := ''; // disorder info
468 if Flags and chCaptured <> 0 then
469 S := Phrases.Lookup('CITYEVENTS', 14)
470 else if CityReport.HappinessBalance < 0 then
471 S := Phrases.Lookup('CITYEVENTS', 0);
472 if S <> '' then
473 begin { disorder }
474 if NonText then
475 begin
476 DarkGradient(Offscreen.Canvas, 99 + 31 + CityNameSpace + 4,
477 y0 + 2, 131, 3);
478 ca.Font.Assign(UniFont[ftSmall]);
479 RisedTextOut(Offscreen.Canvas, 103 + CityNameSpace + 4 + 31,
480 y0 + 1, S);
481 ca.Font.Assign(UniFont[ftNormal]);
482 end;
483 end
484 else
485 begin
486 { s := IntToStr(CityReport.FoodSurplus);
487 ReplaceText(X + (CityNameSpace + 4 + 48) - BiColorTextWidth(ca, S), Y, TextColor, S); }
488 S := IntToStr(CityReport.Science);
489 ReplaceText(X + CityNameSpace + 4 + 370 + 48 - BiColorTextWidth(ca,
490 S), Y, TextColor, S);
491 S := IntToStr(CityReport.Production);
492 ReplaceText(X + CityNameSpace + 4 + 132 - BiColorTextWidth(ca, S), Y,
493 TextColor, S);
494 if NonText then
495 begin
496 // Sprite(offscreen, HGrSystem, x + CityNameSpace + 4 + 333 + 1, y + 6, 10, 10, 66, 115);
497 Sprite(Offscreen, HGrSystem, X + CityNameSpace + 4 + 370 + 48 + 1,
498 Y + 6, 10, 10, 77, 126);
499 Sprite(Offscreen, HGrSystem, X + CityNameSpace + 4 + 132 + 1, Y + 6,
500 10, 10, 88, 115);
501 end;
502 end;
503 S := IntToStr(CityTaxBalance(lix, CityReport));
504 ReplaceText(X + CityNameSpace + 4 + 370 - BiColorTextWidth(ca, S), Y,
505 TextColor, S);
506 // if Project and (cpImp + cpIndex) <> cpImp + imTrGoods then
507 // ReplaceText(x + CityNameSpace + 4 + 333 + 1, y, TextColor, Format('%d/%d', [TrueProd,CityReport.ProjectCost]));
508 if NonText then
509 begin
510 Sprite(Offscreen, HGrSystem, X + CityNameSpace + 4 + 370 + 1, Y + 6,
511 10, 10, 132, 115);
512
513 // food progress
514 CanGrow := (Size < MaxCitySize) and (MyRO.Government <> gFuture) and
515 (CityReport.FoodSurplus > 0) and
516 ((Size < NeedAqueductSize) or (Built[imAqueduct] = 1) and
517 (Size < NeedSewerSize) or (Built[imSewer] = 1));
518 Growth := CutCityFoodSurplus(CityReport.FoodSurplus,
519 (MyRO.Government <> gAnarchy) and (Flags and chCaptured = 0),
520 MyRO.Government, Size);
521 PaintRelativeProgressBar(Offscreen.Canvas, 1, X + 15 + CityNameSpace +
522 4, Y + 7, 68, TrueFood, Growth, CityReport.Storage, CanGrow, MainTexture);
523
524 if Project <> cpImp + imTrGoods then
525 begin
526 DisplayProject(ofs + 104 - 76 + X - 28 + CityNameSpace + 4 + 206 -
527 60, y0 - 15, Project);
528
529 // production progress
530 Growth := CityReport.Production;
531 if (Growth < 0) or (MyRO.Government = gAnarchy) or
532 (Flags and chCaptured <> 0) then
533 Growth := 0;
534 PaintRelativeProgressBar(Offscreen.Canvas, 4,
535 X + CityNameSpace + 4 + 304 - 60 + 9, Y + 7, 68, TrueProd, Growth,
536 CityReport.ProjectCost, True, MainTexture);
537 end;
538 end;
539 end;
540 end
541 else if Kind in [kModels, kEnemyModels] then
542 begin
543 X := 104;
544 Y := y0;
545 if ca = Canvas then
546 begin
547 X := X + SideFrame;
548 Y := Y + TitleHeight;
549 end;
550 if Lit then
551 TextColor := MainTexture.ColorLitText
552 else
553 TextColor := -1;
554 if Kind = kModels then
555 begin
556 Available := 0;
557 for J := 0 to MyRO.nUn - 1 do
558 if (MyUn[J].Loc >= 0) and (MyUn[J].mix = lix) then
559 Inc(Available);
560 if MainScreen.mNames.Checked then
561 S := Tribe[Me].ModelName[lix]
562 else
563 S := Format(Tribe[Me].TPhrase('GENMODEL'), [lix]);
564 if NonText then
565 DisplayProject(8 + ofs, y0 - 15, lix);
566 end
567 else
568 begin
569 Available := MyRO.EnemyReport[PlayerView].UnCount[lix];
570 if MainScreen.mNames.Checked then
571 S := Tribe[PlayerView].ModelName[lix]
572 else
573 S := Format(Tribe[PlayerView].TPhrase('GENMODEL'), [lix]);
574 if NonText then
575 with Tribe[PlayerView].ModelPicture[lix] do
576 Sprite(Offscreen, HGr, 8 + ofs, y0 - 15, 64, 48, pix mod 10 * 65 + 1,
577 pix div 10 * 49 + 1);
578 end;
579 if Available > 0 then
580 ReplaceText(X + 32 - BiColorTextWidth(ca, IntToStr(Available)), Y,
581 TextColor, IntToStr(Available));
582 ReplaceText(X + 40, Y, TextColor, S);
583 end
584 else
585 begin
586 case Kind of
587 kAllEnemyModels, kChooseEnemyModel:
588 if lix = mixAll then
589 S := Phrases.Lookup('PRICECAT_ALLMODEL')
590 else
591 begin
592 mox := @MyRO.EnemyModel[lix];
593 if MainScreen.mNames.Checked then
594 begin
595 S := Tribe[mox.Owner].ModelName[mox.mix];
596 if (Kind = kAllEnemyModels) and (Layers[laImprovements].Lines[ScrollBar.Position + L].Model = 0) then
597 S := Format(Tribe[mox.Owner].TPhrase('OWNED'), [S]);
598 end
599 else
600 S := Format(Tribe[mox.Owner].TPhrase('GENMODEL'), [mox.mix]);
601 if NonText then
602 with Tribe[mox.Owner].ModelPicture[mox.mix] do
603 Sprite(Offscreen, HGr, 8 + ofs, y0 - 15, 64, 48,
604 pix mod 10 * 65 + 1, pix div 10 * 49 + 1);
605 end;
606 kChooseModel:
607 if lix = mixAll then
608 S := Phrases.Lookup('PRICECAT_ALLMODEL')
609 else
610 begin
611 S := Tribe[Me].ModelName[lix];
612 if NonText then
613 DisplayProject(8 + ofs, y0 - 15, lix);
614 end;
615 kProject:
616 begin
617 if lix and cpType <> 0 then
618 S := Phrases.Lookup('CITYTYPE', lix and cpIndex)
619 else if lix and cpImp = 0 then
620 with MyModel[lix and cpIndex] do
621 begin
622 S := Tribe[Me].ModelName[lix and cpIndex];
623 if lix and cpConscripts <> 0 then
624 S := Format(Phrases.Lookup('CONSCRIPTS'), [S]);
625 end
626 else
627 begin
628 S := Phrases.Lookup('IMPROVEMENTS', lix and cpIndex);
629 if (Imp[lix and cpIndex].Kind in [ikNatLocal, ikNatGlobal]) and
630 (MyRO.NatBuilt[lix and cpIndex] > 0) or
631 (lix and cpIndex in [imPower, imHydro, imNuclear]) and
632 (MyCity[cixProject].Built[imPower] + MyCity[cixProject].Built
633 [imHydro] + MyCity[cixProject].Built[imNuclear] > 0) then
634 S := Format(Phrases.Lookup('NATEXISTS'), [S]);
635 end;
636 if NonText then
637 DisplayProject(8 + ofs, y0 - 15, lix);
638 end;
639 kAdvance, kFarAdvance, kScience, kChooseTech, kChooseEnemyTech, kStealTech:
640 begin
641 if lix = adAll then
642 S := Phrases.Lookup('PRICECAT_ALLTECH')
643 else
644 begin
645 if lix = adNexus then
646 S := Phrases.Lookup('NEXUS')
647 else if lix = adNone then
648 S := Phrases.Lookup('NOFARTECH')
649 else if lix = adMilitary then
650 S := Phrases.Lookup('INITUNIT')
651 else
652 begin
653 S := Phrases.Lookup('ADVANCES', lix);
654 if (Kind = kAdvance) and (lix in FutureTech) then
655 if MyRO.Tech[lix] < tsApplicable then
656 S := S + ' 1'
657 else
658 S := S + ' ' + IntToStr(MyRO.Tech[lix] + 1);
659 end;
660 if BiColorTextWidth(ca, S) > TechNameSpace + 8 then
661 begin
662 repeat
663 Delete(S, Length(S), 1);
664 until BiColorTextWidth(ca, S) <= TechNameSpace + 5;
665 S := S + '.';
666 end;
667
668 if NonText then
669 begin // show tech Icon
670 if lix = adNexus then
671 begin
672 Frame(Offscreen.Canvas, (8 + 16 - 1), y0 - 1, (8 + 16 + 36),
673 y0 + 20, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
674 Dump(Offscreen, HGrSystem, (8 + 16), y0, 36, 20, 223, 295)
675 end
676 else if lix = adNone then
677 begin
678 Frame(Offscreen.Canvas, (8 + 16 - 1), y0 - 1, (8 + 16 + 36),
679 y0 + 20, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
680 Dump(Offscreen, HGrSystem, (8 + 16), y0, 36, 20, 260, 295)
681 end
682 else if lix = adMilitary then
683 begin
684 Frame(Offscreen.Canvas, (8 + 16 - 1), y0 - 1, (8 + 16 + 36),
685 y0 + 20, MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
686 Dump(Offscreen, HGrSystem, (8 + 16), y0, 36, 20, 38, 295)
687 end
688 else
689 begin
690 Frame(Offscreen.Canvas, (8 + 16 - 1), y0 - 1,
691 (8 + 16 + xSizeSmall), y0 + ySizeSmall,
692 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
693 if AdvIcon[lix] < 84 then
694 BitBltBitmap(Offscreen, (8 + 16), y0, xSizeSmall,
695 ySizeSmall, SmallImp,
696 (AdvIcon[lix] + SystemIconLines * 7) mod 7 * xSizeSmall,
697 (AdvIcon[lix] + SystemIconLines * 7) div 7 *
698 ySizeSmall)
699 else
700 Dump(Offscreen, HGrSystem, (8 + 16), y0, 36, 20,
701 1 + (AdvIcon[lix] - 84) mod 8 * 37,
702 295 + (AdvIcon[lix] - 84) div 8 * 21);
703 J := AdvValue[lix] div 1000;
704 BitBltBitmap(Offscreen, (8 + 16 - 4), y0 + 2, 14, 14,
705 HGrSystem.Mask, 127 + J * 15,
706 85, SRCAND);
707 Sprite(Offscreen, HGrSystem, (8 + 16 - 5), y0 + 1, 14, 14,
708 127 + J * 15, 85);
709 end;
710 end;
711 end;
712
713 if NonText and (Kind in [kAdvance, kScience]) then
714 begin // show research state
715 for J := 0 to nColumn - 1 do
716 begin
717 FutureCount := 0;
718 if J = 0 then // own science
719 if lix = MyRO.ResearchTech then
720 begin
721 Server(sGetTechCost, Me, 0, Icon);
722 Icon := 4 + MyRO.Research * 4 div Icon;
723 if Icon > 4 + 3 then
724 Icon := 4 + 3
725 end
726 else if (lix >= adMilitary) then
727 Icon := -1
728 else if lix in FutureTech then
729 begin
730 Icon := -1;
731 FutureCount := MyRO.Tech[lix];
732 end
733 else if MyRO.Tech[lix] = tsSeen then
734 Icon := 1
735 else if MyRO.Tech[lix] >= tsApplicable then
736 Icon := 2
737 else
738 Icon := -1
739 else
740 with MyRO.EnemyReport[Column[J]]^ do // enemy science
741 if (MyRO.Alive and (1 shl Column[J]) <> 0) and
742 (TurnOfCivilReport >= 0) and (lix = ResearchTech) and
743 ((lix = adMilitary) or (lix in FutureTech) or
744 (Tech[lix] < tsApplicable)) then
745 begin
746 Icon := 4 + ResearchDone div 25;
747 if Icon > 4 + 3 then
748 Icon := 4 + 3;
749 end
750 else if lix = adMilitary then
751 Icon := -1
752 else if lix in FutureTech then
753 begin
754 Icon := -1;
755 FutureCount := Tech[lix]
756 end
757 else if Tech[lix] >= tsApplicable then
758 Icon := 2
759 else if Tech[lix] = tsSeen then
760 Icon := 1
761 else
762 Icon := -1;
763 if Icon >= 0 then
764 Sprite(Offscreen, HGrSystem, 104 - 33 + 15 + 3 + TechNameSpace +
765 24 * J, y0 + 3, 14, 14, 67 + Icon * 15, 85)
766 else if (Kind = kScience) and (FutureCount > 0) then
767 begin
768 Number := IntToStr(FutureCount);
769 RisedTextOut(ca, 104 - 33 + 15 + 10 + TechNameSpace + 24 * J -
770 BiColorTextWidth(ca, Number) div 2, y0, Number);
771 end;
772 end;
773 end;
774 end; // kAdvance, kScience
775 kTribe:
776 S := TribeNames[lix];
777 kShipPart:
778 begin
779 S := Phrases.Lookup('IMPROVEMENTS', imShipComp + lix) + ' (' +
780 IntToStr(MyRO.Ship[Me].Parts[lix]) + ')';
781 if NonText then
782 DisplayProject(8 + ofs, y0 - 15, cpImp + imShipComp + lix);
783 end;
784 kEnemyShipPart:
785 begin
786 S := Phrases.Lookup('IMPROVEMENTS', imShipComp + lix) + ' (' +
787 IntToStr(MyRO.Ship[DipMem[Me].pContact].Parts[lix]) + ')';
788 if NonText then
789 DisplayProject(8 + ofs, y0 - 15, cpImp + imShipComp + lix);
790 end;
791 kGovernment:
792 begin
793 S := Phrases.Lookup('GOVERNMENT', lix);
794 if NonText then
795 begin
796 Frame(Offscreen.Canvas, 8 + 16 - 1, y0 - 15 + (16 - 2),
797 8 + 16 + xSizeSmall, y0 - 15 + (16 - 1 + ySizeSmall),
798 MainTexture.ColorBevelLight, MainTexture.ColorBevelShade);
799 BitBltBitmap(Offscreen, 8 + 16, y0 - 15 + (16 - 1),
800 xSizeSmall, ySizeSmall, SmallImp, (lix - 1) * xSizeSmall, ySizeSmall);
801 end;
802 end;
803 kMission:
804 S := Phrases.Lookup('SPYMISSION', lix);
805 end;
806 case Kind of
807 kTribe, kMission: // center text
808 if Layers[laImprovements].Lines.Count > MaxLines then
809 X := (InnerWidth - GetSystemMetrics(SM_CXVSCROLL)) div 2 -
810 BiColorTextWidth(ca, S) div 2
811 else
812 X := InnerWidth div 2 - BiColorTextWidth(ca, S) div 2;
813 kAdvance, kFarAdvance, kScience, kChooseTech, kChooseEnemyTech,
814 kStealTech, kGovernment:
815 X := 104 - 33;
816 kAllEnemyModels:
817 X := 104;
818 else
819 X := 104 + 15;
820 end;
821 Y := y0;
822 if ca = Canvas then
823 begin
824 X := X + SideFrame;
825 Y := Y + TitleHeight;
826 end;
827 if Lit then
828 TextColor := MainTexture.ColorLitText
829 else
830 TextColor := -1;
831 { if Kind = kTribe then ReplaceText_Tribe(X, Y, TextColor,
832 Integer(TribeNames.Objects[lix]), S)
833 else } ReplaceText(X, Y, TextColor, S);
834 end;
835end;
836
837procedure TListDlg.OffscreenPaint;
838var
839 I, J: Integer;
840begin
841 case Kind of
842 kCities:
843 Caption := Tribe[Me].TPhrase('TITLE_CITIES');
844 kCityEvents:
845 Caption := Format(Phrases.Lookup('TITLE_EVENTS'),
846 [TurnToString(MyRO.Turn)]);
847 end;
848
849 inherited;
850 Offscreen.Canvas.Font.Assign(UniFont[ftNormal]);
851 FillOffscreen(0, 0, InnerWidth, InnerHeight);
852 with Offscreen.Canvas do
853 begin
854 if Kind = kScience then
855 for I := 1 to nColumn - 1 do
856 begin
857 Pen.Color := $000000;
858 MoveTo(104 - 33 + 15 + TechNameSpace + 24 * I, 0);
859 LineTo(104 - 33 + 15 + TechNameSpace + 24 * I, InnerHeight);
860 MoveTo(104 - 33 + 15 + TechNameSpace + 9 * 2 + 24 * I, 0);
861 LineTo(104 - 33 + 15 + TechNameSpace + 9 * 2 + 24 * I, InnerHeight);
862 if MyRO.EnemyReport[Column[I]].TurnOfCivilReport >= MyRO.Turn - 1 then
863 begin
864 Brush.Color := Tribe[Column[I]].Color;
865 FillRect(rect(104 - 33 + 14 + TechNameSpace + 24 * I + 1 * 2, 0,
866 104 - 33 + 17 + TechNameSpace + 24 * I + 8 * 2, InnerHeight));
867 Brush.Style := TBrushStyle.bsClear;
868 end
869 else
870 begin // colored player columns
871 Pen.Color := Tribe[Column[I]].Color;
872 for J := 1 to 8 do
873 begin
874 MoveTo(104 - 33 + 15 + TechNameSpace + 24 * I + J * 2, 0);
875 LineTo(104 - 33 + 15 + TechNameSpace + 24 * I + J * 2, InnerHeight);
876 end;
877 end;
878 end;
879
880 for I := -1 to DispLines do
881 if (I + ScrollBar.Position >= 0) and (I + ScrollBar.Position < Layer.Lines.Count) then
882 PaintLine(Offscreen.Canvas, I, True, False);
883 end;
884 MarkUsedOffscreen(InnerWidth, 8 + 48 + DispLines * LineDistance);
885end;
886
887procedure TListDlg.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
888 X, Y: Integer);
889var
890 i0, Sel0, iColumn, OldScienceNation, xScreen: Integer;
891 S: string;
892begin
893 Y := Y - TitleHeight;
894 i0 := ScrollBar.Position;
895 Sel0 := Selected;
896 if (X >= SideFrame) and (X < SideFrame + InnerWidth) and (Y >= 0) and
897 (Y < InnerHeight) and (Y mod LineDistance >= 4) and (Y mod LineDistance < 20)
898 then
899 Selected := Y div LineDistance - 1
900 else
901 Selected := -2;
902 if (Selected < -1) or (Selected > DispLines) or (Selected + i0 < 0) or
903 (Selected + i0 >= Layer.Lines.Count) then
904 Selected := -2;
905 if Selected <> Sel0 then begin
906 if Sel0 <> -2 then
907 PaintLine(Canvas, Sel0, False, False);
908 if Selected <> -2 then
909 PaintLine(Canvas, Selected, False, True);
910 end;
911
912 if Kind = kScience then
913 begin // show nation under cursor position
914 OldScienceNation := ScienceNation;
915 ScienceNation := -1;
916 if (X >= SideFrame + (104 - 33 + 15 + TechNameSpace)) and
917 ((X - SideFrame - (104 - 33 + 15 + TechNameSpace)) mod 24 <= 18) and
918 (Y >= 0) and (Y < InnerHeight) then
919 begin
920 iColumn := (X - SideFrame - (104 - 33 + 15 + TechNameSpace)) div 24;
921 if (iColumn >= 1) and (iColumn < nColumn) then
922 ScienceNation := Column[iColumn];
923 end;
924 if ScienceNation <> OldScienceNation then
925 begin
926 Fill(Canvas, 9, Height - 29, Width - 18, 24,
927 (Maintexture.Width - Width) div 2,
928 (Maintexture.Height - Height) div 2);
929 if ScienceNation >= 0 then
930 begin
931 S := Tribe[ScienceNation].TPhrase('SHORTNAME');
932 if MyRO.Alive and (1 shl ScienceNation) = 0 then
933 S := Format(Phrases.Lookup('SCIENCEREPORT_EXTINCT'), [S]) // extinct
934 else if MyRO.EnemyReport[ScienceNation].TurnOfCivilReport < MyRO.Turn - 1
935 then
936 S := S + ' (' + TurnToString(MyRO.EnemyReport[ScienceNation]
937 .TurnOfCivilReport) + ')'; // old report
938 xScreen := (Width - BiColorTextWidth(Canvas, S)) div 2;
939 LoweredTextOut(Canvas, -1, MainTexture, xScreen + 10,
940 Height - 29, S);
941 BitBltCanvas(ScienceNationDotBuffer.Canvas, 0, 0, ScienceNationDot.Width,
942 ScienceNationDot.Height, Canvas, xScreen - 10, Height - 27);
943 ImageOp_BCC(ScienceNationDotBuffer, Templates.Data, Point(0, 0),
944 ScienceNationDot.BoundsRect, MainTexture.ColorBevelShade, Tribe[ScienceNation].Color);
945 BitBltCanvas(Canvas, xScreen - 10, Height - 27, ScienceNationDot.Width,
946 ScienceNationDot.Height, ScienceNationDotBuffer.Canvas, 0, 0);
947 end;
948 end;
949 end;
950end;
951
952procedure TListDlg.FormMouseWheel(Sender: TObject; Shift: TShiftState;
953 WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
954begin
955 if ScrollBar.ProcessMouseWheel(WheelDelta) then begin
956 PaintBox1MouseMove(nil, [], MousePos.X - Left,
957 MousePos.Y - Top);
958 end;
959end;
960
961procedure TListDlg.FormClose(Sender: TObject; var CloseAction: TCloseAction);
962begin
963 //Gtk2Fix;
964end;
965
966function TListDlg.RenameCity(cix: Integer): Boolean;
967var
968 CityNameInfo: TCityNameInfo;
969 InputDlg: TInputDlg;
970begin
971 InputDlg := TInputDlg.Create(nil);
972 try
973 InputDlg.Caption := Phrases.Lookup('TITLE_CITYNAME');
974 InputDlg.EditInput.Text := CityName(MyCity[cix].ID);
975 InputDlg.CenterToRect(BoundsRect);
976 InputDlg.ShowModal;
977 if (InputDlg.ModalResult = mrOK) and (InputDlg.EditInput.Text <> '') and
978 (InputDlg.EditInput.Text <> CityName(MyCity[cix].ID)) then
979 begin
980 CityNameInfo.ID := MyCity[cix].ID;
981 CityNameInfo.NewName := InputDlg.EditInput.Text;
982 if CityNameInfo.GetCommandDataSize > CommandDataMaxSize then
983 Delete(CityNameInfo.NewName, Length(CityNameInfo.NewName) -
984 (CityNameInfo.GetCommandDataSize - 1 - CommandDataMaxSize), MaxInt);
985 Server(CommandWithData(cSetCityName, CityNameInfo.GetCommandDataSize),
986 Me, 0, CityNameInfo);
987 if MainScreen.CityDlg.Visible then
988 begin
989 MainScreen.CityDlg.FormShow(nil);
990 MainScreen.CityDlg.Invalidate;
991 end;
992 Result := True;
993 end else Result := False;
994 finally
995 InputDlg.Free;
996 end;
997end;
998
999function TListDlg.RenameModel(mix: Integer): Boolean;
1000var
1001 ModelNameInfo: TModelNameInfo;
1002 InputDlg: TInputDlg;
1003begin
1004 InputDlg := TInputDlg.Create(nil);
1005 try
1006 InputDlg.Caption := Phrases.Lookup('TITLE_MODELNAME');
1007 InputDlg.EditInput.Text := Tribe[Me].ModelName[mix];
1008 InputDlg.CenterToRect(BoundsRect);
1009 InputDlg.ShowModal;
1010 if (InputDlg.ModalResult = mrOK) and (InputDlg.EditInput.Text <> '') and
1011 (InputDlg.EditInput.Text <> Tribe[Me].ModelName[mix]) then
1012 begin
1013 ModelNameInfo.mix := mix;
1014 ModelNameInfo.NewName := InputDlg.EditInput.Text;
1015 if ModelNameInfo.GetCommandDataSize > CommandDataMaxSize then
1016 Delete(ModelNameInfo.NewName, Length(ModelNameInfo.NewName) -
1017 (ModelNameInfo.GetCommandDataSize - 1 - CommandDataMaxSize), MaxInt);
1018 Server(CommandWithData(cSetModelName, ModelNameInfo.GetCommandDataSize),
1019 Me, 0, ModelNameInfo);
1020 if MainScreen.UnitStatDlg.Visible then
1021 begin
1022 MainScreen.UnitStatDlg.FormShow(nil);
1023 MainScreen.UnitStatDlg.Invalidate;
1024 end;
1025 Result := True;
1026 end else Result := False;
1027 finally
1028 InputDlg.Free;
1029 end;
1030end;
1031
1032procedure TListDlg.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
1033 Shift: TShiftState; X, Y: Integer);
1034var
1035 lix: Integer;
1036begin
1037 if ScrollBar.Position + Selected >= 0 then
1038 lix := Layer.Lines[ScrollBar.Position + Selected].Code;
1039 if Kind in [kScience, kCities, kCityEvents, kModels, kEnemyModels, kAllEnemyModels]
1040 then
1041 Include(Shift, ssShift); // don't close list window
1042 if (ssLeft in Shift) and not (ssShift in Shift) then
1043 begin
1044 if Selected <> -2 then
1045 begin
1046 Result := lix;
1047 Closable := True;
1048 Close;
1049 end;
1050 end
1051 else if (ssLeft in Shift) and (ssShift in Shift) then
1052 begin // show help/info popup
1053 if Selected <> -2 then
1054 case Kind of
1055 kCities:
1056 MainScreen.ZoomToCity(MyCity[lix].Loc);
1057 kCityEvents:
1058 MainScreen.ZoomToCity(MyCity[lix].Loc, False, MyCity[lix].Flags and
1059 CityRepMask);
1060 kModels, kChooseModel:
1061 if lix <> mixAll then
1062 MainScreen.UnitStatDlg.ShowNewContent_OwnModel(wmPersistent, lix);
1063 kEnemyModels:
1064 MainScreen.UnitStatDlg.ShowNewContent_EnemyModel(wmPersistent,
1065 Layers[laImprovements].Lines[ScrollBar.Position + Selected].Model);
1066 kAllEnemyModels, kChooseEnemyModel:
1067 if lix <> mixAll then
1068 MainScreen.UnitStatDlg.ShowNewContent_EnemyModel(wmPersistent, lix);
1069 kAdvance, kFarAdvance, kScience, kChooseTech, kChooseEnemyTech, kStealTech:
1070 if lix = adMilitary then
1071 MainScreen.HelpDlg.ShowNewContent(wmPersistent, hkText,
1072 MainScreen.HelpDlg.TextIndex('MILRES'))
1073 else if lix < adMilitary then
1074 MainScreen.HelpDlg.ShowNewContent(wmPersistent, hkAdv, lix);
1075 kProject:
1076 if lix = cpImp + imTrGoods then
1077 MainScreen.HelpDlg.ShowNewContent(wmPersistent, hkText,
1078 MainScreen.HelpDlg.TextIndex('TRADINGGOODS'))
1079 else if lix and (cpImp + cpType) = 0 then
1080 MainScreen.UnitStatDlg.ShowNewContent_OwnModel(wmPersistent,
1081 lix and cpIndex)
1082 else if (lix and cpType = 0) and (lix <> cpImp + imTrGoods) then
1083 MainScreen.HelpDlg.ShowNewContent(wmPersistent, hkImp,
1084 lix and cpIndex);
1085 kGovernment:
1086 MainScreen.HelpDlg.ShowNewContent(wmPersistent, hkMisc,
1087 Integer(miscGovList));
1088 kShipPart, kEnemyShipPart:
1089 ;
1090 end;
1091 end
1092 else if ssRight in Shift then
1093 begin
1094 if Selected <> -2 then
1095 case Kind of
1096 kCities, kCityEvents:
1097 if RenameCity(lix) then begin
1098 SmartUpdateContent;
1099 Term.MainScreen.RepaintAll;
1100 end;
1101 kModels:
1102 if RenameModel(lix) then begin
1103 SmartUpdateContent;
1104 Term.MainScreen.RepaintAll;
1105 end;
1106 end;
1107 end;
1108end;
1109
1110procedure TListDlg.InitLines;
1111var
1112 Required: array [0 .. nAdv - 1] of Integer;
1113
1114 procedure TryAddImpLine(Layer: TLayer; Project: Integer);
1115 begin
1116 if Server(sSetCityProject - sExecute, Me, cixProject, Project) >= rExecuted
1117 then
1118 begin
1119 Layer.AddLine(Project);
1120 end;
1121 end;
1122
1123 function ModelSortValue(const ModelInfo: TModelInfo;
1124 MixPlayers: Boolean = False): Integer;
1125 begin
1126 Result := (ModelInfo.Domain + 1) shl 28 - ModelInfo.mix;
1127 if MixPlayers then
1128 Dec(Result, ModelCode(ModelInfo) shl 16);
1129 end;
1130
1131 procedure MarkPreqs(I: Integer);
1132 begin
1133 Required[I] := 1;
1134 if MyRO.Tech[I] < tsSeen then
1135 begin
1136 if (AdvPreq[I, 0] >= 0) then
1137 MarkPreqs(AdvPreq[I, 0]);
1138 if (AdvPreq[I, 1] >= 0) then
1139 MarkPreqs(AdvPreq[I, 1]);
1140 end;
1141 end;
1142
1143var
1144 L: TLayerIndex;
1145 Loc1, I, J, p1, dx, dy, mix, emix, EnemyType, TestEnemyType: Integer;
1146 ModelInfo: TModelInfo;
1147 PPicture, PTestPicture: ^TModelPicture;
1148 ModelOk: array [0 .. 4095] of Boolean;
1149 Model: Integer;
1150 Ok: Boolean;
1151begin
1152 for L := Low(TLayerIndex) to High(TLayerIndex) do
1153 begin
1154 Layers[L].Lines.Clear;
1155 Layers[L].FirstShrinkedLine := MaxInt;
1156 end;
1157
1158 case Kind of
1159 kProject:
1160 begin
1161 // improvements
1162 Layers[laImprovements].AddLine(cpImp + imTrGoods);
1163 for I := nWonder to nImp - 1 do
1164 if Imp[I].Kind = ikCommon then
1165 TryAddImpLine(Layers[laImprovements], I + cpImp);
1166 for I := nWonder to nImp - 1 do
1167 if not (Imp[I].Kind in [ikCommon, ikTrGoods]) and
1168 ((MyRO.NatBuilt[I] = 0) or (Imp[I].Kind = ikNatLocal)) then
1169 TryAddImpLine(Layers[laImprovements], I + cpImp);
1170 for I := 0 to nCityType - 1 do
1171 if MyData.ImpOrder[I, 0] >= 0 then
1172 Layers[laImprovements].AddLine(cpType + I);
1173
1174 // wonders
1175 for I := 0 to nWonder - 1 do
1176 TryAddImpLine(Layers[laWonders], I + cpImp);
1177
1178 // units
1179 for I := 0 to MyRO.nModel - 1 do
1180 begin
1181 { if MyModel[i].Kind = mkSlaves then
1182 Ok := MyRO.Wonder[woPyramids].EffectiveOwner = Me
1183 else } if MyModel[I].Domain = dSea then
1184 begin
1185 Ok := False;
1186 for dx := -2 to 2 do
1187 for dy := -2 to 2 do
1188 if Abs(dx) + Abs(dy) = 2 then
1189 begin
1190 Loc1 := dLoc(MyCity[cixProject].Loc, dx, dy);
1191 if (Loc1 >= 0) and (Loc1 < G.lx * G.ly) and
1192 ((MyMap[Loc1] and fTerrain = fShore) or
1193 (MyMap[Loc1] and fCanal > 0)) then begin
1194 Ok := True;
1195 Break;
1196 end;
1197 end;
1198 end
1199 else
1200 Ok := True;
1201 if Ok then
1202 begin
1203 if MyModel[I].Status and msObsolete = 0 then
1204 begin
1205 Layers[laClasses].AddLine(I);
1206 end;
1207 if MyModel[I].Status and msAllowConscripts <> 0 then
1208 begin
1209 Layers[laClasses].AddLine(I + cpConscripts);
1210 end;
1211 end;
1212 end;
1213 Layers[laClasses].FirstShrinkedLine := 0;
1214 end;
1215 kAdvance:
1216 begin
1217 nColumn := 1;
1218 if MyData.FarTech <> adNone then
1219 begin
1220 FillChar(Required, SizeOf(Required), 0);
1221 MarkPreqs(MyData.FarTech);
1222 end;
1223 for I := 0 to nAdv - 1 do
1224 if ((I in FutureTech) or (MyRO.Tech[I] < tsApplicable)) and
1225 (Server(sSetResearch - sExecute, Me, I, nil^) >= rExecuted) and
1226 ((MyData.FarTech = adNone) or (Required[I] > 0)) then
1227 begin
1228 Layers[laImprovements].AddLine(I);
1229 end;
1230 Layers[laImprovements].SortTechs;
1231 if Layers[laImprovements].Lines.Count = 0 then // no more techs -- offer nexus
1232 Layers[laImprovements].AddLine(adNexus);
1233 Ok := False;
1234 for I := 0 to nDomains - 1 do
1235 if (upgrade[I, 0].Preq = preNone) or
1236 (MyRO.Tech[upgrade[I, 0].Preq] >= tsApplicable) then begin
1237 Ok := True;
1238 Break;
1239 end;
1240 if Ok then { new unit class }
1241 Layers[laImprovements].AddLine(adMilitary);
1242 end;
1243 kFarAdvance:
1244 begin
1245 Layers[laImprovements].AddLine(adNone);
1246 for I := 0 to nAdv - 1 do
1247 if not (I in FutureTech) and (MyRO.Tech[I] < tsApplicable) and
1248 ((AdvValue[I] < 2000) or (MyRO.Tech[adMassProduction] > tsNA)) and
1249 ((AdvValue[I] < 1000) or (MyRO.Tech[adScience] > tsNA)) then
1250 begin
1251 Layers[laImprovements].AddLine(I);
1252 end;
1253 Layers[laImprovements].SortTechs;
1254 end;
1255 kChooseTech:
1256 begin
1257 for I := 0 to nAdv - 1 do
1258 if not (I in FutureTech) and (MyRO.Tech[I] >= tsApplicable) and
1259 (MyRO.EnemyReport[DipMem[Me].pContact].Tech[I] < tsSeen) then
1260 begin
1261 Layers[laImprovements].AddLine(I);
1262 end;
1263 Layers[laImprovements].SortTechs;
1264 // if Layers[0].Lines.Count > 1 then
1265 begin
1266 Layers[laImprovements].AddLine(adAll);
1267 end;
1268 end;
1269 kChooseEnemyTech:
1270 begin
1271 for I := 0 to nAdv - 1 do
1272 if not (I in FutureTech) and (MyRO.Tech[I] < tsSeen) and
1273 (MyRO.EnemyReport[DipMem[Me].pContact].Tech[I] >= tsApplicable) then
1274 begin
1275 Layers[laImprovements].AddLine(I);
1276 end;
1277 Layers[laImprovements].SortTechs;
1278 // if LAyers[0].Lines.Count > 1 then
1279 begin
1280 Layers[laImprovements].AddLine(adAll);
1281 end;
1282 end;
1283 kStealTech:
1284 begin
1285 for I := 0 to nAdv - 1 do
1286 if Server(sStealTech - sExecute, Me, I, nil^) >= rExecuted then
1287 begin
1288 Layers[laImprovements].AddLine(I);
1289 end;
1290 Layers[laImprovements].SortTechs;
1291 end;
1292 kScience:
1293 begin
1294 Column[0] := Me;
1295 nColumn := 1;
1296 for EnemyType := 0 to 2 do
1297 for p1 := 0 to nPl - 1 do
1298 if (MyRO.EnemyReport[p1] <> nil) and
1299 ((MyRO.EnemyReport[p1].TurnOfContact >= 0) or
1300 (MyRO.EnemyReport[p1].TurnOfCivilReport >= 0)) then
1301 begin
1302 if MyRO.Alive and (1 shl p1) = 0 then
1303 TestEnemyType := 2 // extinct enemy -- move to right end
1304 else if MyRO.EnemyReport[p1].TurnOfCivilReport >= MyRO.Turn - 1
1305 then
1306 TestEnemyType := 0 // current report -- move to left end
1307 else
1308 TestEnemyType := 1;
1309 if TestEnemyType = EnemyType then
1310 begin
1311 Column[nColumn] := p1;
1312 Inc(nColumn);
1313 end;
1314 end;
1315 for I := 0 to nAdv - 1 do
1316 begin
1317 Ok := (MyRO.Tech[I] <> tsNA) or (MyRO.ResearchTech = I);
1318 for J := 1 to nColumn - 1 do
1319 with MyRO.EnemyReport[Column[J]]^ do
1320 if (Tech[I] <> tsNA) or (TurnOfCivilReport >= 0) and
1321 (ResearchTech = I) then
1322 Ok := True;
1323 if Ok then
1324 Layers[laImprovements].AddLine(I);
1325 end;
1326 Layers[laImprovements].SortTechs;
1327
1328 Ok := MyRO.ResearchTech = adMilitary;
1329 for J := 1 to nColumn - 1 do
1330 with MyRO.EnemyReport[Column[J]]^ do
1331 if (MyRO.Alive and (1 shl Column[J]) <> 0) and
1332 (TurnOfCivilReport >= 0) and (ResearchTech = adMilitary) then begin
1333 Ok := True;
1334 Break;
1335 end;
1336 if Ok then
1337 Layers[laImprovements].AddLine(adMilitary);
1338 end;
1339 kCities { , kChooseCity } :
1340 begin
1341 if ClientMode < scContact then
1342 for I := 0 to MyRO.nCity - 1 do
1343 if MyCity[I].Loc >= 0 then
1344 begin
1345 Layers[laImprovements].AddLine(I);
1346 end;
1347 Layers[laImprovements].SortCities;
1348 Layers[laImprovements].FirstShrinkedLine := 0;
1349 end;
1350 kCityEvents:
1351 begin
1352 for I := 0 to MyRO.nCity - 1 do
1353 if (MyCity[I].Loc >= 0) and (MyCity[I].Flags and CityRepMask <> 0)
1354 then begin
1355 Layers[laImprovements].AddLine(I);
1356 end;
1357 Layers[laImprovements].SortCities;
1358 Layers[laImprovements].FirstShrinkedLine := 0;
1359 end;
1360 { kChooseEnemyCity:
1361 begin
1362 for I := 0 to MyRO.nEnemyCity - 1 do
1363 if (MyRO.EnemyCity[I].Loc >= 0)
1364 and (MyRO.EnemyCity[I].Owner = DipMem[Me].pContact) then
1365 begin
1366 Layers[laImprovements].AddCode(I);
1367 end;
1368 Layers[laImprovements].FirstShrinkedLine := 0;
1369 end; }
1370 kModels:
1371 begin
1372 for mix := 0 to MyRO.nModel - 1 do
1373 begin
1374 MakeModelInfo(Me, mix, MyModel[mix], ModelInfo);
1375 Layers[laImprovements].AddLine(mix, 0, ModelSortValue(ModelInfo));
1376 end;
1377 Layers[laImprovements].SortModels;
1378 Layers[laImprovements].FirstShrinkedLine := 0;
1379 end;
1380 kChooseModel:
1381 begin
1382 for mix := 3 to MyRO.nModel - 1 do
1383 begin // check if opponent already has this model
1384 MakeModelInfo(Me, mix, MyModel[mix], ModelInfo);
1385 Ok := True;
1386 for emix := 0 to MyRO.nEnemyModel - 1 do
1387 if (MyRO.EnemyModel[emix].Owner = DipMem[Me].pContact) and
1388 IsSameModel(MyRO.EnemyModel[emix], ModelInfo) then begin
1389 Ok := False;
1390 Break;
1391 end;
1392 if Ok then
1393 begin
1394 MakeModelInfo(Me, mix, MyModel[mix], ModelInfo);
1395 Layers[laImprovements].AddLine(mix, 0, ModelSortValue(ModelInfo));
1396 end;
1397 end;
1398 Layers[laImprovements].SortModels;
1399 Layers[laImprovements].AddLine(mixAll);
1400 Layers[laImprovements].FirstShrinkedLine := 0;
1401 end;
1402 kChooseEnemyModel:
1403 begin
1404 if MyRO.TestFlags and tfUncover <> 0 then
1405 Server(sGetModels, Me, 0, nil^);
1406 for emix := 0 to MyRO.nEnemyModel - 1 do
1407 ModelOk[emix] := MyRO.EnemyModel[emix].Owner = DipMem[Me].pContact;
1408 for mix := 0 to MyRO.nModel - 1 do
1409 begin // don't list models I already have
1410 MakeModelInfo(Me, mix, MyModel[mix], ModelInfo);
1411 for emix := 0 to MyRO.nEnemyModel - 1 do
1412 ModelOk[emix] := ModelOk[emix] and
1413 not IsSameModel(MyRO.EnemyModel[emix], ModelInfo);
1414 end;
1415 for emix := 0 to MyRO.nEnemyModel - 1 do
1416 if ModelOk[emix] then
1417 begin
1418 if not Assigned(Tribe[DipMem[Me].pContact].ModelPicture
1419 [MyRO.EnemyModel[emix].mix].HGr) then
1420 InitEnemyModel(emix);
1421 Layers[laImprovements].AddLine(emix, 0, ModelSortValue(MyRO.EnemyModel[emix]));
1422 end;
1423 Layers[laImprovements].SortModels;
1424 // if not IsMilReportNew(DipMem[me].pContact) or (Layers[laImprovements].Lines > 1) then
1425 begin
1426 Layers[laImprovements].AddLine(mixAll);
1427 end;
1428 Layers[laImprovements].FirstShrinkedLine := 0;
1429 end;
1430 kEnemyModels:
1431 begin
1432 for I := 0 to MyRO.EnemyReport[PlayerView].nModelCounted - 1 do
1433 begin
1434 Model := MyRO.nEnemyModel - 1;
1435
1436 while (Model >= 0) and
1437 not ((MyRO.EnemyModel[Model].Owner = PlayerView) and
1438 (MyRO.EnemyModel[Model].mix = I)) do
1439 Dec(Model);
1440
1441 if not Assigned(Tribe[PlayerView].ModelPicture[I].HGr) then
1442 InitEnemyModel(Model);
1443
1444 Layers[laImprovements].AddLine(I, Model, ModelSortValue(MyRO.EnemyModel[Model]));
1445 end;
1446 Layers[laImprovements].SortModels;
1447 Layers[laImprovements].FirstShrinkedLine := 0;
1448 end;
1449 kAllEnemyModels:
1450 begin
1451 if (MyRO.TestFlags and tfUncover <> 0) or (G.Difficulty[Me] = 0) then
1452 Server(sGetModels, Me, 0, nil^);
1453 for emix := 0 to MyRO.nEnemyModel - 1 do
1454 if (MyRO.EnemyModel[emix].mix >= 3) and
1455 (MyRO.EnemyModel[emix].Kind in [mkSelfDeveloped, mkEnemyDeveloped])
1456 then
1457 begin
1458 PPicture := @Tribe[MyRO.EnemyModel[emix].Owner].ModelPicture
1459 [MyRO.EnemyModel[emix].mix];
1460 if not Assigned(PPicture.HGr) then
1461 InitEnemyModel(emix);
1462 Ok := True;
1463 if MainScreen.mNames.Checked then
1464 for J := 0 to Layers[laImprovements].Lines.Count - 1 do
1465 begin
1466 Model := Layers[laImprovements].Lines[J].Code;
1467 PTestPicture := @Tribe[MyRO.EnemyModel[Model].Owner]
1468 .ModelPicture[MyRO.EnemyModel[Model].mix];
1469 if (PPicture.HGr = PTestPicture.HGr) and
1470 (PPicture.pix = PTestPicture.pix) and
1471 (ModelHash(MyRO.EnemyModel[emix])
1472 = ModelHash(MyRO.EnemyModel[Model])) then
1473 begin
1474 Layers[laImprovements].Lines[J].Model := 1;
1475 Ok := False;
1476 Break;
1477 end;
1478 end;
1479 if Ok then begin
1480 Layers[laImprovements].AddLine(emix, 0, ModelSortValue(MyRO.EnemyModel[emix], True));
1481 end;
1482 end;
1483 Layers[laImprovements].SortModels;
1484 Layers[laImprovements].FirstShrinkedLine := 0;
1485 end;
1486 kTribe:
1487 for I := 0 to TribeNames.Count - 1 do
1488 begin
1489 Layers[laImprovements].AddLine(I);
1490 end;
1491 (* kDeliver:
1492 if MyRO.Treaty[DipMem[Me].pContact] < trAlliance then
1493 begin // suggest next treaty level
1494 Layers[laImprovements].AddLine(opTreaty + MyRO.Treaty[DipMem[Me].pContact] + 1);
1495 end;
1496 if MyRO.Treaty[DipMem[Me].pContact] = trNone then
1497 begin // suggest peace
1498 Layers[laImprovements].AddLine(opTreaty + trPeace);
1499 end;
1500 if MyRO.Treaty[DipMem[Me].pContact] > trNone then
1501 begin // suggest next treaty level
1502 Layers[laImprovements].AddLine(opTreaty + MyRO.Treaty[DipMem[Me].pContact] - 1);
1503 end; *)
1504 kShipPart:
1505 begin
1506 Layers[laImprovements].Lines.Clear;
1507 for I := 0 to nShipPart - 1 do
1508 if MyRO.Ship[Me].Parts[I] > 0 then
1509 begin
1510 Layers[laImprovements].AddLine(I);
1511 end;
1512 end;
1513 kEnemyShipPart:
1514 begin
1515 Layers[laImprovements].Lines.Clear;
1516 for I := 0 to nShipPart - 1 do
1517 if MyRO.Ship[DipMem[Me].pContact].Parts[I] > 0 then
1518 begin
1519 Layers[laImprovements].AddLine(I);
1520 end;
1521 end;
1522 kGovernment:
1523 for I := 1 to nGov - 1 do
1524 if (GovPreq[I] <> preNA) and
1525 ((GovPreq[I] = preNone) or (MyRO.Tech[GovPreq[I]] >= tsApplicable))
1526 then
1527 begin
1528 Layers[laImprovements].AddLine(I);
1529 end;
1530 kMission:
1531 for I := 0 to nSpyMission - 1 do
1532 begin
1533 Layers[laImprovements].AddLine(I);
1534 end;
1535 end;
1536
1537 // Test if choice fitting to one screen
1538 if Kind = kProject then
1539 if Layers[laImprovements].Lines.Count + Layers[laWonders].Lines.Count + Layers[laClasses].Lines.Count <= MaxLines then
1540 begin
1541 // Add wonders to first page
1542 for I := 0 to Layers[laWonders].Lines.Count - 1 do
1543 Layers[laImprovements].AddLine(Layers[laWonders].Lines[I].Code, Layers[laWonders].Lines[I].Model, Layers[laWonders].Lines[I].ModelSortValue);
1544 Layers[laWonders].Lines.Clear;
1545
1546 Layers[laImprovements].FirstShrinkedLine := Layers[laImprovements].Lines.Count;
1547
1548 // Add models to first page
1549 for I := 0 to Layers[laClasses].Lines.Count - 1 do
1550 Layers[laImprovements].AddLine(Layers[laClasses].Lines[I].Code, Layers[laClasses].Lines[I].Model, Layers[laClasses].Lines[I].ModelSortValue);
1551 Layers[laClasses].Lines.Clear;
1552 end;
1553end;
1554
1555function TListDlg.OnlyChoice(TestKind: TListKind): Integer;
1556begin
1557 Kind := TestKind;
1558 InitLines;
1559 if Layers[laImprovements].Lines.Count = 0 then
1560 Result := -2
1561 else if Layers[laImprovements].Lines.Count > 1 then
1562 Result := -1
1563 else
1564 Result := Layers[laImprovements].Lines[0].Code;
1565end;
1566
1567procedure TListDlg.FormShow(Sender: TObject);
1568var
1569 L: TLayerIndex;
1570 NewTop, NewLeft: Integer;
1571begin
1572 Result := -1;
1573 Closable := False;
1574
1575 if Kind = kTribe then
1576 begin
1577 LineDistance := 21; // looks ugly with scrollbar
1578 MaxLines := (Maintexture.Height - (24 + TitleHeight + NarrowFrame))
1579 div LineDistance - 1;
1580 end
1581 else
1582 begin
1583 LineDistance := 24;
1584 MaxLines := (Maintexture.Height - (24 + TitleHeight + WideFrame))
1585 div LineDistance - 1;
1586 end;
1587 InitLines;
1588
1589 MultiPage := False;
1590 for L := laWonders to High(TLayerIndex) do
1591 if Layers[L].Lines.Count > 0 then begin
1592 MultiPage := True;
1593 Break;
1594 end;
1595
1596 WideBottom := MultiPage or (Kind = kScience) or
1597 not Phrases2FallenBackToEnglish and
1598 (Kind in [kProject, kAdvance, kFarAdvance]);
1599 if (Kind = kAdvance) and (MyData.FarTech <> adNone) or (Kind = kModels) or
1600 (Kind = kEnemyModels) then begin
1601 ScrollBar.SetBorderSpacing(56, 10, 10);
1602 TitleHeight := WideFrame + 20;
1603 end else begin
1604 ScrollBar.SetBorderSpacing(36, 10, 34);
1605 TitleHeight := WideFrame;
1606 end;
1607
1608 DispLines := Layers[laImprovements].Lines.Count;
1609 for L := Low(TLayerIndex) to High(TLayerIndex) do
1610 if Layers[L].Lines.Count > DispLines then
1611 DispLines := Layers[L].Lines.Count;
1612 if WideBottom then
1613 begin
1614 if DispLines > MaxLines then
1615 DispLines := MaxLines;
1616 InnerHeight := LineDistance * (DispLines + 1) + 24;
1617 Height := InnerHeight + TitleHeight + WideFrame;
1618 end
1619 else
1620 begin
1621 if DispLines > MaxLines then
1622 DispLines := MaxLines;
1623 InnerHeight := LineDistance * (DispLines + 1) + 24;
1624 Height := InnerHeight + TitleHeight + NarrowFrame;
1625 end;
1626 Assert(Height <= Maintexture.Height);
1627
1628 TechNameSpace := 224;
1629 case Kind of
1630 kGovernment:
1631 InnerWidth := 272;
1632 kCities, kCityEvents:
1633 InnerWidth := 640 - 18;
1634 kTribe:
1635 if Layers[laImprovements].Lines.Count > MaxLines then
1636 InnerWidth := 280 + GetSystemMetrics(SM_CXVSCROLL)
1637 else
1638 InnerWidth := 280;
1639 kScience:
1640 begin
1641 InnerWidth := 104 - 33 + 15 + 8 + TechNameSpace + 24 * nColumn +
1642 GetSystemMetrics(SM_CXVSCROLL);
1643 if InnerWidth + 2 * SideFrame > 640 then
1644 begin
1645 TechNameSpace := TechNameSpace + 640 - InnerWidth - 2 * SideFrame;
1646 InnerWidth := 640 - 2 * SideFrame
1647 end;
1648 end;
1649 kAdvance, kFarAdvance:
1650 InnerWidth := 104 - 33 + 15 + 8 + TechNameSpace + 24 +
1651 GetSystemMetrics(SM_CXVSCROLL);
1652 kChooseTech, kChooseEnemyTech, kStealTech:
1653 InnerWidth := 104 - 33 + 15 + 8 + TechNameSpace +
1654 GetSystemMetrics(SM_CXVSCROLL);
1655 else
1656 InnerWidth := 363;
1657 end;
1658 Width := InnerWidth + 2 * SideFrame;
1659
1660 CloseBtn.Left := Width - 38;
1661 CaptionLeft := ToggleBtn.Left + ToggleBtn.Width;
1662 CaptionRight := CloseBtn.Left;
1663 SetWindowPos(ScrollBar.ScrollBar.Handle, 0, SideFrame + InnerWidth - GetSystemMetrics(SM_CXVSCROLL),
1664 TitleHeight, GetSystemMetrics(SM_CXVSCROLL), LineDistance * DispLines + 48,
1665 SWP_NOZORDER or SWP_NOREDRAW);
1666
1667 if WindowMode = wmModal then
1668 begin { center on screen }
1669 if Kind = kTribe then
1670 NewLeft := Screen.PrimaryMonitor.Left + (Screen.PrimaryMonitor.Width - 800) * 3 div 8 + 130
1671 else
1672 NewLeft := Screen.PrimaryMonitor.Left + (Screen.PrimaryMonitor.Width - Width) div 2;
1673 NewTop := Screen.PrimaryMonitor.Top + (Screen.PrimaryMonitor.Height - Height) div 2;
1674 if Kind = kProject then
1675 NewTop := NewTop + 48;
1676 BoundsRect := Bounds(NewLeft, NewTop, Width, Height);
1677 end;
1678
1679 LayerImprovementsButton.Visible := MultiPage and (Layers[laImprovements].Lines.Count > 0);
1680 LayerWondersButton.Visible := MultiPage and (Layers[laWonders].Lines.Count > 0);
1681 LayerClassesButton.Visible := MultiPage and (Layers[laClasses].Lines.Count > 0);
1682
1683 if Kind = kProject then
1684 begin
1685 LayerImprovementsButton.Top := Height - 31;
1686 LayerImprovementsButton.Left := Width div 2 - (12 + 29);
1687 LayerImprovementsButton.Down := True;
1688 LayerWondersButton.Top := Height - 31;
1689 LayerWondersButton.Left := Width div 2 - (12 - 29);
1690 LayerWondersButton.Down := False;
1691 LayerClassesButton.Top := Height - 31;
1692 LayerClassesButton.Left := Width div 2 - 12;
1693 LayerClassesButton.Down := False;
1694 end;
1695
1696 Layer := Layers[laImprovements];
1697 Selected := -2;
1698 ScienceNation := -1;
1699 ScrollBar.Init(Layer.Lines.Count - 1, DispLines);
1700
1701 OffscreenPaint;
1702end;
1703
1704procedure TListDlg.ShowNewContent(NewMode: TWindowMode; ListKind: TListKind);
1705var
1706 I: Integer;
1707 ShowFocus, ForceClose: Boolean;
1708begin
1709 ForceClose := (ListKind <> Kind) and
1710 not ((Kind = kCities) and (ListKind = kCityEvents)) and
1711 not ((Kind = kCityEvents) and (ListKind = kCities)) and
1712 not ((Kind = kModels) and (ListKind = kEnemyModels)) and
1713 not ((Kind = kEnemyModels) and (ListKind = kModels));
1714
1715 Kind := ListKind;
1716 ModalIndication := not (Kind in MustChooseKind);
1717 case Kind of
1718 kProject:
1719 Caption := Phrases.Lookup('TITLE_PROJECT');
1720 kAdvance:
1721 Caption := Phrases.Lookup('TITLE_TECHSELECT');
1722 kFarAdvance:
1723 Caption := Phrases.Lookup('TITLE_FARTECH');
1724 kModels, kEnemyModels:
1725 Caption := Phrases.Lookup('FRMILREP');
1726 kAllEnemyModels:
1727 Caption := Phrases.Lookup('TITLE_EMODELS');
1728 kTribe:
1729 Caption := Phrases.Lookup('TITLE_TRIBE');
1730 kScience:
1731 Caption := Phrases.Lookup('TITLE_SCIENCE');
1732 kShipPart, kEnemyShipPart:
1733 Caption := Phrases.Lookup('TITLE_CHOOSESHIPPART');
1734 kChooseTech, kChooseEnemyTech:
1735 Caption := Phrases.Lookup('TITLE_CHOOSETECH');
1736 kChooseModel, kChooseEnemyModel:
1737 Caption := Phrases.Lookup('TITLE_CHOOSEMODEL');
1738 kStealTech:
1739 Caption := Phrases.Lookup('TITLE_CHOOSETECH');
1740 kGovernment:
1741 Caption := Phrases.Lookup('TITLE_GOV');
1742 kMission:
1743 Caption := Phrases.Lookup('TITLE_SPYMISSION');
1744 end;
1745
1746 case Kind of
1747 kMission:
1748 HelpContext := 'SPYMISSIONS';
1749 else
1750 HelpContext := 'CONCEPTS'
1751 end;
1752
1753 if Kind = kAdvance then
1754 begin
1755 ToggleBtn.ButtonIndex := 13;
1756 ToggleBtn.Hint := Phrases.Lookup('FARTECH');
1757 end
1758 else if Kind = kCities then
1759 begin
1760 ToggleBtn.ButtonIndex := 15;
1761 ToggleBtn.Hint := Phrases.Lookup('BTN_PAGE');
1762 end
1763 else
1764 begin
1765 ToggleBtn.ButtonIndex := 28;
1766 ToggleBtn.Hint := Phrases.Lookup('BTN_SELECT');
1767 end;
1768
1769 if Kind = kAdvance then // show focus button?
1770 if MyData.FarTech <> adNone then
1771 ShowFocus := True
1772 else
1773 begin
1774 ShowFocus := False;
1775 for I := 0 to nAdv - 1 do
1776 if not (I in FutureTech) and (MyRO.Tech[I] < tsApplicable) and
1777 ((AdvValue[I] < 2000) or (MyRO.Tech[adMassProduction] > tsNA)) and
1778 ((AdvValue[I] < 1000) or (MyRO.Tech[adScience] > tsNA)) and
1779 (Server(sSetResearch - sExecute, Me, I, nil^) < rExecuted) then begin
1780 ShowFocus := True;
1781 Break;
1782 end;
1783 end;
1784 ToggleBtn.Visible := (Kind = kCities) and not Supervising or (Kind = kAdvance)
1785 and ShowFocus or (Kind = kModels) or (Kind = kEnemyModels);
1786 CloseBtn.Visible := not (Kind in MustChooseKind);
1787
1788 inherited ShowNewContent(NewMode, ForceClose);
1789end;
1790
1791procedure TListDlg.ShowNewContent_CityProject(NewMode: TWindowMode; cix: Integer);
1792begin
1793 cixProject := cix;
1794 ShowNewContent(NewMode, kProject);
1795end;
1796
1797procedure TListDlg.ShowNewContent_MilReport(NewMode: TWindowMode; Player: Integer);
1798begin
1799 PlayerView := Player;
1800 if Player = Me then
1801 ShowNewContent(NewMode, kModels)
1802 else
1803 ShowNewContent(NewMode, kEnemyModels);
1804end;
1805
1806procedure TListDlg.PlayerClick(Sender: TObject);
1807begin
1808 if TComponent(Sender).Tag = Me then
1809 Kind := kModels
1810 else
1811 begin
1812 Kind := kEnemyModels;
1813 PlayerView := TComponent(Sender).Tag;
1814 end;
1815 InitLines;
1816 Selected := -2;
1817 ScrollBar.Init(Layer.Lines.Count - 1, DispLines);
1818 OffscreenPaint;
1819 Invalidate;
1820end;
1821
1822procedure TListDlg.ModeBtnClick(Sender: TObject);
1823begin
1824 LayerImprovementsButton.Down := Sender = LayerImprovementsButton;
1825 LayerWondersButton.Down := Sender = LayerWondersButton;
1826 LayerClassesButton.Down := Sender = LayerClassesButton;
1827 Layer := Layers[TLayerIndex(TComponent(Sender).Tag)];
1828
1829 Selected := -2;
1830 ScrollBar.Init(Layer.Lines.Count - 1, DispLines);
1831 SmartUpdateContent;
1832end;
1833
1834procedure TListDlg.ToggleBtnClick(Sender: TObject);
1835var
1836 p1: Integer;
1837 M: TMenuItem;
1838begin
1839 case Kind of
1840 kAdvance:
1841 begin
1842 Result := adFar;
1843 Closable := True;
1844 Close;
1845 end;
1846 kCities, kCityEvents:
1847 begin
1848 if Kind = kCities then
1849 Kind := kCityEvents
1850 else
1851 Kind := kCities;
1852 OffscreenPaint;
1853 Invalidate;
1854 end;
1855 kModels, kEnemyModels:
1856 begin
1857 EmptyMenu(Popup.Items);
1858 if G.Difficulty[Me] > 0 then
1859 begin
1860 M := TMenuItem.Create(Popup);
1861 M.RadioItem := True;
1862 M.Caption := Tribe[Me].TPhrase('SHORTNAME');
1863 M.Tag := Me;
1864 M.OnClick := PlayerClick;
1865 if Kind = kModels then
1866 M.Checked := True;
1867 Popup.Items.Add(M);
1868 end;
1869 for p1 := 0 to nPl - 1 do
1870 if (p1 <> Me) and (MyRO.EnemyReport[p1] <> nil) and
1871 (MyRO.EnemyReport[p1].TurnOfMilReport >= 0) then
1872 begin
1873 M := TMenuItem.Create(Popup);
1874 M.RadioItem := True;
1875 M.Caption := Tribe[p1].TPhrase('SHORTNAME');
1876 M.Tag := p1;
1877 M.OnClick := PlayerClick;
1878 if (Kind = kEnemyModels) and (p1 = PlayerView) then
1879 M.Checked := True;
1880 Popup.Items.Add(M);
1881 end;
1882 Popup.Popup(Left + ToggleBtn.Left, Top + ToggleBtn.Top +
1883 ToggleBtn.Height);
1884 end;
1885 end;
1886end;
1887
1888function TListDlg.GetSelectionIndex: Integer;
1889begin
1890 if Selected >= 0 then Result := ScrollBar.Position + Selected
1891 else Result := -1;
1892end;
1893
1894procedure TListDlg.SetSelectionIndex(Index: Integer);
1895var
1896 NewSelected: Integer;
1897 NewScrollBarPos: Integer;
1898 Over: Integer;
1899 Under: Integer;
1900begin
1901 if Index < 0 then Index := 0;
1902 if Index > Layer.Lines.Count - 1 then Index := Layer.Lines.Count - 1;
1903
1904 NewSelected := Index - ScrollBar.Position;
1905 NewScrollBarPos := ScrollBar.Position;
1906
1907 Over := NewSelected - Min(DispLines, Layer.Lines.Count - NewScrollBarPos);
1908 if Over > 0 then begin
1909 Inc(NewScrollBarPos, Over);
1910 Dec(NewSelected, Over);
1911 end;
1912
1913 Under := -NewSelected;
1914 if Under > 0 then begin
1915 Dec(NewScrollBarPos, Under);
1916 Inc(NewSelected, Under);
1917 end;
1918
1919 if (NewSelected <> Selected) or (NewScrollBarPos <> ScrollBar.Position) then begin
1920 if Selected >= 0 then PaintLine(Canvas, Selected, False, False);
1921
1922 ScrollBar.Position := NewScrollBarPos;
1923 Selected := NewSelected;
1924
1925 PaintLine(Canvas, Selected, False, True);
1926 end;
1927end;
1928
1929procedure TListDlg.DoOnResize;
1930begin
1931 inherited;
1932 CloseBtn.Left := Width - 38;
1933end;
1934
1935procedure TListDlg.FormKeyDown(Sender: TObject; var Key: Word;
1936 Shift: TShiftState);
1937var
1938 LastSelectionIndex: Integer;
1939begin
1940 if (Key = VK_RIGHT) or (Key = VK_NUMPAD6) then begin
1941 if MultiPage and (Layer.Index <= High(TLayerIndex)) then begin
1942 LastSelectionIndex := GetSelectionIndex;
1943
1944 if (Layer = Layers[laImprovements]) and (Layers[laClasses].Lines.Count > 0) then
1945 Layer := Layers[laClasses]
1946 else if (Layer = Layers[laClasses]) and (Layers[laWonders].Lines.Count > 0) then
1947 Layer := Layers[laWonders];
1948
1949 LayerImprovementsButton.Down := Layer = Layers[laImprovements];
1950 LayerWondersButton.Down := Layer = Layers[laWonders];
1951 LayerClassesButton.Down := Layer = Layers[laClasses];
1952 ScrollBar.Init(Layer.Lines.Count - 1, DispLines);
1953 Selected := -1;
1954 SetSelectionIndex(LastSelectionIndex);
1955 SmartUpdateContent;
1956 end;
1957 end else
1958 if (Key = VK_LEFT) or (Key = VK_NUMPAD4) then begin
1959 if MultiPage and (Layer.Index > laImprovements) then begin
1960 LastSelectionIndex := GetSelectionIndex;
1961
1962 if (Layer = Layers[laWonders]) and (Layers[laClasses].Lines.Count > 0) then
1963 Layer := Layers[laClasses]
1964 else if (Layer = Layers[laClasses]) and (Layers[laImprovements].Lines.Count > 0) then
1965 Layer := Layers[laImprovements];
1966
1967 LayerImprovementsButton.Down := Layer = Layers[laImprovements];
1968 LayerWondersButton.Down := Layer = Layers[laWonders];
1969 LayerClassesButton.Down := Layer = Layers[laClasses];
1970 ScrollBar.Init(Layer.Lines.Count - 1, DispLines);
1971 Selected := -1;
1972 SetSelectionIndex(LastSelectionIndex);
1973 SmartUpdateContent;
1974 end;
1975 end else
1976 if (Key = VK_UP) or (Key = VK_NUMPAD8) then begin
1977 SetSelectionIndex(GetSelectionIndex - 1);
1978 end else
1979 if (Key = VK_DOWN) or (Key = VK_NUMPAD2) then begin
1980 SetSelectionIndex(GetSelectionIndex + 1);
1981 end else
1982 if (Key = VK_HOME) or (Key = VK_NUMPAD7) then begin
1983 SetSelectionIndex(0);
1984 end else
1985 if (Key = VK_END) or (Key = VK_NUMPAD1) then begin
1986 SetSelectionIndex(Layer.Lines.Count);
1987 end else
1988 if (Key = VK_PRIOR) or (Key = VK_NUMPAD9) then begin
1989 SetSelectionIndex(GetSelectionIndex - ScrollBar.PageSize);
1990 end else
1991 if (Key = VK_NEXT) or (Key = VK_NUMPAD3) then begin
1992 SetSelectionIndex(GetSelectionIndex + ScrollBar.PageSize);
1993 end else
1994 if Key = VK_RETURN then begin
1995 PaintBox1MouseDown(Self, TMouseButton.mbLeft, [ssLeft], 0, 0);
1996 end else
1997 if (Key = VK_F2) and (Kind in [kModels, kEnemyModels]) then // my key
1998 // !!! toggle
1999 else if (Key = VK_F3) and (Kind in [kCities, kCityEvents]) then // my key
2000 ToggleBtnClick(nil)
2001 else if ((Key = VK_ESCAPE) or (Key = VK_RETURN)) and not CloseBtn.Visible then
2002 // prevent closing
2003 else
2004 inherited;
2005end;
2006
2007procedure TListDlg.EcoChange;
2008begin
2009 if Visible and (Kind = kCities) then
2010 SmartUpdateContent;
2011end;
2012
2013procedure TListDlg.TechChange;
2014begin
2015 if Visible and (Kind = kScience) then
2016 begin
2017 FormShow(nil);
2018 Invalidate;
2019 end;
2020end;
2021
2022procedure TListDlg.AddCity;
2023begin
2024 if Visible and (Kind = kCities) then
2025 begin
2026 FormShow(nil);
2027 Invalidate;
2028 end;
2029end;
2030
2031procedure TListDlg.RemoveUnit;
2032begin
2033 if Visible and (Kind = kModels) then
2034 SmartUpdateContent;
2035end;
2036
2037procedure TListDlg.ScrollBarUpdate(Sender: TObject);
2038begin
2039 Selected := -2;
2040 SmartUpdateContent(True);
2041end;
2042
2043end.
Note: See TracBrowser for help on using the repository browser.