source: tags/1.3.8/LocalPlayer/Help.pas

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