📄 help.pas
字号:
{$INCLUDE switches}
unit Help;
interface
uses
Protocol,ScreenTools,BaseWin,StringTables,
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
ExtCtrls, ButtonB, PVSB, ButtonBase;
const
MaxHist=16;
{link categories}
hkNoLink=0;hkAdv=1;hkImp=2;hkTer=3;hkFeature=4;hkInternet=5;hkMisc=7;
hkCrossLink=$40;
hkText=$80;
liInvalid=$3FFF; // link index indicates invalid link
{link indices for category hkMisc}
miscCredits=0; miscGovList=1; miscModelList=2; miscJobList=3;
type
THyperText=class(TStringList)
procedure AddLine(s: String =''; Format: integer =0; Picpix: integer =0;
LinkCategory: integer =0; LinkIndex: integer =0);
end;
THelpDlg = class(TBaseDlg)
CloseBtn: TButtonB;
BackBtn: TButtonB;
TopBtn: TButtonB;
procedure FormCreate(Sender:TObject);
procedure FormDestroy(Sender:TObject);
procedure FormPaint(Sender:TObject);
procedure CloseBtnClick(Sender:TObject);
procedure FormShow(Sender: TObject);
procedure PaintBox1MouseMove(Sender: TObject; Shift: TShiftState; x,
y: integer);
procedure PaintBox1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; x, y: integer);
procedure BackBtnClick(Sender: TObject);
procedure TopBtnClick(Sender: TObject);
procedure FormDeactivate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
public
Difficulty: integer;
procedure ShowPage(Category, Index: integer; Modal: boolean = false);
function TextIndex(Item: string): integer;
protected
procedure OffscreenPaint; override;
private
Kind,no,Sel,nHist: integer;
MainText: THyperText;
HelpText: TStringTable;
ExtPic: TBitmap;
sb:TPVScrollbar;
x0: array[-2..15] of integer;
HistKind: array[0..MaxHist-1] of integer;
HistNo: array[0..MaxHist-1] of integer;
HistPos: array[0..MaxHist-1] of integer;
procedure line(ca: TCanvas; i: integer; lit: boolean);
procedure Prepare(sbPos: integer = 0);
procedure OnScroll(var m:TMessage); message WM_VSCROLL;
end;
var
HelpDlg: THelpDlg;
implementation
{$R *.DFM}
uses
ClientTools,Term,Tribes,ShellAPI;
type
THelpLineInfo=packed record
Format, Picpix: Byte;
Link: Word;
end;
procedure THyperText.AddLine(s: String; Format: integer; Picpix: integer;
LinkCategory: integer; LinkIndex: integer);
var
HelpLineInfo: THelpLineInfo;
begin
if LinkIndex<0 then LinkIndex:=liInvalid;
HelpLineInfo.Format:=Format;
HelpLineInfo.Picpix:=Picpix;
HelpLineInfo.Link:=LinkCategory shl 8+LinkIndex;
AddObject(s,TObject(HelpLineInfo));
end;
const
{text formats}
pkNormal=0;pkCaption=1;pkSmallIcon=2;pkBigIcon=3;pkAdvIcon=4;pkTer=5;
pkBigTer=6;pkFeature=7;pkDot=8;pkNormal_Dot=9;pkDomain=10;pkCenter=11;
pkBigFeature=12;pkExp=13;pkTreaty=14;pkExternal=15;pkModel=16;pkNormal_64=17;
pkModelFull=18;pkLogo=19;pkTerImp=20;pkSmallIcon_AsPreq=23;pkAdvIcon_AsPreq=22;
nSeeAlso=14;
SeeAlso: array[0..nSeeAlso-1] of record Kind,no,SeeKind,SeeNo: integer end=
((Kind:hkImp;no:imWalls;SeeKind:hkFeature;SeeNo:mcLongRange),
(Kind:hkImp;no:imGrWall;SeeKind:hkFeature;SeeNo:mcLongRange),
(Kind:hkImp;no:imHydro;SeeKind:hkImp;SeeNo:woHoover),
(Kind:hkImp;no:imWalls;SeeKind:hkImp;SeeNo:imGrWall),
(Kind:hkImp;no:imHighways;SeeKind:hkAdv;SeeNo:adWheel),
(Kind:hkImp;no:imCathedral;SeeKind:hkImp;SeeNo:woBach),
(Kind:hkImp;no:imBank;SeeKind:hkImp;SeeNo:imStockEx),
(Kind:hkImp;no:imShipComp;SeeKind:hkImp;SeeNo:imSpacePort),
(Kind:hkImp;no:imShipPow;SeeKind:hkImp;SeeNo:imSpacePort),
(Kind:hkImp;no:imShipHab;SeeKind:hkImp;SeeNo:imSpacePort),
(Kind:hkFeature;no:mcSub;SeeKind:hkFeature;SeeNo:mcRadar),
(Kind:hkFeature;no:mcDefense;SeeKind:hkAdv;SeeNo:adSteel),
(Kind:hkAdv;no:adWheel;SeeKind:hkImp;SeeNo:imHighways),
(Kind:hkAdv;no:adSteel;SeeKind:hkFeature;SeeNo:mcDefense));
procedure THelpDlg.FormCreate(Sender:TObject);
begin
inherited;
CaptionLeft:=BackBtn.Left+BackBtn.Width;
CaptionRight:=CloseBtn.Left;
MainText:=THyperText.Create;
ExtPic:=TBitmap.Create;
CreatePVSB(sb,Handle,36,457,36+360);
HelpText:=TStringTable.Create;
HelpText.LoadFromFile(HomeDir+'Help\help.txt');
InitButtons(self);
end;
procedure THelpDlg.FormDestroy(Sender:TObject);
begin
MainText.Free;
ExtPic.Free;
HelpText.Free;
end;
procedure THelpDlg.CloseBtnClick(Sender:TObject);
begin
Close
end;
procedure THelpDlg.OnScroll(var m:TMessage);
begin
if ProcessPVSB(sb,m) then
begin OffscreenPaint; SmartInvalidate; Update end
end;
procedure THelpDlg.FormPaint(Sender:TObject);
begin
inherited;
Canvas.Font.Assign(UniFont[ftNormal]);
BtnFrame(Canvas,TopBtn.BoundsRect,DlgTex);
BtnFrame(Canvas,BackBtn.BoundsRect,DlgTex);
BtnFrame(Canvas,CloseBtn.BoundsRect,DlgTex);
end;
procedure THelpDlg.line(ca: TCanvas; i: integer; lit: boolean);
var
TextColor,x,y,j: integer;
TextSize: TSize;
s,s0: string;
procedure ReplaceIcons(spec: string; no: integer);
begin
s0:=s;
while pos(spec,s)>0 do
begin j:=pos(spec,s); s[j]:=' '; s[j+1]:=' '; Insert(' ',s,j); end;
while pos(spec,s0)>0 do
begin
j:=pos(spec,s0);
s0[j]:=' '; s0[j+1]:=' ';
Insert(' ',s0,j);
Sprite(offscreen,HGrSystem,x+1+ca.TextWidth(Copy(s0,1,j-1)),y+5,10,10,
66+no mod 11 *11,115+no div 11 *11);
end;
end;
begin
x:=x0[i]; y:=2+i*24;
if ca=Canvas then
begin x:=x+SideFrame; y:=y+WideFrame end;
if THelpLineInfo(MainText.Objects[sb.si.npos+i]).Format=pkCaption then
RisedTextOut(ca,x,y,MainText[sb.si.npos+i])
else
begin
if lit then TextColor:=InnerTex.clLitText else TextColor:=-1;
s:=MainText[sb.si.npos+i];
ReplaceIcons('%f',0);
ReplaceIcons('%p',2);
ReplaceIcons('%t',4);
ReplaceIcons('%c',6);
ReplaceIcons('%r',12);
ReplaceIcons('%l',8);
ReplaceIcons('%w',13);
if ca=Canvas then
begin
TextSize:=ca.TextExtent(s);
if y+TextSize.cy>=WideFrame+InnerHeight then
TextSize.cy:=WideFrame+InnerHeight-y;
Fill(ca,x,y,TextSize.cx,TextSize.cy,-SideFrame,sb.si.npos*24-WideFrame,
InnerTex);
end;
LoweredTextOut(ca,TextColor,InnerTex,x,y,s);
end
end;
procedure THelpDlg.OffscreenPaint;
var
i,j,yl,srcno,ofs: integer;
s: string;
HelpLineInfo: THelpLineInfo;
begin
inherited;
Fill(offscreen.Canvas,0,0,InnerWidth,InnerHeight,0,sb.si.npos*24,
InnerTex);
with offscreen.Canvas do
begin
Font.Assign(UniFont[ftNormal]);
for i:=-sb.si.npos to InnerHeight div 24 do
if sb.si.npos+i<MainText.Count then
begin
HelpLineInfo:=THelpLineInfo(MainText.Objects[sb.si.npos+i]);
if HelpLineInfo.Format=pkExternal then
begin
yl:=ExtPic.Height;
if 4+i*24+yl>InnerHeight then yl:=InnerHeight-(4+i*24);
BitBlt(Handle,8,4+i*24,ExtPic.Width,yl,
ExtPic.Canvas.Handle,0,0,SRCCOPY);
end
end;
for i:=-2 to InnerHeight div 24 do
if (sb.si.npos+i>=0) and (sb.si.npos+i<MainText.Count) then
begin
HelpLineInfo:=THelpLineInfo(MainText.Objects[sb.si.npos+i]);
if HelpLineInfo.Link<>0 then
begin
if HelpLineInfo.Format in [pkSmallIcon_AsPreq,pkAdvIcon_AsPreq] then
Sprite(offscreen,HGrSystem,12,i*24+5,14,14,65,20)
else if HelpLineInfo.Link and (hkCrossLink shl 8)<>0 then
Sprite(offscreen,HGrSystem,12,i*24+5,14,14,80,1)
else Sprite(offscreen,HGrSystem,10,i*24+5,14,14,65,1);
x0[i]:=24;
end
else x0[i]:=0;
case HelpLineInfo.Format of
pkLogo:
begin
Server(sGetVersion,0,0,j);
s:=Format('%d.%d.%d',[j shr 16 and $FF, j shr 8 and $FF, j and $FF]);
Sprite(offscreen,HGrSystem2,(InnerWidth-122) div 2,i*24+1,122,23,1,176);
Font.Assign(UniFont[ftSmall]);
LoweredTextout(offscreen.Canvas,-1,InnerTex,
(InnerWidth-TextWidth(s)) div 2,i*24+26,s);
Font.Assign(UniFont[ftNormal]);
end;
pkSmallIcon,pkSmallIcon_AsPreq:
begin
Frame(offscreen.Canvas,8-1+x0[i],2-1+i*24,8+xSizeSmall+x0[i],2+20+i*24,
InnerTex.clBevelLight,InnerTex.clBevelShade);
BitBlt(offscreen.Canvas.Handle,8+x0[i],2+i*24,xSizeSmall,ySizeSmall,SmallImp.Canvas.Handle,
HelpLineInfo.Picpix mod 7*xSizeSmall,(HelpLineInfo.Picpix+SystemIconLines*7) div 7*ySizeSmall,SRCCOPY);
x0[i]:=x0[i]+(8+8+36);
end;
pkDomain:
begin
Frame(offscreen.Canvas,8-1+x0[i],2-1+i*24,8+36+x0[i],2+20+i*24,
InnerTex.clBevelLight,InnerTex.clBevelShade);
Dump(offscreen,HGrSystem,8+x0[i],2+i*24,36,20,
75+HelpLineInfo.Picpix*37,295);
x0[i]:=x0[i]+(8+8+36);
end;
pkAdvIcon,pkAdvIcon_AsPreq:
begin
Frame(offscreen.Canvas,8-1+x0[i],2-1+i*24,8+xSizeSmall+x0[i],2+ySizeSmall+i*24,
InnerTex.clBevelLight,InnerTex.clBevelShade);
if AdvIcon[HelpLineInfo.Picpix]<84 then
BitBlt(offscreen.Canvas.Handle,8+x0[i],2+i*24,xSizeSmall,ySizeSmall,
SmallImp.Canvas.Handle, AdvIcon[HelpLineInfo.Picpix] mod 7*xSizeSmall,
(AdvIcon[HelpLineInfo.Picpix]+SystemIconLines*7) div 7*ySizeSmall,SRCCOPY)
else
Dump(offscreen,HGrSystem,8+x0[i],2+i*24,36,20,
1+(AdvIcon[HelpLineInfo.Picpix]-84) mod 8*37,
295+(AdvIcon[HelpLineInfo.Picpix]-84) div 8*21);
j:=AdvValue[HelpLineInfo.Picpix] div 1000;
BitBlt(Handle,x0[i]+4,4+i*24,14,14,
GrExt[HGrSystem].Mask.Canvas.Handle,127+j*15,85,SRCAND);
Sprite(offscreen,HGrSystem,x0[i]+3,3+i*24,14,14,127+j*15,85);
x0[i]:=x0[i]+(8+8+36);
end;
pkBigIcon:
FrameImage(Offscreen.Canvas,BigImp,196,8+i*24,xSizeBig,ySizeBig,
HelpLineInfo.Picpix mod 7 *xSizeBig,
(HelpLineInfo.Picpix+SystemIconLines*7) div 7 *ySizeBig);
pkBigFeature:
begin
DarkGradient(offscreen.Canvas,191,8+i*24,65,1);
with offscreen.Canvas do
begin
Brush.Color:=$C0C0C0;
FrameRect(Rect(217,8+1+i*24,217+14,8+15+i*24));
Brush.Style:=bsClear;
Sprite(offscreen,HGrSystem,219,8+3+i*24,10,10,
66+HelpLineInfo.Picpix mod 11 *11,
137+HelpLineInfo.Picpix div 11 *11);
end;
end;
pkTer,pkBigTer:
begin
if HelpLineInfo.Picpix>=3*12 then srcno:=27
else if HelpLineInfo.Picpix mod 12<9 then
srcno:=HelpLineInfo.Picpix mod 12
else srcno:=27+(HelpLineInfo.Picpix mod 12-9)*18;
if HelpLineInfo.Format=pkTer then ofs:=x0[i] else ofs:=184;
if srcno>=9 then
Sprite(offscreen,HGrTerrain,ofs+8,i*24-3,64,32,131,67);
Sprite(offscreen,HGrTerrain,ofs+8,i*24-3,64,32,
1+srcno mod 9 *65,1+srcno div 9 *33);
if HelpLineInfo.Picpix>=3*12 then {rare resource}
Sprite(offscreen,HGrTerrain,ofs+8,i*24-3,64,32,
521,397+(HelpLineInfo.Picpix-3*12)*33)
else if HelpLineInfo.Picpix>=12 then {special tile}
begin
if HelpLineInfo.Picpix mod 12<9 then
srcno:=HelpLineInfo.Picpix mod 12
else srcno:=18+8+(HelpLineInfo.Picpix mod 12-9)*18;
srcno:=srcno+HelpLineInfo.Picpix div 12*9;
Sprite(offscreen,HGrTerrain,ofs+8,i*24-3,64,32,
1+srcno mod 9 *65,1+srcno div 9 *33);
end;
x0[i]:=64+8+8+ofs;
end;
pkTerImp:
begin
if HelpLineInfo.Picpix=5 then
begin // display mine on hills
Sprite(offscreen,HGrTerrain,8,i*24+9,64,32,131,67);
srcno:=45
end
else srcno:=2; // display on grassland
Sprite(offscreen,HGrTerrain,8,i*24+9,64,32,
1+srcno mod 9 *65,1+srcno div 9 *33);
if HelpLineInfo.Picpix=12 then {river}
Sprite(offscreen,HGrTerrain,8,i*24+9,64,32,326,430)
else if HelpLineInfo.Picpix>=3 then {improvement 2}
Sprite(offscreen,HGrTerrain,8,i*24+9,64,32,
1+(HelpLineInfo.Picpix-3)*65,397)
else {improvement 1}
begin
Sprite(offscreen,HGrTerrain,8,i*24+9,64,32,
1+2*65,298+(HelpLineInfo.Picpix)*33);
Sprite(offscreen,HGrTerrain,8,i*24+9,64,32,
1+5*65,298+(HelpLineInfo.Picpix)*33)
end;
x0[i]:=64+8+8;
end;
pkModel:
begin
Sprite(offscreen,HGrStdUnits,x0[i]+8,i*24-11,64,48,
1+HelpLineInfo.Picpix mod 10 *65,1+HelpLineInfo.Picpix div 10 *49);
x0[i]:=64+8+8+x0[i];
end;
pkModelFull:
begin
Sprite(offscreen,HGrStdUnits,x0[i]+8,i*24+13,64,48,
1+HelpLineInfo.Picpix mod 10 *65,1+HelpLineInfo.Picpix div 10 *49);
x0[i]:=64+8+8+x0[i];
end;
pkFeature:
begin
DarkGradient(offscreen.Canvas,x0[i]+8-1,6+i*24-3,16,1);
Frame(offscreen.canvas,x0[i]+8,6+i*24-2,x0[i]+8+13,6+i*24-2+13,
$C0C0C0,$C0C0C0);
Sprite(offscreen,HGrSystem,x0[i]+8+2,6+i*24,10,10,
66+HelpLineInfo.Picpix mod 11*11,137+HelpLineInfo.Picpix div 11*11);
x0[i]:=x0[i]+8+8+2+13;
end;
pkExp:
begin
Frame(offscreen.Canvas,20-1,8-4+i*24,20+12,8+11+i*24,$000000,$000000);
Dump(offscreen,HGrSystem,20,8-3+i*24,12,14,121+HelpLineInfo.Picpix*13,28);
x0[i]:=20+8+11;
end;
pkTreaty:
begin
Dump(offscreen,HGrSystem,20,8-3+i*24,14,14,67+HelpLineInfo.Picpix*15,100);
x0[i]:=20+8+11;
end;
pkDot:
begin
Sprite(offscreen,HGrSystem,x0[i]+18,8+i*24,8,8,81,16);
x0[i]:=20+8+4;
end;
pkNormal_Dot:
x0[i]:=20+8+4;
pkNormal_64:
x0[i]:=64+8+8;
pkCenter:
x0[i]:=(InnerWidth-offscreen.Canvas.TextWidth(MainText[sb.si.npos+i])) div 2;
else x0[i]:=x0[i]+8
end;
line(offscreen.Canvas,i,false)
end
end;
MarkUsedOffscreen(InnerWidth,InnerHeight+13+48);
end; {OffscreenPaint}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -