📄 innercore.pas
字号:
begin
dec(nPrefStartLoc0);
imax:=nPrefStartLoc0;
end;
i:=Random(imax+1);
StartLoc[p1]:=StartLoc0[i];
StartLoc2[p1]:=StartLoc0[i];
StartLoc0[i]:=StartLoc0[imax];
StartLoc0[imax]:=StartLoc0[nStartLoc0];
end;
SaveMapCenterLoc:=StartLoc[0];
end; {PredefinedStartPositions}
procedure InitGame;
var
p, p1, Loc1: integer;
begin
if FastContact then {Railroad everywhere}
for Loc1:=0 to MapSize-1 do
if RealMap[Loc1] and fTerrain>=fGrass then RealMap[Loc1]:=RealMap[Loc1] or fRR;
{!!!for Loc1:=0 to MapSize-1 do
if RealMap[Loc1] and fterrain>=fGrass then
if random(3)=0 then RealMap[Loc1]:=RealMap[Loc1] or fRoad
else if random(3)=0 then RealMap[Loc1]:=RealMap[Loc1] or fRR;
{random Road and Railroad}
{!!!for Loc1:=0 to MapSize-1 do
if (RealMap[Loc1] and fterrain>=fGrass) and (random(20)=0) then
RealMap[Loc1]:=RealMap[Loc1] or fPoll;}
FillChar(Occupant,MapSize,-1);
FillChar(ZoCMap,MapSize,0);
FillChar(ObserveLevel,MapSize*4,0);
FillChar(UsedByCity,MapSize*4,-1);
GTestFlags:=0;
for p:=0 to nPl-1 do if 1 shl p and GWatching<>0 then with RW[p] do
begin
Researched[p]:=0;
Discovered[p]:=0;
Territory[p]:=0;
nTech[p]:=0;
if Difficulty[p]=0 then ResourceMask[p]:=$FFFFFFFF
else ResourceMask[p]:=$FFFFFFFF and not (fSpecial2 or fRare1 or fRare2);
GrWallContinent[p]:=-1;
GetMem(Map,4*MapSize);
GetMem(MapObservedLast,2*MapSize);
FillChar(MapObservedLast^,2*MapSize,-1);
GetMem(Un,numax*SizeOf(TUn));
GetMem(Model,(nmmax+1)*SizeOf(TModel)); // draft needs one model behind last
GetMem(City,ncmax*SizeOf(TCity));
GetMem(EnemyUn,neumax*SizeOf(TUnitInfo));
GetMem(EnemyCity,necmax*SizeOf(TCityInfo));
GetMem(EnemyModel,nemmax*SizeOf(TModelInfo));
for p1:=0 to nPl-1 do
begin
if 1 shl p1 and GWatching<>0 then
begin
FillChar(RWemix[p,p1],SizeOf(RWemix[p,p1]),255); {-1}
FillChar(Destroyed[p,p1],SizeOf(Destroyed[p,p1]),0);
end;
Attitude[p1]:=atNeutral;
Treaty[p1]:=trNoContact;
EvaStart[p1]:=-PeaceEvaTurns-1;
Tribute[p1]:=0;
if (p1<>p) and (1 shl p1 and GAlive<>0) then
begin // initialize enemy report
GetMem(EnemyReport[p1],SizeOf(TEnemyReport)-2*(INFIN+1-nmmax));
FillChar(EnemyReport[p1].Tech,nAdv,tsNA);
EnemyReport[p1].TurnOfContact:=-1;
EnemyReport[p1].TurnOfCivilReport:=-1;
EnemyReport[p1].TurnOfMilReport:=-1;
EnemyReport[p1].Attitude:=atNeutral;
if 1 shl p and GAlive=0 then Treaty[p1]:=trNone // supervisor
end
else EnemyReport[p1]:=nil;
end;
TestFlags:=GTestFlags;
Credibility:=70;
MaxCredibility:=100;
nUn:=0;
nModel:=0;
nCity:=0;
nEnemyUn:=0;
nEnemyCity:=0;
nEnemyModel:=0;
for Loc1:=0 to MapSize-1 do Map[Loc1]:=fUNKNOWN;
FillChar(Tech,nAdv,tsNA);
FillChar(NatBuilt,SizeOf(NatBuilt),0);
end;
Territory[nPl]:=MapSize;
end; // InitGame
procedure InitRandomGame;
begin
RandSeed:=RND;
CalculatePrimitive;
CreateElevation;
CreateMap(false);
StartPositions;
InitGame;
end; {InitRandomGame}
procedure InitMapGame(Human: integer);
begin
RandSeed:=RND;
FindContinents;
PredefinedStartPositions(Human);
InitGame;
end; {InitMapGame}
procedure ReleaseGame;
var
p1,p2: integer;
begin
for p1:=0 to nPl-1 do if 1 shl p1 and GWatching<>0 then
begin
for p2:=0 to nPl-1 do
if RW[p1].EnemyReport[p2]<>nil then
FreeMem(RW[p1].EnemyReport[p2]);
FreeMem(RW[p1].EnemyUn);
FreeMem(RW[p1].EnemyCity);
FreeMem(RW[p1].EnemyModel);
FreeMem(RW[p1].Un);
FreeMem(RW[p1].City);
FreeMem(RW[p1].Model);
FreeMem(RW[p1].MapObservedLast);
FreeMem(RW[p1].Map);
end
end;
procedure InitMapEditor;
var
p1: integer;
begin
CalculatePrimitive;
FillChar(Occupant,MapSize,-1);
FillChar(ObserveLevel,MapSize*4,0);
with RW[0] do
begin
ResourceMask[0]:=$FFFFFFFF;
GetMem(Map,4*MapSize);
GetMem(MapObservedLast,2*MapSize);
FillChar(MapObservedLast^,2*MapSize,-1);
Un:=nil;
Model:=nil;
City:=nil;
EnemyUn:=nil;
EnemyCity:=nil;
EnemyModel:=nil;
for p1:=0 to nPl-1 do EnemyReport[p1]:=nil;
nUn:=0;
nModel:=0;
nCity:=0;
nEnemyUn:=0;
nEnemyCity:=0;
nEnemyModel:=0;
end;
end;
procedure ReleaseMapEditor;
begin
FreeMem(RW[0].MapObservedLast);
FreeMem(RW[0].Map);
end;
procedure EditTile(Loc, NewTile: integer);
var
dx,dy,Loc1: integer;
begin
case NewTile and fTerrain of
fOcean, fShore: NewTile:=NewTile and fTerrain;
fMountains,fArctic: NewTile:=NewTile and not fRiver;
end;
if NewTile and fRR<>0 then NewTile:=NewTile and not fRoad;
if not ((NewTile and fTerrain) in TerrType_Canalable) then
NewTile:=NewTile and not fCanal;
if Terrain[NewTile and fTerrain].IrrEff=0 then
begin
NewTile:=NewTile and not (fPrefStartPos or fStartPos);
if (NewTile and fTerImp=tiIrrigation) or (NewTile and fTerImp=tiFarm) then
NewTile:=NewTile and not fTerImp
end;
if (Terrain[NewTile and fTerrain].MineEff=0)
and (NewTile and fTerImp=tiMine) then
NewTile:=NewTile and not fTerImp;
RealMap[Loc]:=NewTile;
RealMap[Loc]:=RealMap[Loc] and not fSpecial or SpecialTile(Loc) shl 5;
// automatic: shore and special tiles
for dy:=-3 to 3 do for dx:=-3 to 3 do
if ((dx+dy) and 1=0) and ((dx<>3) and (dx<>-3) or (dy<>3) and (dy<>-3)) then
begin
Loc1:=dLoc(Loc,dx,dy);
if Loc1>=0 then
begin
if CheckShore(Loc1) then
RealMap[Loc1]:=RealMap[Loc1] and not fSpecial or SpecialTile(Loc1) shl 5;
RealMap[Loc1]:=RealMap[Loc1] or fTerritory;
RW[0].Map[Loc1]:=RealMap[Loc1] or fObserved;
end
end;
//RealMap[Loc]:=RealMap[Loc] and not fSpecial;
//RW[0].Map[Loc]:=RealMap[Loc] or fObserved;
end;
{
Map Revealing
____________________________________________________________________
}
procedure Strongest(Loc:integer;var uix,Strength,Bonus,Cnt:integer);
{find strongest defender at Loc}
var
Defender,uix1,Det,Cost,TestStrength,TestBonus,TestDet,TestCost,Domain: integer;
PUn: ^TUn;
PModel: ^TModel;
begin
Defender:=Occupant[Loc];
Cnt:=0;
Det:=-1;
for uix1:=0 to RW[Defender].nUn-1 do
begin
PUn:=@RW[Defender].Un[uix1];
PModel:=@RW[Defender].Model[PUn.mix];
if PModel.Kind=mkSpecial_Glider then Domain:=dGround
else Domain:=PModel.Domain;
if PUn.Loc=Loc then
begin
inc(Cnt);
if PUn.Master<0 then
begin
if Domain<dSea then
begin
TestBonus:=Terrain [RealMap[Loc] and fTerrain].Defense;
if RealMap[Loc] and fTerImp=tiFort then inc(TestBonus,4);
if PUn.Flags and unFortified<>0 then inc(TestBonus,2);
if (PModel.Kind=mkSpecial_TownGuard) and (RealMap[Loc] and fCity<>0) then
inc(TestBonus,4);
end
else TestBonus:=4;
inc(TestBonus,PUn.Exp div ExpCost);
TestStrength:=PModel.Defense*TestBonus*PUn.Health;
if (Domain=dAir) and ((RealMap[Loc] and fCity<>0)
or (RealMap[Loc] and fTerImp=tiBase)) then
TestStrength:=0;
if (Domain=dSea) and (RealMap[Loc] and fTerrain>=fGrass) then
TestStrength:=TestStrength shr 1;
TestDet:=TestStrength;
if PModel.Cap[mcStealth]>0 then
else if PModel.Cap[mcSub]>0 then inc(TestDet,1 shl 29)
else if (Domain=dGround) and (PModel.Cap[mcFanatic]>0) then
inc(TestDet,3 shl 29) // fanatic ground units always defend
else inc(TestDet,2 shl 29);
TestCost:=RW[Defender].Model[PUn.mix].Cost;
if (TestDet>Det) or (TestDet=Det) and (TestCost<Cost) then
begin
uix:=uix1;
Strength:=TestStrength;
Bonus:=TestBonus;
Det:=TestDet;
Cost:=TestCost;
end
end
end
end;
end;
procedure SearchCity(Loc: integer; var p,cix: integer);
// set p to supposed owner before call
var
i: integer;
begin
if RealMap[Loc]<nPl shl 27 then p:=RealMap[Loc] shr 27;
for i:=0 to nPl-1 do
begin
if 1 shl p and GAlive<>0 then with RW[p] do
begin
cix:=nCity-1;
while (cix>=0) and (City[cix].Loc<>Loc) do dec(cix);
if cix>=0 then exit;
end;
assert(i<nPl-1);
p:=(p+1) mod nPl;
end;
end;
procedure MakeCityInfo(p, cix: integer; var ci: TCityInfo);
begin
assert((p>=0) and (p<nPl));
assert((cix>=0) and (cix<RW[p].nCity));
with RW[p].City[cix] do
begin
ci.Loc:=Loc;
ci.ID:=ID;
ci.Owner:=p;
ci.Size:=Size;
ci.Flags:=0;
if Built[imPalace]>0 then inc(ci.Flags,ciCapital);
if (Built[imWalls]>0) or (Continent[Loc]=GrWallContinent[p]) then
inc(ci.Flags,ciWalled);
if Built[imCoastalFort]>0 then inc(ci.Flags,ciCoastalFort);
if Built[imMissileBat]>0 then inc(ci.Flags,ciMissileBat);
end;
end;
procedure TellAboutModel(p,taOwner,tamix: integer);
var
i: integer;
begin
if (p=taOwner) or (Mode<moPlaying) then exit;
i:=0;
while (i<RW[p].nEnemyModel)
and ((RW[p].EnemyModel[i].Owner<>taOwner)
or (RW[p].EnemyModel[i].mix<>tamix)) do inc(i);
if i=RW[p].nEnemyModel then
IntServer(sIntTellAboutModel+p shl 4,taOwner,tamix,nil^);
end;
procedure IntroduceEnemy(p1,p2: integer);
var
i: integer;
begin
RW[p1].Treaty[p2]:=trNone;
RW[p2].Treaty[p1]:=trNone;
for i:=1 to 3 do
begin
if RW[p1].Tech[AgePreq[i]]>=tsApplicable then
RW[p2].EnemyReport[p1].Tech[AgePreq[i]]:=RW[p1].Tech[AgePreq[i]];
if RW[p2].Tech[AgePreq[i]]>=tsApplicable then
RW[p1].EnemyReport[p2].Tech[AgePreq[i]]:=RW[p2].Tech[AgePreq[i]];
end
end;
procedure SetContact(p1,p2: integer);
begin
if (Mode<moPlaying) or (p1=p2) or (RW[p1].Treaty[p2]>trNoContact) then exit;
IntServer(sIntTellAboutNation,p1,p2,nil^);
end;
function DiscoverTile(Loc, p, pTell, Level: integer;
EnableContact: boolean; euix: integer = -2): boolean;
// euix = -2: full discover
// euix = -1: unit and city only, append units in EnemyUn
// euix >= 0: unit and city only, replace EnemyUn[euix]
var
i,uix,cix,Strength,Bonus,Cnt,pFoundCity,cixFoundCity, MinLevel:integer;
Tile: Cardinal;
unx: ^TUn;
mox: ^TModel;
begin
result:=false;
with RW[pTell] do
begin
Tile:=RealMap[Loc] and ResourceMask[pTell];
if Mode>moLoading_Fast then
begin
Tile:=Tile or fObserved;
if Level=lObserveSuper then
Tile:=Tile or fSpiedOut;
if (GrWallContinent[pTell]>=0) and (Continent[Loc]=GrWallContinent[pTell]) then
Tile:=Tile or fGrWall;
if Occupant[Loc]>=0 then
if Occupant[Loc]=pTell then
begin
Tile:=Tile or (fOwned or fUnit);
// Level:=lObserveSuper // always see own units
end
else if Map[Loc] and fUnit<>0 then
Tile:=Tile or fUnit
else
begin
Strongest(Loc,uix,Strength,Bonus,Cnt);
unx:=@RW[Occupant[Loc]].Un[uix];
mox:=@RW[Occupant[Loc]].Model[unx.mix];
if (mox.Cap[mcStealth]>0) and (Tile and fCity=0)
and (Tile and fTerImp<>tiBase) then
MinLevel:=lObserveSuper
else if (mox.Cap[mcSub]>0) and (Tile and fTerrain<fGrass) then
MinLevel:=lObserveAll
else MinLevel:=lObserveUnhidden;
if Level>=MinLevel then
begin
Tile:=Tile or fUnit;
if euix>=0 then uix:=euix
else
begin
uix:=nEnemyUn;
inc(nEnemyUn);
assert(nEnemyUn<neumax);
end;
MakeUnitInfo(Occupant[Loc],unx^,EnemyUn[uix]);
if Cnt>1 then
EnemyUn[uix].Flags:=EnemyUn[uix].Flags or unMulti;
if EnableContact and (mox.Domain=dGround) then
SetContact(pTell,Occupant[Loc]);
if Mode=moPlaying then
begin
TellAboutModel(pTell,Occupant[Loc],unx.mix);
EnemyUn[uix].emix:=RWemix[pTell,Occupant[Loc],unx.mix];
end;
// Level:=lObserveSuper; // don't discover unit twice
if (pTell=p) and (Tile and fCity=0) then result:=true;
end
else Tile:=Tile or Map[Loc] and (fStealthUnit or fHiddenUnit)
end
end; // if Mode>moLoading_Fast
if Tile and fCity<>0 then
if ObserveLevel[Loc] shr (2*pTell) and 3>0 then
Tile:=Tile or Map[Loc] and fOwned
else
begin
pFoundCity:=Tile shr 27;
if pFoundCity=pTell then Tile:=Tile or fOwned
else
begin
if EnableContact then SetContact(pTell,pFoundCity);
cixFoundCity:=RW[pFoundCity].nCity-1;
while (cixFoundCity>=0)
and (RW[pFoundCity].City[cixFoundCity].Loc<>Loc) do
dec(cixFoundCity);
assert(cixFoundCity>=0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -