⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statmain.pas

📁 类似文明的游戏源代码。
💻 PAS
字号:
{$INCLUDE switches}

unit StatMain;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TMainForm = class(TForm)
    OpenDialog: TOpenDialog;
    List: TListBox;
    Panel1: TPanel;
    OpenBtn: TButton;
    procedure OpenBtnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure OpenBook(FileName: String);
  end;

var
  MainForm: TMainForm;

implementation

uses Protocol, CmdList;

{$R *.DFM}

const
lxmax=100; lymax=96;
nPl=15; {max number of players, don't change!}

// old version commands
sToggleCityTile=$7400; {+tile code shl 4}
  {reserves $74XX, $75XX}

type
TLogData=array[word] of Byte;

procedure TMainForm.OpenBtnClick(Sender: TObject);
begin
if opendialog.execute then OpenBook(OpenDialog.FileName);
end;

procedure TMainForm.OpenBook(FileName: String);
var
i,j,d,lx,ly,SaveID,nHeader,nTotal,nMapSize,Pos0,LandMass: integer;
Command, Player, Subject: integer;
Data: pointer;
SaveMap: array[0..lxmax*lymax+2] of cardinal;
s: string[255];
nstat, sstat: array[0..$FF] of integer;
statcommand: array[0..$FF] of integer;
LogFile: TFileStream;
CL: TCmdList;

begin
nMapSize:=0;
List.Clear;
List.Items.Add('');
LogFile:=TFileStream.Create(FileName,fmOpenRead or fmShareExclusive);
LogFile.Position:=0;
LogFile.Read(s[1],8); {file id}
s[0]:=#8;
if s<>'cEvoBook' then
  begin
  List.Items.Add('Invalid format');
  exit;
  end;
LogFile.Read(SaveID,4); {format id}
if SaveID<20 then
  begin
  List.Items.Add('C-evo version older than 0.7.2');
  exit;
  end
else if SaveID<$100 then
  List.Items.Add(Format(' Version:     %d',[SaveID]))
else List.Items.Add(Format(' Version:     %d.%d.%d',
  [SaveID shr 16, SaveID shr 8 and $FF, SaveID and $FF]));

LogFile.Read(lx,4);
LogFile.Read(ly,4);
List.Items.Add(Format(' World Size:  %d Tiles',[lx*ly]));
LogFile.Read(LandMass,4);
if LandMass=0 then
  begin
  inc(nMapSize,lx*ly*4);
  LogFile.read(SaveMap,lx*ly*4) // use predefined map
  end
else
  List.Items.Add(Format(' Landmass:    %d%%',[Landmass]));
if SaveID>=27 then
  begin
  LogFile.Read(d,4);
  List.Items.Add(Format(' End Turn:    %d',[d]));
  end;
LogFile.Read(d,4);
LogFile.Read(d,4);
List.Items.Add(Format(' Last Turn:   %d',[d]));
LogFile.read(SaveMap,4);
if SaveMap[0]<>$80 then
  begin
  inc(nMapSize,((lx*ly-1) div 4+1)*4);
  LogFile.read(SaveMap[4],((lx*ly-1) div 4+1)*4-4);
  end;

for i:=0 to nPl-1 do
  begin
  LogFile.Read(s[0],4);
  if s[0]>#0 then
    begin
    LogFile.Read(s[4],Byte(s[0]) div 4 *4);
    if SaveID>=27 then
      LogFile.Read(d,4);{data version}
    LogFile.Read(d,4);{behavior}
    LogFile.Read(d,4); {difficulty}
    List.Items.Add(Format(' Player %2d:   %s (%d)',[i,s,d]));
    end;
  end;

nHeader:=LogFile.Position+4;
CL:=TCmdList.Create;
CL.LoadFromFile(LogFile);
LogFile.Free;

FillChar(nstat,sizeof(nstat),0);
FillChar(sstat,sizeof(sstat),0);

while CL.Progress<1000 do
  begin
  Pos0:=CL.State.LoadPos;
  CL.Get(Command, player, Subject, Data);
  if player<0 then player:=16;
  case Command of
    sSetDevModelCap..sSetDevModelCap+$3F0: Command:=sSetDevModelCap;
    sMoveUnit..sMoveUnit+$3F0: Command:=sMoveUnit;
    sStartJob..sStartJob+$3F0: Command:=sStartJob;
    sToggleCityTile..sToggleCityTile+$1F0: Command:=sToggleCityTile;
    end;
  if Command=sIntDataChange then CL.GetDataChanges(nil, 0);
  inc(nstat[Command shr 8]);
  inc(sstat[Command shr 8],CL.State.LoadPos-Pos0);
  end;
nTotal:=CL.State.LoadPos;
CL.Free;

// only one toggle
inc(nstat[$74],nstat[$75]); nstat[$75]:=0;
inc(sstat[$74],sstat[$75]); sstat[$75]:=0;

// sort by size
for i:=0 to $FF do statcommand[i]:=i;
for i:=0 to $FE do for j:=i+1 to $FF do
  if sstat[i]<sstat[j] then
    begin
    d:=sstat[i]; sstat[i]:=sstat[j]; sstat[j]:=d;
    d:=nstat[i]; nstat[i]:=nstat[j]; nstat[j]:=d;
    d:=statcommand[i]; statcommand[i]:=statcommand[j]; statcommand[j]:=d;
    end;

List.Items.Add('');
List.Items.Add(' Command              Count       Size');
List.Items.Add(' ----------------------------------------------');
List.Items.Add(Format(' Header                     %10.0n (%.1f%%)',
  [nHeader-nMapSize+0.,(nHeader-nMapSize)*100/(nTotal+nHeader)]));
if LandMass=0 then
  List.Items.Add(Format(' Map                        %10.0n (%.1f%%)',
    [lx*ly*4+0.,(lx*ly*4)*100/(nTotal+nHeader)]));
if SaveMap[0]<>$80 then
  List.Items.Add(Format(' Preview Map                %10.0n (%.1f%%)',
    [((lx*ly-1) div 4+1)*4+0.,(((lx*ly-1) div 4+1)*4)*100/(nTotal+nHeader)]));
for i:=0 to $FF do if nstat[i]>0 then
  begin
  case statcommand[i] of
    $40..$43,$45: s:=Format('Internal %xXX',[statcommand[i]]);
    $44: s:='Trades';
    $46: s:='Status Changes';
    $47: s:='Data Changes';
    $48: s:='Turn';
    $51: s:='SetGov/SetRates';
    $52: s:='SetResearch';
    $53: s:='SetAttitude';
    $58: s:='CreateDevModel';
    $5C: s:='SetDevModelCap';
    $60: s:='RemoveUnit';
    $61: s:='SetUnitHome';
    $62: s:='Load/UnloadUnit';
    $64: s:='MoveUnit';
    $6C: s:='StartJob';
    $70: s:='SetCityProject';
    $72: s:='SetCityTiles';
    $74: s:='ToggleCityTile';
    $80..$FF: s:=Format('ClientEx %xXX',[statcommand[i]]);
    else s:=Format('%xXX',[statcommand[i]]);
    end;
  List.Items.Add(Format(' %-16s %9.0n %10.0n (%.1f%%)',
    [s,nstat[i]+0.,sstat[i]+0.,sstat[i]*100/(nTotal+nHeader)]));
  end;
List.Items.Add(Format(' Total                      %10.0n (%.1f%%)',
  [nTotal+nHeader+0.,100.]));
List.Items.Add('');
end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
if paramcount>0 then OpenBook(ParamStr(1));
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -