Ignore:
Timestamp:
Jan 7, 2017, 11:32:14 AM (8 years ago)
Author:
chronos
Message:
  • Modified: Formated all project source files using Delphi formatter as original indentation and other formatting was really bad.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LocalPlayer/Help.pas

    r2 r6  
    11{$INCLUDE switches}
    2 
    32unit Help;
    43
     
    65
    76uses
    8   Protocol,ScreenTools,BaseWin,StringTables,
     7  Protocol, ScreenTools, BaseWin, StringTables,
    98
    109  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
     
    1211
    1312const
    14 MaxHist=16;
    15 
    16 {link categories}
    17 hkNoLink=0;hkAdv=1;hkImp=2;hkTer=3;hkFeature=4;hkInternet=5;hkModel=6;hkMisc=7;
    18 hkCrossLink=$40;
    19 hkText=$80;
    20 
    21 liInvalid=$3FFF; // link index indicates invalid link
    22 
    23 {link indices for category hkMisc}
    24 miscMain=0; miscCredits=1; miscGovList=2; miscJobList=3; miscSearchResult=7;
    25 
    26 fJungle=8; // pseudo terrain
    27 
     13  MaxHist = 16;
     14
     15  { link categories }
     16  hkNoLink = 0;
     17  hkAdv = 1;
     18  hkImp = 2;
     19  hkTer = 3;
     20  hkFeature = 4;
     21  hkInternet = 5;
     22  hkModel = 6;
     23  hkMisc = 7;
     24  hkCrossLink = $40;
     25  hkText = $80;
     26
     27  liInvalid = $3FFF; // link index indicates invalid link
     28
     29  { link indices for category hkMisc }
     30  miscMain = 0;
     31  miscCredits = 1;
     32  miscGovList = 2;
     33  miscJobList = 3;
     34  miscSearchResult = 7;
     35
     36  fJungle = 8; // pseudo terrain
    2837
    2938type
    30   THyperText=class(TStringList)
    31     procedure AddLine(s: String =''; Format: integer =0; Picpix: integer =0;
    32       LinkCategory: integer =0; LinkIndex: integer =0);
     39  THyperText = class(TStringList)
     40    procedure AddLine(s: String = ''; Format: integer = 0; Picpix: integer = 0;
     41      LinkCategory: integer = 0; LinkIndex: integer = 0);
    3342    procedure LF;
    34     end;
     43  end;
    3544
    3645  THelpDlg = class(TFramedDlg)
     
    3948    TopBtn: TButtonB;
    4049    SearchBtn: TButtonB;
    41     procedure FormCreate(Sender:TObject);
    42     procedure FormDestroy(Sender:TObject);
    43     procedure FormPaint(Sender:TObject);
    44     procedure CloseBtnClick(Sender:TObject);
    45     procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; x,
    46       y: integer);
     50    procedure FormCreate(Sender: TObject);
     51    procedure FormDestroy(Sender: TObject);
     52    procedure FormPaint(Sender: TObject);
     53    procedure CloseBtnClick(Sender: TObject);
     54    procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState;
     55      x, y: integer);
    4756    procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
    4857      Shift: TShiftState; x, y: integer);
     
    5059    procedure TopBtnClick(Sender: TObject);
    5160    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    52     procedure FormKeyDown(Sender: TObject; var Key: Word;
    53       Shift: TShiftState);
     61    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    5462    procedure SearchBtnClick(Sender: TObject);
    5563  public
    5664    Difficulty: integer;
    57     procedure ShowNewContent(NewMode,Category,Index: integer);
     65    procedure ShowNewContent(NewMode, Category, Index: integer);
    5866    procedure ClearHistory;
    5967    function TextIndex(Item: string): integer;
     
    6169    procedure OffscreenPaint; override;
    6270  private
    63     Kind,no,Sel,nHist,CaptionColor: integer;
    64     hADVHELP, hIMPHELP, hFEATUREHELP, hGOVHELP, hSPECIALMODEL, hJOBHELP: integer;
     71    Kind, no, Sel, nHist, CaptionColor: integer;
     72    hADVHELP, hIMPHELP, hFEATUREHELP, hGOVHELP, hSPECIALMODEL,
     73      hJOBHELP: integer;
    6574    SearchContent, NewSearchContent: string;
    6675    CaptionFont: TFont;
    6776    MainText, SearchResult: THyperText;
    6877    HelpText: TStringTable;
    69     ExtPic,TerrIcon: TBitmap;
    70     sb:TPVScrollbar;
    71     x0: array[-2..18] of integer;
    72     HistKind: array[0..MaxHist-1] of integer;
    73     HistNo: array[0..MaxHist-1] of integer;
    74     HistPos: array[0..MaxHist-1] of integer;
    75     HistSearchContent: array[0..MaxHist-1] of shortstring;
     78    ExtPic, TerrIcon: TBitmap;
     79    sb: TPVScrollbar;
     80    x0: array [-2 .. 18] of integer;
     81    HistKind: array [0 .. MaxHist - 1] of integer;
     82    HistNo: array [0 .. MaxHist - 1] of integer;
     83    HistPos: array [0 .. MaxHist - 1] of integer;
     84    HistSearchContent: array [0 .. MaxHist - 1] of shortstring;
    7685    procedure line(ca: TCanvas; i: integer; lit: boolean);
    7786    procedure Prepare(sbPos: integer = 0);
    78     procedure WaterSign(x0,y0,iix: integer);
     87    procedure WaterSign(x0, y0, iix: integer);
    7988    procedure Search(SearchString: string);
    80     procedure OnScroll(var m:TMessage); message WM_VSCROLL;
    81     procedure OnMouseWheel(var m:TMessage); message WM_MOUSEWHEEL;
    82     procedure OnMouseLeave(var Msg:TMessage); message CM_MOUSELEAVE;
     89    procedure OnScroll(var m: TMessage); message WM_VSCROLL;
     90    procedure OnMouseWheel(var m: TMessage); message WM_MOUSEWHEEL;
     91    procedure OnMouseLeave(var Msg: TMessage); message CM_MOUSELEAVE;
    8392  end;
    8493
     
    8998
    9099uses
    91 Directories,ClientTools,Term,Tribes,ShellAPI, Inp,Messg;
     100  Directories, ClientTools, Term, Tribes, ShellAPI, Inp, Messg;
    92101
    93102{$R *.DFM}
    94103
    95104type
    96 THelpLineInfo=packed record
    97   Format, Picpix: Byte;
    98   Link: Word;
     105  THelpLineInfo = packed record
     106    Format, Picpix: Byte;
     107    Link: Word;
    99108  end;
    100109
     
    102111  LinkCategory: integer; LinkIndex: integer);
    103112var
    104 HelpLineInfo: THelpLineInfo;
     113  HelpLineInfo: THelpLineInfo;
    105114begin
    106 if LinkIndex<0 then LinkIndex:=liInvalid;
    107 HelpLineInfo.Format:=Format;
    108 HelpLineInfo.Picpix:=Picpix;
    109 HelpLineInfo.Link:=LinkCategory shl 8+LinkIndex;
    110 AddObject(s,TObject(HelpLineInfo));
     115  if LinkIndex < 0 then
     116    LinkIndex := liInvalid;
     117  HelpLineInfo.Format := Format;
     118  HelpLineInfo.Picpix := Picpix;
     119  HelpLineInfo.Link := LinkCategory shl 8 + LinkIndex;
     120  AddObject(s, TObject(HelpLineInfo));
    111121end;
    112122
    113123procedure THyperText.LF;
    114124begin
    115 AddLine;
     125  AddLine;
    116126end;
    117127
    118 
    119128const
    120 {text formats}
    121 pkNormal=0;pkCaption=1;pkSmallIcon=2;pkBigIcon=3;pkAdvIcon=4;pkTer=5;
    122 pkBigTer=6;pkFeature=7;pkDot=8;pkNormal_Dot=9;pkDomain=10;pkSection=11;
    123 pkBigFeature=12;pkExp=13;pkAITStat=14;pkExternal=15;pkModel=16;pkNormal_64=17;
    124 pkIllu=18;pkLogo=19;pkTerImp=20;pkRightIcon=21;pkAdvIcon_AsPreq=22;
    125 pkSmallIcon_AsPreq=23;pkSpecialIcon=24;pkGov=25;
    126 
    127 nSeeAlso=14;
    128 SeeAlso: array[0..nSeeAlso-1] of record Kind,no,SeeKind,SeeNo: integer end=
    129 ((Kind:hkImp;no:imWalls;SeeKind:hkFeature;SeeNo:mcArtillery),
    130 (Kind:hkImp;no:imHydro;SeeKind:hkImp;SeeNo:woHoover),
    131 (Kind:hkImp;no:imWalls;SeeKind:hkImp;SeeNo:imGrWall),
    132 (Kind:hkImp;no:imHighways;SeeKind:hkAdv;SeeNo:adWheel),
    133 (Kind:hkImp;no:imCathedral;SeeKind:hkImp;SeeNo:woBach),
    134 (Kind:hkImp;no:imBank;SeeKind:hkImp;SeeNo:imStockEx),
    135 (Kind:hkImp;no:imShipComp;SeeKind:hkImp;SeeNo:imSpacePort),
    136 (Kind:hkImp;no:imShipPow;SeeKind:hkImp;SeeNo:imSpacePort),
    137 (Kind:hkImp;no:imShipHab;SeeKind:hkImp;SeeNo:imSpacePort),
    138 (Kind:hkFeature;no:mcSub;SeeKind:hkFeature;SeeNo:mcRadar),
    139 (Kind:hkFeature;no:mcDefense;SeeKind:hkAdv;SeeNo:adSteel),
    140 (Kind:hkFeature;no:mcSE;SeeKind:hkFeature;SeeNo:mcNP),
    141 (Kind:hkAdv;no:adWheel;SeeKind:hkImp;SeeNo:imHighways),
    142 (Kind:hkAdv;no:adSteel;SeeKind:hkFeature;SeeNo:mcDefense));
    143 
    144 nTerrainHelp=14;
    145 TerrainHelp: array[0..nTerrainHelp-1] of integer=
    146 (fGrass,fGrass+12,fPrairie,fForest,fJungle,fHills,fMountains,fSwamp,fTundra,fArctic,
    147 fDesert,3*12{DeadLands},fShore,fOcean);
    148 
    149 nJobHelp=8;
    150 JobHelp: array[0..nJobHelp-1] of integer=
    151   (jRoad,jRR,jCanal,jIrr,jFarm,jMine,jFort,jBase);
    152 
    153 
    154 procedure THelpDlg.FormCreate(Sender:TObject);
     129  { text formats }
     130  pkNormal = 0;
     131  pkCaption = 1;
     132  pkSmallIcon = 2;
     133  pkBigIcon = 3;
     134  pkAdvIcon = 4;
     135  pkTer = 5;
     136  pkBigTer = 6;
     137  pkFeature = 7;
     138  pkDot = 8;
     139  pkNormal_Dot = 9;
     140  pkDomain = 10;
     141  pkSection = 11;
     142  pkBigFeature = 12;
     143  pkExp = 13;
     144  pkAITStat = 14;
     145  pkExternal = 15;
     146  pkModel = 16;
     147  pkNormal_64 = 17;
     148  pkIllu = 18;
     149  pkLogo = 19;
     150  pkTerImp = 20;
     151  pkRightIcon = 21;
     152  pkAdvIcon_AsPreq = 22;
     153  pkSmallIcon_AsPreq = 23;
     154  pkSpecialIcon = 24;
     155  pkGov = 25;
     156
     157  nSeeAlso = 14;
     158  SeeAlso: array [0 .. nSeeAlso - 1] of record Kind, no, SeeKind,
     159    SeeNo: integer end = ((Kind: hkImp; no: imWalls; SeeKind: hkFeature;
     160    SeeNo: mcArtillery), (Kind: hkImp; no: imHydro; SeeKind: hkImp;
     161    SeeNo: woHoover), (Kind: hkImp; no: imWalls; SeeKind: hkImp;
     162    SeeNo: imGrWall), (Kind: hkImp; no: imHighways; SeeKind: hkAdv;
     163    SeeNo: adWheel), (Kind: hkImp; no: imCathedral; SeeKind: hkImp;
     164    SeeNo: woBach), (Kind: hkImp; no: imBank; SeeKind: hkImp; SeeNo: imStockEx),
     165    (Kind: hkImp; no: imShipComp; SeeKind: hkImp; SeeNo: imSpacePort),
     166    (Kind: hkImp; no: imShipPow; SeeKind: hkImp; SeeNo: imSpacePort),
     167    (Kind: hkImp; no: imShipHab; SeeKind: hkImp; SeeNo: imSpacePort),
     168    (Kind: hkFeature; no: mcSub; SeeKind: hkFeature; SeeNo: mcRadar),
     169    (Kind: hkFeature; no: mcDefense; SeeKind: hkAdv; SeeNo: adSteel),
     170    (Kind: hkFeature; no: mcSE; SeeKind: hkFeature; SeeNo: mcNP), (Kind: hkAdv;
     171    no: adWheel; SeeKind: hkImp; SeeNo: imHighways), (Kind: hkAdv; no: adSteel;
     172    SeeKind: hkFeature; SeeNo: mcDefense));
     173
     174  nTerrainHelp = 14;
     175  TerrainHelp: array [0 .. nTerrainHelp - 1] of integer = (fGrass, fGrass + 12,
     176    fPrairie, fForest, fJungle, fHills, fMountains, fSwamp, fTundra, fArctic,
     177    fDesert, 3 * 12 { DeadLands } , fShore, fOcean);
     178
     179  nJobHelp = 8;
     180  JobHelp: array [0 .. nJobHelp - 1] of integer = (jRoad, jRR, jCanal, jIrr,
     181    jFarm, jMine, jFort, jBase);
     182
     183procedure THelpDlg.FormCreate(Sender: TObject);
    155184begin
    156 inherited;
    157 CaptionLeft:=BackBtn.Left+BackBtn.Width;
    158 CaptionRight:=SearchBtn.Left;
    159 inc(ModalFrameIndent,29);
    160 MainText:=THyperText.Create;
    161 SearchResult:=THyperText.Create;
    162 CreatePVSB(sb,Handle,36,551,36+432);
    163 
    164 HelpText:=TStringTable.Create;
    165 HelpText.LoadFromFile(LocalizedFilePath('Help\help.txt'));
    166 hADVHELP:=HelpText.Gethandle('ADVHELP');
    167 hIMPHELP:=HelpText.Gethandle('IMPHELP');
    168 hFEATUREHELP:=HelpText.Gethandle('FEATUREHELP');
    169 hGOVHELP:=HelpText.Gethandle('GOVHELP');
    170 hSPECIALMODEL:=HelpText.Gethandle('SPECIALMODEL');
    171 hJOBHELP:=HelpText.Gethandle('JOBHELP');
    172 
    173 CaptionFont:=Font.Create;
    174 CaptionFont.Assign(UniFont[ftNormal]);
    175 CaptionFont.Style:=CaptionFont.Style+[fsItalic,fsBold];
    176 InitButtons();
    177 
    178 TopBtn.Hint:=Phrases.Lookup('BTN_CONTENTS');
    179 BackBtn.Hint:=Phrases.Lookup('BTN_BACK');
    180 SearchBtn.Hint:=Phrases.Lookup('BTN_SEARCH');
    181 
    182 ExtPic:=TBitmap.Create;
    183 TerrIcon:=TBitmap.Create;
    184 TerrIcon.PixelFormat:=pf24bit;
    185 TerrIcon.Width:=xSizeBig; TerrIcon.Height:=ySizeBig;
    186 SearchContent:='';
    187 nHist:=-1;
     185  inherited;
     186  CaptionLeft := BackBtn.Left + BackBtn.Width;
     187  CaptionRight := SearchBtn.Left;
     188  inc(ModalFrameIndent, 29);
     189  MainText := THyperText.Create;
     190  SearchResult := THyperText.Create;
     191  CreatePVSB(sb, Handle, 36, 551, 36 + 432);
     192
     193  HelpText := TStringTable.Create;
     194  HelpText.LoadFromFile(LocalizedFilePath('Help\help.txt'));
     195  hADVHELP := HelpText.Gethandle('ADVHELP');
     196  hIMPHELP := HelpText.Gethandle('IMPHELP');
     197  hFEATUREHELP := HelpText.Gethandle('FEATUREHELP');
     198  hGOVHELP := HelpText.Gethandle('GOVHELP');
     199  hSPECIALMODEL := HelpText.Gethandle('SPECIALMODEL');
     200  hJOBHELP := HelpText.Gethandle('JOBHELP');
     201
     202  CaptionFont := Font.Create;
     203  CaptionFont.Assign(UniFont[ftNormal]);
     204  CaptionFont.Style := CaptionFont.Style + [fsItalic, fsBold];
     205  InitButtons();
     206
     207  TopBtn.Hint := Phrases.Lookup('BTN_CONTENTS');
     208  BackBtn.Hint := Phrases.Lookup('BTN_BACK');
     209  SearchBtn.Hint := Phrases.Lookup('BTN_SEARCH');
     210
     211  ExtPic := TBitmap.Create;
     212  TerrIcon := TBitmap.Create;
     213  TerrIcon.PixelFormat := pf24bit;
     214  TerrIcon.Width := xSizeBig;
     215  TerrIcon.Height := ySizeBig;
     216  SearchContent := '';
     217  nHist := -1;
    188218end;
    189219
    190220procedure THelpDlg.ClearHistory;
    191221begin
    192 nHist:=-1;
     222  nHist := -1;
    193223end;
    194224
    195 procedure THelpDlg.FormDestroy(Sender:TObject);
     225procedure THelpDlg.FormDestroy(Sender: TObject);
    196226begin
    197 MainText.Free;
    198 SearchResult.Free;
    199 ExtPic.Free;
    200 TerrIcon.Free;
    201 HelpText.Free;
    202 //CaptionFont.Free;
     227  MainText.Free;
     228  SearchResult.Free;
     229  ExtPic.Free;
     230  TerrIcon.Free;
     231  HelpText.Free;
     232  // CaptionFont.Free;
    203233end;
    204234
    205 procedure THelpDlg.CloseBtnClick(Sender:TObject);
     235procedure THelpDlg.CloseBtnClick(Sender: TObject);
    206236begin
    207 Close
     237  Close
    208238end;
    209239
    210 procedure THelpDlg.OnScroll(var m:TMessage);
     240procedure THelpDlg.OnScroll(var m: TMessage);
    211241begin
    212 if ProcessPVSB(sb,m) then
    213   begin Sel:=-1; SmartUpdateContent(true) end
    214 end;
    215 
    216 procedure THelpDlg.OnMouseWheel(var m:TMessage);
    217 begin
    218 if ProcessMouseWheel(sb,m) then
    219   begin
    220   Sel:=-1;
    221   SmartUpdateContent(true);
    222   PaintBox1MouseMove(nil, [], m.lParam and $FFFF-Left, m.lParam shr 16-Top);
     242  if ProcessPVSB(sb, m) then
     243  begin
     244    Sel := -1;
     245    SmartUpdateContent(true)
    223246  end
    224247end;
    225248
    226 procedure THelpDlg.OnMouseLeave(var Msg:TMessage);
     249procedure THelpDlg.OnMouseWheel(var m: TMessage);
    227250begin
    228 if Sel<>-1 then
    229   begin
    230   line(Canvas,Sel,false);
    231   Sel:=-1
     251  if ProcessMouseWheel(sb, m) then
     252  begin
     253    Sel := -1;
     254    SmartUpdateContent(true);
     255    PaintBox1MouseMove(nil, [], m.lParam and $FFFF - Left,
     256      m.lParam shr 16 - Top);
    232257  end
    233258end;
    234259
    235 procedure THelpDlg.FormPaint(Sender:TObject);
     260procedure THelpDlg.OnMouseLeave(var Msg: TMessage);
    236261begin
    237 inherited;
    238 Canvas.Font.Assign(UniFont[ftNormal]);
     262  if Sel <> -1 then
     263  begin
     264    line(Canvas, Sel, false);
     265    Sel := -1
     266  end
     267end;
     268
     269procedure THelpDlg.FormPaint(Sender: TObject);
     270begin
     271  inherited;
     272  Canvas.Font.Assign(UniFont[ftNormal]);
    239273end;
    240274
    241275procedure THelpDlg.line(ca: TCanvas; i: integer; lit: boolean);
    242276var
    243 TextColor,x,y: integer;
    244 TextSize: TSize;
    245 s: string;
     277  TextColor, x, y: integer;
     278  TextSize: TSize;
     279  s: string;
    246280begin
    247 s:=MainText[sb.si.npos+i];
    248 if s='' then exit;
    249 x:=x0[i]; y:=2+i*24;
    250 if ca=Canvas then
    251   begin x:=x+SideFrame; y:=y+WideFrame end;
    252 if THelpLineInfo(MainText.Objects[sb.si.npos+i]).Format
    253   in [pkCaption,pkBigTer,pkRightIcon,pkBigFeature] then
    254   begin
    255   ca.Font.Assign(CaptionFont);
    256 {  ca.brush.color:=CaptionColor;
    257   ca.FillRect(rect(x,i*24,x+24,i*24+24));
    258   ca.brush.color:=$FFFFFF;
    259   ca.FrameRect(rect(x+1,i*24+1,x+24-1,i*24+24-1));
    260   ca.Brush.Style:=bsClear;}
    261   BitBlt(ca.handle,x,y-4,24,24,GrExt[HGrSystem].Data.Canvas.Handle,1,146,SRCCOPY);
    262   BiColorTextOut(ca,$FFFFFF,$7F007F,x+10-ca.Textwidth(s[1]) div 2,y-3,s[1]);
    263   BiColorTextOut(ca,CaptionColor,$7F007F,x+24,y-3,copy(s,2,255));
    264   ca.Font.Assign(UniFont[ftNormal]);
    265   end
    266 else if THelpLineInfo(MainText.Objects[sb.si.npos+i]).Format=pkSection then
    267   begin
    268   ca.Font.Assign(CaptionFont);
    269   BiColorTextOut(ca,CaptionColor,$7F007F,x,y-3,s);
    270   ca.Font.Assign(UniFont[ftNormal]);
    271   end
    272 else
    273   begin
    274   if (Kind=hkMisc) and (no=miscMain) then
     281  s := MainText[sb.si.npos + i];
     282  if s = '' then
     283    exit;
     284  x := x0[i];
     285  y := 2 + i * 24;
     286  if ca = Canvas then
     287  begin
     288    x := x + SideFrame;
     289    y := y + WideFrame
     290  end;
     291  if THelpLineInfo(MainText.Objects[sb.si.npos + i]).Format
     292    in [pkCaption, pkBigTer, pkRightIcon, pkBigFeature] then
     293  begin
    275294    ca.Font.Assign(CaptionFont);
    276   TextColor:=Colors.Canvas.Pixels[clkMisc,cliPaperText];
    277   if ca=Canvas then
    278     begin
    279     TextSize.cx:=BiColorTextWidth(ca,s);
    280     TextSize.cy:=ca.TextHeight(s);
    281     if y+TextSize.cy>=WideFrame+InnerHeight then
    282       TextSize.cy:=WideFrame+InnerHeight-y;
    283     FillSeamless(ca,x,y,TextSize.cx,TextSize.cy,-SideFrame,sb.si.npos*24-WideFrame,
    284       Paper);
    285     end;
    286   BiColorTextOut(ca,TextColor,$7F007F,x,y,s);
    287   if lit then with ca do
    288     begin
    289     assert(ca=Canvas);
    290     pen.color:=TextColor;
    291     moveto(x+1,y+TextSize.cy-2);
    292     lineto(x+TextSize.cx,y+TextSize.cy-2);
    293     end;
    294   if (Kind=hkMisc) and (no=miscMain) then
     295    { ca.brush.color:=CaptionColor;
     296      ca.FillRect(rect(x,i*24,x+24,i*24+24));
     297      ca.brush.color:=$FFFFFF;
     298      ca.FrameRect(rect(x+1,i*24+1,x+24-1,i*24+24-1));
     299      ca.Brush.Style:=bsClear; }
     300    BitBlt(ca.Handle, x, y - 4, 24, 24, GrExt[HGrSystem].Data.Canvas.Handle, 1,
     301      146, SRCCOPY);
     302    BiColorTextOut(ca, $FFFFFF, $7F007F, x + 10 - ca.Textwidth(s[1]) div 2,
     303      y - 3, s[1]);
     304    BiColorTextOut(ca, CaptionColor, $7F007F, x + 24, y - 3, copy(s, 2, 255));
    295305    ca.Font.Assign(UniFont[ftNormal]);
    296306  end
     307  else if THelpLineInfo(MainText.Objects[sb.si.npos + i]).Format = pkSection
     308  then
     309  begin
     310    ca.Font.Assign(CaptionFont);
     311    BiColorTextOut(ca, CaptionColor, $7F007F, x, y - 3, s);
     312    ca.Font.Assign(UniFont[ftNormal]);
     313  end
     314  else
     315  begin
     316    if (Kind = hkMisc) and (no = miscMain) then
     317      ca.Font.Assign(CaptionFont);
     318    TextColor := Colors.Canvas.Pixels[clkMisc, cliPaperText];
     319    if ca = Canvas then
     320    begin
     321      TextSize.cx := BiColorTextWidth(ca, s);
     322      TextSize.cy := ca.TextHeight(s);
     323      if y + TextSize.cy >= WideFrame + InnerHeight then
     324        TextSize.cy := WideFrame + InnerHeight - y;
     325      FillSeamless(ca, x, y, TextSize.cx, TextSize.cy, -SideFrame,
     326        sb.si.npos * 24 - WideFrame, Paper);
     327    end;
     328    BiColorTextOut(ca, TextColor, $7F007F, x, y, s);
     329    if lit then
     330      with ca do
     331      begin
     332        assert(ca = Canvas);
     333        pen.color := TextColor;
     334        moveto(x + 1, y + TextSize.cy - 2);
     335        lineto(x + TextSize.cx, y + TextSize.cy - 2);
     336      end;
     337    if (Kind = hkMisc) and (no = miscMain) then
     338      ca.Font.Assign(UniFont[ftNormal]);
     339  end
    297340end;
    298341
    299 procedure THelpDlg.WaterSign(x0,y0,iix: integer);
     342procedure THelpDlg.WaterSign(x0, y0, iix: integer);
    300343const
    301 nHeaven=28;
    302 maxsum=9*9*255 *75 div 100;
     344  nHeaven = 28;
     345  maxsum = 9 * 9 * 255 * 75 div 100;
    303346type
    304 TLine=array[0..649,0..2] of Byte;
     347  TLine = array [0 .. 649, 0 .. 2] of Byte;
    305348var
    306 x,y,dx,dy,xSrc,ySrc,sum,xx: integer;
    307 Heaven: array[0..nHeaven] of integer;
    308 PaintLine,CoalLine: ^TLine;
    309 ImpLine: array[-1..1] of ^TLine;
     349  x, y, dx, dy, xSrc, ySrc, sum, xx: integer;
     350  Heaven: array [0 .. nHeaven] of integer;
     351  PaintLine, CoalLine: ^TLine;
     352  ImpLine: array [-1 .. 1] of ^TLine;
    310353begin
    311 // assume eiffel tower has free common heaven
    312 for dy:=0 to nHeaven-1 do
    313   Heaven[dy]:=BigImp.Canvas.Pixels[woEiffel mod 7 *xSizeBig,
    314     (SystemIconLines+woEiffel div 7)*ySizeBig+dy];
    315 
    316 xSrc:=iix mod 7 *xSizeBig;
    317 ySrc:=(iix div 7+1) *ySizeBig;
    318 for y:=0 to ySizeBig*2-1 do if (y0+y>=0) and (y0+y<InnerHeight) then
    319   begin
    320   PaintLine:=OffScreen.ScanLine[y0+y];
    321   CoalLine:=Templates.ScanLine[yCoal+y];
    322   for dy:=-1 to 1 do
    323     if ((y+dy) shr 1>=0) and ((y+dy) shr 1<ySizeBig) then
    324       ImpLine[dy]:=BigImp.ScanLine[ySrc+(y+dy) shr 1];
    325   for x:=0 to xSizeBig*2-1 do
    326     begin
    327     sum:=0;
    328     for dx:=-1 to 1 do
     354  // assume eiffel tower has free common heaven
     355  for dy := 0 to nHeaven - 1 do
     356    Heaven[dy] := BigImp.Canvas.Pixels[woEiffel mod 7 * xSizeBig,
     357      (SystemIconLines + woEiffel div 7) * ySizeBig + dy];
     358
     359  xSrc := iix mod 7 * xSizeBig;
     360  ySrc := (iix div 7 + 1) * ySizeBig;
     361  for y := 0 to ySizeBig * 2 - 1 do
     362    if (y0 + y >= 0) and (y0 + y < InnerHeight) then
     363    begin
     364      PaintLine := OffScreen.ScanLine[y0 + y];
     365      CoalLine := Templates.ScanLine[yCoal + y];
     366      for dy := -1 to 1 do
     367        if ((y + dy) shr 1 >= 0) and ((y + dy) shr 1 < ySizeBig) then
     368          ImpLine[dy] := BigImp.ScanLine[ySrc + (y + dy) shr 1];
     369      for x := 0 to xSizeBig * 2 - 1 do
    329370      begin
    330       xx:=xSrc+(x+dx) shr 1;
    331       for dy:=-1 to 1 do
    332         if ((y+dy) shr 1<0) or ((y+dy) shr 1>=ySizeBig)
    333           or ((x+dx) shr 1<0) or ((x+dx) shr 1>=xSizeBig)
    334           or ((y+dy) shr 1<nHeaven)
    335           and (ImpLine[dy,xx,0] shl 16+ImpLine[dy,xx,1] shl 8+ImpLine[dy,xx,2]=Heaven[(y+dy) shr 1]) then
    336           sum:=sum+9*255
    337         else sum:=sum+ImpLine[dy,xx,0]+5*ImpLine[dy,xx,1]+3*ImpLine[dy,xx,2];
     371        sum := 0;
     372        for dx := -1 to 1 do
     373        begin
     374          xx := xSrc + (x + dx) shr 1;
     375          for dy := -1 to 1 do
     376            if ((y + dy) shr 1 < 0) or ((y + dy) shr 1 >= ySizeBig) or
     377              ((x + dx) shr 1 < 0) or ((x + dx) shr 1 >= xSizeBig) or
     378              ((y + dy) shr 1 < nHeaven) and
     379              (ImpLine[dy, xx, 0] shl 16 + ImpLine[dy, xx, 1] shl 8 +
     380              ImpLine[dy, xx, 2] = Heaven[(y + dy) shr 1]) then
     381              sum := sum + 9 * 255
     382            else
     383              sum := sum + ImpLine[dy, xx, 0] + 5 * ImpLine[dy, xx, 1] + 3 *
     384                ImpLine[dy, xx, 2];
     385        end;
     386        if sum < maxsum then
     387        begin // no saturation
     388          sum := 1 shl 22 - (maxsum - sum) * (256 - CoalLine[xCoal + x, 0] * 2);
     389          PaintLine[x0 + x, 0] := PaintLine[x0 + x, 0] * sum shr 22;
     390          PaintLine[x0 + x, 1] := PaintLine[x0 + x, 1] * sum shr 22;
     391          PaintLine[x0 + x, 2] := PaintLine[x0 + x, 2] * sum shr 22;
     392        end
     393      end
     394    end;
     395end;
     396
     397procedure THelpDlg.OffscreenPaint;
     398
     399  procedure PaintTerrIcon(x, y, xSrc, ySrc: integer);
     400  begin
     401    Frame(OffScreen.Canvas, x - 1, y - 1, x + xSizeBig, y + ySizeBig,
     402      $000000, $000000);
     403    if 2 * yyt < 40 then
     404    begin
     405      Sprite(OffScreen, HGrTerrain, x, y, 56, 2 * yyt, xSrc, ySrc);
     406      Sprite(OffScreen, HGrTerrain, x, y + 2 * yyt, 56, 40 - 2 * yyt,
     407        xSrc, ySrc);
     408    end
     409    else
     410      Sprite(OffScreen, HGrTerrain, x, y, 56, 40, xSrc, ySrc);
     411    Sprite(OffScreen, HGrTerrain, x, y, xxt, yyt, xSrc + xxt, ySrc + yyt);
     412    Sprite(OffScreen, HGrTerrain, x, y + yyt, xxt, 40 - yyt, xSrc + xxt, ySrc);
     413    Sprite(OffScreen, HGrTerrain, x + xxt, y, 56 - xxt, yyt, xSrc, ySrc + yyt);
     414    Sprite(OffScreen, HGrTerrain, x + xxt, y + yyt, 56 - xxt, 40 - yyt,
     415      xSrc, ySrc);
     416  end;
     417
     418var
     419  i, j, yl, srcno, ofs, cnt, y: integer;
     420  s: string;
     421  HelpLineInfo: THelpLineInfo;
     422begin
     423  inherited;
     424  CaptionColor := Colors.Canvas.Pixels[clkMisc, cliPaperCaption];
     425  FillSeamless(OffScreen.Canvas, 0, 0, InnerWidth, InnerHeight, 0,
     426    sb.si.npos * 24, Paper);
     427  with OffScreen.Canvas do
     428  begin
     429    Font.Assign(UniFont[ftNormal]);
     430    for i := -sb.si.npos to InnerHeight div 24 do
     431      if sb.si.npos + i < MainText.Count then
     432      begin
     433        HelpLineInfo := THelpLineInfo(MainText.Objects[sb.si.npos + i]);
     434        if HelpLineInfo.Format = pkExternal then
     435        begin
     436          yl := ExtPic.Height;
     437          if 4 + i * 24 + yl > InnerHeight then
     438            yl := InnerHeight - (4 + i * 24);
     439          BitBlt(Handle, 8, 4 + i * 24, ExtPic.Width, yl, ExtPic.Canvas.Handle,
     440            0, 0, SRCCOPY);
     441        end
    338442      end;
    339     if sum<maxsum then
    340       begin // no saturation
    341       sum:=1 shl 22 - (maxsum-sum)*(256-CoalLine[xCoal+x,0]*2);
    342       PaintLine[x0+x,0]:=PaintLine[x0+x,0]*sum shr 22;
    343       PaintLine[x0+x,1]:=PaintLine[x0+x,1]*sum shr 22;
    344       PaintLine[x0+x,2]:=PaintLine[x0+x,2]*sum shr 22;
     443    for i := -2 to InnerHeight div 24 do
     444      if (sb.si.npos + i >= 0) and (sb.si.npos + i < MainText.Count) then
     445      begin
     446        HelpLineInfo := THelpLineInfo(MainText.Objects[sb.si.npos + i]);
     447        if HelpLineInfo.Link <> 0 then
     448        begin
     449          if (Kind = hkMisc) and (no = miscSearchResult) then
     450            Sprite(OffScreen, HGrSystem, 18, 9 + i * 24, 8, 8, 90, 16)
     451          else if HelpLineInfo.Format in [pkSmallIcon_AsPreq, pkAdvIcon_AsPreq]
     452          then
     453            Sprite(OffScreen, HGrSystem, 12, i * 24 + 5, 14, 14, 65, 20)
     454          else if HelpLineInfo.Link and (hkCrossLink shl 8) <> 0 then
     455            Sprite(OffScreen, HGrSystem, 12, i * 24 + 5, 14, 14, 80, 1)
     456          else if not((Kind = hkMisc) and (no = miscMain)) then
     457            Sprite(OffScreen, HGrSystem, 10, i * 24 + 6, 14, 14, 65, 1);
     458          x0[i] := 24;
     459        end
     460        else
     461          x0[i] := 0;
     462        case HelpLineInfo.Format of
     463          pkLogo:
     464            begin
     465              Server(sGetVersion, 0, 0, j);
     466              s := Format('%d.%d.%d', [j shr 16 and $FF, j shr 8 and $FF,
     467                j and $FF]);
     468              PaintLogo(OffScreen.Canvas, (InnerWidth - 122) div 2, i * 24 + 1,
     469                GrExt[HGrSystem].Data.Canvas.Pixels[95, 1], $000000);
     470              Font.Assign(UniFont[ftSmall]);
     471              BiColorTextOut(OffScreen.Canvas, $000000, $7F007F,
     472                (InnerWidth - Textwidth(s)) div 2, i * 24 + 26, s);
     473              Font.Assign(UniFont[ftNormal]);
     474            end;
     475          pkSmallIcon, pkSmallIcon_AsPreq:
     476            begin
     477              Frame(OffScreen.Canvas, 8 - 1 + x0[i], 2 - 1 + i * 24,
     478                8 + xSizeSmall + x0[i], 2 + 20 + i * 24, $000000, $000000);
     479              if HelpLineInfo.Picpix = imPalace then
     480                BitBlt(OffScreen.Canvas.Handle, 8 + x0[i], 2 + i * 24,
     481                  xSizeSmall, ySizeSmall, SmallImp.Canvas.Handle,
     482                  0 * xSizeSmall, 1 * ySizeSmall, SRCCOPY)
     483              else
     484                BitBlt(OffScreen.Canvas.Handle, 8 + x0[i], 2 + i * 24,
     485                  xSizeSmall, ySizeSmall, SmallImp.Canvas.Handle,
     486                  HelpLineInfo.Picpix mod 7 * xSizeSmall,
     487                  (HelpLineInfo.Picpix + SystemIconLines * 7) div 7 *
     488                  ySizeSmall, SRCCOPY);
     489              x0[i] := x0[i] + (8 + 8 + 36);
     490            end;
     491          pkBigIcon:
     492            begin
     493              FrameImage(OffScreen.Canvas, BigImp, x0[i] + 12, i * 24 - 7, 56,
     494                40, HelpLineInfo.Picpix mod 7 * xSizeBig,
     495                HelpLineInfo.Picpix div 7 * ySizeBig);
     496              x0[i] := 64 + 8 + 8 + x0[i];
     497            end;
     498          pkSpecialIcon:
     499            begin
     500              case HelpLineInfo.Picpix of
     501                0:
     502                  FrameImage(OffScreen.Canvas, GrExt[HGrSystem2].Data,
     503                    12 + x0[i], -7 + i * 24, 56, 40, 137, 127);
     504                1:
     505                  begin
     506                    PaintTerrIcon(12 + x0[i], -7 + i * 24,
     507                      1 + 3 * (xxt * 2 + 1), 1 + yyt);
     508                    if 2 * yyt < 40 then
     509                      Sprite(OffScreen, HGrTerrain, 12 + x0[i], -7 + 4 + i * 24,
     510                        56, 2 * yyt, 1 + 3 * (xxt * 2 + 1) + xxt - 28,
     511                        1 + yyt + 1 * (yyt * 3 + 1))
     512                    else
     513                      Sprite(OffScreen, HGrTerrain, 12 + x0[i],
     514                        -7 + 4 + i * 24 - 4, 56, 40, 1 + 3 * (xxt * 2 + 1) + xxt
     515                        - 28, 1 + yyt + 1 * (yyt * 3 + 1) + yyt - 20);
     516                  end;
     517                2:
     518                  begin
     519                    PaintTerrIcon(12 + x0[i], -7 + i * 24,
     520                      1 + 7 * (xxt * 2 + 1), 1 + yyt + 4 * (yyt * 3 + 1));
     521                    if 2 * yyt < 40 then
     522                      Sprite(OffScreen, HGrTerrain, 12 + x0[i], -7 + 4 + i * 24,
     523                        56, 32, 1 + 4 * (xxt * 2 + 1) + xxt - 28,
     524                        1 + yyt + 12 * (yyt * 3 + 1) + yyt - 16)
     525                    else
     526                      Sprite(OffScreen, HGrTerrain, 12 + x0[i], -7 + 4 + i * 24,
     527                        56, 32, 1 + 4 * (xxt * 2 + 1) + xxt - 28,
     528                        1 + yyt + 12 * (yyt * 3 + 1) + yyt - 16)
     529                  end;
     530              end;
     531              x0[i] := 64 + 8 + 8 + x0[i];
     532            end;
     533          pkDomain:
     534            begin
     535              Frame(OffScreen.Canvas, 8 - 1 + x0[i], 2 - 1 + i * 24,
     536                8 + 36 + x0[i], 2 + 20 + i * 24, $000000, $000000);
     537              Dump(OffScreen, HGrSystem, 8 + x0[i], 2 + i * 24, 36, 20,
     538                75 + HelpLineInfo.Picpix * 37, 295);
     539              x0[i] := x0[i] + (8 + 8 + 36);
     540            end;
     541          pkAdvIcon, pkAdvIcon_AsPreq:
     542            begin
     543              Frame(OffScreen.Canvas, 8 - 1 + x0[i], 2 - 1 + i * 24,
     544                8 + xSizeSmall + x0[i], 2 + ySizeSmall + i * 24,
     545                $000000, $000000);
     546              if AdvIcon[HelpLineInfo.Picpix] < 84 then
     547                BitBlt(OffScreen.Canvas.Handle, 8 + x0[i], 2 + i * 24,
     548                  xSizeSmall, ySizeSmall, SmallImp.Canvas.Handle,
     549                  (AdvIcon[HelpLineInfo.Picpix] + SystemIconLines * 7) mod 7 *
     550                  xSizeSmall, (AdvIcon[HelpLineInfo.Picpix] + SystemIconLines *
     551                  7) div 7 * ySizeSmall, SRCCOPY)
     552              else
     553                Dump(OffScreen, HGrSystem, 8 + x0[i], 2 + i * 24, 36, 20,
     554                  1 + (AdvIcon[HelpLineInfo.Picpix] - 84) mod 8 * 37,
     555                  295 + (AdvIcon[HelpLineInfo.Picpix] - 84) div 8 * 21);
     556              j := AdvValue[HelpLineInfo.Picpix] div 1000;
     557              BitBlt(Handle, x0[i] + 4, 4 + i * 24, 14, 14,
     558                GrExt[HGrSystem].Mask.Canvas.Handle, 127 + j * 15, 85, SRCAND);
     559              Sprite(OffScreen, HGrSystem, x0[i] + 3, 3 + i * 24, 14, 14,
     560                127 + j * 15, 85);
     561              x0[i] := x0[i] + (8 + 8 + 36);
     562            end;
     563          pkRightIcon:
     564            begin
     565              if Imp[HelpLineInfo.Picpix].Kind <> ikWonder then
     566                ImpImage(OffScreen.Canvas, InnerWidth - (40 + xSizeBig), i * 24,
     567                  HelpLineInfo.Picpix, gDespotism)
     568              else
     569                WaterSign(InnerWidth - (40 + 2 * xSizeBig), i * 24 - 8,
     570                  HelpLineInfo.Picpix + 7);
     571              x0[i] := x0[i] + 8;
     572            end;
     573          pkIllu:
     574            WaterSign(8, i * 24 - 8, HelpLineInfo.Picpix);
     575          pkBigFeature:
     576            begin
     577              cnt := 0;
     578              for j := nDomains - 1 downto 0 do
     579                if 1 shl j and Feature[HelpLineInfo.Picpix].Domains <> 0 then
     580                begin
     581                  inc(cnt);
     582                  Dump(OffScreen, HGrSystem, InnerWidth - 38 - 38 * cnt,
     583                    i * 24 + 1, 36, 20, 75 + j * 37, 295);
     584                  Frame(OffScreen.Canvas, InnerWidth - 39 - 38 * cnt, i * 24,
     585                    InnerWidth - 2 - 38 * cnt, i * 24 + 21, $000000, $000000);
     586                end;
     587              DarkGradient(OffScreen.Canvas, InnerWidth - 38 - 38 * cnt,
     588                i * 24 + 23, cnt * 38 - 2, 1);
     589              ofs := InnerWidth - (39 + 7) - 19 * cnt;
     590              with OffScreen.Canvas do
     591              begin
     592                Brush.color := $C0C0C0;
     593                FrameRect(Rect(ofs, 1 + 23 + i * 24, ofs + 14,
     594                  15 + 23 + i * 24));
     595                Brush.Style := bsClear;
     596                Sprite(OffScreen, HGrSystem, ofs + 2, 3 + 23 + i * 24, 10, 10,
     597                  66 + HelpLineInfo.Picpix mod 11 * 11,
     598                  137 + HelpLineInfo.Picpix div 11 * 11);
     599              end;
     600              x0[i] := x0[i] + 8;
     601            end;
     602          pkTer, pkBigTer:
     603            begin
     604              if HelpLineInfo.Format = pkBigTer then
     605                y := i * 24 - 3 + yyt
     606              else
     607                y := i * 24 + 13;
     608              if HelpLineInfo.Picpix >= 3 * 12 then
     609                srcno := 2 * 9 + 6
     610              else if HelpLineInfo.Picpix mod 12 = fJungle then
     611                srcno := 18 * 9
     612              else if HelpLineInfo.Picpix mod 12 < fJungle then
     613                srcno := HelpLineInfo.Picpix mod 12
     614              else
     615                srcno := 27 + (HelpLineInfo.Picpix mod 12 - 9) * 18;
     616              if HelpLineInfo.Format = pkTer then
     617              begin
     618                ofs := x0[i] + 8;
     619                x0[i] := 2 * xxt + 8 + ofs;
     620              end
     621              else
     622              begin
     623                ofs := InnerWidth - (2 * xxt + 38);
     624                x0[i] := x0[i] + 8;
     625              end;
     626              if srcno >= fJungle then
     627              begin
     628                Sprite(OffScreen, HGrTerrain, ofs + 4, y - yyt + 2, xxt * 2 - 8,
     629                  yyt * 2 - 4, 5 + 2 * (xxt * 2 + 1),
     630                  3 + yyt + 2 * (yyt * 3 + 1));
     631                Sprite(OffScreen, HGrTerrain, ofs, y - 2 * yyt, xxt * 2,
     632                  yyt * 3 - 2, 1 + srcno mod 9 * (xxt * 2 + 1),
     633                  1 + srcno div 9 * (yyt * 3 + 1));
     634              end
     635              else
     636                Sprite(OffScreen, HGrTerrain, ofs + 4, y - yyt + 2, xxt * 2 - 8,
     637                  yyt * 2 - 4, 5 + srcno mod 9 * (xxt * 2 + 1),
     638                  3 + yyt + srcno div 9 * (yyt * 3 + 1));
     639              if HelpLineInfo.Picpix >= 3 * 12 then { rare resource }
     640                Sprite(OffScreen, HGrTerrain, ofs, y - 2 * yyt, xxt * 2,
     641                  yyt * 3, 1 + 8 * (xxt * 2 + 1),
     642                  1 + (HelpLineInfo.Picpix - 2 * 12) * (yyt * 3 + 1))
     643              else if HelpLineInfo.Picpix >= 12 then { special tile }
     644              begin
     645                if HelpLineInfo.Picpix mod 12 = fJungle then
     646                  srcno := 17 * 9 + 8
     647                else if HelpLineInfo.Picpix mod 12 < fJungle then
     648                  srcno := HelpLineInfo.Picpix mod 12
     649                else
     650                  srcno := 18 + 8 + (HelpLineInfo.Picpix mod 12 - 9) * 18;
     651                srcno := srcno + HelpLineInfo.Picpix div 12 * 9;
     652                Sprite(OffScreen, HGrTerrain, ofs, y - 2 * yyt, xxt * 2,
     653                  yyt * 3, 1 + srcno mod 9 * (xxt * 2 + 1),
     654                  1 + srcno div 9 * (yyt * 3 + 1));
     655              end;
     656            end;
     657          pkTerImp:
     658            begin
     659              ofs := 8;
     660              if HelpLineInfo.Picpix = 5 then
     661              begin // display mine on hills
     662                Sprite(OffScreen, HGrTerrain, ofs + 4, i * 24 + 13 - yyt,
     663                  xxt * 2 - 8, yyt * 2 - 4, 5 + 2 * (xxt * 2 + 1),
     664                  3 + yyt + 2 * (yyt * 3 + 1));
     665                srcno := 45
     666              end
     667              else
     668                srcno := fPrairie; // display on prairie
     669              Sprite(OffScreen, HGrTerrain, ofs + 4, i * 24 + 13 - yyt,
     670                xxt * 2 - 8, yyt * 2 - 4, 5 + srcno mod 9 * (xxt * 2 + 1),
     671                3 + yyt + srcno div 9 * (yyt * 3 + 1));
     672              if HelpLineInfo.Picpix = 12 then { river }
     673                Sprite(OffScreen, HGrTerrain, ofs, i * 24 + 11 - yyt, xxt * 2,
     674                  yyt * 2, 1 + 5 * (xxt * 2 + 1), 1 + yyt + 13 * (yyt * 3 + 1))
     675              else if HelpLineInfo.Picpix >= 3 then { improvement 2 }
     676              begin
     677                if HelpLineInfo.Picpix = 6 then
     678                  Sprite(OffScreen, HGrTerrain, ofs, i * 24 + 11 - 2 * yyt,
     679                    xxt * 2, yyt * 3, 1 + 7 * (xxt * 2 + 1),
     680                    1 + 12 * (yyt * 3 + 1));
     681                Sprite(OffScreen, HGrTerrain, ofs, i * 24 + 11 - 2 * yyt,
     682                  xxt * 2, yyt * 3, 1 + (HelpLineInfo.Picpix - 3) *
     683                  (xxt * 2 + 1), 1 + 12 * (yyt * 3 + 1))
     684              end
     685              else { improvement 1 }
     686              begin
     687                Sprite(OffScreen, HGrTerrain, ofs, i * 24 + 11 - 2 * yyt,
     688                  xxt * 2, yyt * 3, 1 + 2 * (xxt * 2 + 1),
     689                  1 + (9 + HelpLineInfo.Picpix) * (yyt * 3 + 1));
     690                Sprite(OffScreen, HGrTerrain, ofs, i * 24 + 11 - 2 * yyt,
     691                  xxt * 2, yyt * 3, 1 + 5 * (xxt * 2 + 1),
     692                  1 + (9 + HelpLineInfo.Picpix) * (yyt * 3 + 1))
     693              end;
     694              x0[i] := x0[i] + 8;
     695            end;
     696          pkModel:
     697            begin
     698              FrameImage(OffScreen.Canvas, BigImp, x0[i] + 12, i * 24 - 7,
     699                56, 40, 0, 0);
     700              Sprite(OffScreen, HGrStdUnits, x0[i] + 8, i * 24 - 11, 64, 44,
     701                1 + HelpLineInfo.Picpix mod 10 * 65,
     702                1 + HelpLineInfo.Picpix div 10 * 49);
     703              x0[i] := 64 + 8 + 8 + x0[i];
     704            end;
     705          pkFeature:
     706            begin
     707              DarkGradient(OffScreen.Canvas, x0[i] + 8 - 1,
     708                7 + i * 24 - 3, 16, 1);
     709              Frame(OffScreen.Canvas, x0[i] + 8, 7 + i * 24 - 2, x0[i] + 8 + 13,
     710                7 + i * 24 - 2 + 13, $C0C0C0, $C0C0C0);
     711              Sprite(OffScreen, HGrSystem, x0[i] + 8 + 2, 7 + i * 24, 10, 10,
     712                66 + HelpLineInfo.Picpix mod 11 * 11,
     713                137 + HelpLineInfo.Picpix div 11 * 11);
     714              x0[i] := x0[i] + 8 + 8 + 2 + 13;
     715            end;
     716          pkExp:
     717            begin
     718              Frame(OffScreen.Canvas, 20 - 1, 8 - 4 + i * 24, 20 + 12,
     719                8 + 11 + i * 24, $000000, $000000);
     720              Dump(OffScreen, HGrSystem, 20, 8 - 3 + i * 24, 12, 14,
     721                121 + HelpLineInfo.Picpix * 13, 28);
     722              x0[i] := 20 + 8 + 11;
     723            end;
     724          pkAITStat:
     725            begin
     726              Sprite(OffScreen, HGrSystem, 20, 6 + i * 24, 14, 14,
     727                1 + HelpLineInfo.Picpix * 15, 316);
     728              x0[i] := 20 + 8 + 11;
     729            end;
     730          pkGov:
     731            begin
     732              Frame(OffScreen.Canvas, 8 - 1 + x0[i], 2 - 1 + i * 24,
     733                8 + xSizeSmall + x0[i], 2 + 20 + i * 24, $000000, $000000);
     734              BitBlt(OffScreen.Canvas.Handle, 8 + x0[i], 2 + i * 24, xSizeSmall,
     735                ySizeSmall, SmallImp.Canvas.Handle, (HelpLineInfo.Picpix - 1) *
     736                xSizeSmall, ySizeSmall, SRCCOPY);
     737              x0[i] := x0[i] + (8 + 8 + 36);
     738            end;
     739          pkDot:
     740            begin
     741              Sprite(OffScreen, HGrSystem, x0[i] + 18, 9 + i * 24, 8,
     742                8, 81, 16);
     743              x0[i] := 20 + 8 + 4;
     744            end;
     745          pkNormal_Dot:
     746            x0[i] := 20 + 8 + 4;
     747          pkNormal_64:
     748            x0[i] := 64 + 8 + 8;
     749        else
     750          x0[i] := x0[i] + 8
     751        end;
     752        line(OffScreen.Canvas, i, false)
     753      end
     754  end;
     755  MarkUsedOffscreen(InnerWidth, InnerHeight + 13 + 48);
     756end; { OffscreenPaint }
     757
     758procedure THelpDlg.Prepare(sbPos: integer = 0);
     759var
     760  i, j, special, Domain, Headline, TerrType, TerrSubType: integer;
     761  s: string;
     762  ps: pchar;
     763  List: THyperText;
     764  CheckSeeAlso: boolean;
     765
     766  procedure AddAdv(i: integer);
     767  begin
     768    MainText.AddLine(Phrases.Lookup('ADVANCES', i), pkAdvIcon, i,
     769      hkAdv + hkCrossLink, i);
     770  end;
     771
     772  procedure AddPreqAdv(i: integer);
     773  begin
     774    MainText.AddLine(Phrases.Lookup('ADVANCES', i), pkAdvIcon_AsPreq, i,
     775      hkAdv + hkCrossLink, i);
     776  end;
     777
     778  procedure AddImp(i: integer);
     779  begin
     780    MainText.AddLine(Phrases.Lookup('IMPROVEMENTS', i), pkSmallIcon, i,
     781      hkImp + hkCrossLink, i);
     782  end;
     783
     784  procedure AddPreqImp(i: integer);
     785  begin
     786    MainText.AddLine(Phrases.Lookup('IMPROVEMENTS', i), pkSmallIcon_AsPreq, i,
     787      hkImp + hkCrossLink, i);
     788  end;
     789
     790  procedure AddTer(i: integer);
     791  begin
     792    if MainText.Count > 1 then
     793    begin
     794      MainText.LF;
     795    end;
     796    MainText.AddLine(Phrases.Lookup('TERRAIN', i), pkTer, i, hkTer, i);
     797  end;
     798
     799  procedure AddFeature(i: integer);
     800  begin
     801    MainText.AddLine(Phrases.Lookup('FEATURES', i), pkFeature, i,
     802      hkFeature + hkCrossLink, i);
     803  end;
     804
     805  procedure AddModel(i: integer);
     806  var
     807    pix: integer;
     808    Name: string;
     809  begin
     810    if MainText.Count > 1 then
     811      MainText.LF;
     812    FindStdModelPicture(SpecialModelPictureCode[i], pix, Name);
     813    MainText.AddLine(Name, pkModel, pix, hkModel + hkCrossLink, i)
     814  end;
     815
     816  procedure AddStandardBlock(Item: string);
     817  var
     818    i: integer;
     819  begin
     820    with MainText do
     821    begin
     822      if Item = 'LOGO' then
     823      begin
     824        AddLine('', pkLogo);
     825        LF;
     826      end
     827      else if Item = 'TECHFORMULA' then
     828      begin
     829        i := Difficulty;
     830        if i = 0 then
     831          i := 2;
     832        AddLine(Format(HelpText.Lookup('TECHFORMULA'), [TechFormula_M[i],
     833          TechFormula_D[i]]))
     834      end
     835      else if Item = 'EXPERIENCE' then
     836        for i := 0 to nExp - 1 do
     837          AddLine(Phrases.Lookup('EXPERIENCE', i), pkExp, i)
     838      else if Item = 'MODERN' then
     839        for i := 1 to 3 do
     840        begin
     841          LF;
     842          AddLine(Phrases.Lookup('TERRAIN', 3 * 12 + i), pkTer, 3 * 12 + i);
     843        end
     844      else if Item = 'SAVED' then
     845        AddLine(DataDir + 'Saved', pkNormal)
     846      else if Item = 'AITSTAT' then
     847        for i := 0 to 3 do
     848          AddLine(Phrases2.Lookup('AITSTAT', i), pkAITStat, i)
     849    end
     850  end;
     851
     852  procedure DecodeItem(s: string; var Category, Index: integer);
     853  var
     854    i: integer;
     855  begin
     856    if (length(s) > 0) and (s[1] = ':') then
     857    begin
     858      Category := hkMisc;
     859      Index := 0;
     860      for i := 3 to length(s) do
     861        Index := Index * 10 + ord(s[i]) - 48;
     862      case s[2] of
     863        'A':
     864          Category := hkAdv;
     865        'B':
     866          Category := hkImp;
     867        'T':
     868          Category := hkTer;
     869        'F':
     870          Category := hkFeature;
     871        'E':
     872          Category := hkInternet;
     873        'S':
     874          Category := hkModel;
     875        'C':
     876          Index := miscCredits;
     877        'J':
     878          Index := miscJobList;
     879        'G':
     880          Index := miscGovList;
     881      end;
     882      if (Category <> hkMisc) and (Index = 0) then
     883        Index := 200;
     884    end
     885    else
     886    begin
     887      Category := hkText;
     888      Index := HelpText.Gethandle(copy(s, 1, 255));
     889    end;
     890  end;
     891
     892  procedure AddText(s: string);
     893  var
     894    i, p, l, ofs, CurrentFormat, FollowFormat, Picpix, LinkCategory, LinkIndex,
     895      RightMargin: integer;
     896    Name: string;
     897  begin
     898    RightMargin := InnerWidth - 16 - GetSystemMetrics(SM_CXVSCROLL);
     899    FollowFormat := pkNormal;
     900    while s <> '' do
     901    begin
     902      Picpix := 0;
     903      LinkCategory := 0;
     904      LinkIndex := 0;
     905      if s[1] = '$' then
     906      begin // window caption
     907        p := 1;
     908        repeat
     909          inc(p)
     910        until (p > length(s)) or (s[p] = '\');
     911        Caption := copy(s, 2, p - 2);
     912        Delete(s, 1, p);
     913      end
     914      else if s[1] = '&' then
     915      begin // standard block
     916        p := 1;
     917        repeat
     918          inc(p)
     919        until (p > length(s)) or (s[p] = '\');
     920        AddStandardBlock(copy(s, 2, p - 2));
     921        Delete(s, 1, p);
     922      end
     923      else if s[1] = '@' then
     924      begin // image
     925        if (length(s) >= 2) and (s[2] = '@') then
     926        begin // generate from icon
     927          Picpix := 0;
     928          p := 3;
     929          while (p <= length(s)) and (s[p] <> '\') do
     930          begin
     931            Picpix := Picpix * 10 + ord(s[p]) - 48;
     932            inc(p)
     933          end;
     934          if (Picpix < 0) or (Picpix >= nImp) then
     935            Picpix := 0;
     936          MainText.AddLine('', pkIllu, Picpix);
     937          MainText.LF;
     938          MainText.LF;
     939        end
     940        else
     941        begin // external image
     942          p := 1;
     943          repeat
     944            inc(p)
     945          until (p > length(s)) or (s[p] = '\');
     946          if LoadLocalizedGraphicFile(ExtPic, 'Help\' + copy(s, 2, p - 2)) then
     947          begin
     948            MainText.AddLine('', pkExternal);
     949            for i := 0 to (ExtPic.Height - 12) div 24 do
     950              MainText.LF;
     951          end;
     952        end;
     953        Delete(s, 1, p);
     954      end
     955      else
     956      begin
     957        case s[1] of
     958          ':', ';':
     959            begin // link
     960              p := 1;
     961              repeat
     962                inc(p)
     963              until (p > length(s)) or (s[p] = '\') or (s[p] = ' ');
     964              DecodeItem(copy(s, 2, p - 2), LinkCategory, LinkIndex);
     965              CurrentFormat := 0;
     966              if (LinkCategory <> hkText) and (LinkIndex < 200) then
     967              // show icon
     968                case LinkCategory of
     969                  hkAdv:
     970                    begin
     971                      CurrentFormat := pkAdvIcon;
     972                      Picpix := LinkIndex
     973                    end;
     974                  hkImp:
     975                    begin
     976                      CurrentFormat := pkSmallIcon;
     977                      Picpix := LinkIndex
     978                    end;
     979                  hkTer:
     980                    begin
     981                      CurrentFormat := pkTer;
     982                      Picpix := LinkIndex
     983                    end;
     984                  hkFeature:
     985                    begin
     986                      CurrentFormat := pkFeature;
     987                      Picpix := LinkIndex
     988                    end;
     989                  hkModel:
     990                    begin
     991                      CurrentFormat := pkModel;
     992                      FindStdModelPicture(SpecialModelPictureCode[LinkIndex],
     993                        Picpix, Name);
     994                    end;
     995                end;
     996              if s[1] = ':' then
     997                LinkCategory := LinkCategory + hkCrossLink;
     998              if (p > length(s)) or (s[p] = ' ') then
     999                Delete(s, 1, p)
     1000              else
     1001                Delete(s, 1, p - 1)
     1002            end;
     1003          '!': // highlited
     1004            if (length(s) >= 2) and (s[2] = '!') then
     1005            begin
     1006              if MainText.Count > 1 then
     1007                MainText.LF;
     1008              FollowFormat := pkCaption;
     1009              CurrentFormat := pkCaption;
     1010              Delete(s, 1, 2);
     1011            end
     1012            else
     1013            begin
     1014              FollowFormat := pkSection;
     1015              CurrentFormat := pkSection;
     1016              Delete(s, 1, 1);
     1017            end;
     1018          '-':
     1019            begin // list
     1020              FollowFormat := pkNormal_Dot;
     1021              CurrentFormat := pkDot;
     1022              Delete(s, 1, 1);
     1023            end;
     1024        else
     1025          CurrentFormat := FollowFormat;
     1026        end;
     1027        if FollowFormat = pkNormal_Dot then
     1028          ofs := 20 + 4 + 8
     1029        else
     1030          ofs := 8;
     1031        p := 0;
     1032        repeat
     1033          repeat
     1034            inc(p)
     1035          until (p > length(s)) or (s[p] = ' ') or (s[p] = '\');
     1036          if (BiColorTextWidth(OffScreen.Canvas, copy(s, 1, p - 1)) <=
     1037            RightMargin - ofs) then
     1038            l := p - 1
     1039          else
     1040            Break;
     1041        until (p >= length(s)) or (s[l + 1] = '\');
     1042        MainText.AddLine(copy(s, 1, l), CurrentFormat, Picpix, LinkCategory,
     1043          LinkIndex);
     1044        if (l < length(s)) and (s[l + 1] = '\') then
     1045          FollowFormat := pkNormal;
     1046        Delete(s, 1, l + 1);
    3451047      end
    3461048    end
    3471049  end;
    348 end;
    349 
    350 procedure THelpDlg.OffscreenPaint;
    351 
    352   procedure PaintTerrIcon(x,y,xSrc,ySrc: integer);
    353   begin
    354   Frame(offscreen.canvas,x-1,y-1,x+xSizeBig,y+ySizeBig,$000000,$000000);
    355   if 2*yyt<40 then
    356     begin
    357     Sprite(Offscreen, HGrTerrain, x, y, 56, 2*yyt, xSrc, ySrc);
    358     Sprite(Offscreen, HGrTerrain, x, y+2*yyt, 56, 40-2*yyt, xSrc, ySrc);
    359     end
    360   else Sprite(Offscreen, HGrTerrain, x, y, 56, 40, xSrc, ySrc);
    361   Sprite(Offscreen, HGrTerrain, x, y, xxt, yyt, xSrc+xxt, ySrc+yyt);
    362   Sprite(Offscreen, HGrTerrain, x, y+yyt, xxt, 40-yyt, xSrc+xxt, ySrc);
    363   Sprite(Offscreen, HGrTerrain, x+xxt, y, 56-xxt, yyt, xSrc, ySrc+yyt);
    364   Sprite(Offscreen, HGrTerrain, x+xxt, y+yyt, 56-xxt, 40-yyt, xSrc, ySrc);
    365   end;
    366 
    367 var
    368 i,j,yl,srcno,ofs,cnt,y: integer;
    369 s: string;
    370 HelpLineInfo: THelpLineInfo;
    371 begin
    372 inherited;
    373 CaptionColor:=Colors.Canvas.Pixels[clkMisc,cliPaperCaption];
    374 FillSeamless(offscreen.Canvas,0,0,InnerWidth,InnerHeight,0,sb.si.npos*24,
    375   Paper);
    376 with offscreen.Canvas do
    377   begin
    378   Font.Assign(UniFont[ftNormal]);
    379   for i:=-sb.si.npos to InnerHeight div 24 do
    380     if sb.si.npos+i<MainText.Count then
    381       begin
    382       HelpLineInfo:=THelpLineInfo(MainText.Objects[sb.si.npos+i]);
    383       if HelpLineInfo.Format=pkExternal then
    384         begin
    385         yl:=ExtPic.Height;
    386         if 4+i*24+yl>InnerHeight then yl:=InnerHeight-(4+i*24);
    387         BitBlt(Handle,8,4+i*24,ExtPic.Width,yl,
    388           ExtPic.Canvas.Handle,0,0,SRCCOPY);
    389         end
    390       end;
    391   for i:=-2 to InnerHeight div 24 do
    392     if (sb.si.npos+i>=0) and (sb.si.npos+i<MainText.Count) then
    393       begin
    394       HelpLineInfo:=THelpLineInfo(MainText.Objects[sb.si.npos+i]);
    395       if HelpLineInfo.Link<>0 then
    396         begin
    397         if (Kind=hkMisc) and (no=miscSearchResult) then
    398           Sprite(offscreen,HGrSystem,18,9+i*24,8,8,90,16)
    399         else if HelpLineInfo.Format in [pkSmallIcon_AsPreq,pkAdvIcon_AsPreq] then
    400           Sprite(offscreen,HGrSystem,12,i*24+5,14,14,65,20)
    401         else if HelpLineInfo.Link and (hkCrossLink shl 8)<>0 then
    402           Sprite(offscreen,HGrSystem,12,i*24+5,14,14,80,1)
    403         else if not ((Kind=hkMisc) and (no=miscMain)) then
    404           Sprite(offscreen,HGrSystem,10,i*24+6,14,14,65,1);
    405         x0[i]:=24;
    406         end
    407       else x0[i]:=0;
    408       case HelpLineInfo.Format of
    409         pkLogo:
    410           begin
    411           Server(sGetVersion,0,0,j);
    412           s:=Format('%d.%d.%d',[j shr 16 and $FF, j shr 8 and $FF, j and $FF]);
    413           PaintLogo(offscreen.canvas,(InnerWidth-122) div 2,i*24+1,
    414             GrExt[HGrSystem].Data.Canvas.Pixels[95,1],$000000);
    415           Font.Assign(UniFont[ftSmall]);
    416           BiColorTextout(offscreen.Canvas,$000000,$7F007F,
    417             (InnerWidth-TextWidth(s)) div 2,i*24+26,s);
    418           Font.Assign(UniFont[ftNormal]);
    419           end;
    420         pkSmallIcon,pkSmallIcon_AsPreq:
    421           begin
    422           Frame(offscreen.Canvas,8-1+x0[i],2-1+i*24,8+xSizeSmall+x0[i],2+20+i*24,
    423             $000000,$000000);
    424           if HelpLineInfo.Picpix=imPalace then
    425             BitBlt(offscreen.Canvas.Handle,8+x0[i],2+i*24,xSizeSmall,ySizeSmall,SmallImp.Canvas.Handle,
    426               0*xSizeSmall,1*ySizeSmall,SRCCOPY)
    427           else BitBlt(offscreen.Canvas.Handle,8+x0[i],2+i*24,xSizeSmall,ySizeSmall,SmallImp.Canvas.Handle,
    428             HelpLineInfo.Picpix mod 7*xSizeSmall,(HelpLineInfo.Picpix+SystemIconLines*7) div 7*ySizeSmall,SRCCOPY);
    429           x0[i]:=x0[i]+(8+8+36);
    430           end;
    431         pkBigIcon:
    432           begin
    433           FrameImage(offscreen.canvas,BigImp,x0[i]+12,i*24-7,56,40,
    434             HelpLineInfo.Picpix mod 7*xSizeBig,
    435             HelpLineInfo.Picpix div 7*ySizeBig);
    436           x0[i]:=64+8+8+x0[i];
    437           end;
    438         pkSpecialIcon:
    439           begin
    440           case HelpLineInfo.Picpix of
    441             0:
    442               FrameImage(Offscreen.Canvas, GrExt[HGrSystem2].Data, 12+x0[i],-7+i*24, 56, 40, 137, 127);
    443             1:
    444               begin
    445               PaintTerrIcon(12+x0[i],-7+i*24, 1+3*(xxt*2+1), 1+yyt);
    446               if 2*yyt<40 then
    447                 Sprite(Offscreen, HGrTerrain, 12+x0[i],-7+4+i*24, 56, 2*yyt, 1+3*(xxt*2+1)+xxt-28, 1+yyt+1*(yyt*3+1))
    448               else Sprite(Offscreen, HGrTerrain, 12+x0[i],-7+4+i*24-4, 56, 40, 1+3*(xxt*2+1)+xxt-28, 1+yyt+1*(yyt*3+1)+yyt-20);
    449               end;
    450             2:
    451               begin
    452               PaintTerrIcon(12+x0[i],-7+i*24, 1+7*(xxt*2+1), 1+yyt+4*(yyt*3+1));
    453               if 2*yyt<40 then
    454                 Sprite(Offscreen, HGrTerrain, 12+x0[i],-7+4+i*24, 56, 32, 1+4*(xxt*2+1)+xxt-28, 1+yyt+12*(yyt*3+1)+yyt-16)
    455               else Sprite(Offscreen, HGrTerrain, 12+x0[i],-7+4+i*24, 56, 32, 1+4*(xxt*2+1)+xxt-28, 1+yyt+12*(yyt*3+1)+yyt-16)
    456               end;
    457             end;
    458           x0[i]:=64+8+8+x0[i];
    459           end;
    460         pkDomain:
    461           begin
    462           Frame(offscreen.Canvas,8-1+x0[i],2-1+i*24,8+36+x0[i],2+20+i*24,
    463             $000000,$000000);
    464           Dump(offscreen,HGrSystem,8+x0[i],2+i*24,36,20,
    465             75+HelpLineInfo.Picpix*37,295);
    466           x0[i]:=x0[i]+(8+8+36);
    467           end;
    468         pkAdvIcon,pkAdvIcon_AsPreq:
    469           begin
    470           Frame(offscreen.Canvas,8-1+x0[i],2-1+i*24,8+xSizeSmall+x0[i],2+ySizeSmall+i*24,
    471             $000000,$000000);
    472           if AdvIcon[HelpLineInfo.Picpix]<84 then
    473             BitBlt(offscreen.Canvas.Handle,8+x0[i],2+i*24,xSizeSmall,ySizeSmall,
    474               SmallImp.Canvas.Handle, (AdvIcon[HelpLineInfo.Picpix]+SystemIconLines*7) mod 7*xSizeSmall,
    475               (AdvIcon[HelpLineInfo.Picpix]+SystemIconLines*7) div 7*ySizeSmall,SRCCOPY)
    476           else
    477             Dump(offscreen,HGrSystem,8+x0[i],2+i*24,36,20,
    478               1+(AdvIcon[HelpLineInfo.Picpix]-84) mod 8*37,
    479               295+(AdvIcon[HelpLineInfo.Picpix]-84) div 8*21);
    480           j:=AdvValue[HelpLineInfo.Picpix] div 1000;
    481           BitBlt(Handle,x0[i]+4,4+i*24,14,14,
    482             GrExt[HGrSystem].Mask.Canvas.Handle,127+j*15,85,SRCAND);
    483           Sprite(offscreen,HGrSystem,x0[i]+3,3+i*24,14,14,127+j*15,85);
    484           x0[i]:=x0[i]+(8+8+36);
    485           end;
    486         pkRightIcon:
    487           begin
    488           if Imp[HelpLineInfo.Picpix].Kind<>ikWonder then
    489             ImpImage(Offscreen.Canvas,InnerWidth-(40+xSizeBig),i*24,
    490               HelpLineInfo.Picpix, gDespotism)
    491           else WaterSign(InnerWidth-(40+2*xSizeBig),i*24-8,HelpLineInfo.Picpix+7);
    492           x0[i]:=x0[i]+8;
    493           end;
    494         pkIllu:
    495           WaterSign(8,i*24-8,HelpLineInfo.Picpix);
    496         pkBigFeature:
    497           begin
    498           cnt:=0;
    499           for j:=nDomains-1 downto 0 do
    500             if 1 shl j and Feature[HelpLineInfo.Picpix].Domains<>0 then
    501               begin
    502               inc(cnt);
    503               Dump(offscreen,HGrSystem,InnerWidth-38-38*cnt,i*24+1,36,20,75+j*37,295);
    504               Frame(offscreen.canvas,InnerWidth-39-38*cnt,i*24,
    505                 InnerWidth-2-38*cnt,i*24+21,
    506                 $000000,$000000);
    507               end;
    508           DarkGradient(offscreen.Canvas,InnerWidth-38-38*cnt,i*24+23,cnt*38-2,1);
    509           ofs:=InnerWidth-(39+7)-19*cnt;
    510           with offscreen.Canvas do
    511             begin
    512             Brush.Color:=$C0C0C0;
    513             FrameRect(Rect(ofs,1+23+i*24,ofs+14,15+23+i*24));
    514             Brush.Style:=bsClear;
    515             Sprite(offscreen,HGrSystem,ofs+2,3+23+i*24,10,10,
    516               66+HelpLineInfo.Picpix mod 11 *11,
    517               137+HelpLineInfo.Picpix div 11 *11);
    518             end;
    519           x0[i]:=x0[i]+8;
    520           end;
    521         pkTer,pkBigTer:
    522           begin
    523           if HelpLineInfo.Format=pkBigTer then
    524             y:=i*24-3+yyt
    525           else y:=i*24+13;
    526           if HelpLineInfo.Picpix>=3*12 then srcno:=2*9+6
    527           else if HelpLineInfo.Picpix mod 12=fJungle then srcno:=18*9
    528           else if HelpLineInfo.Picpix mod 12<fJungle then
    529             srcno:=HelpLineInfo.Picpix mod 12
    530           else srcno:=27+(HelpLineInfo.Picpix mod 12-9)*18;
    531           if HelpLineInfo.Format=pkTer then
    532             begin ofs:=x0[i]+8; x0[i]:=2*xxt+8+ofs; end
    533           else begin ofs:=InnerWidth-(2*xxt+38); x0[i]:=x0[i]+8; end;
    534           if srcno>=fJungle then
    535             begin
    536             Sprite(offscreen,HGrTerrain,ofs+4,y-yyt+2,xxt*2-8,yyt*2-4,
    537               5+2*(xxt*2+1),3+yyt+2*(yyt*3+1));
    538             Sprite(offscreen,HGrTerrain,ofs,y-2*yyt,xxt*2,yyt*3-2,
    539               1+srcno mod 9 *(xxt*2+1),1+srcno div 9 *(yyt*3+1));
    540             end
    541           else Sprite(offscreen,HGrTerrain,ofs+4,y-yyt+2,xxt*2-8,yyt*2-4,
    542             5+srcno mod 9 *(xxt*2+1),3+yyt+srcno div 9 *(yyt*3+1));
    543           if HelpLineInfo.Picpix>=3*12 then {rare resource}
    544             Sprite(offscreen,HGrTerrain,ofs,y-2*yyt,xxt*2,yyt*3,
    545               1+8*(xxt*2+1), 1+(HelpLineInfo.Picpix-2*12)*(yyt*3+1))
    546           else if HelpLineInfo.Picpix>=12 then {special tile}
    547             begin
    548             if HelpLineInfo.Picpix mod 12=fJungle then srcno:=17*9+8
    549             else if HelpLineInfo.Picpix mod 12<fJungle then
    550               srcno:=HelpLineInfo.Picpix mod 12
    551             else srcno:=18+8+(HelpLineInfo.Picpix mod 12-9)*18;
    552             srcno:=srcno+HelpLineInfo.Picpix div 12*9;
    553             Sprite(offscreen,HGrTerrain,ofs,y-2*yyt,xxt*2,yyt*3,
    554               1+srcno mod 9 *(xxt*2+1),1+srcno div 9 *(yyt*3+1));
    555             end;
    556           end;
    557         pkTerImp:
    558           begin
    559           ofs:=8;
    560           if HelpLineInfo.Picpix=5 then
    561             begin // display mine on hills
    562             Sprite(offscreen,HGrTerrain,ofs+4,i*24+13-yyt,xxt*2-8,yyt*2-4,
    563               5+2*(xxt*2+1),3+yyt+2*(yyt*3+1));
    564             srcno:=45
    565             end
    566           else srcno:=fPrairie; // display on prairie
    567           Sprite(offscreen,HGrTerrain,ofs+4,i*24+13-yyt,xxt*2-8,yyt*2-4,
    568             5+srcno mod 9 *(xxt*2+1),3+yyt+srcno div 9 *(yyt*3+1));
    569           if HelpLineInfo.Picpix=12 then {river}
    570             Sprite(offscreen,HGrTerrain,ofs,i*24+11-yyt,xxt*2,yyt*2,1+5*(xxt*2+1),
    571               1+yyt+13*(yyt*3+1))
    572           else if HelpLineInfo.Picpix>=3 then {improvement 2}
    573             begin
    574             if HelpLineInfo.Picpix=6 then
    575               Sprite(offscreen,HGrTerrain,ofs,i*24+11-2*yyt,xxt*2,yyt*3,
    576                 1+7 *(xxt*2+1),1+12 *(yyt*3+1));
    577             Sprite(offscreen,HGrTerrain,ofs,i*24+11-2*yyt,xxt*2,yyt*3,
    578               1+(HelpLineInfo.Picpix-3)*(xxt*2+1), 1+12*(yyt*3+1))
    579             end
    580           else {improvement 1}
    581             begin
    582             Sprite(offscreen,HGrTerrain,ofs,i*24+11-2*yyt,xxt*2,yyt*3,
    583               1+2*(xxt*2+1),1+(9+HelpLineInfo.Picpix)*(yyt*3+1));
    584             Sprite(offscreen,HGrTerrain,ofs,i*24+11-2*yyt,xxt*2,yyt*3,
    585               1+5*(xxt*2+1),1+(9+HelpLineInfo.Picpix)*(yyt*3+1))
    586             end;
    587           x0[i]:=x0[i]+8;
    588           end;
    589         pkModel:
    590           begin
    591           FrameImage(offscreen.canvas,BigImp,x0[i]+12,i*24-7,56,40,0,0);
    592           Sprite(offscreen,HGrStdUnits,x0[i]+8,i*24-11,64,44,
    593             1+HelpLineInfo.Picpix mod 10 *65,1+HelpLineInfo.Picpix div 10 *49);
    594           x0[i]:=64+8+8+x0[i];
    595           end;
    596         pkFeature:
    597           begin
    598           DarkGradient(offscreen.Canvas,x0[i]+8-1,7+i*24-3,16,1);
    599           Frame(offscreen.canvas,x0[i]+8,7+i*24-2,x0[i]+8+13,7+i*24-2+13,
    600             $C0C0C0,$C0C0C0);
    601           Sprite(offscreen,HGrSystem,x0[i]+8+2,7+i*24,10,10,
    602             66+HelpLineInfo.Picpix mod 11*11,137+HelpLineInfo.Picpix div 11*11);
    603           x0[i]:=x0[i]+8+8+2+13;
    604           end;
    605         pkExp:
    606           begin
    607           Frame(offscreen.Canvas,20-1,8-4+i*24,20+12,8+11+i*24,$000000,$000000);
    608           Dump(offscreen,HGrSystem,20,8-3+i*24,12,14,121+HelpLineInfo.Picpix*13,28);
    609           x0[i]:=20+8+11;
    610           end;
    611         pkAITStat:
    612           begin
    613           Sprite(offscreen,HGrSystem,20,6+i*24,14,14,1+HelpLineInfo.Picpix*15,316);
    614           x0[i]:=20+8+11;
    615           end;
    616         pkGov:
    617           begin
    618           Frame(offscreen.Canvas,8-1+x0[i],2-1+i*24,8+xSizeSmall+x0[i],2+20+i*24,
    619             $000000,$000000);
    620           BitBlt(offscreen.Canvas.Handle,8+x0[i],2+i*24,xSizeSmall,ySizeSmall,SmallImp.Canvas.Handle,
    621             (HelpLineInfo.Picpix-1)*xSizeSmall,ySizeSmall,SRCCOPY);
    622           x0[i]:=x0[i]+(8+8+36);
    623           end;
    624         pkDot:
    625           begin
    626           Sprite(offscreen,HGrSystem,x0[i]+18,9+i*24,8,8,81,16);
    627           x0[i]:=20+8+4;
    628           end;
    629         pkNormal_Dot:
    630           x0[i]:=20+8+4;
    631         pkNormal_64:
    632           x0[i]:=64+8+8;
    633         else x0[i]:=x0[i]+8
    634         end;
    635       line(offscreen.Canvas,i,false)
    636       end
    637   end;
    638 MarkUsedOffscreen(InnerWidth,InnerHeight+13+48);
    639 end; {OffscreenPaint}
    640 
    641 procedure THelpDlg.Prepare(sbPos: integer = 0);
    642 var
    643 i,j,special,Domain,Headline,TerrType,TerrSubType: integer;
    644 s: string;
    645 ps: pchar;
    646 List: THyperText;
    647 CheckSeeAlso: boolean;
    648 
    649   procedure AddAdv(i: integer);
    650   begin
    651   MainText.AddLine(Phrases.Lookup('ADVANCES',i),pkAdvIcon,i,hkAdv+hkCrossLink,i);
    652   end;
    653 
    654   procedure AddPreqAdv(i: integer);
    655   begin
    656   MainText.AddLine(Phrases.Lookup('ADVANCES',i),pkAdvIcon_AsPreq,i,hkAdv+hkCrossLink,i);
    657   end;
    658 
    659   procedure AddImp(i: integer);
    660   begin
    661   MainText.AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon,i,hkImp+hkCrossLink,i);
    662   end;
    663 
    664   procedure AddPreqImp(i: integer);
    665   begin
    666   MainText.AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon_AsPreq,i,hkImp+hkCrossLink,i);
    667   end;
    668 
    669   procedure AddTer(i: integer);
    670   begin
    671   if MainText.Count>1 then begin MainText.LF; end;
    672   MainText.AddLine(Phrases.Lookup('TERRAIN',i),pkTer,i,hkTer,i);
    673   end;
    674 
    675   procedure AddFeature(i: integer);
    676   begin
    677   MainText.AddLine(Phrases.Lookup('FEATURES',i),pkFeature,i,hkFeature+hkCrossLink,i);
    678   end;
    679 
    680   procedure AddModel(i: integer);
    681   var
    682   pix: integer;
    683   Name: string;
    684   begin
    685   if MainText.Count>1 then MainText.LF;
    686   FindStdModelPicture(SpecialModelPictureCode[i],pix,Name);
    687   MainText.AddLine(Name,pkModel,pix,hkModel+hkCrossLink,i)
    688   end;
    689 
    690   procedure AddStandardBlock(Item: string);
    691   var
    692   i: integer;
    693   begin
    694   with MainText do
    695     begin
    696     if Item='LOGO' then
    697       begin AddLine('',pkLogo); LF; end
    698     else if Item='TECHFORMULA' then
    699       begin
    700       i:=Difficulty;
    701       if i=0 then i:=2;
    702       AddLine(Format(HelpText.Lookup('TECHFORMULA'),[TechFormula_M[i],TechFormula_D[i]]))
    703       end
    704     else if Item='EXPERIENCE' then
    705       for i:=0 to nExp-1 do AddLine(Phrases.Lookup('EXPERIENCE',i),pkExp,i)
    706     else if Item='MODERN' then
    707       for i:=1 to 3 do
    708         begin
    709         LF;
    710         AddLine(Phrases.Lookup('TERRAIN',3*12+i),pkTer,3*12+i);
    711         end
    712     else if Item='SAVED' then
    713       AddLine(DataDir+'Saved',pkNormal)
    714     else if Item='AITSTAT' then
    715       for i:=0 to 3 do AddLine(Phrases2.Lookup('AITSTAT',i),pkAITStat,i)
    716     end
    717   end;
    718 
    719   procedure DecodeItem(s: string; var Category, Index: integer);
    720   var
    721   i: integer;
    722   begin
    723   if (length(s)>0) and (s[1]=':') then
    724     begin
    725     Category:=hkMisc;
    726     Index:=0;
    727     for i:=3 to Length(s) do Index:=Index*10+ord(s[i])-48;
    728     case s[2] of
    729       'A': Category:=hkAdv;
    730       'B': Category:=hkImp;
    731       'T': Category:=hkTer;
    732       'F': Category:=hkFeature;
    733       'E': Category:=hkInternet;
    734       'S': Category:=hkModel;
    735       'C': Index:=miscCredits;
    736       'J': Index:=miscJobList;
    737       'G': Index:=miscGovList;
    738       end;
    739     if (Category<>hkMisc) and (Index=0) then
    740       Index:=200;
    741     end
    742   else
    743     begin
    744     Category:=hkText;
    745     Index:=HelpText.GetHandle(copy(s,1,255));
    746     end;
    747   end;
    748 
    749   procedure AddText(s: string);
    750   var
    751   i,p,l,ofs,CurrentFormat,FollowFormat,Picpix,LinkCategory,LinkIndex,RightMargin: integer;
    752   Name: string;
    753   begin
    754   RightMargin:=InnerWidth-16-GetSystemMetrics(SM_CXVSCROLL);
    755   FollowFormat:=pkNormal;
    756   while s<>'' do
    757     begin
    758     Picpix:=0;
    759     LinkCategory:=0;
    760     LinkIndex:=0;
    761     if s[1]='$' then
    762       begin // window caption
    763       p:=1;
    764       repeat inc(p) until (p>Length(s)) or (s[p]='\');
    765       Caption:=Copy(s,2,p-2);
    766       Delete(s,1,p);
    767       end
    768     else if s[1]='&' then
    769       begin // standard block
    770       p:=1;
    771       repeat inc(p) until (p>Length(s)) or (s[p]='\');
    772       AddStandardBlock(Copy(s,2,p-2));
    773       Delete(s,1,p);
    774       end
    775     else if s[1]='@' then
    776       begin // image
    777       if (Length(s)>=2) and (s[2]='@') then
    778         begin // generate from icon
    779         Picpix:=0;
    780         p:=3;
    781         while (p<=Length(s)) and (s[p]<>'\') do
    782           begin Picpix:=Picpix*10+ord(s[p])-48; inc(p) end;
    783         if (Picpix<0) or (Picpix>=nImp) then Picpix:=0;
    784         MainText.AddLine('',pkIllu,Picpix);
    785         MainText.LF;
    786         MainText.LF;
    787         end
    788       else
    789         begin // external image
    790         p:=1;
    791         repeat inc(p) until (p>Length(s)) or (s[p]='\');
    792         if LoadLocalizedGraphicFile(ExtPic, 'Help\'+Copy(s,2,p-2)) then
    793           begin
    794           MainText.AddLine('',pkExternal);
    795           for i:=0 to (ExtPic.Height-12) div 24 do MainText.LF;
    796           end;
    797         end;
    798       Delete(s,1,p);
    799       end
    800     else
    801       begin
    802       case s[1] of
    803         ':',';':
    804           begin // link
    805           p:=1;
    806           repeat inc(p) until (p>Length(s)) or (s[p]='\') or (s[p]=' ');
    807           DecodeItem(copy(s,2,p-2), LinkCategory, LinkIndex);
    808           CurrentFormat:=0;
    809           if (LinkCategory<>hkText) and (LinkIndex<200) then // show icon
    810             case LinkCategory of
    811               hkAdv:
    812                 begin CurrentFormat:=pkAdvIcon; Picpix:=LinkIndex end;
    813               hkImp:
    814                 begin CurrentFormat:=pkSmallIcon; Picpix:=LinkIndex end;
    815               hkTer:
    816                 begin CurrentFormat:=pkTer; Picpix:=LinkIndex end;
    817               hkFeature:
    818                 begin CurrentFormat:=pkFeature; Picpix:=LinkIndex end;
    819               hkModel:
    820                 begin
    821                 CurrentFormat:=pkModel;
    822                 FindStdModelPicture(SpecialModelPictureCode[LinkIndex],Picpix,Name);
    823                 end;
    824               end;
    825           if s[1]=':' then LinkCategory:=LinkCategory+hkCrossLink;
    826           if (p>Length(s)) or (s[p]=' ') then Delete(s,1,p)
    827           else Delete(s,1,p-1)
    828           end;
    829         '!': // highlited
    830           if (length(s)>=2) and (s[2]='!') then
    831             begin
    832             if MainText.Count>1 then MainText.LF;
    833             FollowFormat:=pkCaption;
    834             CurrentFormat:=pkCaption;
    835             Delete(s,1,2);
    836             end
    837           else
    838             begin
    839             FollowFormat:=pkSection;
    840             CurrentFormat:=pkSection;
    841             Delete(s,1,1);
    842             end;
    843         '-':
    844           begin // list
    845           FollowFormat:=pkNormal_Dot;
    846           CurrentFormat:=pkDot;
    847           Delete(s,1,1);
    848           end;
    849         else CurrentFormat:=FollowFormat;
    850         end;
    851       if FollowFormat=pkNormal_Dot then ofs:=20+4+8
    852       else ofs:=8;
    853       p:=0;
    854       repeat
    855         repeat inc(p) until (p>Length(s)) or (s[p]=' ') or (s[p]='\');
    856         if (BiColorTextWidth(Offscreen.Canvas,Copy(s,1,p-1))<=RightMargin-ofs) then
    857           l:=p-1
    858         else Break;
    859       until (p>=Length(s)) or (s[l+1]='\');
    860       MainText.AddLine(Copy(s,1,l),CurrentFormat,Picpix,LinkCategory,LinkIndex);
    861       if (l<Length(s)) and (s[l+1]='\') then FollowFormat:=pkNormal;
    862       Delete(s,1,l+1);
    863       end
    864     end
    865   end;
    8661050
    8671051  procedure AddItem(Item: string);
    8681052  begin
    869   AddText(HelpText.Lookup(Item));
     1053    AddText(HelpText.Lookup(Item));
    8701054  end;
    8711055
    8721056  procedure AddModelText(i: integer);
    8731057  var
    874   pix: integer;
    875   s: string;
    876   begin
    877   with MainText do
    878     begin
    879     if Count>1 then begin LF; LF; end;
    880     FindStdModelPicture(SpecialModelPictureCode[i],pix,s);
    881     AddLine(s,pkSection);
    882     AddLine(Format(HelpText.Lookup('STRENGTH'),
    883       [SpecialModel[i].Attack,SpecialModel[i].Defense]),pkNormal_64);
    884     AddLine(Format(HelpText.Lookup('SPEED'),
    885       [MovementToString(SpecialModel[i].Speed)]),pkModel,pix);
    886     if Difficulty=0 then
    887       AddLine(Format(HelpText.Lookup('BUILDCOST'),
    888         [SpecialModel[i].Cost]),pkNormal_64)
    889     else AddLine(Format(HelpText.Lookup('BUILDCOST'),
    890       [SpecialModel[i].Cost*BuildCostMod[Difficulty] div 12]),pkNormal_64);
    891     s:=HelpText.LookupByHandle(hSPECIALMODEL,i);
    892     if (s<>'') and (s<>'*') then AddText(s);
    893     if SpecialModelPreq[i]>=0 then AddPreqAdv(SpecialModelPreq[i])
    894     else if SpecialModelPreq[i]=preLighthouse then AddPreqImp(woLighthouse)
    895     else if SpecialModelPreq[i]=preBuilder then AddPreqImp(woPyramids)
    896     else if SpecialModelPreq[i]=preLeo then AddPreqImp(woLeo);
    897     if SpecialModelPreq[i]<>preNone then
    898       MainText[Count-1]:=Format(HelpText.Lookup('REQUIRED'),[MainText[Count-1]]);
     1058    pix: integer;
     1059    s: string;
     1060  begin
     1061    with MainText do
     1062    begin
     1063      if Count > 1 then
     1064      begin
     1065        LF;
     1066        LF;
     1067      end;
     1068      FindStdModelPicture(SpecialModelPictureCode[i], pix, s);
     1069      AddLine(s, pkSection);
     1070      AddLine(Format(HelpText.Lookup('STRENGTH'), [SpecialModel[i].Attack,
     1071        SpecialModel[i].Defense]), pkNormal_64);
     1072      AddLine(Format(HelpText.Lookup('SPEED'),
     1073        [MovementToString(SpecialModel[i].Speed)]), pkModel, pix);
     1074      if Difficulty = 0 then
     1075        AddLine(Format(HelpText.Lookup('BUILDCOST'), [SpecialModel[i].Cost]),
     1076          pkNormal_64)
     1077      else
     1078        AddLine(Format(HelpText.Lookup('BUILDCOST'),
     1079          [SpecialModel[i].Cost * BuildCostMod[Difficulty] div 12]),
     1080          pkNormal_64);
     1081      s := HelpText.LookupByHandle(hSPECIALMODEL, i);
     1082      if (s <> '') and (s <> '*') then
     1083        AddText(s);
     1084      if SpecialModelPreq[i] >= 0 then
     1085        AddPreqAdv(SpecialModelPreq[i])
     1086      else if SpecialModelPreq[i] = preLighthouse then
     1087        AddPreqImp(woLighthouse)
     1088      else if SpecialModelPreq[i] = preBuilder then
     1089        AddPreqImp(woPyramids)
     1090      else if SpecialModelPreq[i] = preLeo then
     1091        AddPreqImp(woLeo);
     1092      if SpecialModelPreq[i] <> preNone then
     1093        MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
     1094          [MainText[Count - 1]]);
    8991095    end
    9001096  end;
     
    9021098  procedure AddJobList;
    9031099  var
    904   i,JobCost: integer;
    905   begin
    906   with MainText do
    907     begin
    908     for i:=0 to nJobHelp-1 do
     1100    i, JobCost: integer;
     1101  begin
     1102    with MainText do
     1103    begin
     1104      for i := 0 to nJobHelp - 1 do
    9091105      begin
    910       if i>0 then begin LF; LF end;
    911       AddLine(Phrases.Lookup('JOBRESULT',JobHelp[i]),pkSection);
    912       AddLine;
    913       AddLine('',pkTerImp,i);
    914       AddLine;
    915       AddText(HelpText.LookupByHandle(hJOBHELP,i));
    916       JobCost:=-1;
    917       case JobHelp[i] of
    918         jCanal: JobCost:=CanalWork;
    919         jFort: JobCost:=FortWork;
    920         jBase: JobCost:=BaseWork;
     1106        if i > 0 then
     1107        begin
     1108          LF;
     1109          LF
    9211110        end;
    922       if JobCost>=0 then
    923         AddText(Format(HelpText.Lookup('JOBCOST'),[MovementToString(JobCost)]))
    924       else AddText(HelpText.Lookup('JOBCOSTVAR'));
    925       if JobPreq[JobHelp[i]]<>preNone then
     1111        AddLine(Phrases.Lookup('JOBRESULT', JobHelp[i]), pkSection);
     1112        AddLine;
     1113        AddLine('', pkTerImp, i);
     1114        AddLine;
     1115        AddText(HelpText.LookupByHandle(hJOBHELP, i));
     1116        JobCost := -1;
     1117        case JobHelp[i] of
     1118          jCanal:
     1119            JobCost := CanalWork;
     1120          jFort:
     1121            JobCost := FortWork;
     1122          jBase:
     1123            JobCost := BaseWork;
     1124        end;
     1125        if JobCost >= 0 then
     1126          AddText(Format(HelpText.Lookup('JOBCOST'),
     1127            [MovementToString(JobCost)]))
     1128        else
     1129          AddText(HelpText.Lookup('JOBCOSTVAR'));
     1130        if JobPreq[JobHelp[i]] <> preNone then
    9261131        begin
    927         AddPreqAdv(JobPreq[JobHelp[i]]);
    928         MainText[Count-1]:=Format(HelpText.Lookup('REQUIRED'),[MainText[Count-1]]);
     1132          AddPreqAdv(JobPreq[JobHelp[i]]);
     1133          MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
     1134            [MainText[Count - 1]]);
    9291135        end
    9301136      end;
     
    9341140  procedure AddGraphicCredits;
    9351141  var
    936   i: integer;
    937   s: string;
    938   sr: TSearchRec;
    939   List, plus: tstringlist;
    940   begin
    941   List:=tstringlist.Create;
    942   plus:=tstringlist.Create;
    943   if FindFirst(HomeDir+'Graphics\*.credits.txt',$27,sr)=0 then
    944     repeat
    945       plus.LoadFromFile(HomeDir+'Graphics\'+sr.Name);
    946       List.AddStrings(plus);
    947     until FindNext(sr)<>0;
    948   FindClose(sr);
    949   plus.Free;
    950 
    951   List.Sort;
    952   i:=1;
    953   while i<List.Count do
    954     if List[i]=List[i-1] then List.Delete(i)
    955     else inc(i);
    956 
    957   for i:=0 to List.Count-1 do
    958     begin
    959     s:=List[i];
    960     while BiColorTextWidth(Offscreen.Canvas,s)>InnerWidth-16
    961       -GetSystemMetrics(SM_CXVSCROLL) do
    962       Delete(s,Length(s),1);
    963     MainText.AddLine(s);
     1142    i: integer;
     1143    s: string;
     1144    sr: TSearchRec;
     1145    List, plus: TStringList;
     1146  begin
     1147    List := TStringList.Create;
     1148    plus := TStringList.Create;
     1149    if FindFirst(HomeDir + 'Graphics\*.credits.txt', $27, sr) = 0 then
     1150      repeat
     1151        plus.LoadFromFile(HomeDir + 'Graphics\' + sr.Name);
     1152        List.AddStrings(plus);
     1153      until FindNext(sr) <> 0;
     1154    FindClose(sr);
     1155    plus.Free;
     1156
     1157    List.Sort;
     1158    i := 1;
     1159    while i < List.Count do
     1160      if List[i] = List[i - 1] then
     1161        List.Delete(i)
     1162      else
     1163        inc(i);
     1164
     1165    for i := 0 to List.Count - 1 do
     1166    begin
     1167      s := List[i];
     1168      while BiColorTextWidth(OffScreen.Canvas, s) > InnerWidth - 16 -
     1169        GetSystemMetrics(SM_CXVSCROLL) do
     1170        Delete(s, length(s), 1);
     1171      MainText.AddLine(s);
    9641172    end;
    965   List.Free;
     1173    List.Free;
    9661174  end;
    9671175
    9681176  procedure AddSoundCredits;
    9691177  var
    970   i: integer;
    971   s: string;
    972   List: tstringlist;
    973   begin
    974   List:=tstringlist.Create;
    975   List.LoadFromFile(HomeDir+'Sounds\sound.credits.txt');
    976   for i:=0 to List.Count-1 do
    977     begin
    978     s:=List[i];
    979     while BiColorTextWidth(Offscreen.Canvas,s)>InnerWidth-16
    980       -GetSystemMetrics(SM_CXVSCROLL) do
    981       Delete(s,Length(s),1);
    982     MainText.AddLine(s);
     1178    i: integer;
     1179    s: string;
     1180    List: TStringList;
     1181  begin
     1182    List := TStringList.Create;
     1183    List.LoadFromFile(HomeDir + 'Sounds\sound.credits.txt');
     1184    for i := 0 to List.Count - 1 do
     1185    begin
     1186      s := List[i];
     1187      while BiColorTextWidth(OffScreen.Canvas, s) > InnerWidth - 16 -
     1188        GetSystemMetrics(SM_CXVSCROLL) do
     1189        Delete(s, length(s), 1);
     1190      MainText.AddLine(s);
    9831191    end;
    984   List.Free;
     1192    List.Free;
    9851193  end;
    9861194
    9871195  procedure NextSection(Item: string);
    9881196  begin
    989   if MainText.Count>1 then
    990     if MainText.Count=Headline+1 then MainText.Delete(Headline)
    991     else MainText.LF;
    992   MainText.AddLine(HelpText.Lookup(Item),pkSection);
    993   Headline:=MainText.Count-1;
    994   end;
    995 
    996 begin {Prepare}
    997 with MainText do
    998   begin
    999   offscreen.Canvas.Font.Assign(UniFont[ftNormal]);
    1000   CheckSeeAlso:=false;
    1001   Clear;
    1002   Headline:=-1;
    1003   if (no>=200) or not (Kind in [hkAdv,hkImp,hkTer,hkFeature]) then
    1004     LF;
    1005   case Kind of
    1006     hkText: AddText(HelpText.LookupByHandle(no));
    1007     hkMisc:
    1008       begin
    1009       case no of
    1010         miscMain:
     1197    if MainText.Count > 1 then
     1198      if MainText.Count = Headline + 1 then
     1199        MainText.Delete(Headline)
     1200      else
     1201        MainText.LF;
     1202    MainText.AddLine(HelpText.Lookup(Item), pkSection);
     1203    Headline := MainText.Count - 1;
     1204  end;
     1205
     1206begin { Prepare }
     1207  with MainText do
     1208  begin
     1209    OffScreen.Canvas.Font.Assign(UniFont[ftNormal]);
     1210    CheckSeeAlso := false;
     1211    Clear;
     1212    Headline := -1;
     1213    if (no >= 200) or not(Kind in [hkAdv, hkImp, hkTer, hkFeature]) then
     1214      LF;
     1215    case Kind of
     1216      hkText:
     1217        AddText(HelpText.LookupByHandle(no));
     1218      hkMisc:
     1219        begin
     1220          case no of
     1221            miscMain:
     1222              begin
     1223                Caption := HelpText.Lookup('HELPTITLE_MAIN');
     1224                AddLine(HelpText.Lookup('HELPTITLE_QUICKSTART'), pkSpecialIcon,
     1225                  0, { pkBigIcon,22, } hkText, HelpText.Gethandle('QUICK'));
     1226                LF;
     1227                AddLine(HelpText.Lookup('HELPTITLE_CONCEPTS'), pkBigIcon, 6,
     1228                  hkText, HelpText.Gethandle('CONCEPTS'));
     1229                LF;
     1230                AddLine(HelpText.Lookup('HELPTITLE_TERLIST'), pkSpecialIcon, 1,
     1231                  hkTer, 200);
     1232                LF;
     1233                AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkSpecialIcon, 2,
     1234                  hkMisc, miscJobList);
     1235                LF;
     1236                AddLine(HelpText.Lookup('HELPTITLE_TECHLIST'), pkBigIcon, 39,
     1237                  hkAdv, 200);
     1238                LF;
     1239                FindStdModelPicture(SpecialModelPictureCode[6], i, s);
     1240                AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'), pkModel, i,
     1241                  hkModel, 0);
     1242                LF;
     1243                AddLine(HelpText.Lookup('HELPTITLE_FEATURELIST'), pkBigIcon, 28,
     1244                  hkFeature, 200);
     1245                LF;
     1246                AddLine(HelpText.Lookup('HELPTITLE_IMPLIST'), pkBigIcon,
     1247                  7 * SystemIconLines + imCourt, hkImp, 200);
     1248                LF;
     1249                AddLine(HelpText.Lookup('HELPTITLE_UNIQUELIST'), pkBigIcon,
     1250                  7 * SystemIconLines + imStockEx, hkImp, 201);
     1251                LF;
     1252                AddLine(HelpText.Lookup('HELPTITLE_WONDERLIST'), pkBigIcon,
     1253                  7 * SystemIconLines, hkImp, 202);
     1254                LF;
     1255                AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'), pkBigIcon,
     1256                  gDemocracy + 6, hkMisc, miscGovList);
     1257                LF;
     1258                AddLine(HelpText.Lookup('HELPTITLE_KEYS'), pkBigIcon, 2, hkText,
     1259                  HelpText.Gethandle('HOTKEYS'));
     1260                LF;
     1261                AddLine(HelpText.Lookup('HELPTITLE_ABOUT'), pkBigIcon, 1,
     1262                  hkText, HelpText.Gethandle('ABOUT'));
     1263                LF;
     1264                AddLine(HelpText.Lookup('HELPTITLE_CREDITS'), pkBigIcon, 22,
     1265                  hkMisc, miscCredits);
     1266              end;
     1267            miscCredits:
     1268              begin
     1269                AddItem('CREDITS');
     1270                LF;
     1271                AddGraphicCredits;
     1272                NextSection('CRED_CAPSOUND');
     1273                AddSoundCredits;
     1274                NextSection('CRED_CAPAI');
     1275                Server(sGetAICredits, 0, 0, ps);
     1276                AddText(ps);
     1277                NextSection('CRED_CAPLANG');
     1278                AddItem('AUTHOR');
     1279              end;
     1280            miscJobList:
     1281              begin
     1282                Caption := HelpText.Lookup('HELPTITLE_JOBLIST');
     1283                AddJobList;
     1284                LF;
     1285                AddItem('TERIMPEXCLUDE');
     1286                LF;
     1287                AddItem('TERIMPCITY');
     1288              end;
     1289            miscGovList:
     1290              begin
     1291                Caption := HelpText.Lookup('HELPTITLE_GOVLIST');
     1292                for i := 1 to nGov do
     1293                begin
     1294                  AddLine(Phrases.Lookup('GOVERNMENT', i mod nGov), pkSection);
     1295                  LF;
     1296                  if i = nGov then
     1297                    AddLine('', pkBigIcon, 7 * SystemIconLines + imPalace)
     1298                  else
     1299                    AddLine('', pkBigIcon, i + 6);
     1300                  LF;
     1301                  AddText(HelpText.LookupByHandle(hGOVHELP, i mod nGov));
     1302                  if i mod nGov >= 2 then
     1303                  begin
     1304                    AddPreqAdv(GovPreq[i mod nGov]);
     1305                    MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
     1306                      [MainText[Count - 1]]);
     1307                  end;
     1308                  if i < nGov then
     1309                  begin
     1310                    LF;
     1311                    LF;
     1312                  end
     1313                end
     1314              end;
     1315            miscSearchResult:
     1316              begin
     1317                Caption := HelpText.Lookup('HELPTITLE_SEARCHRESULTS');
     1318                AddText(Format(HelpText.Lookup('MATCHES'), [SearchContent]));
     1319                MainText.AddStrings(SearchResult);
     1320              end
     1321          end; // case no
     1322        end;
     1323
     1324      hkAdv:
     1325        if no = 200 then
     1326        begin // complete advance list
     1327          Caption := HelpText.Lookup('HELPTITLE_TECHLIST');
     1328          List := THyperText.Create;
     1329          for j := 0 to 3 do
    10111330          begin
    1012           Caption:=HelpText.Lookup('HELPTITLE_MAIN');
    1013           AddLine(HelpText.Lookup('HELPTITLE_QUICKSTART'),pkSpecialIcon,0,{pkBigIcon,22,}hkText,HelpText.GetHandle('QUICK')); LF;
    1014           AddLine(HelpText.Lookup('HELPTITLE_CONCEPTS'),pkBigIcon,6,hkText,HelpText.GetHandle('CONCEPTS')); LF;
    1015           AddLine(HelpText.Lookup('HELPTITLE_TERLIST'),pkSpecialIcon,1,hkTer,200); LF;
    1016           AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'),pkSpecialIcon,2,hkMisc,miscJobList); LF;
    1017           AddLine(HelpText.Lookup('HELPTITLE_TECHLIST'),pkBigIcon,39,hkAdv,200); LF;
    1018           FindStdModelPicture(SpecialModelPictureCode[6],i,s);
    1019           AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'),pkModel,i,hkModel,0); LF;
    1020           AddLine(HelpText.Lookup('HELPTITLE_FEATURELIST'),pkBigIcon,28,hkFeature,200); LF;
    1021           AddLine(HelpText.Lookup('HELPTITLE_IMPLIST'),pkBigIcon,7*SystemIconLines+imCourt,hkImp,200); LF;
    1022           AddLine(HelpText.Lookup('HELPTITLE_UNIQUELIST'),pkBigIcon,7*SystemIconLines+imStockEx,hkImp,201); LF;
    1023           AddLine(HelpText.Lookup('HELPTITLE_WONDERLIST'),pkBigIcon,7*SystemIconLines,hkImp,202); LF;
    1024           AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'),pkBigIcon,gDemocracy+6,hkMisc,miscGovList); LF;
    1025           AddLine(HelpText.Lookup('HELPTITLE_KEYS'),pkBigIcon,2,hkText,HelpText.GetHandle('HOTKEYS')); LF;
    1026           AddLine(HelpText.Lookup('HELPTITLE_ABOUT'),pkBigIcon,1,hkText,HelpText.GetHandle('ABOUT')); LF;
    1027           AddLine(HelpText.Lookup('HELPTITLE_CREDITS'),pkBigIcon,22,hkMisc,miscCredits);
     1331            if j > 0 then
     1332            begin
     1333              LF;
     1334              LF;
     1335            end;
     1336            AddLine(HelpText.Lookup('TECHAGE', j), pkSection);
     1337            if j = 1 then
     1338              AddLine(Phrases.Lookup('ADVANCES', adScience) + ' ' +
     1339                HelpText.Lookup('BASETECH'), pkAdvIcon, adScience, hkAdv,
     1340                adScience);
     1341            if j = 2 then
     1342              AddLine(Phrases.Lookup('ADVANCES', adMassProduction) + ' ' +
     1343                HelpText.Lookup('BASETECH'), pkAdvIcon, adMassProduction, hkAdv,
     1344                adMassProduction);
     1345            List.Clear;
     1346            for i := 0 to nAdv - 1 do
     1347              if (i <> adScience) and (i <> adMassProduction) and
     1348                (AdvValue[i] div 1000 = j) then
     1349                List.AddLine(Phrases.Lookup('ADVANCES', i), pkAdvIcon, i,
     1350                  hkAdv, i);
     1351            List.Sort;
     1352            AddStrings(List);
    10281353          end;
    1029         miscCredits:
     1354          List.Free
     1355        end
     1356        else // single advance
     1357        begin
     1358          Caption := Phrases.Lookup('ADVANCES', no);
     1359          LF;
     1360          AddLine(Phrases.Lookup('ADVANCES', no), pkCaption);
     1361          if no in FutureTech then
    10301362          begin
    1031           AddItem('CREDITS');
    1032           LF;
    1033           AddGraphicCredits;
    1034           NextSection('CRED_CAPSOUND');
    1035           AddSoundCredits;
    1036           NextSection('CRED_CAPAI');
    1037           Server(sGetAICredits,0,0,ps);
    1038           AddText(ps);
    1039           NextSection('CRED_CAPLANG');
    1040           AddItem('AUTHOR');
    1041           end;
    1042         miscJobList:
    1043           begin
    1044           Caption:=HelpText.Lookup('HELPTITLE_JOBLIST');
    1045           AddJobList;
    1046           LF;
    1047           AddItem('TERIMPEXCLUDE');
    1048           LF;
    1049           AddItem('TERIMPCITY');
    1050           end;
    1051         miscGovList:
    1052           begin
    1053           Caption:=HelpText.Lookup('HELPTITLE_GOVLIST');
    1054           for i:=1 to nGov do
    1055             begin
    1056             AddLine(Phrases.Lookup('GOVERNMENT',i mod nGov),pkSection);
     1363            AddLine(HelpText.Lookup('HELPSPEC_FUTURE'));
    10571364            LF;
    1058             if i=nGov then
    1059               AddLine('',pkBigIcon,7*SystemIconLines+imPalace)
    1060             else AddLine('',pkBigIcon,i+6);
    1061             LF;
    1062             AddText(HelpText.LookupByHandle(hGOVHELP,i mod nGov));
    1063             if i mod nGov>=2 then
     1365            if no = futResearchTechnology then
     1366              AddItem('FUTURETECHHELP100')
     1367            else
     1368              AddItem('FUTURETECHHELP25');
     1369          end
     1370          else
     1371            AddLine(HelpText.Lookup('HELPSPEC_ADV'));
     1372          if AdvPreq[no, 2] <> preNone then
     1373            NextSection('PREREQALT')
     1374          else
     1375            NextSection('PREREQ');
     1376          for i := 0 to 2 do
     1377            if AdvPreq[no, i] <> preNone then
     1378              AddPreqAdv(AdvPreq[no, i]);
     1379          NextSection('GOVALLOW');
     1380          for i := 2 to nGov - 1 do
     1381            if GovPreq[i] = no then
     1382              AddLine(Phrases.Lookup('GOVERNMENT', i), pkGov, i,
     1383                hkMisc + hkCrossLink, miscGovList);
     1384          NextSection('BUILDALLOW');
     1385          for i := 0 to 27 do
     1386            if Imp[i].Preq = no then
     1387              AddImp(i);
     1388          for i := 28 to nImp - 1 do
     1389            if (Imp[i].Preq = no) and (Imp[i].Kind <> ikCommon) then
     1390              AddImp(i);
     1391          for i := 28 to nImp - 1 do
     1392            if (Imp[i].Preq = no) and (Imp[i].Kind = ikCommon) then
     1393              AddImp(i);
     1394          NextSection('MODELALLOW');
     1395          for i := 0 to nSpecialModel - 1 do
     1396            if SpecialModelPreq[i] = no then
     1397              AddModel(i);
     1398          NextSection('FEATALLOW');
     1399          for i := 0 to nFeature - 1 do
     1400            if Feature[i].Preq = no then
     1401              AddFeature(i);
     1402          NextSection('FOLLOWADV');
     1403          for i := 0 to nAdv - 1 do
     1404            if (AdvPreq[i, 0] = no) or (AdvPreq[i, 1] = no) or
     1405              (AdvPreq[i, 2] = no) then
     1406              AddAdv(i);
     1407          NextSection('UPGRADEALLOW');
     1408          for Domain := 0 to nDomains - 1 do
     1409            for i := 1 to nUpgrade - 1 do
     1410              if upgrade[Domain, i].Preq = no then
    10641411              begin
    1065               AddPreqAdv(GovPreq[i mod nGov]);
    1066               MainText[Count-1]:=Format(HelpText.Lookup('REQUIRED'),[MainText[Count-1]]);
     1412                if upgrade[Domain, i].Strength > 0 then
     1413                  AddLine(Format(HelpText.Lookup('STRENGTHUP'),
     1414                    [Phrases.Lookup('DOMAIN', Domain), upgrade[Domain,
     1415                    i].Strength]), pkDomain, Domain);
     1416                if upgrade[Domain, i].Trans > 0 then
     1417                  AddLine(Format(HelpText.Lookup('TRANSUP'),
     1418                    [Phrases.Lookup('DOMAIN', Domain), upgrade[Domain, i].Trans]
     1419                    ), pkDomain, Domain);
     1420                if no in FutureTech then
     1421                  AddLine(Format(HelpText.Lookup('COSTUP'),
     1422                    [upgrade[Domain, i].Cost]), pkNormal_Dot)
     1423                else
     1424                  AddLine(Format(HelpText.Lookup('COSTMIN'),
     1425                    [upgrade[Domain, i].Cost]), pkNormal_Dot)
    10671426              end;
    1068             if i<nGov then begin LF; LF; end
    1069             end
    1070           end;
    1071         miscSearchResult:
    1072           begin
    1073           Caption:=HelpText.Lookup('HELPTITLE_SEARCHRESULTS');
    1074           AddText(Format(HelpText.Lookup('MATCHES'), [SearchContent]));
    1075           MainText.AddStrings(SearchResult);
    1076           end
    1077         end; // case no
    1078       end;
    1079 
    1080     hkAdv:
    1081       if no=200 then
    1082         begin // complete advance list
    1083         Caption:=HelpText.Lookup('HELPTITLE_TECHLIST');
    1084         List:=THyperText.Create;
    1085         for j:=0 to 3 do
    1086           begin
    1087           if j>0 then begin LF; LF; end;
    1088           AddLine(HelpText.Lookup('TECHAGE',j),pkSection);
    1089           if j=1 then
    1090             AddLine(Phrases.Lookup('ADVANCES',adScience)+' '
    1091               +HelpText.Lookup('BASETECH'),
    1092               pkAdvIcon,adScience,hkAdv,adScience);
    1093           if j=2 then
    1094             AddLine(Phrases.Lookup('ADVANCES',adMassProduction)+' '
    1095               +HelpText.Lookup('BASETECH'),
    1096               pkAdvIcon,adMassProduction,hkAdv,adMassProduction);
    1097           List.Clear;
    1098           for i:=0 to nAdv-1 do
    1099             if (i<>adScience) and (i<>adMassProduction) and (AdvValue[i] div 1000=j) then
    1100               List.AddLine(Phrases.Lookup('ADVANCES',i),pkAdvIcon,i,hkAdv,i);
     1427          NextSection('EXPIRATION');
     1428          for i := 0 to 27 do
     1429            if (Imp[i].Preq <> preNA) and (Imp[i].Expiration = no) then
     1430              AddImp(i);
     1431          NextSection('ADVEFFECT');
     1432          s := HelpText.LookupByHandle(hADVHELP, no);
     1433          if s <> '*' then
     1434            AddText(s);
     1435          NextSection('SEEALSO');
     1436          CheckSeeAlso := true
     1437        end;
     1438
     1439      hkImp:
     1440        if no = 200 then
     1441        begin // complete city improvement list
     1442          Caption := HelpText.Lookup('HELPTITLE_IMPLIST');
     1443          // AddLine(HelpText.Lookup('HELPTITLE_IMPLIST'),pkSection);
     1444          List := THyperText.Create;
     1445          for i := 28 to nImp - 1 do
     1446            if (i <> imTrGoods) and (Imp[i].Preq <> preNA) and
     1447              (Imp[i].Kind = ikCommon) then
     1448              List.AddLine(Phrases.Lookup('IMPROVEMENTS', i), pkSmallIcon,
     1449                i, hkImp, i);
    11011450          List.Sort;
    11021451          AddStrings(List);
     1452          List.Free
     1453        end
     1454        else if no = 201 then
     1455        begin // complete nat. project list
     1456          Caption := HelpText.Lookup('HELPTITLE_UNIQUELIST');
     1457          // AddLine(HelpText.Lookup('HELPTITLE_UNIQUELIST'),pkSection);
     1458          for i := 28 to nImp - 1 do
     1459            if (Imp[i].Preq <> preNA) and
     1460              ((Imp[i].Kind = ikNatLocal) or (Imp[i].Kind = ikNatGlobal)) then
     1461              AddLine(Phrases.Lookup('IMPROVEMENTS', i), pkSmallIcon, i,
     1462                hkImp, i);
     1463          { LF;
     1464            LF;
     1465            AddLine(HelpText.Lookup('HELPTITLE_SHIPPARTLIST'),pkSection);
     1466            for i:=28 to nImp-1 do
     1467            if (Imp[i].Preq<>preNA) and (Imp[i].Kind=ikShipPart) then
     1468            AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon,i,hkImp,i); }
     1469        end
     1470        else if no = 202 then
     1471        begin // complete wonder list
     1472          Caption := HelpText.Lookup('HELPTITLE_WONDERLIST');
     1473          // AddLine(HelpText.Lookup('HELPTITLE_WONDERLIST'),pkSection);
     1474          for i := 0 to 27 do
     1475            if Imp[i].Preq <> preNA then
     1476              AddLine(Phrases.Lookup('IMPROVEMENTS', i), pkSmallIcon, i,
     1477                hkImp, i);
     1478        end
     1479        else
     1480        begin // single building
     1481          Caption := Phrases.Lookup('IMPROVEMENTS', no);
     1482          LF;
     1483          AddLine(Phrases.Lookup('IMPROVEMENTS', no), pkRightIcon, no);
     1484          case Imp[no].Kind of
     1485            ikWonder:
     1486              AddLine(HelpText.Lookup('HELPSPEC_WONDER'));
     1487            ikCommon:
     1488              AddLine(HelpText.Lookup('HELPSPEC_IMP'));
     1489            ikShipPart:
     1490              AddLine(HelpText.Lookup('HELPSPEC_SHIPPART'));
     1491          else
     1492            AddLine(HelpText.Lookup('HELPSPEC_NAT'))
    11031493          end;
    1104         List.Free
     1494          if Imp[no].Kind <> ikShipPart then
     1495          begin
     1496            NextSection('EFFECT');
     1497            AddText(HelpText.LookupByHandle(hIMPHELP, no));
     1498          end;
     1499          if no = woSun then
     1500          begin
     1501            AddFeature(mcFirst);
     1502            AddFeature(mcWill);
     1503            AddFeature(mcAcademy);
     1504          end;
     1505          if (no < 28) and not Phrases2FallenBackToEnglish then
     1506          begin
     1507            LF;
     1508            if Imp[no].Expiration >= 0 then
     1509              AddText(Phrases2.Lookup('HELP_WONDERMORALE1'))
     1510            else
     1511              AddText(Phrases2.Lookup('HELP_WONDERMORALE2'));
     1512          end;
     1513          if Imp[no].Preq <> preNone then
     1514          begin
     1515            NextSection('PREREQ');
     1516            AddPreqAdv(Imp[no].Preq);
     1517          end;
     1518          NextSection('COSTS');
     1519          if Difficulty = 0 then
     1520            s := Format(HelpText.Lookup('BUILDCOST'), [Imp[no].Cost])
     1521          else
     1522            s := Format(HelpText.Lookup('BUILDCOST'),
     1523              [Imp[no].Cost * BuildCostMod[Difficulty] div 12]);
     1524          AddLine(s);
     1525          if Imp[no].Maint > 0 then
     1526            AddLine(Format(HelpText.Lookup('MAINTCOST'), [Imp[no].Maint]));
     1527          j := 0;
     1528          for i := 0 to nImpReplacement - 1 do
     1529            if ImpReplacement[i].NewImp = no then
     1530            begin
     1531              if j = 0 then
     1532              begin
     1533                NextSection('REPLACE');
     1534                AddItem('REPLACETEXT');
     1535                j := 1
     1536              end;
     1537              AddImp(ImpReplacement[i].OldImp);
     1538            end;
     1539          if Imp[no].Kind = ikShipPart then
     1540          begin
     1541            LF;
     1542            if no = imShipComp then
     1543              i := 1
     1544            else if no = imShipPow then
     1545              i := 2
     1546            else { if no=imShipHab then }
     1547              i := 3;
     1548            AddLine(Format(HelpText.Lookup('RAREREQUIRED'),
     1549              [Phrases.Lookup('TERRAIN', 3 * 12 + i)]), pkTer, 3 * 12 + i);
     1550          end;
     1551          if (no < 28) and (Imp[no].Expiration >= 0) then
     1552          begin
     1553            NextSection('EXPIRATION');
     1554            s := Format(HelpText.Lookup('EXPWITH'),
     1555              [Phrases.Lookup('ADVANCES', Imp[no].Expiration)]);
     1556            if no = woPyramids then
     1557              s := s + ' ' + HelpText.Lookup('EXPSLAVE');
     1558            AddText(s);
     1559          end;
     1560          NextSection('SEEALSO');
     1561          if (no < 28) and (Imp[no].Expiration >= 0) then
     1562            AddImp(woEiffel);
     1563          for i := 0 to nImpReplacement - 1 do
     1564            if ImpReplacement[i].OldImp = no then
     1565              AddImp(ImpReplacement[i].NewImp);
     1566          if no = imSupermarket then
     1567            AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkNormal, 0,
     1568              hkMisc + hkCrossLink, miscJobList);
     1569          CheckSeeAlso := true
     1570        end;
     1571
     1572      hkTer:
     1573        if no = 200 then
     1574        begin // complete terrain type list
     1575          Caption := HelpText.Lookup('HELPTITLE_TERLIST');
     1576          // AddLine(HelpText.Lookup('HELPTITLE_TERLIST'),pkSection);
     1577          for i := 0 to nTerrainHelp - 1 do
     1578            AddTer(TerrainHelp[i]);
    11051579        end
    1106       else // single advance
    1107         begin
    1108         Caption:=Phrases.Lookup('ADVANCES',no);
    1109         LF;
    1110         AddLine(Phrases.Lookup('ADVANCES',no),pkCaption);
    1111         if no in FutureTech then
     1580        else
     1581        begin // sigle terrain type
     1582          TerrType := no mod 12;
     1583          if TerrType = fJungle then
     1584            TerrType := fForest;
     1585          TerrSubType := no div 12;
     1586          if no = 3 * 12 then
    11121587          begin
    1113           AddLine(HelpText.Lookup('HELPSPEC_FUTURE'));
    1114           LF;
    1115           if no=futResearchTechnology then
    1116             AddItem('FUTURETECHHELP100')
    1117           else AddItem('FUTURETECHHELP25');
    1118           end
    1119         else AddLine(HelpText.Lookup('HELPSPEC_ADV'));
    1120         if AdvPreq[no,2]<>preNone then NextSection('PREREQALT')
    1121         else NextSection('PREREQ');
    1122         for i:=0 to 2 do
    1123           if AdvPreq[no,i]<>preNone then AddPreqAdv(AdvPreq[no,i]);
    1124         NextSection('GOVALLOW');
    1125         for i:=2 to nGov-1 do
    1126           if GovPreq[i]=no then
    1127             AddLine(Phrases.Lookup('GOVERNMENT',i),pkGov,i,
    1128               hkMisc+hkCrossLink,miscGovList);
    1129         NextSection('BUILDALLOW');
    1130         for i:=0 to 27 do
    1131           if Imp[i].Preq=no then AddImp(i);
    1132         for i:=28 to nImp-1 do
    1133           if (Imp[i].Preq=no) and (Imp[i].Kind<>ikCommon) then AddImp(i);
    1134         for i:=28 to nImp-1 do
    1135           if (Imp[i].Preq=no) and (Imp[i].Kind=ikCommon) then AddImp(i);
    1136         NextSection('MODELALLOW');
    1137         for i:=0 to nSpecialModel-1 do
    1138           if SpecialModelPreq[i]=no then AddModel(i);
    1139         NextSection('FEATALLOW');
    1140         for i:=0 to nFeature-1 do if Feature[i].Preq=no then AddFeature(i);
    1141         NextSection('FOLLOWADV');
    1142         for i:=0 to nAdv-1 do
    1143           if (AdvPreq[i,0]=no) or (AdvPreq[i,1]=no) or (AdvPreq[i,2]=no) then
    1144             AddAdv(i);
    1145         NextSection('UPGRADEALLOW');
    1146         for Domain:=0 to nDomains-1 do for i:=1 to nUpgrade-1 do
    1147           if upgrade[Domain,i].Preq=no then
    1148             begin
    1149             if upgrade[Domain,i].Strength>0 then
    1150               AddLine(Format(HelpText.Lookup('STRENGTHUP'),
    1151                 [Phrases.Lookup('DOMAIN',Domain),upgrade[Domain,i].Strength]),
    1152                 pkDomain,Domain);
    1153             if upgrade[Domain,i].Trans>0 then
    1154               AddLine(Format(HelpText.Lookup('TRANSUP'),
    1155                 [Phrases.Lookup('DOMAIN',Domain),upgrade[Domain,i].Trans]),
    1156                 pkDomain,Domain);
    1157             if no in FutureTech then
    1158               AddLine(Format(HelpText.Lookup('COSTUP'),
    1159                 [upgrade[Domain,i].Cost]),pkNormal_Dot)
    1160             else
    1161               AddLine(Format(HelpText.Lookup('COSTMIN'),
    1162                 [upgrade[Domain,i].Cost]),pkNormal_Dot)
    1163             end;
    1164         NextSection('EXPIRATION');
    1165         for i:=0 to 27 do
    1166           if (Imp[i].Preq<>preNA) and (Imp[i].Expiration=no) then AddImp(i);
    1167         NextSection('ADVEFFECT');
    1168         s:=HelpText.LookupByHandle(hADVHELP,no);
    1169         if s<>'*' then AddText(s);
    1170         NextSection('SEEALSO');
    1171         CheckSeeAlso:=true
    1172         end;
    1173 
    1174     hkImp:
    1175       if no=200 then
    1176         begin // complete city improvement list
    1177         Caption:=HelpText.Lookup('HELPTITLE_IMPLIST');
    1178 //        AddLine(HelpText.Lookup('HELPTITLE_IMPLIST'),pkSection);
    1179         List:=THyperText.Create;
    1180         for i:=28 to nImp-1 do
    1181           if (i<>imTrGoods) and (Imp[i].Preq<>preNA) and (Imp[i].Kind=ikCommon) then
    1182             List.AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon,i,hkImp,i);
    1183         List.Sort;
    1184         AddStrings(List);
    1185         List.Free
    1186         end
    1187       else if no=201 then
    1188         begin // complete nat. project list
    1189         Caption:=HelpText.Lookup('HELPTITLE_UNIQUELIST');
    1190 //        AddLine(HelpText.Lookup('HELPTITLE_UNIQUELIST'),pkSection);
    1191         for i:=28 to nImp-1 do
    1192           if (Imp[i].Preq<>preNA)
    1193             and ((Imp[i].Kind=ikNatLocal) or (Imp[i].Kind=ikNatGlobal)) then
    1194             AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon,i,hkImp,i);
    1195 {        LF;
    1196         LF;
    1197         AddLine(HelpText.Lookup('HELPTITLE_SHIPPARTLIST'),pkSection);
    1198         for i:=28 to nImp-1 do
    1199           if (Imp[i].Preq<>preNA) and (Imp[i].Kind=ikShipPart) then
    1200             AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon,i,hkImp,i);}
    1201         end
    1202       else if no=202 then
    1203         begin // complete wonder list
    1204         Caption:=HelpText.Lookup('HELPTITLE_WONDERLIST');
    1205 //        AddLine(HelpText.Lookup('HELPTITLE_WONDERLIST'),pkSection);
    1206         for i:=0 to 27 do if Imp[i].Preq<>preNA then
    1207           AddLine(Phrases.Lookup('IMPROVEMENTS',i),pkSmallIcon,i,hkImp,i);
    1208         end
    1209       else
    1210         begin // single building
    1211         Caption:=Phrases.Lookup('IMPROVEMENTS',no);
    1212         LF;
    1213         AddLine(Phrases.Lookup('IMPROVEMENTS',no),pkRightIcon,no);
    1214         case Imp[no].Kind of
    1215           ikWonder: AddLine(HelpText.Lookup('HELPSPEC_WONDER'));
    1216           ikCommon: AddLine(HelpText.Lookup('HELPSPEC_IMP'));
    1217           ikShipPart: AddLine(HelpText.Lookup('HELPSPEC_SHIPPART'));
    1218           else AddLine(HelpText.Lookup('HELPSPEC_NAT'))
     1588            TerrType := fDesert;
     1589            TerrSubType := 0
    12191590          end;
    1220         if Imp[no].Kind<>ikShipPart then
     1591          with Terrain[TerrType] do
    12211592          begin
    1222           NextSection('EFFECT');
    1223           AddText(HelpText.LookupByHandle(hIMPHELP,no));
    1224           end;
    1225         if no=woSun then
    1226           begin
    1227           AddFeature(mcFirst);
    1228           AddFeature(mcWill);
    1229           AddFeature(mcAcademy);
    1230           end;
    1231         if (no<28) and not Phrases2FallenBackToEnglish then
    1232           begin
    1233           LF;
    1234           if Imp[no].Expiration>=0 then
    1235             AddText(Phrases2.Lookup('HELP_WONDERMORALE1'))
    1236           else AddText(Phrases2.Lookup('HELP_WONDERMORALE2'));
    1237           end;
    1238         if Imp[no].Preq<>preNone then
    1239           begin
    1240           NextSection('PREREQ');
    1241           AddPreqAdv(Imp[no].Preq);
    1242           end;
    1243         NextSection('COSTS');
    1244         if Difficulty=0 then
    1245           s:=Format(HelpText.Lookup('BUILDCOST'),[Imp[no].Cost])
    1246         else s:=Format(HelpText.Lookup('BUILDCOST'),
    1247           [Imp[no].Cost*BuildCostMod[Difficulty] div 12]);
    1248         AddLine(s);
    1249         if Imp[no].Maint>0 then
    1250           AddLine(Format(HelpText.Lookup('MAINTCOST'),[Imp[no].Maint]));
    1251         j:=0;
    1252         for i:=0 to nImpReplacement-1 do if ImpReplacement[i].NewImp=no then
    1253           begin
    1254           if j=0 then
    1255             begin NextSection('REPLACE'); AddItem('REPLACETEXT'); j:=1 end;
    1256           AddImp(ImpReplacement[i].OldImp);
    1257           end;
    1258         if Imp[no].Kind=ikShipPart then
    1259           begin
    1260           LF;
    1261           if no=imShipComp then i:=1
    1262           else if no=imShipPow then i:=2
    1263           else {if no=imShipHab then} i:=3;
    1264           AddLine(Format(HelpText.Lookup('RAREREQUIRED'),
    1265             [Phrases.Lookup('TERRAIN',3*12+i)]),pkTer,3*12+i);
    1266           end;
    1267         if (no<28) and (Imp[no].Expiration>=0) then
    1268           begin
    1269           NextSection('EXPIRATION');
    1270           s:=Format(HelpText.Lookup('EXPWITH'),[Phrases.Lookup('ADVANCES',Imp[no].Expiration)]);
    1271           if no=woPyramids then s:=s+' '+HelpText.Lookup('EXPSLAVE');
    1272           AddText(s);
    1273           end;
    1274         NextSection('SEEALSO');
    1275         if (no<28) and (Imp[no].Expiration>=0) then AddImp(woEiffel);
    1276         for i:=0 to nImpReplacement-1 do if ImpReplacement[i].OldImp=no then
    1277           AddImp(ImpReplacement[i].NewImp);
    1278         if no=imSupermarket then
    1279           AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'),pkNormal,0,hkMisc+hkCrossLink,miscJobList);
    1280         CheckSeeAlso:=true
    1281         end;
    1282 
    1283     hkTer:
    1284       if no=200 then
    1285         begin // complete terrain type list
    1286         Caption:=HelpText.Lookup('HELPTITLE_TERLIST');
    1287 //        AddLine(HelpText.Lookup('HELPTITLE_TERLIST'),pkSection);
    1288         for i:=0 to nTerrainHelp-1 do AddTer(TerrainHelp[i]);
    1289         end
    1290       else
    1291         begin // sigle terrain type
    1292         TerrType:=no mod 12;
    1293         if TerrType=fJungle then TerrType:=fForest;
    1294         TerrSubType:=no div 12;
    1295         if no=3*12 then
    1296           begin TerrType:=fDesert; TerrSubType:=0 end;
    1297         with Terrain[TerrType] do
    1298           begin
    1299           Caption:=Phrases.Lookup('TERRAIN',no);
    1300           LF;
    1301           AddLine(Phrases.Lookup('TERRAIN',no), pkBigTer, no);
    1302           AddLine(HelpText.Lookup('HELPSPEC_TER'));
    1303           LF;
    1304           if (ProdRes[TerrSubType]>0) or (MineEff>0) then
    1305             AddLine(Format(HelpText.Lookup('RESPROD'),[ProdRes[TerrSubType]]));
    1306           if (no<3*12) and (MineEff>0) then
    1307             MainText[Count-1]:=MainText[Count-1]+' '
    1308               +Format(HelpText.Lookup('MOREMINE'),[MineEff]);
    1309           if (FoodRes[TerrSubType]>0) or (IrrEff>0) then
    1310             AddLine(Format(HelpText.Lookup('RESFOOD'),[FoodRes[TerrSubType]]));
    1311           if (no<3*12) and (IrrEff>0) then
    1312             MainText[Count-1]:=MainText[Count-1]+' '
    1313               +Format(HelpText.Lookup('MOREIRR'),[IrrEff]);
    1314           if TradeRes[TerrSubType]>0 then
    1315             AddLine(Format(HelpText.Lookup('RESTRADE'),[TradeRes[TerrSubType]]));
    1316           if Defense>4 then
    1317             AddLine(Format(HelpText.Lookup('DEFBONUS'),[(Defense-4)*25]));
    1318           if (TerrType>=fGrass) and (TerrType<>fMountains) then
    1319             if MoveCost=2 then
    1320               AddLine(HelpText.Lookup('MOVEHEAVY'))
    1321             else AddLine(HelpText.Lookup('MOVEPLAIN'));
    1322           if no=3*12 then
    1323             begin
     1593            Caption := Phrases.Lookup('TERRAIN', no);
    13241594            LF;
    1325             AddText(HelpText.Lookup('DEADLANDS'));
    1326             end;
    1327           if (TerrType=fDesert) and (no<>fDesert+12) then
    1328             begin
     1595            AddLine(Phrases.Lookup('TERRAIN', no), pkBigTer, no);
     1596            AddLine(HelpText.Lookup('HELPSPEC_TER'));
    13291597            LF;
    1330             AddText(Format(HelpText.Lookup('HOSTILE'),[DesertThurst]));
    1331             end;
    1332           if TerrType=fArctic then
    1333             begin
    1334             LF;
    1335             AddText(Format(HelpText.Lookup('HOSTILE'),[ArcticThurst]));
    1336             end;
    1337           if (no<3*12) and (TransTerrain>=0) then
    1338             begin
    1339             LF;
    1340             i:=TransTerrain;
    1341             if (TerrType<>fGrass) and (i<>fGrass) then
    1342               i:=i+TerrSubType*12; // trafo to same special resource group
    1343             AddLine(Format(HelpText.Lookup('TRAFO'),
    1344               [Phrases.Lookup('TERRAIN',i)]),pkTer,i,hkTer+hkCrossLink,i);
    1345             if no=fSwamp+12 then
     1598            if (ProdRes[TerrSubType] > 0) or (MineEff > 0) then
     1599              AddLine(Format(HelpText.Lookup('RESPROD'),
     1600                [ProdRes[TerrSubType]]));
     1601            if (no < 3 * 12) and (MineEff > 0) then
     1602              MainText[Count - 1] := MainText[Count - 1] + ' ' +
     1603                Format(HelpText.Lookup('MOREMINE'), [MineEff]);
     1604            if (FoodRes[TerrSubType] > 0) or (IrrEff > 0) then
     1605              AddLine(Format(HelpText.Lookup('RESFOOD'),
     1606                [FoodRes[TerrSubType]]));
     1607            if (no < 3 * 12) and (IrrEff > 0) then
     1608              MainText[Count - 1] := MainText[Count - 1] + ' ' +
     1609                Format(HelpText.Lookup('MOREIRR'), [IrrEff]);
     1610            if TradeRes[TerrSubType] > 0 then
     1611              AddLine(Format(HelpText.Lookup('RESTRADE'),
     1612                [TradeRes[TerrSubType]]));
     1613            if Defense > 4 then
     1614              AddLine(Format(HelpText.Lookup('DEFBONUS'),
     1615                [(Defense - 4) * 25]));
     1616            if (TerrType >= fGrass) and (TerrType <> fMountains) then
     1617              if MoveCost = 2 then
     1618                AddLine(HelpText.Lookup('MOVEHEAVY'))
     1619              else
     1620                AddLine(HelpText.Lookup('MOVEPLAIN'));
     1621            if no = 3 * 12 then
     1622            begin
     1623              LF;
     1624              AddText(HelpText.Lookup('DEADLANDS'));
     1625            end;
     1626            if (TerrType = fDesert) and (no <> fDesert + 12) then
     1627            begin
     1628              LF;
     1629              AddText(Format(HelpText.Lookup('HOSTILE'), [DesertThurst]));
     1630            end;
     1631            if TerrType = fArctic then
     1632            begin
     1633              LF;
     1634              AddText(Format(HelpText.Lookup('HOSTILE'), [ArcticThurst]));
     1635            end;
     1636            if (no < 3 * 12) and (TransTerrain >= 0) then
     1637            begin
     1638              LF;
     1639              i := TransTerrain;
     1640              if (TerrType <> fGrass) and (i <> fGrass) then
     1641                i := i + TerrSubType * 12;
     1642              // trafo to same special resource group
     1643              AddLine(Format(HelpText.Lookup('TRAFO'),
     1644                [Phrases.Lookup('TERRAIN', i)]), pkTer, i,
     1645                hkTer + hkCrossLink, i);
     1646              if no = fSwamp + 12 then
    13461647              begin
     1648                LF;
     1649                AddLine(Format(HelpText.Lookup('TRAFO'),
     1650                  [Phrases.Lookup('TERRAIN', TransTerrain + 24)]), pkTer,
     1651                  TransTerrain + 24, hkTer + hkCrossLink, TransTerrain + 24);
     1652              end
     1653              else if i = fGrass then
     1654              begin
     1655                LF;
     1656                AddLine(Format(HelpText.Lookup('TRAFO'),
     1657                  [Phrases.Lookup('TERRAIN', fGrass + 12)]), pkTer, fGrass + 12,
     1658                  hkTer + hkCrossLink, fGrass + 12);
     1659              end
     1660            end;
     1661            NextSection('SPECIAL');
     1662            if no = 3 * 12 then
     1663            begin
    13471664              LF;
    1348               AddLine(Format(HelpText.Lookup('TRAFO'),
    1349                 [Phrases.Lookup('TERRAIN',TransTerrain+24)]),pkTer,TransTerrain+24,
    1350                 hkTer+hkCrossLink,TransTerrain+24);
    1351               end
    1352             else if i=fGrass then
     1665              for special := 1 to 3 do
    13531666              begin
    1354               LF;
    1355               AddLine(Format(HelpText.Lookup('TRAFO'),
    1356                 [Phrases.Lookup('TERRAIN',fGrass+12)]),pkTer,fGrass+12,
    1357                 hkTer+hkCrossLink,fGrass+12);
    1358               end
    1359             end;
    1360           NextSection('SPECIAL');
    1361           if no=3*12 then
    1362             begin
    1363             LF;
    1364             for special:=1 to 3 do
    1365               begin
    1366               if special>1 then LF;
    1367               AddLine(Phrases.Lookup('TERRAIN',3*12+special),pkTer,3*12+special);
     1667                if special > 1 then
     1668                  LF;
     1669                AddLine(Phrases.Lookup('TERRAIN', 3 * 12 + special), pkTer,
     1670                  3 * 12 + special);
    13681671              end
    13691672            end
    1370           else if (no<12) and (no<>fGrass) and (no<>fOcean) then
    1371             begin
    1372             LF;
    1373             for special:=1 to 2 do
    1374               if (no<>fArctic) and (no<>fSwamp) or (special<2) then
     1673            else if (no < 12) and (no <> fGrass) and (no <> fOcean) then
     1674            begin
     1675              LF;
     1676              for special := 1 to 2 do
     1677                if (no <> fArctic) and (no <> fSwamp) or (special < 2) then
    13751678                begin
    1376                 if special>1 then LF;
    1377                 AddLine(Phrases.Lookup('TERRAIN',no+special*12),pkTer,no+special*12);
    1378                 i:=FoodRes[special]-FoodRes[0];
    1379                 if i<>0 then
    1380                   MainText[Count-1]:=MainText[Count-1]+Format(HelpText.Lookup('SPECIALFOOD'),[i]);
    1381                 i:=ProdRes[special]-ProdRes[0];
    1382                 if i<>0 then
    1383                   MainText[Count-1]:=MainText[Count-1]+Format(HelpText.Lookup('SPECIALPROD'),[i]);
    1384                 i:=TradeRes[special]-TradeRes[0];
    1385                 if i<>0 then
    1386                   MainText[Count-1]:=MainText[Count-1]+Format(HelpText.Lookup('SPECIALTRADE'),[i]);
     1679                  if special > 1 then
     1680                    LF;
     1681                  AddLine(Phrases.Lookup('TERRAIN', no + special * 12), pkTer,
     1682                    no + special * 12);
     1683                  i := FoodRes[special] - FoodRes[0];
     1684                  if i <> 0 then
     1685                    MainText[Count - 1] := MainText[Count - 1] +
     1686                      Format(HelpText.Lookup('SPECIALFOOD'), [i]);
     1687                  i := ProdRes[special] - ProdRes[0];
     1688                  if i <> 0 then
     1689                    MainText[Count - 1] := MainText[Count - 1] +
     1690                      Format(HelpText.Lookup('SPECIALPROD'), [i]);
     1691                  i := TradeRes[special] - TradeRes[0];
     1692                  if i <> 0 then
     1693                    MainText[Count - 1] := MainText[Count - 1] +
     1694                      Format(HelpText.Lookup('SPECIALTRADE'), [i]);
    13871695                end;
    13881696            end;
    1389           if no=3*12 then
    1390             begin
    1391             LF;
    1392             AddText(HelpText.Lookup('RARE'));
    1393             end;
    1394           if (no<3*12) and (TerrType in [fDesert,fArctic]) then
    1395             begin
    1396             NextSection('SEEALSO');
    1397             AddImp(woGardens);
    1398             CheckSeeAlso:=true
     1697            if no = 3 * 12 then
     1698            begin
     1699              LF;
     1700              AddText(HelpText.Lookup('RARE'));
     1701            end;
     1702            if (no < 3 * 12) and (TerrType in [fDesert, fArctic]) then
     1703            begin
     1704              NextSection('SEEALSO');
     1705              AddImp(woGardens);
     1706              CheckSeeAlso := true
    13991707            end
    14001708          end
    14011709        end;
    14021710
    1403     hkFeature:
    1404       if no=200 then
     1711      hkFeature:
     1712        if no = 200 then
    14051713        begin // complete feature list
    1406         Caption:=HelpText.Lookup('HELPTITLE_FEATURELIST');
    1407         List:=THyperText.Create;
    1408         for special:=0 to 2 do
     1714          Caption := HelpText.Lookup('HELPTITLE_FEATURELIST');
     1715          List := THyperText.Create;
     1716          for special := 0 to 2 do
    14091717          begin
    1410           if special>0 then begin LF; LF end;
    1411           case special of
    1412             0: AddLine(HelpText.Lookup('HELPTITLE_FEATURE1LIST'),pkSection);
    1413             1: AddLine(HelpText.Lookup('HELPTITLE_FEATURE2LIST'),pkSection);
    1414             2: AddLine(HelpText.Lookup('HELPTITLE_FEATURE3LIST'),pkSection);
    1415             end;
    1416           List.Clear;
    1417           for i:=0 to nFeature-1 do if Feature[i].Preq<>preNA then
    1418             begin
    1419             if i<mcFirstNonCap then j:=0
    1420             else if i in AutoFeature then j:=2
    1421             else j:=1;
    1422             if j=special then
    1423               List.AddLine(Phrases.Lookup('FEATURES',i),pkFeature,i,hkFeature,i);
    1424             end;
    1425           List.Sort;
    1426           AddStrings(List);
     1718            if special > 0 then
     1719            begin
     1720              LF;
     1721              LF
     1722            end;
     1723            case special of
     1724              0:
     1725                AddLine(HelpText.Lookup('HELPTITLE_FEATURE1LIST'), pkSection);
     1726              1:
     1727                AddLine(HelpText.Lookup('HELPTITLE_FEATURE2LIST'), pkSection);
     1728              2:
     1729                AddLine(HelpText.Lookup('HELPTITLE_FEATURE3LIST'), pkSection);
     1730            end;
     1731            List.Clear;
     1732            for i := 0 to nFeature - 1 do
     1733              if Feature[i].Preq <> preNA then
     1734              begin
     1735                if i < mcFirstNonCap then
     1736                  j := 0
     1737                else if i in AutoFeature then
     1738                  j := 2
     1739                else
     1740                  j := 1;
     1741                if j = special then
     1742                  List.AddLine(Phrases.Lookup('FEATURES', i), pkFeature, i,
     1743                    hkFeature, i);
     1744              end;
     1745            List.Sort;
     1746            AddStrings(List);
    14271747          end;
    1428         List.Free
     1748          List.Free
    14291749        end
    1430       else
     1750        else
    14311751        begin // single feature
    1432         Caption:=Phrases.Lookup('FEATURES',no);
    1433         LF;
    1434         AddLine(Phrases.Lookup('FEATURES',no),pkBigFeature,no);
    1435         if no<mcFirstNonCap then
    1436           AddLine(HelpText.Lookup('HELPSPEC_CAP'))
    1437         else if no in AutoFeature then
    1438           AddLine(HelpText.Lookup('HELPSPEC_STANDARD'))
    1439         else AddLine(HelpText.Lookup('HELPSPEC_FEATURE'));
    1440         NextSection('EFFECT');
    1441         AddText(HelpText.LookupByHandle(hFEATUREHELP,no));
    1442         if (Feature[no].Weight<>0) or (Feature[no].Cost<>0) then
     1752          Caption := Phrases.Lookup('FEATURES', no);
     1753          LF;
     1754          AddLine(Phrases.Lookup('FEATURES', no), pkBigFeature, no);
     1755          if no < mcFirstNonCap then
     1756            AddLine(HelpText.Lookup('HELPSPEC_CAP'))
     1757          else if no in AutoFeature then
     1758            AddLine(HelpText.Lookup('HELPSPEC_STANDARD'))
     1759          else
     1760            AddLine(HelpText.Lookup('HELPSPEC_FEATURE'));
     1761          NextSection('EFFECT');
     1762          AddText(HelpText.LookupByHandle(hFEATUREHELP, no));
     1763          if (Feature[no].Weight <> 0) or (Feature[no].Cost <> 0) then
    14431764          begin
    1444           NextSection('COSTS');
    1445           s:=IntToStr(Feature[no].Cost);
    1446           if Feature[no].Cost>=0 then s:='+'+s;
    1447           AddLine(Format(HelpText.Lookup('COSTBASE'),[s]));
    1448           if Feature[no].Weight>0 then
    1449             begin
    1450             AddLine(Format(HelpText.Lookup('WEIGHT'),
    1451               ['+'+IntToStr(Feature[no].Weight)]));
    1452             if no=mcDefense then
    1453               AddLine(Format(HelpText.Lookup('WEIGHT'),['+2']),pkDomain,dGround);
     1765            NextSection('COSTS');
     1766            s := IntToStr(Feature[no].Cost);
     1767            if Feature[no].Cost >= 0 then
     1768              s := '+' + s;
     1769            AddLine(Format(HelpText.Lookup('COSTBASE'), [s]));
     1770            if Feature[no].Weight > 0 then
     1771            begin
     1772              AddLine(Format(HelpText.Lookup('WEIGHT'),
     1773                ['+' + IntToStr(Feature[no].Weight)]));
     1774              if no = mcDefense then
     1775                AddLine(Format(HelpText.Lookup('WEIGHT'), ['+2']),
     1776                  pkDomain, dGround);
    14541777            end
    14551778          end;
    1456         if Feature[no].Preq<>preNone then
     1779          if Feature[no].Preq <> preNone then
    14571780          begin
     1781            LF;
     1782            if Feature[no].Preq = preSun then
     1783              AddPreqImp(woSun) // sun tsu feature
     1784            else
     1785              AddPreqAdv(Feature[no].Preq);
     1786            MainText[Count - 1] := Format(HelpText.Lookup('REQUIRED'),
     1787              [MainText[Count - 1]]);
     1788          end;
     1789          NextSection('SEEALSO');
     1790          CheckSeeAlso := true
     1791        end;
     1792
     1793      hkModel:
     1794        begin
     1795          Caption := HelpText.Lookup('HELPTITLE_MODELLIST');
     1796          for i := 0 to nSpecialModel - 1 do
     1797            if i <> 2 then
     1798              AddModelText(i);
    14581799          LF;
    1459           if Feature[no].Preq=preSun then AddPreqImp(woSun) // sun tsu feature
    1460           else AddPreqAdv(Feature[no].Preq);
    1461           MainText[Count-1]:=Format(HelpText.Lookup('REQUIRED'),[MainText[Count-1]]);
     1800          AddItem('MODELNOTE');
     1801        end;
     1802
     1803    end;
     1804    if CheckSeeAlso then
     1805      for i := 0 to nSeeAlso - 1 do
     1806        if (SeeAlso[i].Kind = Kind) and (SeeAlso[i].no = no) then
     1807          case SeeAlso[i].SeeKind of
     1808            hkImp:
     1809              AddImp(SeeAlso[i].SeeNo);
     1810            hkAdv:
     1811              AddAdv(SeeAlso[i].SeeNo);
     1812            hkFeature:
     1813              AddFeature(SeeAlso[i].SeeNo);
    14621814          end;
    1463         NextSection('SEEALSO');
    1464         CheckSeeAlso:=true
    1465         end;
    1466 
    1467     hkModel:
    1468         begin
    1469         Caption:=HelpText.Lookup('HELPTITLE_MODELLIST');
    1470         for i:=0 to nSpecialModel-1 do if i<>2 then AddModelText(i);
    1471         LF;
    1472         AddItem('MODELNOTE');
    1473         end;
    1474 
     1815    if (Headline >= 0) and (Count = Headline + 1) then
     1816      Delete(Headline)
     1817    else
     1818      LF;
     1819
     1820    InitPVSB(sb, Count - 1, InnerHeight div 24);
     1821    if sbPos <> 0 then
     1822    begin
     1823      sb.si.npos := sbPos;
     1824      sb.si.FMask := SIF_POS;
     1825      SetScrollInfo(sb.h, SB_CTL, sb.si, true);
    14751826    end;
    1476   if CheckSeeAlso then
    1477     for i:=0 to nSeeAlso-1 do
    1478       if (SeeAlso[i].Kind=Kind) and (SeeAlso[i].no=no) then
    1479         case SeeAlso[i].SeeKind of
    1480           hkImp: AddImp(SeeAlso[i].SeeNo);
    1481           hkAdv: AddAdv(SeeAlso[i].SeeNo);
    1482           hkFeature: AddFeature(SeeAlso[i].SeeNo);
    1483           end;
    1484   if (Headline>=0) and (Count=Headline+1) then Delete(Headline)
    1485   else LF;
    1486 
    1487   InitPVSB(sb,Count-1,InnerHeight div 24);
    1488   if sbPos<>0 then
    1489     begin
    1490     sb.si.npos:=sbPos;
    1491     sb.si.FMask:=SIF_POS;
    1492     SetScrollInfo(sb.h,SB_CTL,sb.si,true);
    1493     end;
    1494   BackBtn.Visible:= nHist>0;
    1495   TopBtn.Visible:= (nHist>0) or (Kind<>hkMisc) or (no<>miscMain);
    1496   Sel:=-1;
     1827    BackBtn.Visible := nHist > 0;
     1828    TopBtn.Visible := (nHist > 0) or (Kind <> hkMisc) or (no <> miscMain);
     1829    Sel := -1;
    14971830  end; // with MainText
    1498 end; {Prepare}
     1831end; { Prepare }
    14991832
    15001833procedure THelpDlg.ShowNewContent(NewMode, Category, Index: integer);
    15011834begin
    1502 if (Category<>Kind) or (Index<>no)
    1503   or (Category=hkMisc) and (Index=miscSearchResult) then
    1504   begin
    1505   if nHist=MaxHist then
    1506     begin
    1507     move(HistKind[2],HistKind[1],4*(nHist-2));
    1508     move(HistNo[2],HistNo[1],4*(nHist-2));
    1509     move(HistPos[2],HistPos[1],4*(nHist-2));
    1510     move(HistSearchContent[2],HistSearchContent[1],sizeof(shortstring)*(nHist-2));
     1835  if (Category <> Kind) or (Index <> no) or (Category = hkMisc) and
     1836    (Index = miscSearchResult) then
     1837  begin
     1838    if nHist = MaxHist then
     1839    begin
     1840      move(HistKind[2], HistKind[1], 4 * (nHist - 2));
     1841      move(HistNo[2], HistNo[1], 4 * (nHist - 2));
     1842      move(HistPos[2], HistPos[1], 4 * (nHist - 2));
     1843      move(HistSearchContent[2], HistSearchContent[1],
     1844        sizeof(shortstring) * (nHist - 2));
    15111845    end
    1512   else inc(nHist);
    1513   if nHist>0 then
    1514     begin
    1515     HistKind[nHist-1]:=Kind;
    1516     HistNo[nHist-1]:=no;
    1517     HistPos[nHist-1]:=sb.si.npos;
    1518     HistSearchContent[nHist-1]:=SearchContent
     1846    else
     1847      inc(nHist);
     1848    if nHist > 0 then
     1849    begin
     1850      HistKind[nHist - 1] := Kind;
     1851      HistNo[nHist - 1] := no;
     1852      HistPos[nHist - 1] := sb.si.npos;
     1853      HistSearchContent[nHist - 1] := SearchContent
    15191854    end
    15201855  end;
    1521 Kind:=Category;
    1522 no:=Index;
    1523 SearchContent:=NewSearchContent;
    1524 Prepare;
    1525 OffscreenPaint;
    1526 inherited ShowNewContent(NewMode);
     1856  Kind := Category;
     1857  no := Index;
     1858  SearchContent := NewSearchContent;
     1859  Prepare;
     1860  OffscreenPaint;
     1861  inherited ShowNewContent(NewMode);
    15271862end;
    15281863
     
    15301865  x, y: integer);
    15311866var
    1532 i0,Sel0:integer;
     1867  i0, Sel0: integer;
    15331868begin
    1534 y:=y-WideFrame;
    1535 i0:=sb.si.npos;
    1536 Sel0:=Sel;
    1537 if (x>=SideFrame) and (x<SideFrame+InnerWidth) and (y>=0) and (y<InnerHeight)
    1538   and (y mod 24>=8) then
    1539   Sel:=y div 24
    1540 else Sel:=-1;
    1541 if (Sel+i0>=MainText.Count) or (Sel>=0)
    1542   and (THelpLineInfo(MainText.Objects[Sel+i0]).Link=0) then Sel:=-1;
    1543 if Sel<>Sel0 then
    1544   begin
    1545   if Sel0<>-1 then line(Canvas,Sel0,false);
    1546   if Sel<>-1 then line(Canvas,Sel,true)
     1869  y := y - WideFrame;
     1870  i0 := sb.si.npos;
     1871  Sel0 := Sel;
     1872  if (x >= SideFrame) and (x < SideFrame + InnerWidth) and (y >= 0) and
     1873    (y < InnerHeight) and (y mod 24 >= 8) then
     1874    Sel := y div 24
     1875  else
     1876    Sel := -1;
     1877  if (Sel + i0 >= MainText.Count) or (Sel >= 0) and
     1878    (THelpLineInfo(MainText.Objects[Sel + i0]).Link = 0) then
     1879    Sel := -1;
     1880  if Sel <> Sel0 then
     1881  begin
     1882    if Sel0 <> -1 then
     1883      line(Canvas, Sel0, false);
     1884    if Sel <> -1 then
     1885      line(Canvas, Sel, true)
    15471886  end
    15481887end;
    15491888
    1550 procedure THelpDlg.PaintBox1MouseDown(Sender: TObject;
    1551   Button: TMouseButton; Shift: TShiftState; x, y: integer);
     1889procedure THelpDlg.PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
     1890  Shift: TShiftState; x, y: integer);
    15521891begin
    1553 if Sel>=0 then with THelpLineInfo(MainText.Objects[Sel+sb.si.npos]) do
    1554   if Link shr 8 and $3F=hkInternet then
    1555     case Link and $FF of
    1556       1: ShellExecute(Handle,'open',pchar(HomeDir+'AI Template\AI development manual.html'),'','',
    1557         SW_SHOWNORMAL);
    1558       2: ShellExecute(Handle,'open','http://c-evo.org','','',
    1559         SW_SHOWNORMAL);
    1560       3: ShellExecute(Handle,'open','http://c-evo.org/_sg/contact','','',
    1561         SW_SHOWNORMAL);
     1892  if Sel >= 0 then
     1893    with THelpLineInfo(MainText.Objects[Sel + sb.si.npos]) do
     1894      if Link shr 8 and $3F = hkInternet then
     1895        case Link and $FF of
     1896          1:
     1897            ShellExecute(Handle, 'open',
     1898              pchar(HomeDir + 'AI Template\AI development manual.html'), '', '',
     1899              SW_SHOWNORMAL);
     1900          2:
     1901            ShellExecute(Handle, 'open', 'http://c-evo.org', '', '',
     1902              SW_SHOWNORMAL);
     1903          3:
     1904            ShellExecute(Handle, 'open', 'http://c-evo.org/_sg/contact', '', '',
     1905              SW_SHOWNORMAL);
     1906        end
     1907      else
     1908      begin
     1909        if (Link >= $8000) and (Link and $3FFF = liInvalid) then
     1910          exit; // invalid link;
     1911        if Link >= $8000 then
     1912          ShowNewContent(FWindowMode, hkText, Link and $3FFF)
     1913        else
     1914          ShowNewContent(FWindowMode, Link shr 8 and $3F, Link and $FF);
    15621915      end
    1563   else
    1564     begin
    1565     if (Link>=$8000) and (Link and $3FFF=liInvalid) then
    1566       exit; // invalid link;
    1567     if Link>=$8000 then
    1568       ShowNewContent(FWindowMode, hkText, Link and $3FFF)
    1569     else ShowNewContent(FWindowMode, Link shr 8 and $3F, Link and $FF);
    1570     end
    15711916end;
    15721917
    15731918procedure THelpDlg.BackBtnClick(Sender: TObject);
    15741919begin
    1575 if nHist>0 then
    1576   begin
    1577   dec(nHist);
    1578   if (HistKind[nHist]=hkMisc) and (HistNo[nHist]=miscSearchResult)
    1579     and (HistSearchContent[nHist]<>SearchContent) then
    1580     begin
    1581     SearchContent:=HistSearchContent[nHist];
    1582     Search(SearchContent);
     1920  if nHist > 0 then
     1921  begin
     1922    dec(nHist);
     1923    if (HistKind[nHist] = hkMisc) and (HistNo[nHist] = miscSearchResult) and
     1924      (HistSearchContent[nHist] <> SearchContent) then
     1925    begin
     1926      SearchContent := HistSearchContent[nHist];
     1927      Search(SearchContent);
    15831928    end;
    1584   Kind:=HistKind[nHist];
    1585   no:=HistNo[nHist];
    1586   Prepare(HistPos[nHist]);
     1929    Kind := HistKind[nHist];
     1930    no := HistNo[nHist];
     1931    Prepare(HistPos[nHist]);
     1932    OffscreenPaint;
     1933    Invalidate;
     1934  end
     1935end;
     1936
     1937procedure THelpDlg.TopBtnClick(Sender: TObject);
     1938begin
     1939  nHist := 0;
     1940  Kind := hkMisc;
     1941  no := miscMain;
     1942  Prepare;
    15871943  OffscreenPaint;
    15881944  Invalidate;
    1589   end
    1590 end;
    1591 
    1592 procedure THelpDlg.TopBtnClick(Sender: TObject);
    1593 begin
    1594 nHist:=0;
    1595 Kind:=hkMisc;
    1596 no:=miscMain;
    1597 Prepare;
    1598 OffscreenPaint;
    1599 Invalidate;
    16001945end;
    16011946
    16021947procedure THelpDlg.FormClose(Sender: TObject; var Action: TCloseAction);
    16031948begin
    1604 ExtPic.Height:=0;
    1605 inherited;
     1949  ExtPic.Height := 0;
     1950  inherited;
    16061951end;
    16071952
    16081953function THelpDlg.TextIndex(Item: string): integer;
    16091954begin
    1610 result:=HelpText.GetHandle(Item)
     1955  result := HelpText.Gethandle(Item)
    16111956end;
    16121957
     
    16141959  Shift: TShiftState);
    16151960begin
    1616 if Key=VK_F1 then // my key
    1617 else inherited
     1961  if Key = VK_F1 then // my key
     1962  else
     1963    inherited
    16181964end;
    16191965
    16201966procedure THelpDlg.SearchBtnClick(Sender: TObject);
    16211967begin
    1622 InputDlg.Caption:=Phrases.Lookup('SEARCH');
    1623 InputDlg.EInput.Text:=SearchContent;
    1624 InputDlg.CenterToRect(BoundsRect);
    1625 InputDlg.ShowModal;
    1626 if (InputDlg.ModalResult=mrOK) and (length(InputDlg.EInput.Text)>=2) then
    1627   begin
    1628   Search(InputDlg.EInput.Text);
    1629   case SearchResult.Count of
    1630     0: SimpleMessage(Format(HelpText.Lookup('NOMATCHES'), [InputDlg.EInput.Text]));
    1631     1:
    1632       with THelpLineInfo(SearchResult.Objects[0]) do
    1633         if Link>=$8000 then
    1634           ShowNewContent(FWindowMode, hkText, Link and $3FFF)
    1635         else ShowNewContent(FWindowMode, Link shr 8 and $3F, Link and $FF);
     1968  InputDlg.Caption := Phrases.Lookup('SEARCH');
     1969  InputDlg.EInput.Text := SearchContent;
     1970  InputDlg.CenterToRect(BoundsRect);
     1971  InputDlg.ShowModal;
     1972  if (InputDlg.ModalResult = mrOK) and (length(InputDlg.EInput.Text) >= 2) then
     1973  begin
     1974    Search(InputDlg.EInput.Text);
     1975    case SearchResult.Count of
     1976      0:
     1977        SimpleMessage(Format(HelpText.Lookup('NOMATCHES'),
     1978          [InputDlg.EInput.Text]));
     1979      1:
     1980        with THelpLineInfo(SearchResult.Objects[0]) do
     1981          if Link >= $8000 then
     1982            ShowNewContent(FWindowMode, hkText, Link and $3FFF)
     1983          else
     1984            ShowNewContent(FWindowMode, Link shr 8 and $3F, Link and $FF);
    16361985    else
    16371986      begin
    1638       NewSearchContent:=InputDlg.EInput.Text;
    1639       ShowNewContent(FWindowMode, hkMisc, miscSearchResult);
     1987        NewSearchContent := InputDlg.EInput.Text;
     1988        ShowNewContent(FWindowMode, hkMisc, miscSearchResult);
    16401989      end
    16411990    end
     
    16451994procedure THelpDlg.Search(SearchString: string);
    16461995var
    1647 h, i, PrevHandle, PrevIndex, p, RightMargin: integer;
    1648 s: string;
    1649 mADVHELP, mIMPHELP, mFEATUREHELP: set of 0..255;
    1650 bGOVHELP, bSPECIALMODEL, bJOBHELP: boolean;
     1996  h, i, PrevHandle, PrevIndex, p, RightMargin: integer;
     1997  s: string;
     1998  mADVHELP, mIMPHELP, mFEATUREHELP: set of 0 .. 255;
     1999  bGOVHELP, bSPECIALMODEL, bJOBHELP: boolean;
    16512000begin
    1652 SearchResult.Clear;
    1653 mADVHELP:=[];
    1654 mIMPHELP:=[];
    1655 mFEATUREHELP:=[];
    1656 bGOVHELP:=false;
    1657 bSPECIALMODEL:=false;
    1658 bJOBHELP:=false;
    1659 
    1660 // search in generic reference
    1661 SearchString:=UpperCase(SearchString);
    1662 for i:=0 to 35+4 do
    1663   begin
    1664   s:=Phrases.Lookup('TERRAIN',i);
    1665   if pos(SearchString,UpperCase(s))>0 then
    1666     if i<36 then
    1667       SearchResult.AddLine(s+' '+HelpText.Lookup('HELPSPEC_TER'),pkNormal,0,
    1668         hkTer+hkCrossLink,i)
    1669     else
     2001  SearchResult.Clear;
     2002  mADVHELP := [];
     2003  mIMPHELP := [];
     2004  mFEATUREHELP := [];
     2005  bGOVHELP := false;
     2006  bSPECIALMODEL := false;
     2007  bJOBHELP := false;
     2008
     2009  // search in generic reference
     2010  SearchString := UpperCase(SearchString);
     2011  for i := 0 to 35 + 4 do
     2012  begin
     2013    s := Phrases.Lookup('TERRAIN', i);
     2014    if pos(SearchString, UpperCase(s)) > 0 then
     2015      if i < 36 then
     2016        SearchResult.AddLine(s + ' ' + HelpText.Lookup('HELPSPEC_TER'),
     2017          pkNormal, 0, hkTer + hkCrossLink, i)
     2018      else
    16702019      begin
    1671       SearchResult.AddLine(Phrases.Lookup('TERRAIN',36)+' '
    1672         +HelpText.Lookup('HELPSPEC_TER'),pkNormal,0,hkTer+hkCrossLink,36);
    1673       if i>36 then
    1674         SearchResult.AddLine(Phrases.Lookup('IMPROVEMENTS',imShipComp+i-37)
    1675           +' '+HelpText.Lookup('HELPSPEC_SHIPPART'),
    1676           pkNormal,0,hkImp+hkCrossLink,imShipComp+i-37);
    1677       break
     2020        SearchResult.AddLine(Phrases.Lookup('TERRAIN', 36) + ' ' +
     2021          HelpText.Lookup('HELPSPEC_TER'), pkNormal, 0,
     2022          hkTer + hkCrossLink, 36);
     2023        if i > 36 then
     2024          SearchResult.AddLine(Phrases.Lookup('IMPROVEMENTS',
     2025            imShipComp + i - 37) + ' ' + HelpText.Lookup('HELPSPEC_SHIPPART'),
     2026            pkNormal, 0, hkImp + hkCrossLink, imShipComp + i - 37);
     2027        Break
    16782028      end
    16792029  end;
    1680 for i:=0 to nJobHelp-1 do
    1681   if pos(SearchString,UpperCase(Phrases.Lookup('JOBRESULT',JobHelp[i])))>0 then
    1682     begin
    1683     SearchResult.AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'),pkNormal,0,
    1684       hkMisc+hkCrossLink,miscJobList);
    1685     bJOBHELP:=true;
    1686     break
     2030  for i := 0 to nJobHelp - 1 do
     2031    if pos(SearchString, UpperCase(Phrases.Lookup('JOBRESULT', JobHelp[i]))) > 0
     2032    then
     2033    begin
     2034      SearchResult.AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkNormal, 0,
     2035        hkMisc + hkCrossLink, miscJobList);
     2036      bJOBHELP := true;
     2037      Break
    16872038    end;
    1688 for i:=0 to nAdv-1 do
    1689   begin
    1690   s:=Phrases.Lookup('ADVANCES',i);
    1691   if pos(SearchString,UpperCase(s))>0 then
    1692     begin
    1693     if i in FutureTech then s:=s+' '+HelpText.Lookup('HELPSPEC_FUTURE')
    1694     else s:=s+' '+HelpText.Lookup('HELPSPEC_ADV');
    1695     SearchResult.AddLine(s,pkNormal,0,hkAdv+hkCrossLink,i);
    1696     include(mADVHELP,i);
     2039  for i := 0 to nAdv - 1 do
     2040  begin
     2041    s := Phrases.Lookup('ADVANCES', i);
     2042    if pos(SearchString, UpperCase(s)) > 0 then
     2043    begin
     2044      if i in FutureTech then
     2045        s := s + ' ' + HelpText.Lookup('HELPSPEC_FUTURE')
     2046      else
     2047        s := s + ' ' + HelpText.Lookup('HELPSPEC_ADV');
     2048      SearchResult.AddLine(s, pkNormal, 0, hkAdv + hkCrossLink, i);
     2049      include(mADVHELP, i);
    16972050    end
    16982051  end;
    1699 for i:=0 to nSpecialModel-1 do
    1700   begin
    1701   FindStdModelPicture(SpecialModelPictureCode[i],h,s);
    1702   if pos(SearchString,UpperCase(s))>0 then
    1703     begin
    1704     SearchResult.AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'),pkNormal,0,
    1705       hkModel+hkCrossLink,0);
    1706     bSPECIALMODEL:=true;
    1707     break
     2052  for i := 0 to nSpecialModel - 1 do
     2053  begin
     2054    FindStdModelPicture(SpecialModelPictureCode[i], h, s);
     2055    if pos(SearchString, UpperCase(s)) > 0 then
     2056    begin
     2057      SearchResult.AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'), pkNormal, 0,
     2058        hkModel + hkCrossLink, 0);
     2059      bSPECIALMODEL := true;
     2060      Break
    17082061    end;
    17092062  end;
    1710 for i:=0 to nFeature-1 do
    1711   begin
    1712   s:=Phrases.Lookup('FEATURES',i);
    1713   if pos(SearchString,UpperCase(s))>0 then
    1714     begin
    1715     if i<mcFirstNonCap then s:=s+' '+HelpText.Lookup('HELPSPEC_CAP')
    1716     else if i in AutoFeature then s:=s+' '+HelpText.Lookup('HELPSPEC_STANDARD')
    1717     else s:=s+' '+HelpText.Lookup('HELPSPEC_FEATURE');
    1718     SearchResult.AddLine(s,pkNormal,0,hkFeature+hkCrossLink,i);
    1719     include(mFEATUREHELP,i);
     2063  for i := 0 to nFeature - 1 do
     2064  begin
     2065    s := Phrases.Lookup('FEATURES', i);
     2066    if pos(SearchString, UpperCase(s)) > 0 then
     2067    begin
     2068      if i < mcFirstNonCap then
     2069        s := s + ' ' + HelpText.Lookup('HELPSPEC_CAP')
     2070      else if i in AutoFeature then
     2071        s := s + ' ' + HelpText.Lookup('HELPSPEC_STANDARD')
     2072      else
     2073        s := s + ' ' + HelpText.Lookup('HELPSPEC_FEATURE');
     2074      SearchResult.AddLine(s, pkNormal, 0, hkFeature + hkCrossLink, i);
     2075      include(mFEATUREHELP, i);
    17202076    end
    17212077  end;
    1722 for i:=0 to nImp-1 do
    1723   begin
    1724   s:=Phrases.Lookup('IMPROVEMENTS',i);
    1725   if pos(SearchString,UpperCase(s))>0 then
    1726     begin
    1727     case Imp[i].Kind of
    1728       ikWonder: s:=s+' '+HelpText.Lookup('HELPSPEC_WONDER');
    1729       ikCommon: s:=s+' '+HelpText.Lookup('HELPSPEC_IMP');
    1730       ikShipPart: s:=s+' '+HelpText.Lookup('HELPSPEC_SHIPPART');
    1731       else s:=s+' '+HelpText.Lookup('HELPSPEC_NAT')
     2078  for i := 0 to nImp - 1 do
     2079  begin
     2080    s := Phrases.Lookup('IMPROVEMENTS', i);
     2081    if pos(SearchString, UpperCase(s)) > 0 then
     2082    begin
     2083      case Imp[i].Kind of
     2084        ikWonder:
     2085          s := s + ' ' + HelpText.Lookup('HELPSPEC_WONDER');
     2086        ikCommon:
     2087          s := s + ' ' + HelpText.Lookup('HELPSPEC_IMP');
     2088        ikShipPart:
     2089          s := s + ' ' + HelpText.Lookup('HELPSPEC_SHIPPART');
     2090      else
     2091        s := s + ' ' + HelpText.Lookup('HELPSPEC_NAT')
    17322092      end;
    1733     SearchResult.AddLine(s,pkNormal,0,hkImp+hkCrossLink,i);
    1734     include(mIMPHELP,i);
     2093      SearchResult.AddLine(s, pkNormal, 0, hkImp + hkCrossLink, i);
     2094      include(mIMPHELP, i);
    17352095    end
    17362096  end;
    1737 for i:=0 to nGov-1 do
    1738   if pos(SearchString,UpperCase(Phrases.Lookup('GOVERNMENT',i)))>0 then
    1739     begin
    1740     SearchResult.AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'),pkNormal,0,
    1741       hkMisc+hkCrossLink,miscGovList);
    1742     bGOVHELP:=true;
    1743     break
     2097  for i := 0 to nGov - 1 do
     2098    if pos(SearchString, UpperCase(Phrases.Lookup('GOVERNMENT', i))) > 0 then
     2099    begin
     2100      SearchResult.AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'), pkNormal, 0,
     2101        hkMisc + hkCrossLink, miscGovList);
     2102      bGOVHELP := true;
     2103      Break
    17442104    end;
    17452105
    1746 // full text search
    1747 h:=-1;
    1748 repeat
    1749   PrevHandle:=h;
    1750   PrevIndex:=i;
    1751   if not HelpText.Search(SearchString, h, i) then
    1752     break;
    1753   if h=hADVHELP then
    1754     begin
    1755     if (i>=0) and ((i<>PrevIndex) or (h<>PrevHandle)) and not (i in mADVHELP) then
     2106  // full text search
     2107  h := -1;
     2108  repeat
     2109    PrevHandle := h;
     2110    PrevIndex := i;
     2111    if not HelpText.Search(SearchString, h, i) then
     2112      Break;
     2113    if h = hADVHELP then
     2114    begin
     2115      if (i >= 0) and ((i <> PrevIndex) or (h <> PrevHandle)) and
     2116        not(i in mADVHELP) then
    17562117      begin
    1757       s:=Phrases.Lookup('ADVANCES',i);
    1758       if i in FutureTech then s:=s+' '+HelpText.Lookup('HELPSPEC_FUTURE')
    1759       else s:=s+' '+HelpText.Lookup('HELPSPEC_ADV');
    1760       SearchResult.AddLine(s,pkNormal,0,hkAdv+hkCrossLink,i)
     2118        s := Phrases.Lookup('ADVANCES', i);
     2119        if i in FutureTech then
     2120          s := s + ' ' + HelpText.Lookup('HELPSPEC_FUTURE')
     2121        else
     2122          s := s + ' ' + HelpText.Lookup('HELPSPEC_ADV');
     2123        SearchResult.AddLine(s, pkNormal, 0, hkAdv + hkCrossLink, i)
    17612124      end
    17622125    end
    1763   else if h=hIMPHELP then
    1764     begin
    1765     if (i>=0) and ((i<>PrevIndex) or (h<>PrevHandle)) and not (i in mIMPHELP) then
     2126    else if h = hIMPHELP then
     2127    begin
     2128      if (i >= 0) and ((i <> PrevIndex) or (h <> PrevHandle)) and
     2129        not(i in mIMPHELP) then
    17662130      begin
    1767       s:=Phrases.Lookup('IMPROVEMENTS',i);
    1768       case Imp[i].Kind of
    1769         ikWonder: s:=s+' '+HelpText.Lookup('HELPSPEC_WONDER');
    1770         ikCommon: s:=s+' '+HelpText.Lookup('HELPSPEC_IMP');
    1771         ikShipPart: s:=s+' '+HelpText.Lookup('HELPSPEC_SHIPPART');
    1772         else s:=s+' '+HelpText.Lookup('HELPSPEC_NAT')
     2131        s := Phrases.Lookup('IMPROVEMENTS', i);
     2132        case Imp[i].Kind of
     2133          ikWonder:
     2134            s := s + ' ' + HelpText.Lookup('HELPSPEC_WONDER');
     2135          ikCommon:
     2136            s := s + ' ' + HelpText.Lookup('HELPSPEC_IMP');
     2137          ikShipPart:
     2138            s := s + ' ' + HelpText.Lookup('HELPSPEC_SHIPPART');
     2139        else
     2140          s := s + ' ' + HelpText.Lookup('HELPSPEC_NAT')
    17732141        end;
    1774       SearchResult.AddLine(s,pkNormal,0,hkImp+hkCrossLink,i)
     2142        SearchResult.AddLine(s, pkNormal, 0, hkImp + hkCrossLink, i)
    17752143      end
    17762144    end
    1777   else if h=hFEATUREHELP then
    1778     begin
    1779     if (i>=0) and ((i<>PrevIndex) or (h<>PrevHandle)) and not (i in mFEATUREHELP) then
     2145    else if h = hFEATUREHELP then
     2146    begin
     2147      if (i >= 0) and ((i <> PrevIndex) or (h <> PrevHandle)) and
     2148        not(i in mFEATUREHELP) then
    17802149      begin
    1781       s:=Phrases.Lookup('FEATURES',i);
    1782       if i<mcFirstNonCap then s:=s+' '+HelpText.Lookup('HELPSPEC_CAP')
    1783       else if i in AutoFeature then s:=s+' '+HelpText.Lookup('HELPSPEC_STANDARD')
    1784       else s:=s+' '+HelpText.Lookup('HELPSPEC_FEATURE');
    1785       SearchResult.AddLine(s,pkNormal,0,hkFeature+hkCrossLink,i);
     2150        s := Phrases.Lookup('FEATURES', i);
     2151        if i < mcFirstNonCap then
     2152          s := s + ' ' + HelpText.Lookup('HELPSPEC_CAP')
     2153        else if i in AutoFeature then
     2154          s := s + ' ' + HelpText.Lookup('HELPSPEC_STANDARD')
     2155        else
     2156          s := s + ' ' + HelpText.Lookup('HELPSPEC_FEATURE');
     2157        SearchResult.AddLine(s, pkNormal, 0, hkFeature + hkCrossLink, i);
    17862158      end
    17872159    end
    1788   else if h=hGOVHELP then
    1789     begin
    1790     if (i>=0) and (h<>PrevHandle) and not bGOVHELP then
    1791       SearchResult.AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'),pkNormal,0,
    1792         hkMisc+hkCrossLink,miscGovList)
     2160    else if h = hGOVHELP then
     2161    begin
     2162      if (i >= 0) and (h <> PrevHandle) and not bGOVHELP then
     2163        SearchResult.AddLine(HelpText.Lookup('HELPTITLE_GOVLIST'), pkNormal, 0,
     2164          hkMisc + hkCrossLink, miscGovList)
    17932165    end
    1794   else if h=hSPECIALMODEL then
    1795     begin
    1796     if (i>=0) and (h<>PrevHandle) and not bSPECIALMODEL then
    1797       SearchResult.AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'),pkNormal,0,
    1798         hkModel+hkCrossLink,0)
     2166    else if h = hSPECIALMODEL then
     2167    begin
     2168      if (i >= 0) and (h <> PrevHandle) and not bSPECIALMODEL then
     2169        SearchResult.AddLine(HelpText.Lookup('HELPTITLE_MODELLIST'), pkNormal,
     2170          0, hkModel + hkCrossLink, 0)
    17992171    end
    1800   else if h=hJOBHELP then
    1801     begin
    1802     if (i>=0) and (h<>PrevHandle) and not bJOBHELP then
    1803       SearchResult.AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'),pkNormal,0,
    1804         hkMisc+hkCrossLink,miscJobList)
     2172    else if h = hJOBHELP then
     2173    begin
     2174      if (i >= 0) and (h <> PrevHandle) and not bJOBHELP then
     2175        SearchResult.AddLine(HelpText.Lookup('HELPTITLE_JOBLIST'), pkNormal, 0,
     2176          hkMisc + hkCrossLink, miscJobList)
    18052177    end
    1806   else if {(h<>hMAIN) and} (h<>PrevHandle) then
    1807     begin
    1808     s:=HelpText.LookupByHandle(h);
    1809     p:=pos('$',s);
    1810     if p>0 then
     2178    else if { (h<>hMAIN) and } (h <> PrevHandle) then
     2179    begin
     2180      s := HelpText.LookupByHandle(h);
     2181      p := pos('$', s);
     2182      if p > 0 then
    18112183      begin
    1812       s:=copy(s,p+1,maxint);
    1813       p:=pos('\',s);
    1814       if p>0 then
    1815         s:=copy(s,1,p-1);
    1816       SearchResult.AddLine(s, pkNormal, 0, hkText+hkCrossLink, h);
     2184        s := copy(s, p + 1, maxint);
     2185        p := pos('\', s);
     2186        if p > 0 then
     2187          s := copy(s, 1, p - 1);
     2188        SearchResult.AddLine(s, pkNormal, 0, hkText + hkCrossLink, h);
    18172189      end
    18182190    end
    1819 until false;
    1820 
    1821 // cut lines to fit to window
    1822 RightMargin:=InnerWidth-16-GetSystemMetrics(SM_CXVSCROLL);
    1823 Offscreen.Canvas.Font.Assign(UniFont[ftNormal]);
    1824 for i:=0 to SearchResult.Count-1 do
    1825   begin
    1826   while BiColorTextWidth(Offscreen.Canvas, SearchResult[i])>RightMargin-32 do
    1827     SearchResult[i]:=copy(SearchResult[i], 1, length(SearchResult[i])-1)
    1828   end;
    1829 end;
     2191    until false;
     2192
     2193    // cut lines to fit to window
     2194    RightMargin := InnerWidth - 16 - GetSystemMetrics(SM_CXVSCROLL);
     2195    OffScreen.Canvas.Font.Assign(UniFont[ftNormal]);
     2196    for i := 0 to SearchResult.Count - 1 do
     2197    begin
     2198      while BiColorTextWidth(OffScreen.Canvas, SearchResult[i]) >
     2199        RightMargin - 32 do
     2200        SearchResult[i] := copy(SearchResult[i], 1, length(SearchResult[i]) - 1)
     2201    end;
     2202  end;
    18302203
    18312204end.
    1832 
Note: See TracChangeset for help on using the changeset viewer.