source: branches/highdpi/LocalPlayer/Help.pas

Last change on this file was 467, checked in by chronos, 5 months ago
  • Modified: DpiControls unit split into multiple units according to their LCL names.
File size: 77.1 KB
Line 
1{$INCLUDE Switches.inc}
2unit Help;
3
4interface
5
6uses
7 Dpi.Graphics, Dpi.Common,
8 Protocol, ScreenTools, BaseWin, StringTables, Math, LCLIntf, LCLType,
9 Messages, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls,
10 ButtonB, PVSB, Types, Generics.Collections, IsoEngine;
11
12const
13 MaxHist = 16;
14
15 fJungle = 8; // Pseudo terrain
16
17type
18 { Link categories }
19 TLinkCategory = (
20 hkNoLink,
21 hkAdv,
22 hkImp,
23 hkTer,
24 hkFeature ,
25 hkInternet,
26 hkModel,
27 hkMisc,
28 hkText);
29
30 { Link indices for category hkMisc }
31 TMiscLinkIndex = (
32 miscMain,
33 miscCredits,
34 miscGovList,
35 miscJobList,
36 miscSearchResult);
37
38 TTextFormat = (
39 pkNormal,
40 pkCaption,
41 pkSmallIcon,
42 pkBigIcon,
43 pkAdvIcon,
44 pkTer,
45 pkBigTer,
46 pkFeature,
47 pkDot,
48 pkNormal_Dot,
49 pkDomain,
50 pkSection,
51 pkBigFeature,
52 pkExp,
53 pkAITStat,
54 pkExternal,
55 pkModel,
56 pkNormal_64,
57 pkIllu,
58 pkLogo,
59 pkTerImp,
60 pkRightIcon,
61 pkAdvIcon_AsPreq,
62 pkSmallIcon_AsPreq,
63 pkSpecialIcon,
64 pkGov);
65
66 { THyperText }
67
68 THyperText = class(TStringList)
69 public
70 procedure AddLine(S: String = ''; Format: TTextFormat = pkNormal; Picpix: Integer = 0;
71 LinkCategory: TLinkCategory = hkNoLink; LinkIndex: Integer = 0; CrossLink: Boolean = False);
72 procedure LineFeed;
73 procedure AppendList(Source: THyperText);
74 end;
75
76 { THistItem }
77
78 THistItem = class
79 Kind: TLinkCategory;
80 No: Integer;
81 Pos: Integer;
82 SearchContent: string;
83 procedure Assign(Source: THistItem);
84 end;
85
86 { THistItems }
87
88 THistItems = class(TObjectList<THistItem>)
89 function AddNew(Kind: TLinkCategory; No, Pos: Integer; SearchContent: string): THistItem;
90 end;
91
92 { THelpDlg }
93
94 THelpDlg = class(TFramedDlg)
95 CloseBtn: TButtonB;
96 BackBtn: TButtonB;
97 TopBtn: TButtonB;
98 SearchBtn: TButtonB;
99 procedure FormCreate(Sender: TObject);
100 procedure FormDestroy(Sender: TObject);
101 procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
102 WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
103 procedure FormPaint(Sender: TObject);
104 procedure CloseBtnClick(Sender: TObject);
105 procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
106 X, Y: Integer);
107 procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
108 Shift: TShiftState; X, Y: Integer);
109 procedure BackBtnClick(Sender: TObject);
110 procedure TopBtnClick(Sender: TObject);
111 procedure FormClose(Sender: TObject; var Action: TCloseAction);
112 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
113 procedure SearchBtnClick(Sender: TObject);
114 protected
115 procedure OffscreenPaint; override;
116 private
117 Kind: TLinkCategory;
118 No: Integer;
119 Sel: Integer;
120 CaptionColor: Integer;
121 hADVHELP, hIMPHELP, hFEATUREHELP, hGOVHELP, hSPECIALMODEL, hJOBHELP: Integer;
122 SearchContent: string;
123 NewSearchContent: string;
124 CaptionFont: TDpiFont;
125 MainText: THyperText;
126 SearchResult: THyperText;
127 HelpText: TStringTable;
128 ExtPic: TDpiBitmap;
129 TerrIcon: TDpiBitmap;
130 ScrollBar: TPVScrollbar;
131 NoMap: TIsoMap;
132 x0: array [-2..180] of Integer;
133 procedure PaintTerrIcon(X, Y, xSrc, ySrc: Integer);
134 procedure ScrollBarUpdate(Sender: TObject);
135 procedure Line(ACanvas: TDpiCanvas; I: Integer; Lit: Boolean);
136 procedure Prepare(sbPos: Integer = 0);
137 procedure ShowNewContentProcExecute(NewMode: TWindowMode; HelpContext: string);
138 procedure WaterSign(x0, y0, iix: Integer);
139 procedure Search(SearchString: string);
140 procedure OnScroll(var Msg: TMessage); message WM_VSCROLL;
141 procedure OnMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
142 public
143 HistItems: THistItems;
144 Difficulty: Integer;
145 procedure ClearHistory;
146 procedure ShowNewContent(NewMode: TWindowMode; Category: TLinkCategory; Index: Integer);
147 function TextIndex(Item: string): Integer;
148 end;
149
150
151implementation
152
153uses
154 Directories, ClientTools, Term, Tribes, Inp, Messg, PixelPointer, Global,
155 KeyBindings;
156
157{$R *.lfm}
158
159type
160
161 { THelpLineInfo }
162
163 THelpLineInfo = class
164 Format: TTextFormat;
165 Picpix: Byte;
166 Category: TLinkCategory;
167 Index: Integer;
168 CrossLink: Boolean;
169 procedure Assign(Source: THelpLineInfo);
170 end;
171
172 TSeeAlso = record
173 Kind: TLinkCategory;
174 No: Integer;
175 SeeKind: TLinkCategory;
176 SeeNo: Integer;
177 end;
178
179const
180 SeeAlso: array[0..13] of TSeeAlso = ((Kind: hkImp; no: imWalls; SeeKind: hkFeature;
181 SeeNo: mcArtillery), (Kind: hkImp; no: imHydro; SeeKind: hkImp;
182 SeeNo: woHoover), (Kind: hkImp; no: imWalls; SeeKind: hkImp;
183 SeeNo: imGrWall), (Kind: hkImp; no: imHighways; SeeKind: hkAdv;
184 SeeNo: adWheel), (Kind: hkImp; no: imCathedral; SeeKind: hkImp;
185 SeeNo: woBach), (Kind: hkImp; no: imBank; SeeKind: hkImp; SeeNo: imStockEx),
186 (Kind: hkImp; no: imShipComp; SeeKind: hkImp; SeeNo: imSpacePort),
187 (Kind: hkImp; no: imShipPow; SeeKind: hkImp; SeeNo: imSpacePort),
188 (Kind: hkImp; no: imShipHab; SeeKind: hkImp; SeeNo: imSpacePort),
189 (Kind: hkFeature; no: mcSub; SeeKind: hkFeature; SeeNo: mcRadar),
190 (Kind: hkFeature; no: mcDefense; SeeKind: hkAdv; SeeNo: adSteel),
191 (Kind: hkFeature; no: mcSE; SeeKind: hkFeature; SeeNo: mcNP), (Kind: hkAdv;
192 no: adWheel; SeeKind: hkImp; SeeNo: imHighways), (Kind: hkAdv; no: adSteel;
193 SeeKind: hkFeature; SeeNo: mcDefense));
194
195 TerrainHelp: array[0..13] of Integer = (fGrass, fGrass + 12,
196 fPrairie, fForest, fJungle, fHills, fMountains, fSwamp, fTundra, fArctic,
197 fDesert, 3 * 12 { DeadLands }, fShore, fOcean);
198
199 JobHelp: array[0..7] of Integer = (jRoad, jRR, jCanal, jIrr,
200 jFarm, jMine, jFort, jBase);
201
202{ THelpLineInfo }
203
204procedure THelpLineInfo.Assign(Source: THelpLineInfo);
205begin
206 Format := Source.Format;
207 PicPix := Source.PicPix;
208 Category := Source.Category;
209 Index := Source.Index;
210end;
211
212{ THistItem }
213
214procedure THistItem.Assign(Source: THistItem);
215begin
216 Kind := Source.Kind;
217 No := Source.No;
218 Pos := Source.Pos;
219 SearchContent := Source.SearchContent;
220end;
221
222{ THistItems }
223
224function THistItems.AddNew(Kind: TLinkCategory; No, Pos: Integer; SearchContent: string
225 ): THistItem;
226begin
227 Result := THistItem.Create;
228 Result.Kind := Kind;
229 Result.No := No;
230 Result.Pos := Pos;
231 Result.SearchContent := SearchContent;
232 Add(Result);
233end;
234
235procedure THyperText.AddLine(S: String; Format: TTextFormat; Picpix: Integer;
236 LinkCategory: TLinkCategory = hkNoLink; LinkIndex: Integer = 0;
237 CrossLink: Boolean = False);
238var
239 HelpLineInfo: THelpLineInfo;
240begin
241 HelpLineInfo := THelpLineInfo.Create;
242 HelpLineInfo.Format := Format;
243 HelpLineInfo.Picpix := Picpix;
244 HelpLineInfo.Category := LinkCategory;
245 HelpLineInfo.Index := LinkIndex;
246 HelpLineInfo.CrossLink := CrossLink;
247 AddObject(S, HelpLineInfo);
248end;
249
250procedure THyperText.LineFeed;
251begin
252 AddLine;
253end;
254
255procedure THyperText.AppendList(Source: THyperText);
256var
257 I: Integer;
258 HelpLineInfo: THelpLineInfo;
259begin
260 for I := 0 to Source.Count - 1 do begin
261 HelpLineInfo := THelpLineInfo.Create;
262 HelpLineInfo.Assign(THelpLineInfo(Source.Objects[I]));
263 AddObject(Source.Strings[I], HelpLineInfo);
264 end;
265end;
266
267procedure THelpDlg.FormCreate(Sender: TObject);
268begin
269 NoMap := TIsoMap.Create;
270
271 HistItems := THistItems.Create;
272
273 CaptionLeft := BackBtn.Left + BackBtn.Width;
274 CaptionRight := SearchBtn.Left;
275 Inc(ModalFrameIndent, 29);
276 MainText := THyperText.Create;
277 MainText.OwnsObjects := True;
278 SearchResult := THyperText.Create;
279 SearchResult.OwnsObjects := True;
280 ScrollBar := TPVScrollbar.Create(Self);
281 ScrollBar.SetBorderSpacing(36, 9, 11);
282 ScrollBar.OnUpdate := ScrollBarUpdate;
283
284 HelpText := TStringTable.Create;
285 HelpText.LoadFromFile(LocalizedFilePath('Help' + DirectorySeparator + 'Help.txt'));
286 hADVHELP := HelpText.Gethandle('ADVHELP');
287 hIMPHELP := HelpText.Gethandle('IMPHELP');
288 hFEATUREHELP := HelpText.Gethandle('FEATUREHELP');
289 hGOVHELP := HelpText.Gethandle('GOVHELP');
290 hSPECIALMODEL := HelpText.Gethandle('SPECIALMODEL');
291 hJOBHELP := HelpText.Gethandle('JOBHELP');
292
293 CaptionFont := Font.Create;
294 CaptionFont.Assign(UniFont[ftNormal]);
295 CaptionFont.Style := CaptionFont.Style + [fsItalic, fsBold];
296 InitButtons;
297
298 TopBtn.Hint := Phrases.Lookup('BTN_CONTENTS');
299 BackBtn.Hint := Phrases.Lookup('BTN_BACK');
300 SearchBtn.Hint := Phrases.Lookup('BTN_SEARCH');
301
302 ExtPic := TDpiBitmap.Create;
303 TerrIcon := TDpiBitmap.Create;
304 TerrIcon.PixelFormat := pf24bit;
305 TerrIcon.SetSize(xSizeBig, ySizeBig);
306 TerrIcon.Canvas.FillRect(0, 0, TerrIcon.Width, TerrIcon.Height);
307 SearchContent := '';
308 ShowNewContentProc := ShowNewContentProcExecute;
309end;
310
311procedure THelpDlg.ShowNewContentProcExecute(NewMode: TWindowMode;
312 HelpContext: string);
313begin
314 ShowNewContent(NewMode, hkText, TextIndex(HelpContext));
315end;
316
317procedure THelpDlg.FormDestroy(Sender: TObject);
318begin
319 ShowNewContentProc := nil;
320 FreeAndNil(ScrollBar);
321 FreeAndNil(MainText);
322 FreeAndNil(SearchResult);
323 FreeAndNil(ExtPic);
324 FreeAndNil(TerrIcon);
325 FreeAndNil(HelpText);
326 // FreeAndNil(CaptionFont);
327 FreeAndNil(HistItems);
328 FreeAndNil(NoMap);
329end;
330
331procedure THelpDlg.FormMouseWheel(Sender: TObject; Shift: TShiftState;
332 WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
333begin
334 if ScrollBar.ProcessMouseWheel(WheelDelta) then begin
335 PaintBox1MouseMove(nil, [], MousePos.X - Left,
336 MousePos.Y - Top);
337 end;
338end;
339
340procedure THelpDlg.CloseBtnClick(Sender: TObject);
341begin
342 Close;
343end;
344
345procedure THelpDlg.OnScroll(var Msg: TMessage);
346begin
347 { TODO: Handled by MouseWheel event
348 if ScrollBar.Process(Msg) then begin
349 Sel := -1;
350 SmartUpdateContent(True)
351 end;
352 }
353end;
354
355procedure THelpDlg.OnMouseLeave(var Msg: TMessage);
356begin
357 if Sel <> -1 then begin
358 Line(Canvas, Sel, False);
359 Sel := -1;
360 end;
361end;
362
363procedure THelpDlg.ClearHistory;
364begin
365 HistItems.Clear;
366end;
367
368procedure THelpDlg.FormPaint(Sender: TObject);
369begin
370 inherited;
371 Canvas.Font.Assign(UniFont[ftNormal]);
372end;
373
374procedure THelpDlg.Line(ACanvas: TDpiCanvas; I: Integer; Lit: Boolean);
375var
376 TextColor: TColor;
377 X, Y: Integer;
378 TextSize: TSize;
379 S: string;
380begin
381 S := MainText[ScrollBar.Position + I];
382 if S = '' then
383 Exit;
384 X := x0[I];
385 Y := 2 + I * 24;
386 if ACanvas = Canvas then
387 begin
388 X := X + SideFrame;
389 Y := Y + WideFrame;
390 end;
391 if THelpLineInfo(MainText.Objects[ScrollBar.Position + I]).Format
392 in [pkCaption, pkBigTer, pkRightIcon, pkBigFeature] then
393 begin
394 ACanvas.Font.Assign(CaptionFont);
395 { ACanvas.brush.color:=CaptionColor;
396 ACanvas.FillRect(rect(X,I*24,X+24,I*24+24));
397 ACanvas.Brush.Color:=$FFFFFF;
398 ACanvas.FrameRect(rect(X+1,I*24+1,X+24-1,I*24+24-1));
399 ACanvas.Brush.Style:=bsClear; }
400 DpiBitBltCanvas(ACanvas, X, Y - 4, 24, 24, HGrSystem.Data.Canvas, 1,
401 146);
402 BiColorTextOut(ACanvas, $FFFFFF, $7F007F, X + 10 - ACanvas.Textwidth(S[1]) div 2,
403 Y - 3, S[1]);
404 BiColorTextOut(ACanvas, CaptionColor, $7F007F, X + 24, Y - 3, Copy(S, 2, 255));
405 ACanvas.Font.Assign(UniFont[ftNormal]);
406 end
407 else if THelpLineInfo(MainText.Objects[ScrollBar.Position + I]).Format = pkSection then
408 begin
409 ACanvas.Font.Assign(CaptionFont);
410 BiColorTextOut(ACanvas, CaptionColor, $7F007F, X, Y - 3, S);
411 ACanvas.Font.Assign(UniFont[ftNormal]);
412 end
413 else
414 begin
415 if (Kind = hkMisc) and (No = Integer(miscMain)) then
416 ACanvas.Font.Assign(CaptionFont);
417 TextColor := Colors.Canvas.Pixels[clkMisc, cliPaperText];
418 if ACanvas = Canvas then
419 begin
420 TextSize.cx := BiColorTextWidth(ACanvas, S);
421 TextSize.cy := ACanvas.TextHeight(S);
422 if Y + TextSize.cy >= WideFrame + InnerHeight then
423 TextSize.cy := WideFrame + InnerHeight - Y;
424 FillSeamless(ACanvas, X, Y, TextSize.cx, TextSize.cy, -SideFrame,
425 ScrollBar.Position * 24 - WideFrame, Paper);
426 end;
427 BiColorTextOut(ACanvas, TextColor, $7F007F, X, Y, S);
428 if lit then
429 with ACanvas do
430 begin
431 Assert(ACanvas = Canvas);
432 Pen.Color := TextColor;
433 MoveTo(X + 1, Y + TextSize.cy - 2);
434 LineTo(X + TextSize.cx, Y + TextSize.cy - 2);
435 end;
436 if (Kind = hkMisc) and (No = Integer(miscMain)) then
437 ACanvas.Font.Assign(UniFont[ftNormal]);
438 end;
439end;
440
441procedure THelpDlg.WaterSign(x0, y0, iix: Integer);
442const
443 nHeaven = 28;
444 MaxSum = 9 * 9 * 255 * 75 div 100;
445var
446 X, Y, dx, dy, xSrc, ySrc, Sum, xx: Integer;
447 Heaven: array [0..nHeaven] of Integer;
448 PaintPtr: TPixelPointer;
449 CoalPtr: TPixelPointer;
450 ImpPtr: array [-1..1] of TPixelPointer;
451begin
452 // assume eiffel tower has free common heaven
453 for dy := 0 to nHeaven - 1 do
454 Heaven[dy] := BigImp.Canvas.Pixels[woEiffel mod 7 * xSizeBig,
455 (SystemIconLines + woEiffel div 7) * ySizeBig + dy];
456
457 BigImp.BeginUpdate;
458 Offscreen.BeginUpdate;
459 xSrc := iix mod 7 * xSizeBig;
460 ySrc := (iix div 7 + 1) * ySizeBig;
461 PaintPtr := TPixelPointer.Create(OffScreen, ScaleToNative(x0), ScaleToNative(y0));
462 CoalPtr := TPixelPointer.Create(Templates.Data, ScaleToNative(xCoal), ScaleToNative(yCoal));
463 for dy := -1 to 1 do
464 ImpPtr[dy] := TPixelPointer.Create(BigImp, ScaleToNative(xSrc), ScaleToNative(ySrc));
465 for Y := 0 to ScaleToNative(ySizeBig) * 2 - 1 do begin
466 if ((ScaleToNative(y0) + Y) >= 0) and ((ScaleToNative(y0) + Y) < ScaleToNative(InnerHeight)) then begin
467 for dy := -1 to 1 do
468 if ((Max(Y + ScaleToNative(dy), 0) shr 1) >= 0) and ((Max(Y + ScaleToNative(dy), 0) shr 1) < ScaleToNative(ySizeBig)) then
469 ImpPtr[dy].SetXY(0, Max(Y + ScaleToNative(dy), 0) shr 1);
470 for X := 0 to ScaleToNative(xSizeBig * 2) - 1 do begin
471 Sum := 0;
472 for dx := -1 to 1 do begin
473 xx := Max((X + ScaleToNative(dx)), 0) shr 1;
474 for dy := -1 to 1 do begin
475 ImpPtr[dy].SetX(xx);
476 if ((Y + ScaleToNative(dy)) shr 1 < 0) or ((Y + ScaleToNative(dy)) shr 1 >= ScaleToNative(ySizeBig)) or
477 ((X + ScaleToNative(dx)) shr 1 < 0) or ((X + ScaleToNative(dx)) shr 1 >= ScaleToNative(xSizeBig)) or
478 ((Y + ScaleToNative(dy)) shr 1 < ScaleToNative(nHeaven)) and
479 (ImpPtr[dy].Pixel^.B shl 16 + ImpPtr[dy].Pixel^.G shl 8 +
480 ImpPtr[dy].Pixel^.R = Heaven[(ScaleFromNative(Y + ScaleToNative(dy))) shr 1]) then
481 Sum := Sum + 9 * 255
482 else
483 Sum := Sum + ImpPtr[dy].Pixel^.B + 5 * ImpPtr[dy].Pixel^.G + 3 *
484 ImpPtr[dy].Pixel^.R;
485 end;
486 end;
487 if Sum < MaxSum then begin // No saturation
488 Sum := 1 shl 22 - (MaxSum - Sum) * (256 - CoalPtr.Pixel^.B * 2);
489 PaintPtr.Pixel^.B := Min(PaintPtr.Pixel^.B * Sum shr 22, 255);
490 PaintPtr.Pixel^.G := Min(PaintPtr.Pixel^.G * Sum shr 22, 255);
491 PaintPtr.Pixel^.R := Min(PaintPtr.Pixel^.R * Sum shr 22, 255);
492 end;
493 PaintPtr.NextPixel;
494 CoalPtr.NextPixel;
495 end;
496 end;
497 PaintPtr.NextLine;
498 CoalPtr.NextLine;
499 end;
500 Offscreen.EndUpdate;
501 BigImp.EndUpdate;
502end;
503
504procedure THelpDlg.PaintTerrIcon(X, Y, xSrc, ySrc: Integer);
505begin
506 with NoMap do begin
507 Frame(OffScreen.Canvas, X - 1, Y - 1, X + xSizeBig, Y + ySizeBig,
508 $000000, $000000);
509 if 2 * yyt < 40 then begin
510 Sprite(OffScreen, HGrTerrain, X, Y, 56, 2 * yyt, xSrc, ySrc);
511 Sprite(OffScreen, HGrTerrain, X, Y + 2 * yyt, 56, 40 - 2 * yyt,
512 xSrc, ySrc);
513 end else
514 Sprite(OffScreen, HGrTerrain, X, Y, 56, 40, xSrc, ySrc);
515 Sprite(OffScreen, HGrTerrain, X, Y, xxt, yyt, xSrc + xxt, ySrc + yyt);
516 Sprite(OffScreen, HGrTerrain, X, Y + yyt, xxt, 40 - yyt, xSrc + xxt, ySrc);
517 Sprite(OffScreen, HGrTerrain, X + xxt, Y, 56 - xxt, yyt, xSrc, ySrc + yyt);
518 Sprite(OffScreen, HGrTerrain, X + xxt, Y + yyt, 56 - xxt, 40 - yyt,
519 xSrc, ySrc);
520 end;
521end;
522
523procedure THelpDlg.OffscreenPaint;
524var
525 I, J, yl, srcno, ofs, cnt, Y: Integer;
526 S: string;
527 HelpLineInfo: THelpLineInfo;
528begin
529 inherited;
530 CaptionColor := Colors.Canvas.Pixels[clkMisc, cliPaperCaption];
531 FillSeamless(OffScreen.Canvas, 0, 0, InnerWidth, InnerHeight, 0,
532 ScrollBar.Position * 24, Paper);
533 with OffScreen.Canvas do
534 begin
535 Font.Assign(UniFont[ftNormal]);
536 for I := -ScrollBar.Position to InnerHeight div 24 do
537 if ScrollBar.Position + I < MainText.Count then
538 begin
539 HelpLineInfo := THelpLineInfo(MainText.Objects[ScrollBar.Position + I]);
540 if HelpLineInfo.Format = pkExternal then
541 begin
542 yl := ExtPic.Height;
543 if 4 + I * 24 + yl > InnerHeight then
544 yl := InnerHeight - (4 + I * 24);
545 DpiBitBltCanvas(OffScreen.Canvas, 8, 4 + I * 24, ExtPic.Width, yl, ExtPic.Canvas,
546 0, 0);
547 end;
548 end;
549 for I := -2 to InnerHeight div 24 do
550 if (ScrollBar.Position + I >= 0) and (ScrollBar.Position + I < MainText.Count) then
551 begin
552 HelpLineInfo := THelpLineInfo(MainText.Objects[ScrollBar.Position + I]);
553 if (HelpLineInfo.Category <> hkNoLink) or (HelpLineInfo.Index <> 0) then
554 begin
555 if (Kind = hkMisc) and (No = Integer(miscSearchResult)) then
556 Sprite(OffScreen, HGrSystem, 18, 9 + I * 24, 8, 8, 90, 16)
557 else if HelpLineInfo.Format in [pkSmallIcon_AsPreq, pkAdvIcon_AsPreq]
558 then
559 Sprite(OffScreen, HGrSystem, 12, I * 24 + 5, 14, 14, 65, 20)
560 else if HelpLineInfo.CrossLink then
561 Sprite(OffScreen, HGrSystem, 12, I * 24 + 5, 14, 14, 80, 1)
562 else if not((Kind = hkMisc) and (No = Integer(miscMain))) then
563 Sprite(OffScreen, HGrSystem, 10, I * 24 + 6, 14, 14, 65, 1);
564 x0[I] := 24;
565 end
566 else
567 x0[I] := 0;
568 case HelpLineInfo.Format of
569 pkLogo:
570 begin
571 Server(sGetVersion, 0, 0, J);
572 S := Format('%d.%d.%d', [J shr 16 and $FF, J shr 8 and $FF,
573 J and $FF]);
574 PaintLogo(OffScreen.Canvas, (InnerWidth - 122) div 2, I * 24 + 1,
575 HGrSystem.Data.Canvas.Pixels[95, 1], $000000);
576 Font.Assign(UniFont[ftSmall]);
577 BiColorTextOut(OffScreen.Canvas, $000000, $7F007F,
578 (InnerWidth - Textwidth(S)) div 2, I * 24 + 26, S);
579 Font.Assign(UniFont[ftNormal]);
580 end;
581 pkSmallIcon, pkSmallIcon_AsPreq:
582 begin
583 ScreenTools.Frame(OffScreen.Canvas, 8 - 1 + x0[I], 2 - 1 + I * 24,
584 8 + xSizeSmall + x0[I], 2 + 20 + I * 24, $000000, $000000);
585 if HelpLineInfo.Picpix = imPalace then
586 DpiBitBltCanvas(OffScreen.Canvas, 8 + x0[I], 2 + I * 24,
587 xSizeSmall, ySizeSmall, SmallImp.Canvas,
588 0 * xSizeSmall, 1 * ySizeSmall)
589 else
590 DpiBitBltCanvas(OffScreen.Canvas, 8 + x0[I], 2 + I * 24,
591 xSizeSmall, ySizeSmall, SmallImp.Canvas,
592 HelpLineInfo.Picpix mod 7 * xSizeSmall,
593 (HelpLineInfo.Picpix + SystemIconLines * 7) div 7 *
594 ySizeSmall);
595 x0[I] := x0[I] + (8 + 8 + 36);
596 end;
597 pkBigIcon:
598 begin
599 FrameImage(OffScreen.Canvas, BigImp, x0[I] + 12, I * 24 - 7, 56,
600 40, HelpLineInfo.Picpix mod 7 * xSizeBig,
601 HelpLineInfo.Picpix div 7 * ySizeBig);
602 x0[I] := 64 + 8 + 8 + x0[I];
603 end;
604 pkSpecialIcon:
605 begin
606 case HelpLineInfo.Picpix of
607 0:
608 FrameImage(OffScreen.Canvas, HGrSystem2.Data,
609 12 + x0[I], -7 + I * 24, 56, 40, 137, 127);
610 1:
611 with NoMap do begin
612 PaintTerrIcon(12 + x0[I], -7 + I * 24,
613 1 + 3 * (xxt * 2 + 1), 1 + yyt);
614 if 2 * yyt < 40 then
615 Sprite(OffScreen, HGrTerrain, 12 + x0[I], -7 + 4 + I * 24,
616 56, 2 * yyt, 1 + 3 * (xxt * 2 + 1) + xxt - 28,
617 1 + yyt + 1 * (yyt * 3 + 1))
618 else
619 Sprite(OffScreen, HGrTerrain, 12 + x0[I],
620 -7 + 4 + I * 24 - 4, 56, 40, 1 + 3 * (xxt * 2 + 1) + xxt
621 - 28, 1 + yyt + 1 * (yyt * 3 + 1) + yyt - 20);
622 end;
623 2:
624 with NoMap do begin
625 PaintTerrIcon(12 + x0[I], -7 + I * 24,
626 1 + 7 * (xxt * 2 + 1), 1 + yyt + 4 * (yyt * 3 + 1));
627 if 2 * yyt < 40 then
628 Sprite(OffScreen, HGrTerrain, 12 + x0[I], -7 + 4 + I * 24,
629 56, 32, 1 + 4 * (xxt * 2 + 1) + xxt - 28,
630 1 + yyt + 12 * (yyt * 3 + 1) + yyt - 16)
631 else
632 Sprite(OffScreen, HGrTerrain, 12 + x0[I], -7 + 4 + I * 24,
633 56, 32, 1 + 4 * (xxt * 2 + 1) + xxt - 28,
634 1 + yyt + 12 * (yyt * 3 + 1) + yyt - 16)
635 end;
636 end;
637 x0[I] := 64 + 8 + 8 + x0[I];
638 end;
639 pkDomain:
640 begin
641 ScreenTools.Frame(OffScreen.Canvas, 8 - 1 + x0[I], 2 - 1 + I * 24,
642 8 + 36 + x0[I], 2 + 20 + I * 24, $000000, $000000);
643 Dump(OffScreen, HGrSystem, 8 + x0[I], 2 + I * 24, 36, 20,
644 75 + HelpLineInfo.Picpix * 37, 295);
645 x0[I] := x0[I] + (8 + 8 + 36);
646 end;
647 pkAdvIcon, pkAdvIcon_AsPreq:
648 begin
649 ScreenTools.Frame(OffScreen.Canvas, 8 - 1 + x0[I], 2 - 1 + I * 24,
650 8 + xSizeSmall + x0[I], 2 + ySizeSmall + I * 24,
651 $000000, $000000);
652 if AdvIcon[HelpLineInfo.Picpix] < 84 then
653 DpiBitBltCanvas(OffScreen.Canvas, 8 + x0[I], 2 + I * 24,
654 xSizeSmall, ySizeSmall, SmallImp.Canvas,
655 (AdvIcon[HelpLineInfo.Picpix] + SystemIconLines * 7) mod 7 *
656 xSizeSmall, (AdvIcon[HelpLineInfo.Picpix] + SystemIconLines *
657 7) div 7 * ySizeSmall)
658 else
659 Dump(OffScreen, HGrSystem, 8 + x0[I], 2 + I * 24, 36, 20,
660 1 + (AdvIcon[HelpLineInfo.Picpix] - 84) mod 8 * 37,
661 295 + (AdvIcon[HelpLineInfo.Picpix] - 84) div 8 * 21);
662 J := AdvValue[HelpLineInfo.Picpix] div 1000;
663 DpiBitBltCanvas(OffScreen.Canvas, x0[I] + 4, 4 + I * 24, 14, 14,
664 HGrSystem.Mask.Canvas, 127 + J * 15, 85, SRCAND);
665 Sprite(OffScreen, HGrSystem, x0[I] + 3, 3 + I * 24, 14, 14,
666 127 + J * 15, 85);
667 x0[I] := x0[I] + (8 + 8 + 36);
668 end;
669 pkRightIcon:
670 begin
671 if Imp[HelpLineInfo.Picpix].Kind <> ikWonder then
672 ImpImage(OffScreen.Canvas, InnerWidth - (40 + xSizeBig), I * 24,
673 HelpLineInfo.Picpix, gDespotism)
674 else
675 WaterSign(InnerWidth - (40 + 2 * xSizeBig), I * 24 - 8,
676 HelpLineInfo.Picpix + 7);
677 x0[I] := x0[I] + 8;
678 end;
679 pkIllu:
680 WaterSign(8, I * 24 - 8, HelpLineInfo.Picpix);
681 pkBigFeature:
682 begin
683 cnt := 0;
684 for J := nDomains - 1 downto 0 do
685 if 1 shl J and Feature[HelpLineInfo.Picpix].Domains <> 0 then
686 begin
687 Inc(cnt);
688 Dump(OffScreen, HGrSystem, InnerWidth - 38 - 38 * cnt,
689 I * 24 + 1, 36, 20, 75 + J * 37, 295);
690 ScreenTools.Frame(OffScreen.Canvas, InnerWidth - 39 - 38 * cnt, I * 24,
691 InnerWidth - 2 - 38 * cnt, I * 24 + 21, $000000, $000000);
692 end;
693 DarkGradient(OffScreen.Canvas, InnerWidth - 38 - 38 * cnt,
694 I * 24 + 23, cnt * 38 - 2, 1);
695 ofs := InnerWidth - (39 + 7) - 19 * cnt;
696 with OffScreen.Canvas do
697 begin
698 Brush.Color := $C0C0C0;
699 FrameRect(Rect(ofs, 1 + 23 + I * 24, ofs + 14,
700 15 + 23 + I * 24));
701 Brush.Style := bsClear;
702 Sprite(OffScreen, HGrSystem, ofs + 2, 3 + 23 + I * 24, 10, 10,
703 66 + HelpLineInfo.Picpix mod 11 * 11,
704 137 + HelpLineInfo.Picpix div 11 * 11);
705 end;
706 x0[I] := x0[I] + 8;
707 end;
708 pkTer, pkBigTer:
709 with NoMap do begin
710 if HelpLineInfo.Format = pkBigTer then
711 Y := I * 24 - 3 + yyt
712 else
713 Y := I * 24 + 13;
714 if HelpLineInfo.Picpix >= 3 * 12 then
715 srcno := 2 * 9 + 6
716 else if HelpLineInfo.Picpix mod 12 = fJungle then
717 srcno := 18 * 9
718 else if HelpLineInfo.Picpix mod 12 < fJungle then
719 srcno := HelpLineInfo.Picpix mod 12
720 else
721 srcno := 27 + (HelpLineInfo.Picpix mod 12 - 9) * 18;
722 if HelpLineInfo.Format = pkTer then
723 begin
724 ofs := x0[I] + 8;
725 x0[I] := 2 * xxt + 8 + ofs;
726 end
727 else
728 begin
729 ofs := InnerWidth - (2 * xxt + 38);
730 x0[I] := x0[I] + 8;
731 end;
732 if srcno >= fJungle then
733 begin
734 Sprite(OffScreen, HGrTerrain, ofs + 4, Y - yyt + 2, xxt * 2 - 8,
735 yyt * 2 - 4, 5 + 2 * (xxt * 2 + 1),
736 3 + yyt + 2 * (yyt * 3 + 1));
737 Sprite(OffScreen, HGrTerrain, ofs, Y - 2 * yyt, xxt * 2,
738 yyt * 3 - 2, 1 + srcno mod 9 * (xxt * 2 + 1),
739 1 + srcno div 9 * (yyt * 3 + 1));
740 end
741 else
742 Sprite(OffScreen, HGrTerrain, ofs + 4, Y - yyt + 2, xxt * 2 - 8,
743 yyt * 2 - 4, 5 + srcno mod 9 * (xxt * 2 + 1),
744 3 + yyt + srcno div 9 * (yyt * 3 + 1));
745 if HelpLineInfo.Picpix >= 3 * 12 then { rare resource }
746 Sprite(OffScreen, HGrTerrain, ofs, Y - 2 * yyt, xxt * 2,
747 yyt * 3, 1 + 8 * (xxt * 2 + 1),
748 1 + (HelpLineInfo.Picpix - 2 * 12) * (yyt * 3 + 1))
749 else if HelpLineInfo.Picpix >= 12 then { special tile }
750 begin
751 if HelpLineInfo.Picpix mod 12 = fJungle then
752 srcno := 17 * 9 + 8
753 else if HelpLineInfo.Picpix mod 12 < fJungle then
754 srcno := HelpLineInfo.Picpix mod 12
755 else
756 srcno := 18 + 8 + (HelpLineInfo.Picpix mod 12 - 9) * 18;
757 srcno := srcno + HelpLineInfo.Picpix div 12 * 9;
758 Sprite(OffScreen, HGrTerrain, ofs, Y - 2 * yyt, xxt * 2,
759 yyt * 3, 1 + srcno mod 9 * (xxt * 2 + 1),
760 1 + srcno div 9 * (yyt * 3 + 1));
761 end;
762 end;
763 pkTerImp:
764 with NoMap do begin
765 ofs := 8;
766 if HelpLineInfo.Picpix = 5 then
767 begin // display mine on hills
768 Sprite(OffScreen, HGrTerrain, ofs + 4, I * 24 + 13 - yyt,
769 xxt * 2 - 8, yyt * 2 - 4, 5 + 2 * (xxt * 2 + 1),
770 3 + yyt + 2 * (yyt * 3 + 1));
771 srcno := 45;
772 end
773 else
774 srcno := fPrairie; // display on prairie
775 Sprite(OffScreen, HGrTerrain, ofs + 4, I * 24 + 13 - yyt,
776 xxt * 2 - 8, yyt * 2 - 4, 5 + srcno mod 9 * (xxt * 2 + 1),
777 3 + yyt + srcno div 9 * (yyt * 3 + 1));
778 if HelpLineInfo.Picpix = 12 then { river }
779 Sprite(OffScreen, HGrTerrain, ofs, I * 24 + 11 - yyt, xxt * 2,
780 yyt * 2, 1 + 5 * (xxt * 2 + 1), 1 + yyt + 13 * (yyt * 3 + 1))
781 else if HelpLineInfo.Picpix >= 3 then { improvement 2 }
782 begin
783 if HelpLineInfo.Picpix = 6 then
784 Sprite(OffScreen, HGrTerrain, ofs, I * 24 + 11 - 2 * yyt,
785 xxt * 2, yyt * 3, 1 + 7 * (xxt * 2 + 1),
786 1 + 12 * (yyt * 3 + 1));
787 Sprite(OffScreen, HGrTerrain, ofs, I * 24 + 11 - 2 * yyt,
788 xxt * 2, yyt * 3, 1 + (HelpLineInfo.Picpix - 3) *
789 (xxt * 2 + 1), 1 + 12 * (yyt * 3 + 1))
790 end
791 else { improvement 1 }
792 begin
793 Sprite(OffScreen, HGrTerrain, ofs, I * 24 + 11 - 2 * yyt,
794 xxt * 2, yyt * 3, 1 + 2 * (xxt * 2 + 1),
795 1 + (9 + HelpLineInfo.Picpix) * (yyt * 3 + 1));
796 Sprite(OffScreen, HGrTerrain, ofs, I * 24 + 11 - 2 * yyt,
797 xxt * 2, yyt * 3, 1 + 5 * (xxt * 2 + 1),
798 1 + (9 + HelpLineInfo.Picpix) * (yyt * 3 + 1))
799 end;
800 x0[I] := x0[I] + 8;
801 end;
802 pkModel:
803 begin
804 FrameImage(OffScreen.Canvas, BigImp, x0[I] + 12, I * 24 - 7,
805 56, 40, 0, 0);
806 Sprite(OffScreen, HGrStdUnits, x0[I] + 8, I * 24 - 11, 64, 44,
807 1 + HelpLineInfo.Picpix mod 10 * 65,
808 1 + HelpLineInfo.Picpix div 10 * 49);
809 x0[I] := 64 + 8 + 8 + x0[I];
810 end;
811 pkFeature:
812 begin
813 DarkGradient(OffScreen.Canvas, x0[I] + 8 - 1,
814 7 + I * 24 - 3, 16, 1);
815 ScreenTools.Frame(OffScreen.Canvas, x0[I] + 8, 7 + I * 24 - 2, x0[I] + 8 + 13,
816 7 + I * 24 - 2 + 13, $C0C0C0, $C0C0C0);
817 Sprite(OffScreen, HGrSystem, x0[I] + 8 + 2, 7 + I * 24, 10, 10,
818 66 + HelpLineInfo.Picpix mod 11 * 11,
819 137 + HelpLineInfo.Picpix div 11 * 11);
820 x0[I] := x0[I] + 8 + 8 + 2 + 13;
821 end;
822 pkExp:
823 begin
824 ScreenTools.Frame(OffScreen.Canvas, 20 - 1, 8 - 4 + I * 24, 20 + 12,
825 8 + 11 + I * 24, $000000, $000000);
826 Dump(OffScreen, HGrSystem, 20, 8 - 3 + I * 24, 12, 14,
827 121 + HelpLineInfo.Picpix * 13, 28);
828 x0[I] := 20 + 8 + 11;
829 end;
830 pkAITStat:
831 begin
832 Sprite(OffScreen, HGrSystem, 20, 6 + I * 24, 14, 14,
833 1 + HelpLineInfo.Picpix * 15, 316);
834 x0[I] := 20 + 8 + 11;
835 end;
836 pkGov:
837 begin
838 ScreenTools.Frame(OffScreen.Canvas, 8 - 1 + x0[I], 2 - 1 + I * 24,
839 8 + xSizeSmall + x0[I], 2 + 20 + I * 24, $000000, $000000);
840 DpiBitBltCanvas(OffScreen.Canvas, 8 + x0[I], 2 + I * 24, xSizeSmall,
841 ySizeSmall, SmallImp.Canvas, (HelpLineInfo.Picpix - 1) *
842 xSizeSmall, ySizeSmall);
843 x0[I] := x0[I] + (8 + 8 + 36);
844 end;
845 pkDot:
846 begin
847 Sprite(OffScreen, HGrSystem, x0[I] + 18, 9 + I * 24, 8,
848 8, 81, 16);
849 x0[I] := 20 + 8 + 4;
850 end;
851 pkNormal_Dot:
852 x0[I] := 20 + 8 + 4;
853 pkNormal_64:
854 x0[I] := 64 + 8 + 8;
855 else
856 x0[I] := x0[I] + 8;
857 end;
858 Self.Line(OffScreen.Canvas, I, False)
859 end;
860 end;
861 MarkUsedOffscreen(InnerWidth, InnerHeight + 13 + 48);
862end;
863
864procedure THelpDlg.ScrollBarUpdate(Sender: TObject);
865begin
866 Sel := -1;
867 SmartUpdateContent(True);
868end;
869
870procedure THelpDlg.Prepare(sbPos: Integer = 0);
871var
872 I, J, Special, Domain, Headline, TerrType, TerrSubType: Integer;
873 S: string;
874 ps: PChar;
875 List: THyperText;
876 CheckSeeAlso: Boolean;
877
878 procedure AddAdvance(I: Integer);
879 begin
880 MainText.AddLine(Phrases.Lookup('ADVANCES', I), pkAdvIcon, I,
881 hkAdv, I, True);
882 end;
883
884 procedure AddPreqAdv(I: Integer);
885 begin
886 MainText.AddLine(Phrases.Lookup('ADVANCES', I), pkAdvIcon_AsPreq, I,
887 hkAdv, I, True);
888 end;
889
890 procedure AddImprovement(I: Integer);
891 begin
892 MainText.AddLine(Phrases.Lookup('IMPROVEMENTS', I), pkSmallIcon, I,
893 hkImp, I, True);
894 end;
895
896 procedure AddPreqImp(I: Integer);
897 begin
898 MainText.AddLine(Phrases.Lookup('IMPROVEMENTS', I), pkSmallIcon_AsPreq, I,
899 hkImp, I, True);
900 end;
901
902 procedure AddTerrain(I: Integer);
903 begin
904 if MainText.Count > 1 then
905 begin
906 MainText.LineFeed;
907 end;
908 MainText.AddLine(Phrases.Lookup('TERRAIN', I), pkTer, I, hkTer, I);
909 end;
910
911 procedure AddFeature(I: Integer);
912 begin
913 MainText.AddLine(Phrases.Lookup('FEATURES', I), pkFeature, I,
914 hkFeature, I, True);
915 end;
916
917 procedure AddModel(I: Integer);
918 var
919 pix: Integer;
920 Name: string;
921 begin
922 if MainText.Count > 1 then
923 MainText.LineFeed;
924 FindStdModelPicture(SpecialModelPictureCode[I], pix, Name);
925 MainText.AddLine(Name, pkModel, pix, hkModel, I, True);
926 end;
927
928 procedure AddStandardBlock(Item: string);
929 var
930 I: Integer;
931 begin
932 with MainText do
933 begin
934 if Item = 'LOGO' then
935 begin
936 AddLine('', pkLogo);
937 LineFeed;
938 end
939 else if Item = 'TECHFORMULA' then
940 begin
941 I := Difficulty;
942 if I = 0 then
943 I := 2;
944 AddLine(Format(HelpText.Lookup('TECHFORMULA'), [TechFormula_M[I],
945 TechFormula_D[I]]));
946 end
947 else if Item = 'EXPERIENCE' then
948 for I := 0 to nExp - 1 do
949 AddLine(Phrases.Lookup('EXPERIENCE', I), pkExp, I)
950 else if Item = 'MODERN' then
951 for I := 1 to 3 do
952 begin
953 LineFeed;
954 AddLine(Phrases.Lookup('TERRAIN', 3 * 12 + I), pkTer, 3 * 12 + I);
955 end
956 else if Item = 'SAVED' then
957 AddLine(DataDir + 'Saved', pkNormal)
958 else if Item = 'AITSTAT' then
959 for I := 0 to 3 do
960 AddLine(Phrases2.Lookup('AITSTAT', I), pkAITStat, I)
961 end;
962 end;
963
964 procedure DecodeItem(S: string; var Category: TLinkCategory; var Index: Integer);
965 var
966 I: Integer;
967 begin
968 if (Length(S) > 0) and (S[1] = ':') then begin
969 Category := hkMisc;
970 Index := 0;
971 for I := 3 to Length(S) do
972 Index := Index * 10 + Ord(S[I]) - 48;
973 case S[2] of
974 'A': Category := hkAdv;
975 'B': Category := hkImp;
976 'T': Category := hkTer;
977 'F': Category := hkFeature;
978 'E': Category := hkInternet;
979 'S': Category := hkModel;
980 'C': Index := Integer(miscCredits);
981 'J': Index := Integer(miscJobList);
982 'G': Index := Integer(miscGovList);
983 end;
984 if (Category <> hkMisc) and (Index = 0) then
985 Index := 200;
986 end else begin
987 Category := hkText;
988 Index := HelpText.GetHandle(Copy(S, 1, 255));
989 end;
990 end;
991
992 procedure AddTextual(S: string);
993 var
994 I: Integer;
995 P: Integer;
996 L: Integer;
997 ofs: Integer;
998 CurrentFormat: TTextFormat;
999 FollowFormat: TTextFormat;
1000 Picpix: Integer;
1001 LinkCategory: TLinkCategory;
1002 CrossLink: Boolean;
1003 LinkIndex: Integer;
1004 RightMargin: Integer;
1005 Name: string;
1006 Text: string;
1007 begin
1008 CrossLink := False;
1009 RightMargin := InnerWidth - 16 - DpiGetSystemMetrics(SM_CXVSCROLL);
1010 FollowFormat := pkNormal;
1011 while S <> '' do
1012 begin
1013 Picpix := 0;
1014 LinkCategory := hkNoLink;
1015 LinkIndex := 0;
1016 if S[1] = '$' then
1017 begin // Window caption
1018 P := 1;
1019 repeat
1020 Inc(P);
1021 until (P > Length(S)) or (S[P] = '\');
1022 Caption := Copy(S, 2, P - 2);
1023 Delete(S, 1, P);
1024 end
1025 else if S[1] = '&' then
1026 begin // Standard block
1027 P := 1;
1028 repeat
1029 Inc(P);
1030 until (P > Length(S)) or (S[P] = '\');
1031 AddStandardBlock(Copy(S, 2, P - 2));
1032 Delete(S, 1, P);
1033 end
1034 else if S[1] = '@' then
1035 begin // Image
1036 if (Length(S) >= 2) and (S[2] = '@') then
1037 begin // Generate from icon
1038 Picpix := 0;
1039 P := 3;
1040 while (P <= Length(S)) and (S[P] <> '\') do
1041 begin
1042 Picpix := Picpix * 10 + Ord(S[P]) - 48;
1043 Inc(P);
1044 end;
1045 if (Picpix < 0) or (Picpix >= nImp) then
1046 Picpix := 0;
1047 MainText.AddLine('', pkIllu, Picpix);
1048 MainText.LineFeed;
1049 MainText.LineFeed;
1050 end
1051 else
1052 begin // external image
1053 P := 1;
1054 repeat
1055 Inc(P);
1056 until (P > Length(S)) or (S[P] = '\');
1057 if LoadGraphicFile(ExtPic, LocalizedFilePath('Help' +
1058 DirectorySeparator + Copy(S, 2, P - 2)) + '.png') then
1059 begin
1060 MainText.AddLine('', pkExternal);
1061 for I := 0 to (ExtPic.Height - 12) div 24 do
1062 MainText.LineFeed;
1063 end;
1064 end;
1065 Delete(S, 1, P);
1066 end
1067 else
1068 begin
1069 case S[1] of
1070 ':', ';':
1071 begin // link
1072 P := 1;
1073 repeat
1074 Inc(P);
1075 until (P > Length(S)) or (S[P] = '\') or (S[P] = ' ');
1076 DecodeItem(Copy(S, 2, P - 2), LinkCategory, LinkIndex);
1077 CurrentFormat := pkNormal;
1078 if (LinkCategory <> hkText) and (LinkIndex < 200) then
1079 // show icon
1080 case LinkCategory of
1081 hkAdv:
1082 begin
1083 CurrentFormat := pkAdvIcon;
1084 Picpix := LinkIndex;
1085 end;
1086 hkImp:
1087 begin
1088 CurrentFormat := pkSmallIcon;
1089 Picpix := LinkIndex;
1090 end;
1091 hkTer:
1092 begin
1093 CurrentFormat := pkTer;
1094 Picpix := LinkIndex;
1095 end;
1096 hkFeature:
1097 begin
1098 CurrentFormat := pkFeature;
1099 Picpix := LinkIndex;
1100 end;
1101 hkModel:
1102 begin
1103 CurrentFormat := pkModel;
1104 FindStdModelPicture(SpecialModelPictureCode[LinkIndex],
1105 Picpix, Name);
1106 end;
1107 end;
1108 if S[1] = ':' then
1109 CrossLink := True;
1110 if (P > Length(S)) or (S[P] = ' ') then
1111 Delete(S, 1, P)
1112 else
1113 Delete(S, 1, P - 1)
1114 end;
1115 '!': // highlighted
1116 if (Length(S) >= 2) and (S[2] = '!') then
1117 begin
1118 if MainText.Count > 1 then
1119 MainText.LineFeed;
1120 FollowFormat := pkCaption;
1121 CurrentFormat := pkCaption;
1122 Delete(S, 1, 2);
1123 end
1124 else
1125 begin
1126 FollowFormat := pkSection;
1127 CurrentFormat := pkSection;
1128 Delete(S, 1, 1);
1129 end;
1130 '-':
1131 begin // list
1132 FollowFormat := pkNormal_Dot;
1133 CurrentFormat := pkDot;
1134 Delete(S, 1, 1);
1135 end;
1136 else
1137 CurrentFormat := FollowFormat;
1138 end;
1139 if FollowFormat = pkNormal_Dot then
1140 ofs := 20 + 4 + 8
1141 else
1142 ofs := 8;
1143 P := 0;
1144 repeat
1145 repeat
1146 Inc(P)
1147 until (P > Length(S)) or (S[P] = ' ') or (S[P] = '\');
1148 if (BiColorTextWidth(OffScreen.Canvas, Copy(S, 1, P - 1)) <=
1149 RightMargin - ofs) then
1150 L := P - 1
1151 else
1152 Break;
1153 until (P >= Length(S)) or (S[L + 1] = '\');
1154 Text := Copy(S, 1, L);
1155 if LinkCategory = hkInternet then begin
1156 if LinkIndex = 1 then Text := AITemplateManual
1157 else if LinkIndex = 2 then Text := CevoHomepageShort
1158 else if LinkIndex = 3 then Text := CevoContactShort;
1159 end;
1160 MainText.AddLine(Text, CurrentFormat, Picpix, LinkCategory,
1161 LinkIndex, CrossLink);
1162 if (L < Length(S)) and (S[L + 1] = '\') then
1163 FollowFormat := pkNormal;
1164 Delete(S, 1, L + 1);
1165 end;
1166 end;
1167 end;
1168
1169 procedure AddItem(Item: string);
1170 begin
1171 AddTextual(HelpText.Lookup(Item));
1172 end;
1173
1174 procedure AddModelText(I: Integer);
1175 var
1176 pix: Integer;
1177 S: string;
1178 begin
1179 with MainText do begin
1180 if Count > 1 then begin
1181 LineFeed;
1182 LineFeed;
1183 end;
1184 FindStdModelPicture(SpecialModelPictureCode[I], pix, S);
1185 AddLine(S, pkSection);
1186 AddLine(Format(HelpText.Lookup('STRENGTH'), [SpecialModel[I].Attack,
1187 SpecialModel[I].Defense]), pkNormal_64);
1188 AddLine(Format(HelpText.Lookup('SPEED'),
1189 [MovementToString(SpecialModel[I].Speed)]), pkModel, pix);
1190 if Difficulty = 0 then
1191 AddLine(Format(HelpText.Lookup('BUILDCOST'), [SpecialModel[I].Cost]),
1192 pkNormal_64)
1193 else
1194 AddLine(Format(HelpText.Lookup('BUILDCOST'),
1195 [SpecialModel[I].Cost * BuildCostMod[Difficulty] div 12]),
1196 pkNormal_64);
1197 S := HelpText.LookupByHandle(hSPECIALMODEL, I);
1198 if (S <> '') and (S <> '*') then
1199 AddTextual(S);
1200 if SpecialModelPreq[I] >= 0 then
1201 AddPreqAdv(SpecialModelPreq[I])
1202 else if SpecialModelPreq[I] = preLighthouse then
1203 AddPreqImp(woLighthouse)
1204 else if SpecialModelPreq[I] = preBuilder then
1205 AddPreqImp(woPyramids)
1206 else if SpecialModelPreq[I] = preLeo then
1207 AddPreqImp(woLeo);
1208 if SpecialModelPreq[I] <> preNone then
1209 MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
1210 [MainText[Count - 1]]);
1211 end
1212 end;
1213
1214 procedure AddJobList;
1215 var
1216 I, JobCost: Integer;
1217 begin
1218 with MainText do begin
1219 for I := 0 to Length(JobHelp) - 1 do begin
1220 if I > 0 then begin
1221 LineFeed;
1222 LineFeed;
1223 end;
1224 AddLine(Phrases.Lookup('JOBRESULT', JobHelp[I]), pkSection);
1225 AddLine;
1226 AddLine('', pkTerImp, I);
1227 AddLine;
1228 AddTextual(HelpText.LookupByHandle(hJOBHELP, I));
1229 JobCost := -1;
1230 case JobHelp[I] of
1231 jCanal: JobCost := CanalWork;
1232 jFort: JobCost := FortWork;
1233 jBase: JobCost := BaseWork;
1234 end;
1235 if JobCost >= 0 then
1236 AddTextual(Format(HelpText.Lookup('JOBCOST'),
1237 [MovementToString(JobCost)]))
1238 else
1239 AddTextual(HelpText.Lookup('JOBCOSTVAR'));
1240 if JobPreq[JobHelp[I]] <> preNone then begin
1241 AddPreqAdv(JobPreq[JobHelp[I]]);
1242 MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
1243 [MainText[Count - 1]]);
1244 end;
1245 end;
1246 end;
1247 end;
1248
1249 procedure AddGraphicCredits;
1250 var
1251 I: Integer;
1252 S: string;
1253 sr: TSearchRec;
1254 List, Plus: TStringList;
1255 begin
1256 List := TStringList.Create;
1257 Plus := TStringList.Create;
1258 if FindFirst(GetGraphicsDir + DirectorySeparator + '*.credits.txt', $27, sr) = 0 then
1259 repeat
1260 Plus.LoadFromFile(GetGraphicsDir + DirectorySeparator + sr.Name);
1261 List.AddStrings(Plus);
1262 until FindNext(sr) <> 0;
1263 FindClose(sr);
1264 FreeAndNil(Plus);
1265
1266 List.Sort;
1267 I := 1;
1268 while I < List.Count do
1269 if List[I] = List[I - 1] then
1270 List.Delete(I)
1271 else
1272 Inc(I);
1273
1274 for I := 0 to List.Count - 1 do begin
1275 S := List[I];
1276 while BiColorTextWidth(OffScreen.Canvas, S) > InnerWidth - 16 -
1277 DpiGetSystemMetrics(SM_CXVSCROLL) do
1278 Delete(S, Length(S), 1);
1279 MainText.AddLine(S);
1280 end;
1281 FreeAndNil(List);
1282 end;
1283
1284 procedure AddSoundCredits;
1285 var
1286 I: Integer;
1287 S: string;
1288 List: TStringList;
1289 begin
1290 List := TStringList.Create;
1291 List.LoadFromFile(GetSoundsDir + DirectorySeparator + 'sound.credits.txt');
1292 for I := 0 to List.Count - 1 do begin
1293 S := List[I];
1294 while BiColorTextWidth(OffScreen.Canvas, S) > InnerWidth - 16 -
1295 DpiGetSystemMetrics(SM_CXVSCROLL) do
1296 Delete(S, Length(S), 1);
1297 MainText.AddLine(S);
1298 end;
1299 FreeAndNil(List);
1300 end;
1301
1302 procedure NextSection(Item: string);
1303 begin
1304 if MainText.Count > 1 then
1305 if MainText.Count = Headline + 1 then
1306 MainText.Delete(Headline)
1307 else
1308 MainText.LineFeed;
1309 MainText.AddLine(HelpText.Lookup(Item), pkSection);
1310 Headline := MainText.Count - 1;
1311 end;
1312
1313begin { Prepare }
1314 with MainText do begin
1315 OffScreen.Canvas.Font.Assign(UniFont[ftNormal]);
1316 CheckSeeAlso := False;
1317 Clear;
1318 Headline := -1;
1319 if (No >= 200) or not (Kind in [hkAdv, hkImp, hkTer, hkFeature]) then
1320 LineFeed;
1321 case Kind of
1322 hkText:
1323 AddTextual(HelpText.LookupByHandle(No));
1324 hkMisc:
1325 begin
1326 case No of
1327 Integer(miscMain):
1328 begin
1329 Caption := HelpText.Lookup('HELPTITLE_MAIN');
1330 AddLine(HelpText.Lookup('HELPTITLE_QUICKSTART'), pkSpecialIcon,
1331 0, { pkBigIcon,22, } hkText, HelpText.GetHandle('QUICK'));
1332 LineFeed;
1333 AddLine(HelpText.Lookup('HELPTITLE_CONCEPTS'), pkBigIcon, 6,
1334 hkText, HelpText.Gethandle('CONCEPTS'));
1335 LineFeed;
1336 AddLine(HelpText.Lookup('HELPTITLE_TERLIST'), pkSpecialIcon, 1,
1337 hkTer, 200);
1338 LineFeed;
1339 AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkSpecialIcon, 2,
1340 hkMisc, Integer(miscJobList));
1341 LineFeed;
1342 AddLine(HelpText.Lookup('HELPTITLE_TECHLIST'), pkBigIcon, 39,
1343 hkAdv, 200);
1344 LineFeed;
1345 FindStdModelPicture(SpecialModelPictureCode[6], I, S);
1346 AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'), pkModel, I,
1347 hkModel, 0);
1348 LineFeed;
1349 AddLine(HelpText.Lookup('HELPTITLE_FEATURELIST'), pkBigIcon, 28,
1350 hkFeature, 200);
1351 LineFeed;
1352 AddLine(HelpText.Lookup('HELPTITLE_IMPLIST'), pkBigIcon,
1353 7 * SystemIconLines + imCourt, hkImp, 200);
1354 LineFeed;
1355 AddLine(HelpText.Lookup('HELPTITLE_UNIQUELIST'), pkBigIcon,
1356 7 * SystemIconLines + imStockEx, hkImp, 201);
1357 LineFeed;
1358 AddLine(HelpText.Lookup('HELPTITLE_WONDERLIST'), pkBigIcon,
1359 7 * SystemIconLines, hkImp, 202);
1360 LineFeed;
1361 AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'), pkBigIcon,
1362 gDemocracy + 6, hkMisc, Integer(miscGovList));
1363 LineFeed;
1364 AddLine(HelpText.Lookup('HELPTITLE_KEYS'), pkBigIcon, 2, hkText,
1365 HelpText.Gethandle('HOTKEYS'));
1366 LineFeed;
1367 AddLine(HelpText.Lookup('HELPTITLE_ABOUT'), pkBigIcon, 1,
1368 hkText, HelpText.Gethandle('ABOUT'));
1369 LineFeed;
1370 AddLine(HelpText.Lookup('HELPTITLE_CREDITS'), pkBigIcon, 22,
1371 hkMisc, Integer(miscCredits));
1372 end;
1373 Integer(miscCredits):
1374 begin
1375 AddItem('CREDITS');
1376 LineFeed;
1377 AddGraphicCredits;
1378 NextSection('CRED_CAPSOUND');
1379 AddSoundCredits;
1380 NextSection('CRED_CAPAI');
1381 Server(sGetAICredits, 0, 0, ps);
1382 AddTextual(ps);
1383 NextSection('CRED_CAPLANG');
1384 AddItem('AUTHOR');
1385 end;
1386 Integer(miscJobList):
1387 begin
1388 Caption := HelpText.Lookup('HELPTITLE_JOBLIST');
1389 AddJobList;
1390 LineFeed;
1391 AddItem('TERIMPEXCLUDE');
1392 LineFeed;
1393 AddItem('TERIMPCITY');
1394 end;
1395 Integer(miscGovList):
1396 begin
1397 Caption := HelpText.Lookup('HELPTITLE_GOVLIST');
1398 for I := 1 to nGov do
1399 begin
1400 AddLine(Phrases.Lookup('GOVERNMENT', I mod nGov), pkSection);
1401 LineFeed;
1402 if I = nGov then
1403 AddLine('', pkBigIcon, 7 * SystemIconLines + imPalace)
1404 else
1405 AddLine('', pkBigIcon, I + 6);
1406 LineFeed;
1407 AddTextual(HelpText.LookupByHandle(hGOVHELP, I mod nGov));
1408 if I mod nGov >= 2 then
1409 begin
1410 AddPreqAdv(GovPreq[I mod nGov]);
1411 MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
1412 [MainText[Count - 1]]);
1413 end;
1414 if I < nGov then
1415 begin
1416 LineFeed;
1417 LineFeed;
1418 end;
1419 end;
1420 end;
1421 Integer(miscSearchResult):
1422 begin
1423 Caption := HelpText.Lookup('HELPTITLE_SEARCHRESULTS');
1424 AddTextual(Format(HelpText.Lookup('MATCHES'), [SearchContent]));
1425 MainText.AppendList(SearchResult);
1426 end;
1427 end; // case No
1428 end;
1429
1430 hkAdv:
1431 if No = 200 then
1432 begin // complete advance list
1433 Caption := HelpText.Lookup('HELPTITLE_TECHLIST');
1434 List := THyperText.Create;
1435 List.OwnsObjects := True;
1436 for J := 0 to 3 do
1437 begin
1438 if J > 0 then
1439 begin
1440 LineFeed;
1441 LineFeed;
1442 end;
1443 AddLine(HelpText.Lookup('TECHAGE', J), pkSection);
1444 if J = 1 then
1445 AddLine(Phrases.Lookup('ADVANCES', adScience) + ' ' +
1446 HelpText.Lookup('BASETECH'), pkAdvIcon, adScience, hkAdv,
1447 adScience);
1448 if J = 2 then
1449 AddLine(Phrases.Lookup('ADVANCES', adMassProduction) + ' ' +
1450 HelpText.Lookup('BASETECH'), pkAdvIcon, adMassProduction, hkAdv,
1451 adMassProduction);
1452 List.Clear;
1453 for I := 0 to nAdv - 1 do
1454 if (I <> adScience) and (I <> adMassProduction) and
1455 (AdvValue[I] div 1000 = J) then
1456 List.AddLine(Phrases.Lookup('ADVANCES', I), pkAdvIcon, I,
1457 hkAdv, I);
1458 List.Sort;
1459 AppendList(List);
1460 end;
1461 FreeAndNil(List);
1462 end
1463 else // single advance
1464 begin
1465 Caption := Phrases.Lookup('ADVANCES', No);
1466 LineFeed;
1467 AddLine(Phrases.Lookup('ADVANCES', No), pkCaption);
1468 if No in FutureTech then
1469 begin
1470 AddLine(HelpText.Lookup('HELPSPEC_FUTURE'));
1471 LineFeed;
1472 if No = futResearchTechnology then
1473 AddItem('FUTURETECHHELP100')
1474 else
1475 AddItem('FUTURETECHHELP25');
1476 end
1477 else
1478 AddLine(HelpText.Lookup('HELPSPEC_ADV'));
1479 if AdvPreq[No, 2] <> preNone then
1480 NextSection('PREREQALT')
1481 else
1482 NextSection('PREREQ');
1483 for I := 0 to 2 do
1484 if AdvPreq[No, I] <> preNone then
1485 AddPreqAdv(AdvPreq[No, I]);
1486 NextSection('GOVALLOW');
1487 for I := 2 to nGov - 1 do
1488 if GovPreq[I] = No then
1489 AddLine(Phrases.Lookup('GOVERNMENT', I), pkGov, I,
1490 hkMisc, Integer(miscGovList), True);
1491 NextSection('BUILDALLOW');
1492 for I := 0 to nWonder - 1 do
1493 if Imp[I].Preq = No then
1494 AddImprovement(I);
1495 for I := nWonder to nImp - 1 do
1496 if (Imp[I].Preq = No) and (Imp[I].Kind <> ikCommon) then
1497 AddImprovement(I);
1498 for I := nWonder to nImp - 1 do
1499 if (Imp[I].Preq = No) and (Imp[I].Kind = ikCommon) then
1500 AddImprovement(I);
1501 NextSection('MODELALLOW');
1502 for I := 0 to nSpecialModel - 1 do
1503 if SpecialModelPreq[I] = No then
1504 AddModel(I);
1505 NextSection('FEATALLOW');
1506 for I := 0 to nFeature - 1 do
1507 if Feature[I].Preq = No then
1508 AddFeature(I);
1509 NextSection('FOLLOWADV');
1510 for I := 0 to nAdv - 1 do
1511 if (AdvPreq[I, 0] = No) or (AdvPreq[I, 1] = No) or
1512 (AdvPreq[I, 2] = No) then
1513 AddAdvance(I);
1514 NextSection('UPGRADEALLOW');
1515 for Domain := 0 to nDomains - 1 do
1516 for I := 1 to nUpgrade - 1 do
1517 if upgrade[Domain, I].Preq = No then
1518 begin
1519 if upgrade[Domain, I].Strength > 0 then
1520 AddLine(Format(HelpText.Lookup('STRENGTHUP'),
1521 [Phrases.Lookup('DOMAIN', Domain), upgrade[Domain,
1522 I].Strength]), pkDomain, Domain);
1523 if upgrade[Domain, I].Trans > 0 then
1524 AddLine(Format(HelpText.Lookup('TRANSUP'),
1525 [Phrases.Lookup('DOMAIN', Domain), upgrade[Domain, I].Trans]
1526 ), pkDomain, Domain);
1527 if No in FutureTech then
1528 AddLine(Format(HelpText.Lookup('COSTUP'),
1529 [upgrade[Domain, I].Cost]), pkNormal_Dot)
1530 else
1531 AddLine(Format(HelpText.Lookup('COSTMIN'),
1532 [upgrade[Domain, I].Cost]), pkNormal_Dot)
1533 end;
1534 NextSection('EXPIRATION');
1535 for I := 0 to nWonder - 1 do
1536 if (Imp[I].Preq <> preNA) and (Imp[I].Expiration = No) then
1537 AddImprovement(I);
1538 NextSection('ADVEFFECT');
1539 S := HelpText.LookupByHandle(hADVHELP, No);
1540 if S <> '*' then
1541 AddTextual(S);
1542 NextSection('SEEALSO');
1543 CheckSeeAlso := True;
1544 end;
1545
1546 hkImp:
1547 if No = 200 then
1548 begin // complete city improvement list
1549 Caption := HelpText.Lookup('HELPTITLE_IMPLIST');
1550 // AddLine(HelpText.Lookup('HELPTITLE_IMPLIST'),pkSection);
1551 List := THyperText.Create;
1552 List.OwnsObjects := True;
1553 for I := nWonder to nImp - 1 do
1554 if (I <> imTrGoods) and (Imp[I].Preq <> preNA) and
1555 (Imp[I].Kind = ikCommon) then
1556 List.AddLine(Phrases.Lookup('IMPROVEMENTS', I), pkSmallIcon,
1557 I, hkImp, I);
1558 List.Sort;
1559 AppendList(List);
1560 FreeAndNil(List);
1561 end
1562 else if No = 201 then
1563 begin // complete nat. project list
1564 Caption := HelpText.Lookup('HELPTITLE_UNIQUELIST');
1565 // AddLine(HelpText.Lookup('HELPTITLE_UNIQUELIST'),pkSection);
1566 for I := nWonder to nImp - 1 do
1567 if (Imp[I].Preq <> preNA) and
1568 ((Imp[I].Kind = ikNatLocal) or (Imp[I].Kind = ikNatGlobal)) then
1569 AddLine(Phrases.Lookup('IMPROVEMENTS', I), pkSmallIcon, I,
1570 hkImp, I);
1571 { LineFeed;
1572 LineFeed;
1573 AddLine(HelpText.Lookup('HELPTITLE_SHIPPARTLIST'),pkSection);
1574 for I:= nWonder to nImp-1 do
1575 if (Imp[I].Preq<>preNA) and (Imp[I].Kind=ikShipPart) then
1576 AddLine(Phrases.Lookup('IMPROVEMENTS',I),pkSmallIcon,I,hkImp,I); }
1577 end
1578 else if No = 202 then
1579 begin // complete wonder list
1580 Caption := HelpText.Lookup('HELPTITLE_WONDERLIST');
1581 // AddLine(HelpText.Lookup('HELPTITLE_WONDERLIST'),pkSection);
1582 for I := 0 to nWonder - 1 do
1583 if Imp[I].Preq <> preNA then
1584 AddLine(Phrases.Lookup('IMPROVEMENTS', I), pkSmallIcon, I,
1585 hkImp, I);
1586 end
1587 else
1588 begin // single building
1589 Caption := Phrases.Lookup('IMPROVEMENTS', No);
1590 LineFeed;
1591 AddLine(Phrases.Lookup('IMPROVEMENTS', No), pkRightIcon, No);
1592 case Imp[No].Kind of
1593 ikWonder: AddLine(HelpText.Lookup('HELPSPEC_WONDER'));
1594 ikCommon: AddLine(HelpText.Lookup('HELPSPEC_IMP'));
1595 ikShipPart: AddLine(HelpText.Lookup('HELPSPEC_SHIPPART'));
1596 else
1597 AddLine(HelpText.Lookup('HELPSPEC_NAT'))
1598 end;
1599 if Imp[No].Kind <> ikShipPart then begin
1600 NextSection('EFFECT');
1601 AddTextual(HelpText.LookupByHandle(hIMPHELP, No));
1602 end;
1603 if No = woSun then begin
1604 AddFeature(mcFirst);
1605 AddFeature(mcWill);
1606 AddFeature(mcAcademy);
1607 end;
1608 if (No < nWonder) and not Phrases2FallenBackToEnglish then
1609 begin
1610 LineFeed;
1611 if Imp[No].Expiration >= 0 then
1612 AddTextual(Phrases2.Lookup('HELP_WONDERMORALE1'))
1613 else
1614 AddTextual(Phrases2.Lookup('HELP_WONDERMORALE2'));
1615 end;
1616 if Imp[No].Preq <> preNone then
1617 begin
1618 NextSection('PREREQ');
1619 AddPreqAdv(Imp[No].Preq);
1620 end;
1621 NextSection('COSTS');
1622 if Difficulty = 0 then
1623 S := Format(HelpText.Lookup('BUILDCOST'), [Imp[No].Cost])
1624 else
1625 S := Format(HelpText.Lookup('BUILDCOST'),
1626 [Imp[No].Cost * BuildCostMod[Difficulty] div 12]);
1627 AddLine(S);
1628 if Imp[No].Maint > 0 then
1629 AddLine(Format(HelpText.Lookup('MAINTCOST'), [Imp[No].Maint]));
1630 J := 0;
1631 for I := 0 to nImpReplacement - 1 do
1632 if ImpReplacement[I].NewImp = No then
1633 begin
1634 if J = 0 then
1635 begin
1636 NextSection('REPLACE');
1637 AddItem('REPLACETEXT');
1638 J := 1;
1639 end;
1640 AddImprovement(ImpReplacement[I].OldImp);
1641 end;
1642 if Imp[No].Kind = ikShipPart then
1643 begin
1644 LineFeed;
1645 if No = imShipComp then
1646 I := 1
1647 else if No = imShipPow then
1648 I := 2
1649 else { if No=imShipHab then }
1650 I := 3;
1651 AddLine(Format(HelpText.Lookup('RAREREQUIRED'),
1652 [Phrases.Lookup('TERRAIN', 3 * 12 + I)]), pkTer, 3 * 12 + I);
1653 end;
1654 if (No < nWonder) and (Imp[No].Expiration >= 0) then
1655 begin
1656 NextSection('EXPIRATION');
1657 S := Format(HelpText.Lookup('EXPWITH'),
1658 [Phrases.Lookup('ADVANCES', Imp[No].Expiration)]);
1659 if No = woPyramids then
1660 S := S + ' ' + HelpText.Lookup('EXPSLAVE');
1661 AddTextual(S);
1662 end;
1663 NextSection('SEEALSO');
1664 if (No < nWonder) and (Imp[No].Expiration >= 0) then
1665 AddImprovement(woEiffel);
1666 for I := 0 to nImpReplacement - 1 do
1667 if ImpReplacement[I].OldImp = No then
1668 AddImprovement(ImpReplacement[I].NewImp);
1669 if No = imSupermarket then
1670 AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkNormal, 0,
1671 hkMisc, Integer(miscJobList), True);
1672 CheckSeeAlso := True;
1673 end;
1674
1675 hkTer:
1676 if No = 200 then
1677 begin // complete terrain type list
1678 Caption := HelpText.Lookup('HELPTITLE_TERLIST');
1679 // AddLine(HelpText.Lookup('HELPTITLE_TERLIST'),pkSection);
1680 for I := 0 to Length(TerrainHelp) - 1 do
1681 AddTerrain(TerrainHelp[I]);
1682 end
1683 else
1684 begin // sigle terrain type
1685 TerrType := No mod 12;
1686 if TerrType = fJungle then
1687 TerrType := fForest;
1688 TerrSubType := No div 12;
1689 if No = 3 * 12 then
1690 begin
1691 TerrType := fDesert;
1692 TerrSubType := 0;
1693 end;
1694 with Terrain[TerrType] do
1695 begin
1696 Caption := Phrases.Lookup('TERRAIN', No);
1697 LineFeed;
1698 AddLine(Phrases.Lookup('TERRAIN', No), pkBigTer, No);
1699 AddLine(HelpText.Lookup('HELPSPEC_TER'));
1700 LineFeed;
1701 if (ProdRes[TerrSubType] > 0) or (MineEff > 0) then
1702 AddLine(Format(HelpText.Lookup('RESPROD'),
1703 [ProdRes[TerrSubType]]));
1704 if (No < 3 * 12) and (MineEff > 0) then
1705 MainText[Count - 1] := MainText[Count - 1] + ' ' +
1706 Format(HelpText.Lookup('MOREMINE'), [MineEff]);
1707 if (FoodRes[TerrSubType] > 0) or (IrrEff > 0) then
1708 AddLine(Format(HelpText.Lookup('RESFOOD'),
1709 [FoodRes[TerrSubType]]));
1710 if (No < 3 * 12) and (IrrEff > 0) then
1711 MainText[Count - 1] := MainText[Count - 1] + ' ' +
1712 Format(HelpText.Lookup('MOREIRR'), [IrrEff]);
1713 if TradeRes[TerrSubType] > 0 then
1714 AddLine(Format(HelpText.Lookup('RESTRADE'),
1715 [TradeRes[TerrSubType]]));
1716 if Defense > 4 then
1717 AddLine(Format(HelpText.Lookup('DEFBONUS'),
1718 [(Defense - 4) * 25]));
1719 if (TerrType >= fGrass) and (TerrType <> fMountains) then
1720 if MoveCost = 2 then
1721 AddLine(HelpText.Lookup('MOVEHEAVY'))
1722 else
1723 AddLine(HelpText.Lookup('MOVEPLAIN'));
1724 if No = 3 * 12 then
1725 begin
1726 LineFeed;
1727 AddTextual(HelpText.Lookup('DEADLANDS'));
1728 end;
1729 if (TerrType = fDesert) and (No <> fDesert + 12) then
1730 begin
1731 LineFeed;
1732 AddTextual(Format(HelpText.Lookup('HOSTILE'), [DesertThurst]));
1733 end;
1734 if TerrType = fArctic then
1735 begin
1736 LineFeed;
1737 AddTextual(Format(HelpText.Lookup('HOSTILE'), [ArcticThurst]));
1738 end;
1739 if (No < 3 * 12) and (TransTerrain >= 0) then
1740 begin
1741 LineFeed;
1742 I := TransTerrain;
1743 if (TerrType <> fGrass) and (I <> fGrass) then
1744 I := I + TerrSubType * 12;
1745 // trafo to same Special resource group
1746 AddLine(Format(HelpText.Lookup('TRAFO'),
1747 [Phrases.Lookup('TERRAIN', I)]), pkTer, I,
1748 hkTer, I, True);
1749 if No = fSwamp + 12 then
1750 begin
1751 LineFeed;
1752 AddLine(Format(HelpText.Lookup('TRAFO'),
1753 [Phrases.Lookup('TERRAIN', TransTerrain + 24)]), pkTer,
1754 TransTerrain + 24, hkTer, TransTerrain + 24, True);
1755 end
1756 else if I = fGrass then
1757 begin
1758 LineFeed;
1759 AddLine(Format(HelpText.Lookup('TRAFO'),
1760 [Phrases.Lookup('TERRAIN', fGrass + 12)]), pkTer, fGrass + 12,
1761 hkTer, fGrass + 12, True);
1762 end;
1763 end;
1764 NextSection('SPECIAL');
1765 if No = 3 * 12 then
1766 begin
1767 LineFeed;
1768 for Special := 1 to 3 do
1769 begin
1770 if Special > 1 then
1771 LineFeed;
1772 AddLine(Phrases.Lookup('TERRAIN', 3 * 12 + Special), pkTer,
1773 3 * 12 + Special);
1774 end;
1775 end
1776 else if (No < 12) and (No <> fGrass) and (No <> fOcean) then
1777 begin
1778 LineFeed;
1779 for Special := 1 to 2 do
1780 if (No <> fArctic) and (No <> fSwamp) or (Special < 2) then
1781 begin
1782 if Special > 1 then
1783 LineFeed;
1784 AddLine(Phrases.Lookup('TERRAIN', No + Special * 12), pkTer,
1785 No + Special * 12);
1786 I := FoodRes[Special] - FoodRes[0];
1787 if I <> 0 then
1788 MainText[Count - 1] := MainText[Count - 1] +
1789 Format(HelpText.Lookup('SPECIALFOOD'), [I]);
1790 I := ProdRes[Special] - ProdRes[0];
1791 if I <> 0 then
1792 MainText[Count - 1] := MainText[Count - 1] +
1793 Format(HelpText.Lookup('SPECIALPROD'), [I]);
1794 I := TradeRes[Special] - TradeRes[0];
1795 if I <> 0 then
1796 MainText[Count - 1] := MainText[Count - 1] +
1797 Format(HelpText.Lookup('SPECIALTRADE'), [I]);
1798 end;
1799 end;
1800 if No = 3 * 12 then
1801 begin
1802 LineFeed;
1803 AddTextual(HelpText.Lookup('RARE'));
1804 end;
1805 if (No < 3 * 12) and (TerrType in [fDesert, fArctic]) then
1806 begin
1807 NextSection('SEEALSO');
1808 AddImprovement(woGardens);
1809 CheckSeeAlso := True;
1810 end;
1811 end;
1812 end;
1813
1814 hkFeature:
1815 if No = 200 then
1816 begin // complete feature list
1817 Caption := HelpText.Lookup('HELPTITLE_FEATURELIST');
1818 List := THyperText.Create;
1819 List.OwnsObjects := True;
1820 for Special := 0 to 2 do
1821 begin
1822 if Special > 0 then
1823 begin
1824 LineFeed;
1825 LineFeed;
1826 end;
1827 case Special of
1828 0: AddLine(HelpText.Lookup('HELPTITLE_FEATURE1LIST'), pkSection);
1829 1: AddLine(HelpText.Lookup('HELPTITLE_FEATURE2LIST'), pkSection);
1830 2: AddLine(HelpText.Lookup('HELPTITLE_FEATURE3LIST'), pkSection);
1831 end;
1832 List.Clear;
1833 for I := 0 to nFeature - 1 do
1834 if Feature[I].Preq <> preNA then
1835 begin
1836 if I < mcFirstNonCap then
1837 J := 0
1838 else if I in AutoFeature then
1839 J := 2
1840 else
1841 J := 1;
1842 if J = Special then
1843 List.AddLine(Phrases.Lookup('FEATURES', I), pkFeature, I,
1844 hkFeature, I);
1845 end;
1846 List.Sort;
1847 AppendList(List);
1848 end;
1849 FreeAndNil(List);
1850 end
1851 else
1852 begin // single feature
1853 Caption := Phrases.Lookup('FEATURES', No);
1854 LineFeed;
1855 AddLine(Phrases.Lookup('FEATURES', No), pkBigFeature, No);
1856 if No < mcFirstNonCap then
1857 AddLine(HelpText.Lookup('HELPSPEC_CAP'))
1858 else if No in AutoFeature then
1859 AddLine(HelpText.Lookup('HELPSPEC_STANDARD'))
1860 else
1861 AddLine(HelpText.Lookup('HELPSPEC_FEATURE'));
1862 NextSection('EFFECT');
1863 AddTextual(HelpText.LookupByHandle(hFEATUREHELP, No));
1864 if (Feature[No].Weight <> 0) or (Feature[No].Cost <> 0) then
1865 begin
1866 NextSection('COSTS');
1867 S := IntToStr(Feature[No].Cost);
1868 if Feature[No].Cost >= 0 then
1869 S := '+' + S;
1870 AddLine(Format(HelpText.Lookup('COSTBASE'), [S]));
1871 if Feature[No].Weight > 0 then
1872 begin
1873 AddLine(Format(HelpText.Lookup('WEIGHT'),
1874 ['+' + IntToStr(Feature[No].Weight)]));
1875 if No = mcDefense then
1876 AddLine(Format(HelpText.Lookup('WEIGHT'), ['+2']),
1877 pkDomain, dGround);
1878 end;
1879 end;
1880 if Feature[No].Preq <> preNone then
1881 begin
1882 LineFeed;
1883 if Feature[No].Preq = preSun then
1884 AddPreqImp(woSun) // sun tsu feature
1885 else
1886 AddPreqAdv(Feature[No].Preq);
1887 MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
1888 [MainText[Count - 1]]);
1889 end;
1890 NextSection('SEEALSO');
1891 CheckSeeAlso := True;
1892 end;
1893
1894 hkModel:
1895 begin
1896 Caption := HelpText.Lookup('HELPTITLE_MODELLIST');
1897 for I := 0 to nSpecialModel - 1 do
1898 if I <> 2 then
1899 AddModelText(I);
1900 LineFeed;
1901 AddItem('MODELNOTE');
1902 end;
1903
1904 end;
1905 if CheckSeeAlso then
1906 for I := 0 to Length(SeeAlso) - 1 do
1907 if (SeeAlso[I].Kind = Kind) and (SeeAlso[I].No = No) then
1908 case SeeAlso[I].SeeKind of
1909 hkImp: AddImprovement(SeeAlso[I].SeeNo);
1910 hkAdv: AddAdvance(SeeAlso[I].SeeNo);
1911 hkFeature: AddFeature(SeeAlso[I].SeeNo);
1912 end;
1913 if (Headline >= 0) and (Count = Headline + 1) then
1914 Delete(Headline)
1915 else
1916 LineFeed;
1917
1918 //Self.Show;
1919 ScrollBar.Init(Count - 1, InnerHeight div 24);
1920 ScrollBar.SetPos(sbPos);
1921 BackBtn.Visible := HistItems.Count > 1;
1922 TopBtn.Visible := (HistItems.Count > 1) or (Kind <> hkMisc) or (No <> Integer(miscMain));
1923 Sel := -1;
1924 end; // with MainText
1925end;
1926
1927procedure THelpDlg.ShowNewContent(NewMode: TWindowMode; Category: TLinkCategory;
1928 Index: Integer);
1929begin
1930 if (Category <> Kind) or (Index <> No) or (Category = hkMisc) and
1931 (Index = Integer(miscSearchResult)) then begin
1932 if HistItems.Count = MaxHist then HistItems.Delete(0);
1933 if HistItems.Count = 0 then
1934 HistItems.AddNew(Category, Index, ScrollBar.Position, NewSearchContent)
1935 else HistItems.AddNew(Kind, No, ScrollBar.Position, SearchContent);
1936 end;
1937 Kind := Category;
1938 No := Index;
1939 SearchContent := NewSearchContent;
1940 Prepare;
1941 OffscreenPaint;
1942 inherited ShowNewContent(NewMode);
1943end;
1944
1945procedure THelpDlg.PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
1946 X, Y: Integer);
1947var
1948 i0, Sel0: Integer;
1949begin
1950 Y := Y - WideFrame;
1951 i0 := ScrollBar.Position;
1952 Sel0 := Sel;
1953 if (X >= SideFrame) and (X < SideFrame + InnerWidth) and (Y >= 0) and
1954 (Y < InnerHeight) and (Y mod 24 >= 8) then
1955 Sel := Y div 24
1956 else
1957 Sel := -1;
1958 if (Sel + i0 >= MainText.Count) or (Sel >= 0) and
1959 (THelpLineInfo(MainText.Objects[Sel + i0]).Category = hkNoLink) and
1960 (THelpLineInfo(MainText.Objects[Sel + i0]).Index = 0)then
1961 Sel := -1;
1962 if Sel <> Sel0 then
1963 begin
1964 if Sel0 <> -1 then
1965 Line(Canvas, Sel0, False);
1966 if Sel <> -1 then
1967 Line(Canvas, Sel, True);
1968 end;
1969end;
1970
1971procedure THelpDlg.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
1972 Shift: TShiftState; X, Y: Integer);
1973begin
1974 if Sel >= 0 then
1975 with THelpLineInfo(MainText.Objects[Sel + ScrollBar.Position]) do
1976 if Category = hkInternet then
1977 case Index of
1978 1: OpenDocument(HomeDir + AITemplateFileName);
1979 2: OpenURL(CevoHomepage);
1980 3: OpenURL(CevoContact);
1981 end
1982 else
1983 begin
1984 if Index < 0 then Exit; // invalid link;
1985 ShowNewContent(FWindowMode, Category, Index);
1986 end;
1987end;
1988
1989procedure THelpDlg.BackBtnClick(Sender: TObject);
1990var
1991 HistItem: THistItem;
1992begin
1993 if HistItems.Count > 1 then begin
1994 HistItem := THistItem.Create;
1995 HistItem.Assign(HistItems.Last);
1996 HistItems.Delete(HistItems.Count - 1);
1997 if (HistItem.Kind = hkMisc) and (HistItem.No = Integer(miscSearchResult)) and
1998 (HistItem.SearchContent <> SearchContent) then
1999 begin
2000 SearchContent := HistItem.SearchContent;
2001 Search(SearchContent);
2002 end;
2003 Kind := HistItem.Kind;
2004 No := HistItem.No;
2005 Prepare(HistItem.Pos);
2006 OffscreenPaint;
2007 Invalidate;
2008 FreeAndNil(HistItem);
2009 end;
2010end;
2011
2012procedure THelpDlg.TopBtnClick(Sender: TObject);
2013begin
2014 while HistItems.Count > 1 do HistItems.Delete(HistItems.Count - 1);
2015 Kind := hkMisc;
2016 No := Integer(miscMain);
2017 Prepare;
2018 OffscreenPaint;
2019 Invalidate;
2020end;
2021
2022procedure THelpDlg.FormClose(Sender: TObject; var Action: TCloseAction);
2023begin
2024 ExtPic.Height := 0;
2025 inherited;
2026end;
2027
2028function THelpDlg.TextIndex(Item: string): Integer;
2029begin
2030 Result := HelpText.GetHandle(Item);
2031end;
2032
2033procedure THelpDlg.FormKeyDown(Sender: TObject; var Key: Word;
2034 Shift: TShiftState);
2035begin
2036 if KeyToShortCut(Key, Shift) = BHelp.ShortCut then // my key
2037 else
2038 inherited;
2039end;
2040
2041procedure THelpDlg.SearchBtnClick(Sender: TObject);
2042begin
2043 InputDlg.Caption := Phrases.Lookup('SEARCH');
2044 InputDlg.EInput.Text := SearchContent;
2045 InputDlg.CenterToRect(BoundsRect);
2046 InputDlg.ShowModal;
2047 if (InputDlg.ModalResult = mrOK) and (Length(InputDlg.EInput.Text) >= 2) then
2048 begin
2049 Search(InputDlg.EInput.Text);
2050 case SearchResult.Count of
2051 0: begin
2052 Gtk2Fix;
2053 SimpleMessage(Format(HelpText.Lookup('NOMATCHES'),
2054 [InputDlg.EInput.Text]));
2055 end;
2056 1:
2057 with THelpLineInfo(SearchResult.Objects[0]) do
2058 ShowNewContent(FWindowMode, Category, Index);
2059 else begin
2060 NewSearchContent := InputDlg.EInput.Text;
2061 ShowNewContent(FWindowMode, hkMisc, Integer(miscSearchResult));
2062 end;
2063 end;
2064 end;
2065end;
2066
2067procedure THelpDlg.Search(SearchString: string);
2068var
2069 H, I, PrevHandle, PrevIndex, P, RightMargin: Integer;
2070 S: string;
2071 mADVHELP, mIMPHELP, mFEATUREHELP: set of 0..255;
2072 bGOVHELP, bSPECIALMODEL, bJOBHELP: Boolean;
2073begin
2074 SearchResult.Clear;
2075 mADVHELP := [];
2076 mIMPHELP := [];
2077 mFEATUREHELP := [];
2078 bGOVHELP := False;
2079 bSPECIALMODEL := False;
2080 bJOBHELP := False;
2081
2082 // Search in generic reference
2083 SearchString := UpperCase(SearchString);
2084 for I := 0 to 35 + 4 do begin
2085 S := Phrases.Lookup('TERRAIN', I);
2086 if Pos(SearchString, UpperCase(S)) > 0 then
2087 if I < 36 then
2088 SearchResult.AddLine(S + ' ' + HelpText.Lookup('HELPSPEC_TER'),
2089 pkNormal, 0, hkTer, I, True)
2090 else
2091 begin
2092 SearchResult.AddLine(Phrases.Lookup('TERRAIN', 36) + ' ' +
2093 HelpText.Lookup('HELPSPEC_TER'), pkNormal, 0,
2094 hkTer, 36, True);
2095 if I > 36 then
2096 SearchResult.AddLine(Phrases.Lookup('IMPROVEMENTS',
2097 imShipComp + I - 37) + ' ' + HelpText.Lookup('HELPSPEC_SHIPPART'),
2098 pkNormal, 0, hkImp, imShipComp + I - 37, True);
2099 Break;
2100 end;
2101 end;
2102 for I := 0 to Length(JobHelp) - 1 do
2103 if Pos(SearchString, UpperCase(Phrases.Lookup('JOBRESULT', JobHelp[I]))) > 0
2104 then
2105 begin
2106 SearchResult.AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkNormal, 0,
2107 hkMisc, Integer(miscJobList), True);
2108 bJOBHELP := True;
2109 Break;
2110 end;
2111 for I := 0 to nAdv - 1 do
2112 begin
2113 S := Phrases.Lookup('ADVANCES', I);
2114 if Pos(SearchString, UpperCase(S)) > 0 then
2115 begin
2116 if I in FutureTech then
2117 S := S + ' ' + HelpText.Lookup('HELPSPEC_FUTURE')
2118 else
2119 S := S + ' ' + HelpText.Lookup('HELPSPEC_ADV');
2120 SearchResult.AddLine(S, pkNormal, 0, hkAdv, I, True);
2121 Include(mADVHELP, I);
2122 end;
2123 end;
2124 for I := 0 to nSpecialModel - 1 do
2125 begin
2126 FindStdModelPicture(SpecialModelPictureCode[I], H, S);
2127 if Pos(SearchString, UpperCase(S)) > 0 then
2128 begin
2129 SearchResult.AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'), pkNormal, 0,
2130 hkModel, 0, True);
2131 bSPECIALMODEL := True;
2132 Break;
2133 end;
2134 end;
2135 for I := 0 to nFeature - 1 do
2136 begin
2137 S := Phrases.Lookup('FEATURES', I);
2138 if Pos(SearchString, UpperCase(S)) > 0 then
2139 begin
2140 if I < mcFirstNonCap then
2141 S := S + ' ' + HelpText.Lookup('HELPSPEC_CAP')
2142 else if I in AutoFeature then
2143 S := S + ' ' + HelpText.Lookup('HELPSPEC_STANDARD')
2144 else
2145 S := S + ' ' + HelpText.Lookup('HELPSPEC_FEATURE');
2146 SearchResult.AddLine(S, pkNormal, 0, hkFeature, I, True);
2147 Include(mFEATUREHELP, I);
2148 end;
2149 end;
2150 for I := 0 to nImp - 1 do
2151 begin
2152 S := Phrases.Lookup('IMPROVEMENTS', I);
2153 if Pos(SearchString, UpperCase(S)) > 0 then
2154 begin
2155 case Imp[I].Kind of
2156 ikWonder:
2157 S := S + ' ' + HelpText.Lookup('HELPSPEC_WONDER');
2158 ikCommon:
2159 S := S + ' ' + HelpText.Lookup('HELPSPEC_IMP');
2160 ikShipPart:
2161 S := S + ' ' + HelpText.Lookup('HELPSPEC_SHIPPART');
2162 else
2163 S := S + ' ' + HelpText.Lookup('HELPSPEC_NAT')
2164 end;
2165 SearchResult.AddLine(S, pkNormal, 0, hkImp, I, True);
2166 Include(mIMPHELP, I);
2167 end
2168 end;
2169 for I := 0 to nGov - 1 do
2170 if Pos(SearchString, UpperCase(Phrases.Lookup('GOVERNMENT', I))) > 0 then
2171 begin
2172 SearchResult.AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'), pkNormal, 0,
2173 hkMisc, Integer(miscGovList), True);
2174 bGOVHELP := True;
2175 Break;
2176 end;
2177
2178 // Full text search
2179 H := -1;
2180 repeat
2181 PrevHandle := H;
2182 PrevIndex := I;
2183 if not HelpText.Search(SearchString, H, I) then
2184 Break;
2185 if H = hADVHELP then
2186 begin
2187 if (I >= 0) and ((I <> PrevIndex) or (H <> PrevHandle)) and
2188 not(I in mADVHELP) then
2189 begin
2190 S := Phrases.Lookup('ADVANCES', I);
2191 if I in FutureTech then
2192 S := S + ' ' + HelpText.Lookup('HELPSPEC_FUTURE')
2193 else
2194 S := S + ' ' + HelpText.Lookup('HELPSPEC_ADV');
2195 SearchResult.AddLine(S, pkNormal, 0, hkAdv, I, True);
2196 end;
2197 end
2198 else if H = hIMPHELP then
2199 begin
2200 if (I >= 0) and ((I <> PrevIndex) or (H <> PrevHandle)) and
2201 not(I in mIMPHELP) then
2202 begin
2203 S := Phrases.Lookup('IMPROVEMENTS', I);
2204 case Imp[I].Kind of
2205 ikWonder:
2206 S := S + ' ' + HelpText.Lookup('HELPSPEC_WONDER');
2207 ikCommon:
2208 S := S + ' ' + HelpText.Lookup('HELPSPEC_IMP');
2209 ikShipPart:
2210 S := S + ' ' + HelpText.Lookup('HELPSPEC_SHIPPART');
2211 else
2212 S := S + ' ' + HelpText.Lookup('HELPSPEC_NAT')
2213 end;
2214 SearchResult.AddLine(S, pkNormal, 0, hkImp, I, True);
2215 end;
2216 end
2217 else if H = hFEATUREHELP then
2218 begin
2219 if (I >= 0) and ((I <> PrevIndex) or (H <> PrevHandle)) and
2220 not(I in mFEATUREHELP) then
2221 begin
2222 S := Phrases.Lookup('FEATURES', I);
2223 if I < mcFirstNonCap then
2224 S := S + ' ' + HelpText.Lookup('HELPSPEC_CAP')
2225 else if I in AutoFeature then
2226 S := S + ' ' + HelpText.Lookup('HELPSPEC_STANDARD')
2227 else
2228 S := S + ' ' + HelpText.Lookup('HELPSPEC_FEATURE');
2229 SearchResult.AddLine(S, pkNormal, 0, hkFeature, I, True);
2230 end;
2231 end
2232 else if H = hGOVHELP then
2233 begin
2234 if (I >= 0) and (H <> PrevHandle) and not bGOVHELP then
2235 SearchResult.AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'), pkNormal, 0,
2236 hkMisc, Integer(miscGovList), True);
2237 end
2238 else if H = hSPECIALMODEL then
2239 begin
2240 if (I >= 0) and (H <> PrevHandle) and not bSPECIALMODEL then
2241 SearchResult.AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'), pkNormal,
2242 0, hkModel, 0, True);
2243 end
2244 else if H = hJOBHELP then
2245 begin
2246 if (I >= 0) and (H <> PrevHandle) and not bJOBHELP then
2247 SearchResult.AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkNormal, 0,
2248 hkMisc, Integer(miscJobList), True);
2249 end
2250 else if { (h<>hMAIN) and } (H <> PrevHandle) then
2251 begin
2252 S := HelpText.LookupByHandle(H);
2253 P := Pos('$', S);
2254 if P > 0 then
2255 begin
2256 S := Copy(S, P + 1, MaxInt);
2257 P := Pos('\', S);
2258 if P > 0 then
2259 S := Copy(S, 1, P - 1);
2260 SearchResult.AddLine(S, pkNormal, 0, hkText, H, True);
2261 end;
2262 end;
2263 until False;
2264
2265 // Cut lines to fit to window
2266 RightMargin := InnerWidth - 16 - DpiGetSystemMetrics(SM_CXVSCROLL);
2267 OffScreen.Canvas.Font.Assign(UniFont[ftNormal]);
2268 for I := 0 to SearchResult.Count - 1 do
2269 begin
2270 while BiColorTextWidth(OffScreen.Canvas, SearchResult[I]) >
2271 RightMargin - 32 do
2272 SearchResult[I] := Copy(SearchResult[I], 1, Length(SearchResult[I]) - 1)
2273 end;
2274end;
2275
2276end.
Note: See TracBrowser for help on using the repository browser.