📄 outercore.pas
字号:
if (Loc>=0) and (Model[mix].Kind<>mkDiplomat)
and ((Home>=0) or (Loc1>=0))
and (RealMap[Loc] shr 27=Cardinal(p1)) then
begin
OldLoc:=Loc;
if Master>=0 then
begin // transport unload
if Model[mix].Domain=dAir then dec(Un[Master].AirLoad)
else dec(Un[Master].TroopLoad);
Master:=-1;
end
else FreeUnit(pTurn,uix);
if Home>=0 then Loc:=City[Home].Loc
else Loc:=Loc1;
PlaceUnit(pTurn,uix);
UpdateUnitMap(OldLoc);
UpdateUnitMap(Loc);
Flags:=Flags or unWithdrawn;
Happened:=Happened or phPeaceEvacuation;
end
end;
TribeExtinct:=true;
nUpdateLoc:=0;
for cix:=0 to nCity-1 do with City[cix] do if Loc>=0 then
begin {next turn for all cities - city loop 1}
Flags:=Flags and (chCaptured or chProductionSabotaged);
// check for siege
SiegedTiles:=0;
for fix:=0 to 26 do if Tiles and (1 shl fix) and not (1 shl 13)<>0 then
begin
dy:=fix shr 2-3; dx:=fix and 3 shl 1 -3 + (dy+3) and 1;
Loc1:=dLoc(Loc,dx,dy);
assert(UsedByCity[Loc1]=Loc);
p1:=RealMap[Loc1] shr 27;
if (RealMap[Loc1] and fCity<>0)
or (p1<nPl) and (p1<>pTurn) and (RW[pTurn].Treaty[p1]>=trPeace)
or (ZoCMap[Loc1]>0) and (Occupant[Loc1]<>pTurn)
and (Treaty[Occupant[Loc1]]<trAlliance) then
begin
Tiles:=Tiles and not (1 shl fix);
UsedByCity[Loc1]:=-1;
Flags:=Flags or chSiege;
inc(SiegedTiles);
end;
end;
while SiegedTiles>0 do // replace sieged tiles
begin
fix:=NextBest(pTurn,cix);
if fix<0 then break;
AddCityTile(pTurn,cix,fix);
dec(SiegedTiles);
end;
with CityReport do
begin
HypoTiles:=-1;
HypoTax:=-1;
HypoLux:=-1;
GetCityReport(pTurn,cix,CityReport);
SizeMod:=0;
Disorder:=(Working-Happy>Size shr 1) or (Government=gAnarchy);
if Disorder and (Government<>gAnarchy) then
begin inc(Flags,chDisorder); ProdRep:=0; end;
if Flags and chCaptured<>0 then
begin Disorder:=true; dec(Flags,$10000); ProdRep:=0; end;
CheckGrow:=false;
if not Disorder
and ((Government=gLybertarianism)
or (Size>=NeedAqueductSize) and (FoodRep<Eaten+2))
and (FoodRep>Eaten) then
inc(Money,FoodRep-Eaten)
else if not (Disorder and (FoodRep>Eaten)) then
begin {calculate new food storage}
i:=FoodRep-Eaten;
// if (i>2) and (Government=gDespotism) then i:=2;
Food:=Food+i;
CheckGrow:= FoodRep>Eaten;
end;
if CheckGrow and (GTestFlags and tfImmGrow<>0) then {fast growth}
inc(SizeMod)
else if CheckGrow and (Food>=Storage) then {normal growth}
begin
if Built[imGranary]=1 then dec(Food,Storage shr 1)
else dec(Food,Storage);
inc(SizeMod)
end
else if Food<0 then {famine}
begin
Food:=0;
// check if settlers or conscripts there to disband
uix:=-1;
for i:=0 to nUn-1 do
if (Un[i].Loc>=0) and (Un[i].Home=cix)
and ((Model[Un[i].mix].Kind=mkSettler)
{and (GWonder[woFreeSettlers].EffectiveOwner<>pTurn)}
or (Un[i].Flags and unConscripts<>0))
and ((uix=-1) or (Model[Un[i].mix].Cost<Model[Un[uix].mix].Cost)
or (Model[Un[i].mix].Cost=Model[Un[uix].mix].Cost)
and (Un[i].Exp<Un[uix].Exp)) then
uix:=i;
if uix>=0 then
begin RemoveUnit_UpdateMap(pTurn,uix); inc(Flags,chUnitLost); end
else begin dec(SizeMod); inc(Flags,chPopDecrease) end
end;
if Prod>ProdCost then
begin inc(Money,Prod-ProdCost); Prod:=ProdCost end;
if ProdRep<Support then
if Flags and chUnitLost=0 then
begin {one unit lost}
Det:=MaxInt;
for i:=0 to nUn-1 do if (Un[i].Loc>=0) and (Un[i].Home=cix) then
with Model[Un[i].mix] do
begin
TestDet:=Un[i].Health+Un[i].Exp shl 8+Cost shl 16; // value of unit
if (Flags and mdDoubleSupport<>0) then
TestDet:=TestDet shr 1; // double support, tend to disband first
if TestDet<Det then
begin uix:=i; Det:=TestDet end;
end;
RemoveUnit_UpdateMap(pTurn,uix);
inc(Flags,chUnitLost);
end
else else if not Disorder and (Flags and chProductionSabotaged=0) then
if Project and (cpImp+cpIndex)=cpImp+imTrGoods then
inc(Money,ProdRep-Support)
else inc(Prod,ProdRep-Support);
if GTestFlags and tfImmImprove<>0 then Prod:=ProdCost;
DoProd:= (Project and (cpImp+cpIndex)<>cpImp+imTrGoods)
and (Prod>=ProdCost);
// check if wonder already built
if (Project and cpImp<>0) and (Project and cpIndex<28)
and (GWonder[Project and cpIndex].CityID<>-1) then
begin inc(Flags,chOldWonder); DoProd:=false; end;
// check if producing settlers would disband city
if DoProd and (Project and (cpImp or cpDisbandCity)=0)
and ((Size+SizeMod-2<2) and (Model[Project and cpIndex].Kind=mkSettler)
or (Size+SizeMod-1<2) and ((Model[Project and cpIndex].Kind=mkSlaves)
or (Project and cpConscripts<>0))) then
begin inc(Flags,chNoSettlerProd); DoProd:=false; end;
if DoProd then
begin {project complete}
dec(Prod,ProdCost);
if Project and cpImp=0 then {produce unit}
begin
if nUn<numax then
begin
CreateUnit(pTurn,Project and cpIndex);
Un[nUn-1].Loc:=Loc;
with Un[nUn-1] do
begin
Home:=cix;
if (Model[mix].Domain<dSea) and (Built[imElite]=1) then
Exp:=ExpCost*(nExp-1){elite}
else if (Model[mix].Domain<dSea) and (Built[imBarracks]=1)
or (Model[mix].Domain=dSea) and (Built[imDockyard]=1)
or (Model[mix].Domain=dAir) and (Built[imAirport]=1) then
Exp:=ExpCost*2;{vet}
if Project and cpConscripts<>0 then Flags:=Flags or unConscripts
end;
PlaceUnit(pTurn,nUn-1);
UpdateUnitMap(Loc);
if Model[Project and cpIndex].Kind=mkSettler then
dec(SizeMod,2) {settler produced - city shrink}
else if (Model[Project and cpIndex].Kind=mkSlaves)
or (Project and cpConscripts<>0) then
dec(SizeMod); {slaves/conscripts produced - city shrink}
end;
Project0:=Project or cpRepeat or cpCompleted;
end
else if Imp[Project and cpIndex].Kind=ikShipPart then
begin {produce ship parts}
inc(GShip[pTurn].Parts[Project and cpIndex-imShipComp]);
Project0:=Project or cpCompleted;
end
else {produce improvement}
begin
NewImp:=Project and cpIndex;
inc(Money,Prod);{change rest to money}
Project0:=Project or cpCompleted;
Project:=cpImp+imTrGoods;
Prod:=0;
if Imp[NewImp].Kind in [ikNatLocal,ikNatGlobal] then
begin // nat. project
for i:=0 to nCity-1 do
if (City[i].Loc>=0) and (City[i].Built[NewImp]=1) then
begin {allowed only once}
inc(Money,Imp[NewImp].Cost
*BuildCostMod[Difficulty[pTurn]] div 12);
City[i].Built[NewImp]:=0;
end;
NatBuilt[NewImp]:=1;
// immediate nat. project effects
case NewImp of
imGrWall: GrWallContinent[pTurn]:=Continent[Loc];
end;
end;
if NewImp<28 then
begin // wonder
GWonder[NewImp].CityID:=ID;
GWonder[NewImp].EffectiveOwner:=pTurn;
CheckExpiration(NewImp);
// immediate wonder effects
case NewImp of
woOracle:
ResourceMask[pTurn]:=ResourceMask[pTurn] or (fRare1 or fRare2);
woManhattan:
GColdWarStart:=GTurn;
woEiffel:
begin // reactivate wonders
for i:=0 to 27 do if Imp[i].Expiration>=0 then
for cix2:=0 to nCity-1 do
if (City[cix2].Loc>=0) and (City[cix2].Built[i]=1) then
GWonder[i].EffectiveOwner:=pTurn
end;
woDarwin: inc(Research,
TechBaseCost(nTech[pTurn],Difficulty[pTurn])
+TechBaseCost(nTech[pTurn]+2,Difficulty[pTurn]));
woLeo: CheckSpecialModels(pTurn,preLeo);
woPyramids: CheckSpecialModels(pTurn,preBuilder);
woMir:
for p1:=0 to nPl-1 do
if (p1<>pTurn) and (1 shl p1 and GAlive<>0)
and (RW[pTurn].Treaty[p1]=trNoContact) then
IntroduceEnemy(pTurn,p1)
end;
end;
for i:=0 to nImpReplacement-1 do // sell obsolete buildings
if (ImpReplacement[i].New=NewImp)
and (Built[ImpReplacement[i].Old]>0) then
begin
inc(RW[pTurn].Money, Imp[ImpReplacement[i].Old].Cost
*BuildCostMod[Difficulty[pTurn]] div 12);
Built[ImpReplacement[i].Old]:=0;
end;
Built[NewImp]:=1;
end;
Prod0:=Prod;
inc(Flags,chProduction)
end
else
begin
Project0:=Project0 and not cpCompleted;
if Project0 and not cpAuto<>Project and not cpAuto then
Project0:=Project;
Prod0:=Prod;
end;
if not Disorder then
begin
{sum research points and taxes}
inc(Research,Science);
inc(Money,Tax);
end;
Pollution:=Pollution+PollRep;
if SizeMod>0 then
if CityGrowth(pTurn,cix) then inc(Flags,chPopIncrease)
else inc(Flags,chNoGrowthWarning);
if Size+SizeMod<2 then
begin // city is erased
RemoveDomainUnits(dSea,pTurn,Loc);
RemoveDomainUnits(dAir,pTurn,Loc);
Map[Loc]:=Map[Loc] and not fCity; // !!! do this in inner core
UpdateLoc[nUpdateLoc]:=Loc;
inc(nUpdateLoc);
DestroyCity(pTurn,cix,true);
end
else
begin
TribeExtinct:=false;
while SizeMod<0 do begin CityShrink(pTurn,cix); inc(SizeMod) end;
end
end
end;{city loop 1}
if nUpdateLoc>0 then
begin
CheckBorders(-1,pTurn);
for i:=0 to nUpdateLoc-1 do UpdateUnitMap(UpdateLoc[i],true);
if Mode=moPlaying then
for p1:=0 to nPl-1 do
if (1 shl p1 and GWatching<>0) and (p1<>pTurn) then
for i:=0 to nUpdateLoc-1 do
if ObserveLevel[UpdateLoc[i]] shr (2*p1) and 3>=lObserveUnhidden then
CallPlayer(cShowCityChanged,p1,UpdateLoc[i]);
end;
// pay tribute
for p1:=0 to nPl-1 do if Tribute[p1]<0 then
begin
i:=-Tribute[p1];
if Money<WantedTribute then
i:=(i*Money*2+WantedTribute) div (2*WantedTribute);
Money:=Money-i;
TributePaid[p1]:=-i;
RW[p1].Money:=RW[p1].Money+i;
RW[p1].TributePaid[pTurn]:=i;
dec(WantedTribute,-Tribute[p1]);
end;
{pay improvement maintenance - city loop 1a}
if (GTestFlags and tfImmImprove=0) and (Government<>gAnarchy) then
for cix:=0 to nCity-1 do with City[cix] do if Loc>=0 then
for i:=28 to nImp-1 do if Built[i]=1 then
begin //
dec(Money,Imp[i].Maint);
if Money<0 then
begin {out of money - sell improvement}
inc(Money,Imp[i].Cost*BuildCostMod[Difficulty[pTurn]] div 12);
Built[i]:=0;
if Imp[i].Kind<>ikCommon then
begin
NatBuilt[i]:=0;
if i=imGrWall then GrWallContinent[pTurn]:=-1;
end;
inc(Flags,chImprovementLost)
end
end;{city loop 1a}
for uix:=0 to nUn-1 do with Un[uix] do if Loc>=0 then
begin // unit loop 2
if Health<100 then
begin {recovery}
if (Master>=0) and (Model[Un[Master].mix].Cap[mcHospital]>0) then
Recovery:=FastRecovery {hospital ship}
else if RealMap[Loc] and fTerImp=tiBase then
Recovery:=CityRecovery
else if RealMap[Loc] and fCity<>0 then
begin {unit in city}
cix:=nCity-1;
while (cix>=0) and (City[cix].Loc<>Loc) do dec(cix);
if City[cix].Flags and chDisorder<>0 then
Recovery:=NoCityRecovery
else if (Model[mix].Domain=dGround)
and (City[cix].Built[imBarracks]+City[cix].Built[imElite]>0)
or (Model[mix].Domain=dSea) and (City[cix].Built[imDockyard]=1)
or (Model[mix].Domain=dAir) and (City[cix].Built[imAirport]=1) then
Recovery:=FastRecovery {city has baracks/shipyard/airport}
else Recovery:=CityRecovery
end
else if (RealMap[Loc] and fTerrain>=fGrass) and (Model[mix].Domain<>dAir) then
Recovery:=NoCityRecovery
else Recovery:=0;
if Model[mix].Speed>0 then {recovery depends on movement unused}
Recovery:=Recovery*Movement div Model[mix].Speed;
if Recovery>Health then Recovery:=Health; // health max. doubled each turn
if Recovery>100-Health then Recovery:=100-Health;
inc(Health,Recovery);
end;
if Flags and unMountainDelay<>0 then
begin
Movement:=0;
Flags:=Flags and not unMountainDelay
end
else Movement:=UnitSpeed(pTurn,mix,Health); {refresh movement}
assert(Loc>=0);
if Model[mix].Kind<>mkDiplomat then
begin // check treaty violation
p1:=RealMap[Loc] shr 27;
if (p1<nPl) and (p1<>pTurn)
and (Treaty[p1] in [trPeace,trFriendlyContact]) then
begin
if Job=jCity then Job:=jNone;
if GTurn>EvaStart[p1]+PeaceEvaTurns then
begin
EvaStart[p1]:=GTurn;
Happened:=Happened or phPeaceViolation;
end;
end;
end;
Loc1:=Loc;
Job0:=Job;
if Job>=jRoad then JobDone:=Work(pTurn,uix);
{settlers do terrain improvement jobs}
if (Health<=0) or TribeExtinct then RemoveUnit_UpdateMap(pTurn,uix);
if (Job0=jCity) and JobDone then // new city, tell enemies
begin
UpdateUnitMap(Loc1,true);
if Mode=moPlaying then
for p1:=0 to nPl-1 do
if (1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -