source: trunk/LocalPlayer/Help.pas

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