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

📄 outercore.pas

📁 类似文明的游戏源代码。
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  Government:=gDespotism;
  Money:=0;
  TaxRate:=30;
  LuxRate:=0;
  Research:=0;
  ResearchTech:=-2;
  AnarchyStart:=-AnarchyTurns-1;
  Happened:=0;
  LastValidStat[p]:=-1;
  Worked[p]:=0;
  Founded[p]:=0;
  DevModelTurn[p]:=-1;

  if Brain[bix[p]].DataSize>0 then
    begin
    GetMem(SavedData[p], Brain[bix[p]].DataSize*4);
    GetMem(Data, Brain[bix[p]].DataSize*4);
    FillChar(SavedData[p]^,Brain[bix[p]].DataSize*4,0);
    FillChar(Data^,Brain[bix[p]].DataSize*4,0);
    end
  else begin Data:=nil; SavedData[p]:=nil end;
  if bix[p]=bixTerm then
    begin
    GetMem(BorderHelper,MapSize);
    FillChar(BorderHelper^,MapSize,0);
    end
  else BorderHelper:=nil;
  for i:=0 to nStat-1 do GetMem(Stat[i,p],4*(MaxTurn+1));
  end;

pTurn:=-1;
if Mode<moPlaying then Notify(ntInitPlayers)
else Notify(ntEndInfo);
Game.lx:=lx; Game.ly:=ly; Game.LandMass:=LandMass; Game.MaxTurn:=MaxTurn;
move(Difficulty,Game.Difficulty,SizeOf(Difficulty));
//GameEx.lx:=lx; GameEx.ly:=ly; GameEx.LandMass:=LandMass;
//GameEx.MaxTurn:=MaxTurn; GameEx.RND:=RND;
//move(Difficulty,GameEx.Difficulty,SizeOf(Difficulty));
AICredits:='';
for i:=0 to nBrain-1 do if @Brain[i].Client<>nil then
  if i in BrainUsed then
    begin
{    if Brain[i].Flags and fBroadcast<>0 then
      begin
      GameEx.Controlled:=0;
      for p:=0 to nPl-1 do if bix[p]=i then
        GameEx.Controlled:=GameEx.Controlled or (1 shl p);
      if Mode<moPlaying then Brain[i].Client(cLoadGameEx,-1,GameEx)
      else Brain[i].Client(cNewGameEx,-1,GameEx)
      end
    else}
      begin
      for p:=0 to nPl-1 do if bix[p]=i then Game.RO[p]:=@RW[p]
      else Game.RO[p]:=nil;
      if Mode<moPlaying then Brain[i].Client(cLoadGame,-1,Game)
      else Brain[i].Client(cNewGame,-1,Game)
      end;
    if (i>bixTerm) and (Brain[i].Credits<>'') then
      if AICredits='' then AICredits:=Brain[i].Credits
      else AICredits:=AICredits+'\'+Brain[i].Credits
    end
  else
    begin {module no longer used -- unload}
    Brain[i].Client(cReleaseModule,-1,nil^);
    if i>bixTerm then FreeLibrary(Brain[i].hm);
    Brain[i].Client:=nil;
    end;
AICredits:=AICredits+#0;

CreateStartUnits;
CheckBorders(-1);
AutoSaveExists:=false;
pDipActive:=-1;
pTurn:=0;
end;{StartGame}

procedure GenerateStat(p: integer);
var
cix,uix: integer;
begin
if Difficulty[p]>0 then with RW[p] do
  begin
  Stat[stPop,p,GTurn]:=0;
  for cix:=0 to nCity-1 do if City[cix].Loc>=0 then
    inc(Stat[stPop,p,GTurn],City[cix].Size);
  Stat[stScience,p,GTurn]:=Researched[p]*50;
  if (RW[p].ResearchTech>=0) and (RW[p].ResearchTech<>adMilitary) then
    inc(Stat[stScience,p,GTurn],
      Research*100 div TechBaseCost(nTech[p],Difficulty[p]));
  Stat[stMil,p,GTurn]:=0;
  for uix:=0 to nUn-1 do if Un[uix].Loc>=0 then
    with Model[Un[uix].mix] do
      case Kind of
        mkSelfDeveloped..mkScout-1:
          inc(Stat[stMil,p,GTurn],Cost*Un[uix].Health div 100);
        mkSlaves: inc(Stat[stPop,p,GTurn]);
        mkSettler: inc(Stat[stPop,p,GTurn],2);
        end;
  Stat[stExplore,p,GTurn]:=Discovered[p];
  Stat[stTerritory,p,GTurn]:=Territory[p];
  Stat[stWork,p,GTurn]:=Worked[p];
  LastValidStat[p]:=GTurn;
  end;
end;

procedure BeforeTurn0;
var
p1,uix: integer;
begin
for uix:=0 to RW[pTurn].nUn-1 do {init movement points for first turn}
  with RW[pTurn].Un[uix] do Movement:=RW[pTurn].Model[mix].Speed;

if Difficulty[pTurn]>0 then
  DiscoverViewAreas(pTurn)
else {supervisor}
  begin
  DiscoverAll(pTurn,lObserveSuper);
  for p1:=1 to nPl-1 do
    if 1 shl p1 and GAlive<>0 then
      begin
      GiveCivilReport(pTurn, p1);
      GiveMilReport(pTurn, p1)
      end;
  end
end;

function LoadGame(const Path, FileName: string; Turn: integer): boolean;
var
i,j,ix,d,p1,Command,Subject: integer;
{$IFDEF TEXTLOG}LoadPos0: integer;{$ENDIF}
Data: pointer;
LogFile: TFileStream;
s: string[255];
SaveMap: array[0..lxmax*lymax-1] of Byte;
started,StatRequest: boolean;
begin
SavePath:=Path;
LogFileName:=FileName;
LoadTurn:=Turn;
LogFile:=TFileStream.Create(SavePath+LogFileName,fmOpenRead or fmShareExclusive);
LogFile.Position:=0;
LogFile.read(s[1],8); {file id}
LogFile.read(i,4); {c-evo version}

if (i>=FirstBookCompatibleVersion) and (i<=Version) then
  begin
  result:=true;
  LogFile.read(lx,4);
  LogFile.read(ly,4);
  MapSize:=lx*ly;
  LogFile.read(LandMass,4);
  if LandMass=0 then
    LogFile.read(RealMap,MapSize*4); // use predefined map
  LogFile.read(MaxTurn,4);
  LogFile.read(RND,4);
  LogFile.read(GTurn,4);
  LogFile.read(SaveMap,4);
  if SaveMap[0]<>$80 then
    LogFile.read(SaveMap[4],((MapSize-1) div 4+1)*4-4);
  for p1:=0 to nPl-1 do
    begin
    LogFile.read(s[0],4);
    if s[0]=#0 then bixView[p1]:=-1
    else
      begin
      LogFile.read(s[4],Byte(s[0]) div 4 *4);
      LogFile.read(OriginalDataVersion[p1],4);
      LogFile.read(d,4);{behavior}
      LogFile.read(Difficulty[p1],4);
      j:=nBrain-1;
      while (j>=0) and (AnsiCompareFileName(Brain[j].FileName,s)<>0) do
        dec(j);
      if j<0 then
        begin // ai not found -- replace by local player
        ProcessClientData[p1]:=false;
        MissingBrain:=s;
        Notify(ntAIError);
        j:=bixTerm;
        end
      else ProcessClientData[p1]:=true;
      if j=bixNoTerm then j:=bixSuper_Virtual;
        // crashed tournament -- load as supervisor
      bixView[p1]:=j;
      end;
    end;
  end
else result:=false;

if result then
  begin
  CL:=TCmdList.Create;
  CL.LoadFromFile(LogFile);
  end;
LogFile.Free;
if not result then exit;

Notify(ntStartDone);
if LoadTurn<0 then LoadTurn:=GTurn;
if LoadTurn=0 then Mode:=moLoading
else Mode:=moLoading_Fast;
{$IFDEF TEXTLOG}AssignFile(TextLog,SavePath+LogFileName+'.txt');Rewrite(TextLog);{$ENDIF}
LoadOK:=true;
StartGame;
Notify(ntLoadBegin);

started:=false;
StatRequest:=false;
{$IFDEF LOADPERF}QueryPerformanceCounter(time_total0); time_a:=0; time_b:=0; time_c:=0;{$ENDIF}
while CL.Progress<1000 do
  begin
  CL.Get(Command, p1, Subject, Data);
  if p1<0 then p1:=pTurn;
  if StatRequest
    and (Command and (sctMask or sExecute)<>sctInternal or sExecute) then
    begin GenerateStat(pTurn); StatRequest:=false end;
      // complete all internal commands following an sTurn before generating statistics
  if (Command=sTurn) and not started then
    begin
    {$IFDEF TEXTLOG}WriteLn(TextLog,'---Turn 0 P0---');{$ENDIF}
    for p1:=0 to nPl-1 do if bix[p1]>=0 then
      Brain[bix[p1]].Client(cReplay,p1,nil^);
    BeforeTurn0;
    StatRequest:=true;
    started:=true;
    end
  else if (Command=sTurn) and (pTurn=0) and (GTurn=LoadTurn) then
    begin CL.Cut; Break; end
  else if Command=sIntDataChange then
    begin
    {$IFDEF TEXTLOG}LoadPos0:=CL.State.LoadPos;{$ENDIF}
    if ProcessClientData[p1] then
      CL.GetDataChanges(RW[p1].Data, Brain[bix[p1]].DataSize)
    else CL.GetDataChanges(nil, 0);
    {$IFDEF TEXTLOG}WriteLn(TextLog,Format('Data Changes P%d (%d Bytes)', [p1,CL.State.LoadPos-LoadPos0]));{$ENDIF}
    end
  else
    begin
    {$IFDEF TEXTLOG}CmdInfo:=Format('Command %x',[Command]);{$ENDIF}
    if Command and (sctMask or sExecute)=sctInternal or sExecute then
      IntServer(Command, p1, Subject, Data^) // internal command
    else
      begin
      StatRequest:= Command=sTurn;
      Server(Command, p1, Subject, Data^);
      end;
    {$IFDEF TEXTLOG}WriteLn(TextLog,CmdInfo);{$ENDIF}
    end;
  Notify(ntLoadState+CL.Progress*128 div 1000);
  end;
if StatRequest then GenerateStat(pTurn);
assert(started);
{$IFDEF TEXTLOG}CloseFile(TextLog);{$ENDIF}
{$IFDEF LOADPERF}QueryPerformanceCounter(time_total);{time in s is: (time_total-time_total0)/PerfFreq}{$ENDIF}
NoLogChanges;
if LogFileName[1]='~' then
  begin Delete(LogFileName,1,1); nLogOpened:=-1 end
else nLogOpened:=CL.State.nLog;

Mode:=moPlaying;
LastEndClientCommand:=-1;
if (GTestFlags and tfUncover<>0) or (Difficulty[pTurn]=0) then
  DiscoverAll(pTurn,lObserveSuper) {supervisor - all tiles visible}
else DiscoverViewAreas(pTurn);

for p1:=0 to nPl-1 do if 1 shl p1 and GWatching<>0 then
  for ix:=0 to RW[p1].nEnemyUn-1 do with RW[p1].EnemyUn[ix] do
    emix:=RWemix[p1,Owner,mix];
{$IFOPT O-}CheckBorders(-2);{$ENDIF} // !!! for testing only
Notify(ntEndInfo);
if not LoadOK then Notify(ntLoadError);
Brain[bix[0]].Client(cShowGame,0,nil^);
Notify(ntBackOff);
Inform(pTurn);
ChangeClientWhenDone(cResume,0,nil^,0);
end; //LoadGame

procedure StartNewGame(const Path, FileName, Map: string; Newlx, Newly,
  NewLandMass, NewMaxTurn: integer);
var
p: integer;
begin
Notify(ntStartDone);
SavePath:=Path;
LogFileName:=FileName;
MapFileName:=Map;
if FastContact then begin lx:=24; ly:=42; end
else begin lx:=Newlx; ly:=Newly end;
MapSize:=lx*ly;
if MapFileName<>'' then LandMass:=0
else LandMass:=NewLandMass;
MaxTurn:=NewMaxTurn;
Randomize;
RND:=RandSeed;
Mode:=moPlaying;
CL:=TCmdList.Create;
StartGame;
NoLogChanges;
for p:=0 to nPl-1 do if bix[p]>=0 then
  Brain[bix[p]].Client(cGetReady,p,nil^);
LogChanges;
CL.Put(sTurn, 0, 0, nil);
BeforeTurn0;
GenerateStat(pTurn);
nLogOpened:=-1;
LastEndClientCommand:=-1;
Brain[bix[0]].Client(cShowGame,0,nil^);
Notify(ntBackOff);
Inform(pTurn);
ChangeClientWhenDone(cTurn,0,nil^,0)
end;

procedure DirectHelp(StartHelp: boolean);
begin
InitBrain(bixTerm);
if StartHelp then Brain[bixTerm].Client(cStartHelp,-1,nil^)
else Brain[bixTerm].Client(cHelpOnly,-1,nil^);
AICredits:=#0;
end;

procedure EditMap(const Map: string; Newlx, Newly, NewLandMass: integer);
var
p1,Loc1: integer;
Game: TNewGameData;
begin
Notify(ntStartDone);
Notify(ntInitLocalHuman);
MapFileName:=Map;
lx:=Newlx;
ly:=Newly;
MapSize:=lx*ly;
LandMass:=NewLandMass;
bix[0]:=bixTerm;
Difficulty[0]:=0;
InitBrain(bixTerm);

Randomize;
GAlive:=0;
GWatching:=1;
if not LoadMap(MapFileName) then
  for Loc1:=0 to MapSize-1 do RealMap[Loc1]:=fOcean or fTerritory;
MaxDist:=Distance(0,MapSize-lx shr 1);
CL:=nil;
InitMapEditor;
RW[0].Data:=nil;
RW[0].BorderHelper:=nil;
RW[0].Alive:=0;
Game.lx:=lx; Game.ly:=ly;
Game.RO[0]:=@RW[0];
Game.Difficulty[0]:=0;
for p1:=1 to nPl-1 do begin Game.RO[p1]:=nil; Game.Difficulty[p1]:=-1 end;
Brain[bixTerm].Client(cNewMap,-1,Game);

DiscoverAll(0,lObserveSuper);
Notify(ntEndInfo);
Brain[bix[0]].Client(cShowGame,0,nil^);
Notify(ntBackOff);
ChangeClientWhenDone(cEditMap,0,nil^,0)
end;

procedure BeforeTurn;
var
i,p1,p2,dx,dy,uix,cix,cix2,fix,Loc1,Cost,SizeMod,Job0,Recovery,
  WantedTribute,Det,TestDet,OldLoc,NewImp,SiegedTiles,nUpdateLoc: integer;
CityReport: TCityReport;
UpdateLoc: array[0..numax-1] of integer;
Disorder, DoProd, TribeExtinct, ShipComplete, JobDone, CheckGrow: boolean;
begin
assert(1 shl pTurn and GWatching<>0);
if (1 shl pTurn and GAlive=0) and (Difficulty[pTurn]>0) then
  exit;

MaskD(ObserveLevel,MapSize,not Cardinal(3 shl (2*pTurn)));
if Mode>moLoading_Fast then
  MaskD(RW[pTurn].Map^,MapSize,not Cardinal(fUnit or fHiddenUnit or fStealthUnit
    or fObserved or fSpiedOut or fOwned or fGrWall));
RW[pTurn].nEnemyUn:=0;

if Difficulty[pTurn]>0 then with RW[pTurn] do
  begin
  // force paying tribute
  WantedTribute:=0;
  for p1:=0 to nPl-1 do if Tribute[p1]<0 then
    inc(WantedTribute,-Tribute[p1]);
  if Money<WantedTribute then
    begin
    TaxRate:=100;
    LuxRate:=0;
    Happened:=Happened or phBankrupt;
    end;

  if GWonder[woMir].EffectiveOwner=pTurn then
    GWonder[woMir].EffectiveOwner:=-1; // MIR effect lasts one turn

  if nCity>0 then for p1:=0 to nPl-1 do
    if GTurn=EvaStart[p1]+PeaceEvaTurns then
      begin // peace contract -- remove all units from p1's territory
      Loc1:=City[0].Loc; // search destination for homeless units
      for cix:=1 to nCity-1 do
        if (City[cix].Loc>=0) and ((Loc1<0) or (City[cix].Built[imPalace]>0)) then
          Loc1:=City[cix].Loc;
      for uix:=0 to nUn-1 do with Un[uix] do

⌨️ 快捷键说明

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