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

📄 outercore.pas

📁 类似文明的游戏源代码。
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  DataSize: integer);
begin
CCCommand:=Command;
CCPlayer:=Player;
if DataSize>0 then move(Data,CCData,DataSize);
Notify(ntChangeClient);
end;

procedure PutMessage(Level: integer; Text: string);
begin
Brain[bix[0]].Client(cDebugMessage,Level,pchar(Text)^);
end;

procedure ForceClientDeactivation;
var
NullOffer: TOffer;
begin
if pDipActive<0 then Server(sTurn,pTurn,0,nil^) // no nego mode
else case LastEndClientCommand of // nego mode
  scContact: Server(scReject,pDipActive,0,nil^);
  scDipCancelTreaty, scDipBreak: Server(scDipNotice,pDipActive,0,nil^);
  else
    begin // make null offer
    NullOffer.nDeliver:=0;
    NullOffer.nCost:=0;
    Server(scDipOffer,pDipActive,0,NullOffer);
    end
  end
end;

procedure CallPlayer(Command,p: integer; var Data);
begin
{$IFOPT O-}
HandoverStack[nHandoverStack]:=p;
HandoverStack[nHandoverStack+1]:=Command;
inc(nHandoverStack,2);
{$ENDIF}
Brain[bix[p]].Client(Command,p,Data);
{$IFOPT O-}dec(nHandoverStack,2);{$ENDIF}
end;

procedure ChangeClient;
//hand over control to other client (as specified by CC...)
var
p: integer;
T: int64;
begin
QueryPerformanceCounter(T);
PutMessage(1 shl 16+2, Format('CLIENT: took %.1f ms',
  [{$IFDEF VER100}(T.LowPart-LastClientTime.LowPart)
  {$ELSE}(T-LastClientTime){$ENDIF}*1000.0/PerfFreq]));
LastClientTime:=T;
PutMessage(1 shl 16+2, Format('CLIENT: calling %d (%s)',
  [CCPlayer,Brain[bix[CCPlayer]].Name]));
if CCCommand=cTurn then
  for p:=0 to nPl-1 do if (p<>CCPlayer) and (1 shl p and GWatching<>0) then
    CallPlayer(cShowTurnChange,p,CCPlayer);

p:=CCPlayer;
CCPlayer:=-1;
CallPlayer(CCCommand,p,CCData);
if (Mode=moPlaying) and (bix[p]>bixTerm) and (CCPlayer<0) then
  begin
  Notify(ntDeactivationMissing+p);
  ForceClientDeactivation;
  end
end;

procedure Inform(p: integer);
var
i,p1: integer;
begin
RW[p].Turn:=GTurn;
if (p=pTurn) and (GTurn=MaxTurn) then
  RW[p].Happened:=RW[p].Happened or phTimeUp;
RW[p].Alive:=GAlive;
move(GWonder,RW[p].Wonder,SizeOf(GWonder));
move(GShip,RW[p].Ship,SizeOf(GShip));
if GWinner>=0 then
  RW[p].Happened:=RW[p].Happened or phShipComplete or GWinner shl 16;
for p1:=0 to nPl-1 do
  if (p1<>p) and (bix[p1]>=0) and (Difficulty[p1]>0) then
    RW[p].EnemyReport[p1].Credibility:=RW[p1].Credibility;
for i:=0 to RW[p].nEnemyModel-1 do with RW[p].EnemyModel[i] do
  Lost:=Destroyed[p,Owner,mix];
end;

procedure LogChanges;
var
p,ix: integer;
begin
for p:=0 to nPl-1 do
  if (1 shl p and GWatching<>0) and ProcessClientData[p] then
    begin
    // log unit status changes
    for ix:=0 to RW[p].nUn-1 do with RW[p].Un[ix] do
      if (Loc>=0) and (SavedStatus<>Status) then
        begin
        CL.Put(sIntSetUnitStatus, p, ix, @Status);
        SavedStatus:=Status
        end;
    // log city status changes
    for ix:=0 to RW[p].nCity-1 do with RW[p].City[ix] do
      if (Loc>=0) and (SavedStatus<>Status) then
        begin
        CL.Put(sIntSetCityStatus, p, ix, @Status);
        SavedStatus:=Status
        end;
    // log model status changes
    for ix:=0 to RW[p].nModel-1 do with RW[p].Model[ix] do
      if SavedStatus<>Status then
        begin
        CL.Put(sIntSetModelStatus, p, ix, @Status);
        SavedStatus:=Status
        end;
    // log enemy city status changes
    for ix:=0 to RW[p].nEnemyCity-1 do with RW[p].EnemyCity[ix] do
      if (Loc>=0) and (SavedStatus<>Status) then
        begin
        CL.Put(sIntSetECityStatus, p, ix, @Status);
        SavedStatus:=Status
        end;
    // log data changes
    if Brain[bix[p]].DataSize>0 then
      begin
      CL.PutDataChanges(sIntDataChange, p, SavedData[p], RW[p].Data,
        Brain[bix[p]].DataSize);
      move(RW[p].Data^,SavedData[p]^,Brain[bix[p]].DataSize*4);
      end
    end;
end;

procedure NoLogChanges;
var
p,ix: integer;
begin
for p:=0 to nPl-1 do
  if (1 shl p and GWatching<>0) and ProcessClientData[p] then
    begin
    for ix:=0 to RW[p].nUn-1 do with RW[p].Un[ix] do
      SavedStatus:=Status;
    for ix:=0 to RW[p].nCity-1 do with RW[p].City[ix] do
      SavedStatus:=Status;
    for ix:=0 to RW[p].nModel-1 do with RW[p].Model[ix] do
      SavedStatus:=Status;
    for ix:=0 to RW[p].nEnemyCity-1 do with RW[p].EnemyCity[ix] do
      SavedStatus:=Status;
    if Brain[bix[p]].DataSize>0 then
      move(RW[p].Data^,SavedData[p]^,Brain[bix[p]].DataSize*4);
    end;
end;

function HasChanges(p: integer): boolean;
type
TDWordList= array[0..INFIN] of Cardinal;
PDWortList=^TDWordList;
var
ix: integer;
begin
result:=false;
for ix:=0 to RW[p].nUn-1 do with RW[p].Un[ix] do
  if (Loc>=0) and (SavedStatus<>Status) then result:=true;
for ix:=0 to RW[p].nCity-1 do with RW[p].City[ix] do
  if (Loc>=0) and (SavedStatus<>Status) then result:=true;
for ix:=0 to RW[p].nModel-1 do with RW[p].Model[ix] do
  if SavedStatus<>Status then result:=true;
for ix:=0 to RW[p].nEnemyCity-1 do with RW[p].EnemyCity[ix] do
  if (Loc>=0) and (SavedStatus<>Status) then result:=true;
if RW[p].Data<>nil then for ix:=0 to Brain[bix[p]].DataSize-1 do
  if PDWortList(SavedData[p])[ix]<>PDWortList(RW[p].Data)[ix] then result:=true
end;

procedure InitBrain(bix: integer);
var
InitModuleData: TInitModuleData;
begin
assert(bix<>bixSuper_Virtual);
with Brain[bix] do
  begin
  if @Client<>nil then exit;
  if bix=bixNoTerm then
    Client:=NoTerm.Client
  else if bix=bixTerm then
    Client:=LocalHuman.Client
  else
    begin {init brain module}
    Notify(ntInitModule+bix);
    hm:=LoadLibrary(pchar(DLLName));
    if hm=0 then
      begin
      Client:=nil;
      Notify(ntDLLError+bix);
      end
    else
      begin
      Client:=GetProcAddress(hm,'client');
      if @Client=nil then Notify(ntClientError+bix);
      end
    end;
  if @Client<>nil then
    begin
    InitModuleData.Server:=@Server;
    InitModuleData.DataVersion:=0;
    InitModuleData.DataSize:=0;
    Client(cInitModule,-1,InitModuleData);
    DataVersion:=InitModuleData.DataVersion;
    DataSize:=(InitModuleData.DataSize+3) div 4;
    if DataSize>MaxDataSize then DataSize:=0
    end
  end
end;

procedure SaveMap(FileName: string);
var
i: integer;
MapFile: TFileStream;
s: string[255];
begin
MapFile:=TFileStream.Create(HomeDir+'Maps\'+FileName, fmCreate or fmShareExclusive);
MapFile.Position:=0;
s:='cEvoMap'#0; MapFile.write(s[1],8); {file id}
i:=0; MapFile.write(i,4); {format id}
MapFile.write(MaxTurn,4);
MapFile.write(lx,4);
MapFile.write(ly,4);
MapFile.write(RealMap,MapSize*4);
MapFile.Free;
end;

function LoadMap(FileName: string): boolean;
var
i,Loc1: integer;
MapFile: TFileStream;
s: string[255];
begin
result:=false;
MapFile:=nil;
try
  MapFile:=TFileStream.Create(HomeDir+'Maps\'+FileName, fmOpenRead or fmShareExclusive);
  MapFile.Position:=0;
  MapFile.read(s[1],8); {file id}
  MapFile.read(i,4); {format id}
  if i=0 then
    begin
    MapFile.read(i,4); //MaxTurn
    MapFile.read(lx,4);
    MapFile.read(ly,4);
    ly:=ly and not 1;
    if lx>lxmax then lx:=lxmax;
    if ly>lymax then ly:=lymax;
    MapSize:=lx*ly;
    MapFile.read(RealMap,MapSize*4);
    for Loc1:=0 to MapSize-1 do
      RealMap[Loc1]:=RealMap[Loc1] and ($7F01FFFF or fPrefStartPos or fStartPos)
        or fTerritory;
    result:=true;
    end;
  MapFile.Free;
except
  if MapFile<>nil then MapFile.Free;
  end;
end;

procedure SaveGame(FileName: string; auto: boolean);
var
x,y,i,zero,Tile,nLocal: integer;
LogFile: TFileStream;
s: string[255];
SaveMap: array[0..lxmax*lymax-1] of Byte;
begin
nLocal:=0;
for i:=0 to nPl-1 do if bix[i]=bixTerm then inc(nLocal);
if Difficulty[0]=0 then nLocal:=0;
if nLocal<=1 then for y:=0 to ly-1 do for x:=0 to lx-1 do
  begin
  Tile:=RW[0].Map[(x+SaveMapCenterLoc+lx shr 1) mod lx +lx*y];
  SaveMap[x+lx*y]:=Tile and fTerrain + Tile and (fCity or fUnit or fOwned) shr 16;
  end;

if auto and AutoSaveExists then // append to existing file
  LogFile:=TFileStream.Create(SavePath+FileName,
    fmOpenReadWrite or fmShareExclusive)
else // create new file
  LogFile:=TFileStream.Create(SavePath+FileName, fmCreate or fmShareExclusive);

zero:=0;
LogFile.Position:=0;
s:='cEvoBook'; LogFile.write(s[1],8); {file id}
i:=Version; LogFile.write(i,4); {c-evo version}
LogFile.write(lx,4);
LogFile.write(ly,4);
LogFile.write(LandMass,4);
if LandMass=0 then
  LogFile.write(MapField^,MapSize*4);

LogFile.write(MaxTurn,4);
LogFile.write(RND,4);
LogFile.write(GTurn,4);
if nLocal>1 then // multiplayer game -- no quick view
  begin i:=$80; LogFile.write(i,4); end
else LogFile.write(SaveMap,((MapSize-1) div 4+1)*4);
for i:=0 to nPl-1 do
  if bix[i]<0 then LogFile.write(zero,4)
  else
    begin
    s:=Brain[bixView[i]].FileName; move(zero,s[Length(s)+1],4);
    LogFile.write(s,(Length(s) div 4+1)*4);
    LogFile.write(OriginalDataVersion[i],4);
    s:=''; {behavior} move(zero,s[Length(s)+1],4);
    LogFile.write(s,(Length(s) div 4+1)*4);
    LogFile.write(Difficulty[i],4);
    end;

if auto and AutoSaveExists then CL.AppendToFile(LogFile, AutoSaveState)
else CL.SaveToFile(LogFile);
LogFile.Free;
if auto then
  begin AutoSaveState:=CL.State; AutoSaveExists:=true end
end;

procedure StartGame;
var
i,p,p1,Human,nAlive: integer;
Game: TNewGameData;
//GameEx: TNewGameExData;
BrainUsed: Set of 0..254; {used brains}
begin
for p1:=0 to nPl-1 do
  begin
  if bixView[p1]=bixSuper_Virtual then bix[p1]:=bixTerm // supervisor and local human use same module
  else bix[p1]:=bixView[p1];
  if bixView[p1]<0 then Difficulty[p1]:=-1;
  end;

if bix[0]<>bixNoTerm then Notify(ntInitLocalHuman);
BrainUsed:=[];
for p:=0 to nPl-1 do if bix[p]>=0 then
  begin {initiate selected control module}
  InitBrain(bix[p]);
  if Mode=moPlaying then
    begin // new game, this data version is original
    OriginalDataVersion[p]:=Brain[bix[p]].DataVersion;
    ProcessClientData[p]:=true;
    end
  else // loading game, compare with data version read from file
    ProcessClientData[p]:=ProcessClientData[p]
      and (OriginalDataVersion[p]=Brain[bix[p]].DataVersion);
  if @Brain[bix[p]].Client=nil then // client function not found
    if bix[0]=bixNoTerm then
      bix[p]:=-1
    else
      begin
      bix[p]:=bixTerm;
      OriginalDataVersion[p]:=-1;
      ProcessClientData[p]:=false;
      end;
  if bix[p]>=0 then include(BrainUsed,bix[p])
  end;

Notify(ntCreateWorld);
nAlive:=0;
GAlive:=0;
GWatching:=0;
for p1:=0 to nPl-1 do if bix[p1]>=0 then
  begin
  inc(GWatching,1 shl p1);
  if Difficulty[p1]>0 then
    begin inc(GAlive,1 shl p1); inc(nAlive); end
  end;
WinOnAlone:= (bix[0]=bixNoTerm) and (nAlive>1);
GWinner:=-1;
GColdWarStart:=-ColdWarTurns-1;
DebugMap:=nil;

if LandMass>0 then
  begin // random map
  InitRandomGame;
  PreviewElevation:=false;
  MapField:=nil;
  end
else
  begin // predefined map
  if Mode=moPlaying then
    LoadMap(MapFileName); // new game -- load map from file
  GetMem(MapField,MapSize*4);
  move(RealMap,MapField^,MapSize*4);
  Human:=0;
  for p1:=0 to nPl-1 do if bix[p1]=bixTerm then inc(Human,1 shl p1);
  InitMapGame(Human);
  end;
MaxDist:=Distance(0,MapSize-lx shr 1);

GTurn:=0;
for i:=0 to 27 do with GWonder[i] do
  begin CityID:=-1; EffectiveOwner:=-1 end;
FillChar(GShip,SizeOf(GShip),0);
GetMem(ToWork,2*MapSize*nJob);
FillChar(ToWork^,2*MapSize*nJob,0);

for p:=0 to nPl-1 do if 1 shl p and GWatching<>0 then with RW[p] do
  begin

⌨️ 快捷键说明

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