📄 outercore.pas
字号:
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 + -