source: trunk/LocalPlayer/Help.pas@ 350

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