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

📄 outercore.pas

📁 类似文明的游戏源代码。
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        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 + -