Changeset 522 for trunk/AI/StdAI


Ignore:
Timestamp:
Jan 7, 2024, 10:24:51 PM (12 months ago)
Author:
chronos
Message:
  • Modified: Code cleanup.
  • Added: High DPI aware SetWindowPos function.
Location:
trunk/AI/StdAI
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/AI/StdAI/AI.pas

    r486 r522  
    624624        begin
    625625          Inc(I);
    626           if random(I) = 0 then
     626          if Random(I) = 0 then
    627627            Result := ad;
    628628        end;
     
    11881188  begin
    11891189    if (Data.LastResearchTech = adHorsebackRiding) and (RO.ResearchTech < 0) and
    1190       (random(6) = 0) and (HavePort or (ContinentPresence[0] and not
     1190      (Random(6) = 0) and (HavePort or (ContinentPresence[0] and not
    11911191      (1 shl Me or PresenceUnknown) <> 0)) then
    11921192    begin
     
    21092109                begin
    21102110                  Inc(BestCount);
    2111                   if random(BestCount) = 0 then
     2111                  if Random(BestCount) = 0 then
    21122112                  begin
    21132113                    AttackScore := TestScore;
     
    22502250          begin
    22512251            Inc(BestCount);
    2252             if random(BestCount) = 0 then
     2252            if Random(BestCount) = 0 then
    22532253            begin
    22542254              PatrolScore := TestScore;
     
    24062406      begin
    24072407        Inc(Count);
    2408         if random(Count) = 0 then
     2408        if Random(Count) = 0 then
    24092409          Result := mix;
    24102410      end;
  • trunk/AI/StdAI/Barbarina.pas

    r486 r522  
    762762          begin
    763763            Inc(BestCount);
    764             if random(BestCount) = 0 then
     764            if Random(BestCount) = 0 then
    765765            begin
    766766              PatrolScore := TestScore;
     
    888888  var
    889889    I, F, uix, Loc1, A, B: Integer;
    890     ready, go: Boolean;
     890    Ready, Go: Boolean;
    891891    TransportPlan: TGroupTransportPlan;
    892892  begin
    893     go := False;
     893    Go := False;
    894894    for F := 0 to maxCOD - 1 do
    895895      if (F < nContinent) and (ContinentPresence[F] and not
    896896        (1 shl Me or PresenceUnknown) <> 0) then
    897         go := True; // any enemy island known?
    898     if not go then
     897        Go := True; // any enemy island known?
     898    if not Go then
    899899      Exit;
    900900
    901901    SeaTransport_BeginInitialize;
    902     go := False;
     902    Go := False;
    903903    for uix := 0 to RO.nUn - 1 do
    904904      if not Moved[uix] then
     
    915915            end;
    916916          end;
    917     if go then
     917    if Go then
    918918    begin
    919       go := False;
     919      Go := False;
    920920      for uix := 0 to RO.nUn - 1 do
    921921        if not Moved[uix] then
     
    928928            end;
    929929    end;
    930     if go then
     930    if Go then
    931931      for Loc1 := 0 to MapSize - 1 do
    932932        if Map[Loc1] and fTerrain >= fGrass then
     
    941941    begin
    942942      Moved[TransportPlan.uixTransport] := True;
    943       ready := MyUnit[TransportPlan.uixTransport].Loc = TransportPlan.LoadLoc;
    944       if not ready then
     943      Ready := MyUnit[TransportPlan.uixTransport].Loc = TransportPlan.LoadLoc;
     944      if not Ready then
    945945      begin
    946946        Unit_MoveEx(TransportPlan.uixTransport, TransportPlan.LoadLoc);
    947         ready := MyUnit[TransportPlan.uixTransport].Loc = TransportPlan.LoadLoc;
    948       end;
    949       if ready then
     947        Ready := MyUnit[TransportPlan.uixTransport].Loc = TransportPlan.LoadLoc;
     948      end;
     949      if Ready then
    950950        for I := 0 to TransportPlan.nLoad - 1 do
    951951        begin
    952952          Loc_to_ab(TransportPlan.LoadLoc,
    953953            MyUnit[TransportPlan.uixLoad[I]].Loc, A, B);
    954           ready := ready and (abs(A) <= 1) and (abs(B) <= 1);
    955         end;
    956       if ready then
     954          Ready := Ready and (Abs(A) <= 1) and (Abs(B) <= 1);
     955        end;
     956      if Ready then
    957957      begin
    958958        for I := 0 to TransportPlan.nLoad - 1 do
     
    16461646      begin
    16471647        Inc(nPreq);
    1648         if random(nPreq) = 0 then
     1648        if Random(nPreq) = 0 then
    16491649          ChosenPreq := ad;
    16501650      end;
     
    17361736  I := 0;
    17371737  while (I < nResearchOrder) and (not NeedSeaUnits and (ResearchOrder[I] < 0) or
    1738       IsResearched(abs(ResearchOrder[I]))) do
     1738      IsResearched(Abs(ResearchOrder[I]))) do
    17391739    Inc(I);
    17401740  if I >= nResearchOrder then // list done, continue with future tech
    17411741  begin
    1742     if random(2) = 1 then
     1742    if Random(2) = 1 then
    17431743      Result := futArtificialIntelligence
    17441744    else
     
    17501750    nPreq := 0;
    17511751    ChosenPreq := -1;
    1752     ChoosePreq(abs(ResearchOrder[I]));
     1752    ChoosePreq(Abs(ResearchOrder[I]));
    17531753    Assert(nPreq > 0);
    17541754    Result := ChosenPreq;
  • trunk/AI/StdAI/CustomAI.pas

    r447 r522  
    246246procedure ab_to_V8(A, B: Integer; var V8: Integer);
    247247begin
    248   Assert((abs(A) <= 1) and (abs(B) <= 1) and ((A <> 0) or (B <> 0)));
     248  Assert((Abs(A) <= 1) and (Abs(B) <= 1) and ((A <> 0) or (B <> 0)));
    249249  V8 := ab_v8[2 * B + B + A];
    250250end;
     
    373373begin
    374374  Loc_to_ab(Loc0, Loc1, A, B);
    375   dx := abs(A - B);
    376   dy := abs(A + B);
    377   Result := dx + dy + abs(dx - dy) shr 1;
    378 end;
    379 
     375  dx := Abs(A - B);
     376  dy := Abs(A + B);
     377  Result := dx + dy + Abs(dx - dy) shr 1;
     378end;
    380379
    381380procedure Init(NewGameData: TNewGameData);
     
    392391{$ENDIF}
    393392end;
    394 
    395393
    396394constructor TCustomAI.Create(Nation: Integer);
     
    410408  Server(sSetDebugMap, Me, 0, nodata^);
    411409end;
    412 
    413410
    414411procedure TCustomAI.Process(Command: Integer; var Data);
     
    495492            begin
    496493              Inc(Count);
    497               if random(Count) = 0 then
     494              if Random(Count) = 0 then
    498495                NewResearch := ad;
    499496            end;
     
    623620      begin
    624621        Inc(Count);
    625         if random(Count) = 0 then
     622        if Random(Count) = 0 then
    626623          Steal := ad;
    627624      end;
     
    11091106end;
    11101107
    1111 
    11121108// negotiation
    11131109function TCustomAI.Nego_CheckMyAction: Integer;
     
    11221118end;
    11231119
    1124 
    11251120initialization
    11261121  nodata := Pointer(0);
  • trunk/AI/StdAI/CustomAI_Reload.pas

    r447 r522  
    55
    66uses
    7 {$IFDEF DEBUG}SysUtils,{$ENDIF} // necessary for debug exceptions
     7{$IFDEF DEBUG}SysUtils,{$ENDIF}// necessary for debug exceptions
    88  Protocol;
    99
    1010type
    11 TNegoTime=(BeginOfTurn, EndOfTurn, EnemyCalled);
    12 
    13 TCustomAI=class
    14 public
    15   procedure Process(Command: Integer; var Data);
    16 
    17   // overridables
    18   constructor Create(Nation: Integer); virtual;
    19   destructor Destroy; override;
    20   procedure SetDataDefaults; virtual;
    21   procedure SetDataRandom; virtual;
    22   procedure OnBeforeEnemyAttack(UnitInfo: TUnitInfo;
    23     ToLoc, EndHealth, EndHealthDef: Integer); virtual;
    24   procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); virtual;
    25   procedure OnAfterEnemyAttack; virtual;
    26   procedure OnAfterEnemyCapture; virtual;
    27 
    28 protected
    29   Me: Integer; // index of the controlled nation
    30   RO: ^TPlayerContext;
    31   Map: ^TTileList;
    32   MyUnit: ^TUnList;
    33   MyCity: ^TCityList;
    34   MyModel: ^TModelList;
    35 
    36   cixStateImp: array[imPalace..imSpacePort] of Integer;
    37 
    38   // negotiation
    39   Opponent: Integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode
    40   MyAction, MyLastAction, OppoAction: Integer;
    41   MyOffer, MyLastOffer, OppoOffer: TOffer;
    42 
    43   // overridables
    44   procedure DoTurn; virtual;
    45   procedure DoNegotiation; virtual;
    46   function ChooseResearchAdvance: Integer; virtual;
    47   function ChooseStealAdvance: Integer; virtual;
    48   function ChooseGovernment: Integer; virtual;
    49   function WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; virtual;
    50   function OnNegoRejected_CancelTreaty: Boolean; virtual;
    51 
    52   // general functions
    53   function IsResearched(Advance: Integer): Boolean;
    54   function ResearchCost: Integer;
    55   function ChangeAttitude(Nation, Attitude: Integer): Integer;
    56   function Revolution: Integer;
    57   function ChangeRates(Tax,Lux: Integer): Integer;
    58   function PrepareNewModel(Domain: Integer): Integer;
    59   function SetNewModelFeature(F, Count: Integer): Integer;
    60   function AdvanceResearchable(Advance: Integer): Boolean;
    61   function AdvanceStealable(Advance: Integer): Boolean;
    62   function DebugMessage(Level: Integer; Text: string): Boolean;
    63   function SetDebugMap(var DebugMap): Boolean;
    64 
    65   // unit functions
    66   procedure Unit_FindMyDefender(Loc: Integer; var uix: Integer);
    67   procedure Unit_FindEnemyDefender(Loc: Integer; var euix: Integer);
    68   function Unit_Move(uix,ToLoc: Integer): Integer;
    69   function Unit_Step(uix,ToLoc: Integer): Integer;
    70   function Unit_Attack(uix,ToLoc: Integer): Integer;
    71   function Unit_DoMission(uix,MissionType,ToLoc: Integer): Integer;
    72   function Unit_MoveForecast(uix,ToLoc: Integer; var RemainingMovement: Integer): Boolean;
    73   function Unit_AttackForecast(uix,ToLoc,AttackMovement: Integer; var RemainingHealth: Integer): Boolean;
    74   function Unit_DefenseForecast(euix,ToLoc: Integer; var RemainingHealth: Integer): Boolean;
    75   function Unit_Disband(uix: Integer): Integer;
    76   function Unit_StartJob(uix,NewJob: Integer): Integer;
    77   function Unit_SetHomeHere(uix: Integer): Integer;
    78   function Unit_Load(uix: Integer): Integer;
    79   function Unit_Unload(uix: Integer): Integer;
    80   function Unit_AddToCity(uix: Integer): Integer;
    81 
    82   // city functions
    83   procedure City_FindMyCity(Loc: Integer; var cix: Integer);
    84   procedure City_FindEnemyCity(Loc: Integer; var ecix: Integer);
    85   function City_HasProject(cix: Integer): Boolean;
    86   function City_CurrentImprovementProject(cix: Integer): Integer;
    87   function City_CurrentUnitProject(cix: Integer): Integer;
    88   function City_GetTileInfo(cix,TileLoc: Integer; var TileInfo: TTileInfo): Integer;
    89   function City_GetReport(cix: Integer; var Report: TCityReport): Integer;
    90   function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer; var Report: TCityReport): Integer;
    91   function City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer;
    92   function City_StartUnitProduction(cix,mix: Integer): Integer;
    93   function City_StartEmigration(cix,mix: Integer; AllowDisbandCity, AsConscripts: Boolean): Integer;
    94   function City_StartImprovement(cix,iix: Integer): Integer;
    95   function City_Improvable(cix,iix: Integer): Boolean;
    96   function City_StopProduction(cix: Integer): Integer;
    97   function City_BuyProject(cix: Integer): Integer;
    98   function City_SellImprovement(cix,iix: Integer): Integer;
    99   function City_RebuildImprovement(cix,iix: Integer): Integer;
    100   function City_SetTiles(cix,NewTiles: Integer): Integer;
    101 
    102   // negotiation
    103   function Nego_CheckMyAction: Integer;
    104 
    105 private
    106   HaveTurned: Boolean;
    107   UnwantedNego: set of 0..nPl-1;
    108   Contacted: set of 0..nPl-1;
    109   procedure StealAdvance;
    110   end;
    111 
    112 
    113 var
    114 Server: TServerCall;
    115 G: TNewGameData;
    116 RWDataSize, MapSize: Integer;
    117 decompose24: Cardinal;
    118 nodata: Pointer;
     11  TNegoTime = (BeginOfTurn, EndOfTurn, EnemyCalled);
     12
     13  TCustomAI = class
     14  public
     15    procedure Process(Command: Integer; var Data);
     16
     17    // overridables
     18    constructor Create(Nation: Integer); virtual;
     19    destructor Destroy; override;
     20    procedure SetDataDefaults; virtual;
     21    procedure SetDataRandom; virtual;
     22    procedure OnBeforeEnemyAttack(UnitInfo: TUnitInfo;
     23      ToLoc, EndHealth, EndHealthDef: Integer); virtual;
     24    procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); virtual;
     25    procedure OnAfterEnemyAttack; virtual;
     26    procedure OnAfterEnemyCapture; virtual;
     27  protected
     28    Me: Integer; // index of the controlled nation
     29    RO: ^TPlayerContext;
     30    Map: ^TTileList;
     31    MyUnit: ^TUnList;
     32    MyCity: ^TCityList;
     33    MyModel: ^TModelList;
     34
     35    cixStateImp: array[imPalace..imSpacePort] of Integer;
     36
     37    // negotiation
     38    Opponent: Integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode
     39    MyAction, MyLastAction, OppoAction: Integer;
     40    MyOffer, MyLastOffer, OppoOffer: TOffer;
     41
     42    // overridables
     43    procedure DoTurn; virtual;
     44    procedure DoNegotiation; virtual;
     45    function ChooseResearchAdvance: Integer; virtual;
     46    function ChooseStealAdvance: Integer; virtual;
     47    function ChooseGovernment: Integer; virtual;
     48    function WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; virtual;
     49    function OnNegoRejected_CancelTreaty: Boolean; virtual;
     50
     51    // general functions
     52    function IsResearched(Advance: Integer): Boolean;
     53    function ResearchCost: Integer;
     54    function ChangeAttitude(Nation, Attitude: Integer): Integer;
     55    function Revolution: Integer;
     56    function ChangeRates(Tax, Lux: Integer): Integer;
     57    function PrepareNewModel(Domain: Integer): Integer;
     58    function SetNewModelFeature(F, Count: Integer): Integer;
     59    function AdvanceResearchable(Advance: Integer): Boolean;
     60    function AdvanceStealable(Advance: Integer): Boolean;
     61    function DebugMessage(Level: Integer; Text: string): Boolean;
     62    function SetDebugMap(var DebugMap): Boolean;
     63
     64    // unit functions
     65    procedure Unit_FindMyDefender(Loc: Integer; var uix: Integer);
     66    procedure Unit_FindEnemyDefender(Loc: Integer; var euix: Integer);
     67    function Unit_Move(uix, ToLoc: Integer): Integer;
     68    function Unit_Step(uix, ToLoc: Integer): Integer;
     69    function Unit_Attack(uix, ToLoc: Integer): Integer;
     70    function Unit_DoMission(uix, MissionType, ToLoc: Integer): Integer;
     71    function Unit_MoveForecast(uix, ToLoc: Integer;
     72      var RemainingMovement: Integer): Boolean;
     73    function Unit_AttackForecast(uix, ToLoc, AttackMovement: Integer;
     74      var RemainingHealth: Integer): Boolean;
     75    function Unit_DefenseForecast(euix, ToLoc: Integer;
     76      var RemainingHealth: Integer): Boolean;
     77    function Unit_Disband(uix: Integer): Integer;
     78    function Unit_StartJob(uix, NewJob: Integer): Integer;
     79    function Unit_SetHomeHere(uix: Integer): Integer;
     80    function Unit_Load(uix: Integer): Integer;
     81    function Unit_Unload(uix: Integer): Integer;
     82    function Unit_AddToCity(uix: Integer): Integer;
     83
     84    // city functions
     85    procedure City_FindMyCity(Loc: Integer; var cix: Integer);
     86    procedure City_FindEnemyCity(Loc: Integer; var ecix: Integer);
     87    function City_HasProject(cix: Integer): Boolean;
     88    function City_CurrentImprovementProject(cix: Integer): Integer;
     89    function City_CurrentUnitProject(cix: Integer): Integer;
     90    function City_GetTileInfo(cix, TileLoc: Integer; var TileInfo: TTileInfo): Integer;
     91    function City_GetReport(cix: Integer; var Report: TCityReport): Integer;
     92    function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer;
     93      var Report: TCityReport): Integer;
     94    function City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer;
     95    function City_StartUnitProduction(cix, mix: Integer): Integer;
     96    function City_StartEmigration(cix, mix: Integer;
     97      AllowDisbandCity, AsConscripts: Boolean): Integer;
     98    function City_StartImprovement(cix, iix: Integer): Integer;
     99    function City_Improvable(cix, iix: Integer): Boolean;
     100    function City_StopProduction(cix: Integer): Integer;
     101    function City_BuyProject(cix: Integer): Integer;
     102    function City_SellImprovement(cix, iix: Integer): Integer;
     103    function City_RebuildImprovement(cix, iix: Integer): Integer;
     104    function City_SetTiles(cix, NewTiles: Integer): Integer;
     105
     106    // negotiation
     107    function Nego_CheckMyAction: Integer;
     108  private
     109    HaveTurned: Boolean;
     110    UnwantedNego: set of 0..nPl - 1;
     111    Contacted: set of 0..nPl - 1;
     112    procedure StealAdvance;
     113  end;
     114
     115var
     116  Server: TServerCall;
     117  G: TNewGameData;
     118  RWDataSize, MapSize: Integer;
     119  decompose24: cardinal;
     120  nodata: Pointer;
    119121
    120122const
    121 CityOwnTile = 13; // = ab_to_V21(0,0)
    122 
    123 // additional return codes
    124 rLocationReached=       $00010000; // Unit_Move: move was not interrupted, location reached
    125 rMoreTurns=             $00020000; // Unit_Move: move was not interrupted, location not reached yet
     123  CityOwnTile = 13; // = ab_to_V21(0,0)
     124
     125  // additional return codes
     126  rLocationReached = $00010000;
     127  // Unit_Move: move was not interrupted, location reached
     128  rMoreTurns = $00020000;
     129// Unit_Move: move was not interrupted, location not reached yet
    126130
    127131type
    128 TVicinity8Loc=array[0..7] of Integer;
    129 TVicinity21Loc=array[0..27] of Integer;
    130 
     132  TVicinity8Loc = array[0..7] of Integer;
     133  TVicinity21Loc = array[0..27] of Integer;
    131134
    132135procedure Init(NewGameData: TNewGameData);
    133136
    134 procedure ab_to_Loc(Loc0,A,B: Integer; var Loc: Integer);
    135 procedure Loc_to_ab(Loc0,Loc: Integer; var A,B: Integer);
    136 procedure ab_to_V8(A,B: Integer; var V8: Integer);
    137 procedure V8_to_ab(V8: Integer; var A,B: Integer);
    138 procedure ab_to_V21(A,B: Integer; var V21: Integer);
    139 procedure V21_to_ab(V21: Integer; var A,B: Integer);
     137procedure ab_to_Loc(Loc0, A, B: Integer; var Loc: Integer);
     138procedure Loc_to_ab(Loc0, Loc: Integer; var A, B: Integer);
     139procedure ab_to_V8(A, B: Integer; var V8: Integer);
     140procedure V8_to_ab(V8: Integer; var A, B: Integer);
     141procedure ab_to_V21(A, B: Integer; var V21: Integer);
     142procedure V21_to_ab(V21: Integer; var A, B: Integer);
    140143procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc);
    141144procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc);
     
    145148
    146149const
    147 ab_v8: array[-4..4] of Integer = (5,6,7,4,-1,0,3,2,1);
    148 v8_a: array[0..7] of Integer = (1,1,0,-1,-1,-1,0,1);
    149 v8_b: array[0..7] of Integer = (0,1,1,1,0,-1,-1,-1);
    150 
    151 
    152 procedure ab_to_Loc(Loc0,A,B: Integer; var Loc: Integer);
     150  ab_v8: array[-4..4] of Integer = (5, 6, 7, 4, -1, 0, 3, 2, 1);
     151  v8_a: array[0..7] of Integer = (1, 1, 0, -1, -1, -1, 0, 1);
     152  v8_b: array[0..7] of Integer = (0, 1, 1, 1, 0, -1, -1, -1);
     153
     154procedure ab_to_Loc(Loc0, A, B: Integer; var Loc: Integer);
    153155{relative location from Loc0}
    154156var
    155 y0: Integer;
    156 begin
    157 Assert((Loc0>=0) and (Loc0<MapSize) and (A-B+G.lx>=0));
    158 y0:=Cardinal(Loc0)*decompose24 shr 24;
    159 Loc:=(Loc0+(A-B+y0 and 1+G.lx+G.lx) shr 1) mod G.lx +G.lx*(y0+A+B);
    160 if Loc>=MapSize then Loc:=-$1000
    161 end;
    162 
    163 procedure Loc_to_ab(Loc0,Loc: Integer; var A,B: Integer);
     157  y0: Integer;
     158begin
     159  Assert((Loc0 >= 0) and (Loc0 < MapSize) and (A - B + G.lx >= 0));
     160  y0 := cardinal(Loc0) * decompose24 shr 24;
     161  Loc := (Loc0 + (A - B + y0 and 1 + G.lx + G.lx) shr 1) mod G.lx + G.lx * (y0 + A + B);
     162  if Loc >= MapSize then Loc := -$1000;
     163end;
     164
     165procedure Loc_to_ab(Loc0, Loc: Integer; var A, B: Integer);
    164166{$IFDEF FPC} // freepascal
    165167var
    166 dx,dy: Integer;
    167 begin
    168 dx:=((Loc mod G.lx *2 +Loc div G.lx and 1)
    169   -(Loc0 mod G.lx *2 +Loc0 div G.lx and 1)+3*G.lx) mod (2*G.lx) -G.lx;
    170 dy:=Loc div G.lx-Loc0 div G.lx;
    171 A:=(dx+dy) div 2;
    172 B:=(dy-dx) div 2;
    173 end;
    174 {$ELSE} // delphi
    175 register;
     168  dx, dy: Integer;
     169begin
     170  dx := ((Loc mod G.lx * 2 + Loc div G.lx and 1)
     171    -(Loc0 mod G.lx * 2 + Loc0 div G.lx and 1) + 3 * G.lx) mod (2 * G.lx) - G.lx;
     172  dy := Loc div G.lx - Loc0 div G.lx;
     173  A := (dx + dy) div 2;
     174  B := (dy - dx) div 2;
     175end;
     176{$ELSE}// delphi
     177  register;
    176178asm
    177 push ebx
    178 
    179 // calculate
    180 push ecx
    181 div Byte ptr [G]
    182 xor ebx,ebx
    183 mov bl,ah  // ebx:=Loc0 mod G.lx
    184 mov ecx,eax
    185 and ecx,$000000FF // ecx:=Loc0 div G.lx
    186 mov eax,edx
    187 div Byte ptr [G]
    188 xor edx,edx
    189 mov dl,ah // edx:=Loc mod G.lx
    190 and eax,$000000FF // eax:=Loc div G.lx
    191 sub edx,ebx // edx:=Loc mod G.lx-Loc0 mod G.lx
    192 mov ebx,eax
    193 sub ebx,ecx // ebx:=dy
    194 and eax,1
    195 and ecx,1
    196 add edx,edx
    197 add eax,edx
    198 sub eax,ecx // eax:=dx, not normalized
    199 pop ecx
    200 
    201 // normalize
    202 mov edx,dword ptr [G]
    203 cmp eax,edx
    204 jl @A
    205   sub eax,edx
    206   sub eax,edx
    207   jmp @ok
    208 @A:
    209 neg edx
    210 cmp eax,edx
    211 jnl @ok
    212   sub eax,edx
    213   sub eax,edx
    214 
    215 // return results
    216 @ok:
    217 mov edx,ebx
    218 sub edx,eax
    219 add eax,ebx
    220 sar edx,1 // edx:=b
    221 mov ebx,[B]
    222 mov [ebx],edx
    223 sar eax,1 // eax:=a
    224 mov [A],eax
    225 
    226 pop ebx
     179         PUSH    EBX
     180
     181         // calculate
     182         PUSH    ECX
     183         DIV    Byte ptr [G]
     184         XOR     EBX,EBX
     185         MOV     BL,AH  // ebx:=Loc0 mod G.lx
     186         MOV     ECX,EAX
     187         AND     ECX,$000000FF // ecx:=Loc0 div G.lx
     188         MOV     EAX,EDX
     189         DIV    Byte ptr [G]
     190         XOR     EDX,EDX
     191         MOV     DL,AH // edx:=Loc mod G.lx
     192         AND     EAX,$000000FF // eax:=Loc div G.lx
     193         SUB     EDX,EBX // edx:=Loc mod G.lx-Loc0 mod G.lx
     194         MOV     EBX,EAX
     195         SUB     EBX,ECX // ebx:=dy
     196         AND     EAX,1
     197         AND     ECX,1
     198         ADD     EDX,EDX
     199         ADD     EAX,EDX
     200         SUB     EAX,ECX // eax:=dx, not normalized
     201         POP     ECX
     202
     203         // normalize
     204         MOV     EDX,dword ptr [G]
     205         CMP     EAX,EDX
     206         JL      @A
     207         SUB     EAX,EDX
     208         SUB     EAX,EDX
     209         JMP    @ok
     210         @A:
     211         NEG     EDX
     212         CMP     EAX,EDX
     213         JNL    @ok
     214         SUB     EAX,EDX
     215         SUB     EAX,EDX
     216
     217         // return results
     218         @ok:
     219         MOV     EDX,EBX
     220         SUB     EDX,EAX
     221         ADD     EAX,EBX
     222         SAR     EDX,1 // edx:=b
     223         MOV     EBX,[B]
     224         MOV     [EBX],EDX
     225         SAR     EAX,1 // eax:=a
     226         MOV     [A],EAX
     227
     228         POP     EBX
    227229end;
    228230{$ENDIF}
    229231
    230 procedure ab_to_V8(A,B: Integer; var V8: Integer);
    231 begin
    232 Assert((abs(A)<=1) and (abs(B)<=1) and ((A<>0) or (B<>0)));
    233 V8:=ab_v8[2*B+B+A];
    234 end;
    235 
    236 procedure V8_to_ab(V8: Integer; var A,B: Integer);
    237 begin
    238 A:=v8_a[V8]; B:=V8_b[V8];
    239 end;
    240 
    241 procedure ab_to_V21(A,B: Integer; var V21: Integer);
    242 begin
    243 V21:=(A+B+3) shl 2+(A-B+3) shr 1;
    244 end;
    245 
    246 procedure V21_to_ab(V21: Integer; var A,B: Integer);
    247 var
    248 dx,dy: Integer;
    249 begin
    250 dy:=V21 shr 2-3;
    251 dx:=V21 and 3 shl 1 -3 + (dy+3) and 1;
    252 A:=(dx+dy) div 2;
    253 B:=(dy-dx) div 2;
     232procedure ab_to_V8(A, B: Integer; var V8: Integer);
     233begin
     234  Assert((Abs(A) <= 1) and (Abs(B) <= 1) and ((A <> 0) or (B <> 0)));
     235  V8 := ab_v8[2 * B + B + A];
     236end;
     237
     238procedure V8_to_ab(V8: Integer; var A, B: Integer);
     239begin
     240  A := v8_a[V8];
     241  B := V8_b[V8];
     242end;
     243
     244procedure ab_to_V21(A, B: Integer; var V21: Integer);
     245begin
     246  V21 := (A + B + 3) shl 2 + (A - B + 3) shr 1;
     247end;
     248
     249procedure V21_to_ab(V21: Integer; var A, B: Integer);
     250var
     251  dx, dy: Integer;
     252begin
     253  dy := V21 shr 2 - 3;
     254  dx := V21 and 3 shl 1 - 3 + (dy + 3) and 1;
     255  A := (dx + dy) div 2;
     256  B := (dy - dx) div 2;
    254257end;
    255258
    256259procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc);
    257260var
    258 x0,y0,lx: Integer;
    259 begin
    260 lx:=G.lx;
    261 y0:=Cardinal(Loc0)*decompose24 shr 24;
    262 x0:=Loc0-y0*lx; // Loc0 mod lx;
    263 VicinityLoc[1]:=Loc0+lx*2;
    264 VicinityLoc[3]:=Loc0-1;
    265 VicinityLoc[5]:=Loc0-lx*2;
    266 VicinityLoc[7]:=Loc0+1;
    267 Inc(Loc0,y0 and 1);
    268 VicinityLoc[0]:=Loc0+lx;
    269 VicinityLoc[2]:=Loc0+lx-1;
    270 VicinityLoc[4]:=Loc0-lx-1;
    271 VicinityLoc[6]:=Loc0-lx;
    272 
    273 // world is round!
    274 if x0<lx-1 then
     261  x0, y0, lx: Integer;
     262begin
     263  lx := G.lx;
     264  y0 := cardinal(Loc0) * decompose24 shr 24;
     265  x0 := Loc0 - y0 * lx; // Loc0 mod lx;
     266  VicinityLoc[1] := Loc0 + lx * 2;
     267  VicinityLoc[3] := Loc0 - 1;
     268  VicinityLoc[5] := Loc0 - lx * 2;
     269  VicinityLoc[7] := Loc0 + 1;
     270  Inc(Loc0, y0 and 1);
     271  VicinityLoc[0] := Loc0 + lx;
     272  VicinityLoc[2] := Loc0 + lx - 1;
     273  VicinityLoc[4] := Loc0 - lx - 1;
     274  VicinityLoc[6] := Loc0 - lx;
     275
     276  // world is round!
     277  if x0 < lx - 1 then
    275278  begin
    276   if x0=0 then
     279    if x0 = 0 then
    277280    begin
    278     Inc(VicinityLoc[3],lx);
    279     if y0 and 1=0 then
    280       begin
    281       Inc(VicinityLoc[2],lx);
    282       Inc(VicinityLoc[4],lx);
    283       end
     281      Inc(VicinityLoc[3], lx);
     282      if y0 and 1 = 0 then
     283      begin
     284        Inc(VicinityLoc[2], lx);
     285        Inc(VicinityLoc[4], lx);
     286      end;
     287    end;
     288  end
     289  else
     290  begin
     291    Dec(VicinityLoc[7], lx);
     292    if y0 and 1 = 1 then
     293    begin
     294      Dec(VicinityLoc[0], lx);
     295      Dec(VicinityLoc[6], lx);
     296    end;
     297  end;
     298
     299  // check south pole
     300  case G.ly - y0 of
     301    1:
     302    begin
     303      VicinityLoc[0] := -$1000;
     304      VicinityLoc[1] := -$1000;
     305      VicinityLoc[2] := -$1000;
     306    end;
     307    2: VicinityLoc[1] := -$1000;
     308  end;
     309end;
     310
     311procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc);
     312var
     313  dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: Integer;
     314  dst: ^Integer;
     315begin
     316  y0 := cardinal(Loc0) * decompose24 shr 24;
     317  xComp0 := Loc0 - y0 * G.lx - 1; // Loc0 mod G.lx -1
     318  xCompSwitch := xComp0 - 1 + y0 and 1;
     319  if xComp0 < 0 then Inc(xComp0, G.lx);
     320  if xCompSwitch < 0 then Inc(xCompSwitch, G.lx);
     321  xCompSwitch := xCompSwitch xor xComp0;
     322  yComp := G.lx * (y0 - 3);
     323  dst := @VicinityLoc;
     324  bit := 1;
     325  for dy := 0 to 6 do
     326    if yComp < MapSize then
     327    begin
     328      xComp0 := xComp0 xor xCompSwitch;
     329      xComp := xComp0;
     330      for dx := 0 to 3 do
     331      begin
     332        if bit and $67F7F76 <> 0 then dst^ := xComp + yComp
     333        else
     334          dst^ := -1;
     335        Inc(xComp);
     336        if xComp >= G.lx then Dec(xComp, G.lx);
     337        Inc(dst);
     338        bit := bit shl 1;
     339      end;
     340      Inc(yComp, G.lx);
    284341    end
    285   end
    286 else
    287   begin
    288   Dec(VicinityLoc[7],lx);
    289   if y0 and 1=1 then
     342    else
    290343    begin
    291     Dec(VicinityLoc[0],lx);
    292     Dec(VicinityLoc[6],lx);
    293     end
    294   end;
    295 
    296 // check south pole
    297 case G.ly-y0 of
    298   1:
    299     begin
    300     VicinityLoc[0]:=-$1000;
    301     VicinityLoc[1]:=-$1000;
    302     VicinityLoc[2]:=-$1000;
     344      for dx := 0 to 3 do
     345      begin
     346        dst^ := -$1000;
     347        Inc(dst);
     348      end;
    303349    end;
    304   2: VicinityLoc[1]:=-$1000;
    305   end
    306 end;
    307 
    308 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc);
    309 var
    310 dx,dy,bit,y0,xComp,yComp,xComp0,xCompSwitch: Integer;
    311 dst: ^Integer;
    312 begin
    313 y0:=Cardinal(Loc0)*decompose24 shr 24;
    314 xComp0:=Loc0-y0*G.lx-1; // Loc0 mod G.lx -1
    315 xCompSwitch:=xComp0-1+y0 and 1;
    316 if xComp0<0 then Inc(xComp0,G.lx);
    317 if xCompSwitch<0 then Inc(xCompSwitch,G.lx);
    318 xCompSwitch:=xCompSwitch xor xComp0;
    319 yComp:=G.lx*(y0-3);
    320 dst:=@VicinityLoc;
    321 bit:=1;
    322 for dy:=0 to 6 do
    323   if yComp<MapSize then
    324     begin
    325     xComp0:=xComp0 xor xCompSwitch;
    326     xComp:=xComp0;
    327     for dx:=0 to 3 do
    328       begin
    329       if bit and $67F7F76<>0 then dst^:=xComp+yComp
    330       else dst^:=-1;
    331       Inc(xComp);
    332       if xComp>=G.lx then Dec(xComp, G.lx);
    333       Inc(dst);
    334       bit:=bit shl 1;
    335       end;
    336     Inc(yComp,G.lx);
    337     end
    338   else
    339     begin
    340     for dx:=0 to 3 do
    341       begin dst^:=-$1000; Inc(dst); end;
    342     end
    343 end;
    344 
     350end;
    345351
    346352procedure Init(NewGameData: TNewGameData);
    347353{$IFDEF DEBUG}var Loc: Integer;{$ENDIF}
    348354begin
    349 G:=NewGameData;
    350 MapSize:=G.lx*G.ly;
    351 decompose24:=(1 shl 24-1) div G.lx +1;
     355  G := NewGameData;
     356  MapSize := G.lx * G.ly;
     357  decompose24 := (1 shl 24 - 1) div G.lx + 1;
    352358{$IFDEF DEBUG}for Loc:=0 to MapSize-1 do Assert(Cardinal(Loc)*decompose24 shr 24=Cardinal(Loc div G.lx));{$ENDIF}
    353359end;
    354360
    355 
    356361constructor TCustomAI.Create(Nation: Integer);
    357362begin
    358 inherited Create;
    359 Me:=Nation;
    360 RO:=Pointer(G.RO[Nation]);
    361 Map:=Pointer(RO.Map);
    362 MyUnit:=Pointer(RO.Un);
    363 MyCity:=Pointer(RO.City);
    364 MyModel:=Pointer(RO.Model);
    365 Opponent:=-1;
     363  inherited Create;
     364  Me := Nation;
     365  RO := Pointer(G.RO[Nation]);
     366  Map := Pointer(RO.Map);
     367  MyUnit := Pointer(RO.Un);
     368  MyCity := Pointer(RO.City);
     369  MyModel := Pointer(RO.Model);
     370  Opponent := -1;
    366371end;
    367372
    368373destructor TCustomAI.Destroy;
    369374begin
    370 Server(sSetDebugMap,Me,0,nodata^);
    371 end;
    372 
     375  Server(sSetDebugMap, Me, 0, nodata^);
     376end;
    373377
    374378procedure TCustomAI.Process(Command: Integer; var Data);
    375379var
    376 Nation,NewResearch,NewGov,count,ad,cix,iix: Integer;
    377 NegoTime: TNegoTime;
    378 begin
    379 case Command of
    380   cTurn, cContinue:
     380  Nation, NewResearch, NewGov, Count, ad, cix, iix: Integer;
     381  NegoTime: TNegoTime;
     382begin
     383  case Command of
     384    cTurn, cContinue:
    381385    begin
    382     if RO.Alive and (1 shl Me)=0 then
     386      if RO.Alive and (1 shl Me) = 0 then
    383387      begin // I'm dead, huhu
    384       Server(sTurn,Me,0,nodata^);
    385       Exit
     388        Server(sTurn, Me, 0, nodata^);
     389        Exit;
    386390      end;
    387     if Command=cTurn then
    388       begin
    389       FillChar(cixStateImp, SizeOf(cixStateImp), $FF);
    390       for cix:=0 to RO.nCity-1 do if MyCity[cix].Loc>=0 then
    391         for iix:=imPalace to imSpacePort do
    392           if MyCity[cix].Built[iix]>0 then
    393             cixStateImp[iix]:=cix;
    394       if RO.Happened and phChangeGov<>0 then
     391      if Command = cTurn then
     392      begin
     393        FillChar(cixStateImp, SizeOf(cixStateImp), $FF);
     394        for cix := 0 to RO.nCity - 1 do if MyCity[cix].Loc >= 0 then
     395            for iix := imPalace to imSpacePort do
     396              if MyCity[cix].Built[iix] > 0 then
     397                cixStateImp[iix] := cix;
     398        if RO.Happened and phChangeGov <> 0 then
    395399        begin
    396         NewGov:=ChooseGovernment;
    397         if NewGov>gAnarchy then
    398           Server(sSetGovernment,Me,NewGov,nodata^);
     400          NewGov := ChooseGovernment;
     401          if NewGov > gAnarchy then
     402            Server(sSetGovernment, Me, NewGov, nodata^);
    399403        end;
    400       HaveTurned:=False;
    401       Contacted:=[];
     404        HaveTurned := False;
     405        Contacted := [];
    402406      end;
    403     if (Command=cContinue) and (MyAction=scContact) then
    404       begin
    405       if OnNegoRejected_CancelTreaty then
    406         if RO.Treaty[Opponent]>=trPeace then
    407           if Server(sCancelTreaty,Me,0,nodata^)<rExecuted then
    408             Assert(False)
     407      if (Command = cContinue) and (MyAction = scContact) then
     408      begin
     409        if OnNegoRejected_CancelTreaty then
     410          if RO.Treaty[Opponent] >= trPeace then
     411            if Server(sCancelTreaty, Me, 0, nodata^) < rExecuted then
     412              Assert(False);
    409413      end
    410     else UnwantedNego:=[];
    411     Opponent:=-1;
    412     repeat
    413       if HaveTurned then NegoTime:=EndOfTurn
    414       else NegoTime:=BeginOfTurn;
    415       if RO.Government<>gAnarchy then
    416         for Nation:=0 to nPl-1 do
    417            if (Nation<>Me) and (1 shl Nation and RO.Alive<>0)
    418              and (RO.Treaty[Nation]>=trNone)
    419              and not (Nation in Contacted) and not (Nation in UnwantedNego)
    420              and (Server(scContact-sExecute + Nation shl 4, Me, 0, nodata^)>=rExecuted) then
    421              if WantNegotiation(Nation, NegoTime) then
    422                begin
    423                if Server(scContact + Nation shl 4, Me, 0, nodata^)>=rExecuted then
    424                  begin
    425                  Include(Contacted, Nation);
    426                  Opponent:=Nation;
    427                  MyAction:=scContact;
    428                  Exit;
    429                  end;
    430                end
    431              else Include(UnwantedNego,Nation);
    432       if NegoTime=BeginOfTurn then
     414      else
     415        UnwantedNego := [];
     416      Opponent := -1;
     417      repeat
     418        if HaveTurned then NegoTime := EndOfTurn
     419        else
     420          NegoTime := BeginOfTurn;
     421        if RO.Government <> gAnarchy then
     422          for Nation := 0 to nPl - 1 do
     423            if (Nation <> Me) and (1 shl Nation and RO.Alive <> 0) and
     424              (RO.Treaty[Nation] >= trNone) and not (Nation in Contacted) and not
     425              (Nation in UnwantedNego) and
     426              (Server(scContact - sExecute + Nation shl 4, Me, 0, nodata^) >= rExecuted) then
     427              if WantNegotiation(Nation, NegoTime) then
     428              begin
     429                if Server(scContact + Nation shl 4, Me, 0, nodata^) >= rExecuted then
     430                begin
     431                  Include(Contacted, Nation);
     432                  Opponent := Nation;
     433                  MyAction := scContact;
     434                  Exit;
     435                end;
     436              end
     437              else
     438                Include(UnwantedNego, Nation);
     439        if NegoTime = BeginOfTurn then
    433440        begin
    434         DoTurn;
    435         HaveTurned:=True;
    436         Contacted:=[];
    437         UnwantedNego:=[];
     441          DoTurn;
     442          HaveTurned := True;
     443          Contacted := [];
     444          UnwantedNego := [];
    438445        end
    439       else Break;
    440     until False;
    441     if RO.Happened and phTech<>0 then
    442       begin
    443       NewResearch:=ChooseResearchAdvance;
    444       if NewResearch<0 then
     446        else
     447          Break;
     448      until False;
     449      if RO.Happened and phTech <> 0 then
     450      begin
     451        NewResearch := ChooseResearchAdvance;
     452        if NewResearch < 0 then
    445453        begin // choose random research
    446         count:=0;
    447         for ad:=0 to nAdv-1 do if AdvanceResearchable(ad) then
    448           begin Inc(count); if random(count)=0 then NewResearch:=ad end
     454          Count := 0;
     455          for ad := 0 to nAdv - 1 do if AdvanceResearchable(ad) then
     456            begin
     457              Inc(Count);
     458              if Random(Count) = 0 then NewResearch := ad;
     459            end;
    449460        end;
    450       Server(sSetResearch,Me,NewResearch,nodata^)
     461        Server(sSetResearch, Me, NewResearch, nodata^);
    451462      end;
    452     if (Me=1) and (RO.Turn=800) then
    453       begin
    454       count:=0;
    455       Server(sReload,Me,0,count)
     463      if (Me = 1) and (RO.Turn = 800) then
     464      begin
     465        Count := 0;
     466        Server(sReload, Me, 0, Count);
    456467      end
    457     else if (RO.Turn>10) and (random(1000)=0) then
    458       begin
    459       count:=RO.Turn-10;
    460       Server(sReload,Me,0,count)
     468      else if (RO.Turn > 10) and (Random(1000) = 0) then
     469      begin
     470        Count := RO.Turn - 10;
     471        Server(sReload, Me, 0, Count);
    461472      end
    462     else if Server(sTurn,Me,0,nodata^)<rExecuted then
    463       Assert(False);
     473      else if Server(sTurn, Me, 0, nodata^) < rExecuted then
     474        Assert(False);
    464475    end;
    465   scContact:
    466     if WantNegotiation(Integer(Data), EnemyCalled) then
    467       begin
    468       if Server(scDipStart, Me, 0, nodata^)<rExecuted then
    469         Assert(False);
    470       Opponent:=Integer(Data);
    471       MyAction:=scDipStart;
     476    scContact:
     477      if WantNegotiation(Integer(Data), EnemyCalled) then
     478      begin
     479        if Server(scDipStart, Me, 0, nodata^) < rExecuted then
     480          Assert(False);
     481        Opponent := Integer(Data);
     482        MyAction := scDipStart;
    472483      end
    473     else
    474       begin
    475       if Server(scReject, Me, 0, nodata^)<rExecuted then
    476         Assert(False);
     484      else
     485      begin
     486        if Server(scReject, Me, 0, nodata^) < rExecuted then
     487          Assert(False);
    477488      end;
    478   scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak:
     489    scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak:
    479490    begin
    480     OppoAction:=Command;
    481     if Command=scDipOffer then OppoOffer:=TOffer(Data);
    482     MyLastAction:=MyAction;
    483     MyLastOffer:=MyOffer;
    484     if (OppoAction=scDipCancelTreaty) or (OppoAction=scDipBreak) then
    485       MyAction:=scDipNotice
    486     else begin MyAction:=scDipOffer; MyOffer.nDeliver:=0; MyOffer.nCost:=0; end;
    487     DoNegotiation;
    488     Assert((MyAction=scDipNotice) or (MyAction=scDipAccept)
    489       or (MyAction=scDipCancelTreaty) or (MyAction=scDipOffer)
    490       or (MyAction=scDipBreak));
    491     if MyAction=scDipOffer then Server(MyAction, Me, 0, MyOffer)
    492     else Server(MyAction, Me, 0, nodata^);
     491      OppoAction := Command;
     492      if Command = scDipOffer then OppoOffer := TOffer(Data);
     493      MyLastAction := MyAction;
     494      MyLastOffer := MyOffer;
     495      if (OppoAction = scDipCancelTreaty) or (OppoAction = scDipBreak) then
     496        MyAction := scDipNotice
     497      else
     498      begin
     499        MyAction := scDipOffer;
     500        MyOffer.nDeliver := 0;
     501        MyOffer.nCost := 0;
     502      end;
     503      DoNegotiation;
     504      Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or
     505        (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak));
     506      if MyAction = scDipOffer then Server(MyAction, Me, 0, MyOffer)
     507      else
     508        Server(MyAction, Me, 0, nodata^);
    493509    end;
    494   cShowEndContact:
    495     Opponent:=-1;
     510    cShowEndContact:
     511      Opponent := -1;
    496512  end;
    497513end;
     
    514530end;
    515531
    516 procedure TCustomAI.OnBeforeEnemyAttack(UnitInfo: TUnitInfo; ToLoc, EndHealth,
    517   EndHealthDef: Integer);
     532procedure TCustomAI.OnBeforeEnemyAttack(UnitInfo: TUnitInfo;
     533  ToLoc, EndHealth, EndHealthDef: Integer);
    518534begin
    519535end;
     
    533549function TCustomAI.ChooseResearchAdvance: Integer;
    534550begin
    535 Result:=-1
     551  Result := -1;
    536552end;
    537553
    538554function TCustomAI.ChooseStealAdvance: Integer;
    539555begin
    540 Result:=-1
     556  Result := -1;
    541557end;
    542558
    543559function TCustomAI.ChooseGovernment: Integer;
    544560begin
    545 Result:=gDespotism
     561  Result := gDespotism;
    546562end;
    547563
    548564function TCustomAI.WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean;
    549565begin
    550 Result:=False;
     566  Result := False;
    551567end;
    552568
    553569function TCustomAI.OnNegoRejected_CancelTreaty: Boolean;
    554570begin
    555 Result:=False;
    556 end;
     571  Result := False;
     572end;
     573
    557574{$HINTS ON}
    558575
    559576procedure TCustomAI.StealAdvance;
    560577var
    561 Steal, ad, count: Integer;
    562 begin
    563 Steal:=ChooseStealAdvance;
    564 if Steal<0 then
     578  Steal, ad, Count: Integer;
     579begin
     580  Steal := ChooseStealAdvance;
     581  if Steal < 0 then
    565582  begin // choose random advance
    566   count:=0;
    567   for ad:=0 to nAdv-1 do if AdvanceStealable(ad) then
    568     begin Inc(count); if random(count)=0 then Steal:=ad end
    569   end;
    570 if Steal>=0 then Server(sStealTech,Me,Steal,nodata^);
    571 RO.Happened:=RO.Happened and not phStealTech
     583    Count := 0;
     584    for ad := 0 to nAdv - 1 do if AdvanceStealable(ad) then
     585      begin
     586        Inc(Count);
     587        if Random(Count) = 0 then Steal := ad;
     588      end;
     589  end;
     590  if Steal >= 0 then Server(sStealTech, Me, Steal, nodata^);
     591  RO.Happened := RO.Happened and not phStealTech;
    572592end;
    573593
    574594function TCustomAI.IsResearched(Advance: Integer): Boolean;
    575595begin
    576 Result:= RO.Tech[Advance]>=tsApplicable
     596  Result := RO.Tech[Advance] >= tsApplicable;
    577597end;
    578598
    579599function TCustomAI.ResearchCost: Integer;
    580600begin
    581 Server(sGetTechCost,Me,0,Result)
     601  Server(sGetTechCost, Me, 0, Result);
    582602end;
    583603
    584604function TCustomAI.ChangeAttitude(Nation, Attitude: Integer): Integer;
    585605begin
    586 Result:=Server(sSetAttitude+Nation shl 4,Me,Attitude,nodata^)
     606  Result := Server(sSetAttitude + Nation shl 4, Me, Attitude, nodata^);
    587607end;
    588608
    589609function TCustomAI.Revolution: Integer;
    590610begin
    591 Result:=Server(sRevolution,Me,0,nodata^);
    592 end;
    593 
    594 function TCustomAI.ChangeRates(Tax,Lux: Integer): Integer;
    595 begin
    596 Result:=Server(sSetRates,Me,Tax div 10 and $F+Lux div 10 and $F shl 4,nodata^)
     611  Result := Server(sRevolution, Me, 0, nodata^);
     612end;
     613
     614function TCustomAI.ChangeRates(Tax, Lux: Integer): Integer;
     615begin
     616  Result := Server(sSetRates, Me, Tax div 10 and $F + Lux div 10 and $F shl 4, nodata^);
    597617end;
    598618
    599619function TCustomAI.PrepareNewModel(Domain: Integer): Integer;
    600620begin
    601 Result:=Server(sCreateDevModel,Me,Domain,nodata^);
     621  Result := Server(sCreateDevModel, Me, Domain, nodata^);
    602622end;
    603623
    604624function TCustomAI.SetNewModelFeature(F, Count: Integer): Integer;
    605625begin
    606 Result:=Server(sSetDevModelCap+Count shl 4,Me,F,nodata^)
     626  Result := Server(sSetDevModelCap + Count shl 4, Me, F, nodata^);
    607627end;
    608628
    609629function TCustomAI.AdvanceResearchable(Advance: Integer): Boolean;
    610630begin
    611 Result:= Server(sSetResearch-sExecute,Me,Advance,nodata^)>=rExecuted;
     631  Result := Server(sSetResearch - sExecute, Me, Advance, nodata^) >= rExecuted;
    612632end;
    613633
    614634function TCustomAI.AdvanceStealable(Advance: Integer): Boolean;
    615635begin
    616 Result:= Server(sStealTech-sExecute,Me,Advance,nodata^)>=rExecuted;
     636  Result := Server(sStealTech - sExecute, Me, Advance, nodata^) >= rExecuted;
    617637end;
    618638
    619639function TCustomAI.DebugMessage(Level: Integer; Text: string): Boolean;
    620640begin
    621 Text:=Copy('P'+char(48+Me)+' '+Text,1,254);
    622 Server(sMessage,Me,Level,PChar(Text)^);
    623 
    624 Result:=True;
     641  Text := Copy('P' + char(48 + Me) + ' ' + Text, 1, 254);
     642  Server(sMessage, Me, Level, PChar(Text)^);
     643
     644  Result := True;
    625645  // always returns true so that it can be used like
    626646  // "assert(DebugMessage(...));" -> not compiled in release build
     
    629649function TCustomAI.SetDebugMap(var DebugMap): Boolean;
    630650begin
    631 Server(sSetDebugMap, Me, 0, DebugMap);
    632 
    633 Result:=True;
     651  Server(sSetDebugMap, Me, 0, DebugMap);
     652
     653  Result := True;
    634654  // always returns true so that it can be used like
    635655  // "assert(SetDebugMap(...));" -> not compiled in release build
     
    638658procedure TCustomAI.Unit_FindMyDefender(Loc: Integer; var uix: Integer);
    639659begin
    640 if Server(sGetDefender,Me,Loc,uix)<rExecuted then uix:=-1
     660  if Server(sGetDefender, Me, Loc, uix) < rExecuted then uix := -1;
    641661end;
    642662
    643663procedure TCustomAI.Unit_FindEnemyDefender(Loc: Integer; var euix: Integer);
    644664begin
    645 euix:=RO.nEnemyUn-1;
    646 while (euix>=0) and (RO.EnemyUn[euix].Loc<>Loc) do
    647   Dec(euix);
    648 end;
    649 
    650 function TCustomAI.Unit_Move(uix,ToLoc: Integer): Integer;
    651 var
    652 Step: Integer;
    653 DestinationReached: Boolean;
    654 Advice: TMoveAdviceData;
    655 begin
    656 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit
     665  euix := RO.nEnemyUn - 1;
     666  while (euix >= 0) and (RO.EnemyUn[euix].Loc <> Loc) do
     667    Dec(euix);
     668end;
     669
     670function TCustomAI.Unit_Move(uix, ToLoc: Integer): Integer;
     671var
     672  Step: Integer;
     673  DestinationReached: Boolean;
     674  Advice: TMoveAdviceData;
     675begin
     676  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit
    657677{Loc_to_ab(MyUnit[uix].Loc,ToLoc,a,b);
    658678Assert((A<>0) or (B<>0));
     
    669689else}
    670690  begin // move to non-adjacent tile, find shortest path
    671   Advice.ToLoc:=ToLoc;
    672   Advice.MoreTurns:=9999;
    673   Advice.MaxHostile_MovementLeft:=100;
    674   Result:=Server(sGetMoveAdvice,Me,uix,Advice);
    675   end;
    676 if Result=eOk then
     691    Advice.ToLoc := ToLoc;
     692    Advice.MoreTurns := 9999;
     693    Advice.MaxHostile_MovementLeft := 100;
     694    Result := Server(sGetMoveAdvice, Me, uix, Advice);
     695  end;
     696  if Result = eOk then
    677697  begin
    678   DestinationReached:=False;
    679   Step:=0;
    680   repeat
    681     if Result and (rExecuted or rUnitRemoved)=rExecuted then // check if destination reached
    682       if (ToLoc>=0) and (Advice.MoreTurns=0) and (Step=Advice.nStep-1)
    683         and ((Map[ToLoc] and (fUnit or fOwned)=fUnit) // attack
    684           or (Map[ToLoc] and (fCity or fOwned)=fCity)
    685           and ((MyModel[MyUnit[uix].mix].Domain<>dGround) // bombardment
    686             or (MyModel[MyUnit[uix].mix].Flags and mdCivil<>0))) then // can't capture
    687         begin DestinationReached:=True; Break end // stop next to destination
    688       else if Step=Advice.nStep then
    689         DestinationReached:=True; // normal move -- stop at destination
    690 
    691     if (Step=Advice.nStep) or (Result<>eOK) and (Result<>eLoaded) then
    692       Break;
    693 
    694     Result:=Server(sMoveUnit+(Advice.dx[Step] and 7) shl 4 +(Advice.dy[Step] and 7) shl 7,
    695       Me,uix,nodata^);
    696     Inc(Step);
    697     if RO.Happened and phStealTech<>0 then StealAdvance;
    698   until False;
    699   if DestinationReached then
    700     if Advice.nStep=25 then
    701       Result:=Unit_Move(uix,ToLoc) // Shinkansen
    702     else if Advice.MoreTurns=0 then
    703       Result:=Result or rLocationReached
    704     else Result:=Result or rMoreTurns;
     698    DestinationReached := False;
     699    Step := 0;
     700    repeat
     701      if Result and (rExecuted or rUnitRemoved) = rExecuted then
     702        // check if destination reached
     703        if (ToLoc >= 0) and (Advice.MoreTurns = 0) and (Step = Advice.nStep - 1) and
     704          ((Map[ToLoc] and (fUnit or fOwned) = fUnit) // attack
     705          or (Map[ToLoc] and (fCity or fOwned) = fCity) and
     706          ((MyModel[MyUnit[uix].mix].Domain <> dGround) // bombardment
     707          or (MyModel[MyUnit[uix].mix].Flags and mdCivil <> 0))) then // can't capture
     708        begin
     709          DestinationReached := True;
     710          Break;
     711        end // stop next to destination
     712        else if Step = Advice.nStep then
     713          DestinationReached := True; // normal move -- stop at destination
     714
     715      if (Step = Advice.nStep) or (Result <> eOK) and (Result <> eLoaded) then
     716        Break;
     717
     718      Result := Server(sMoveUnit + (Advice.dx[Step] and 7) shl 4 +
     719        (Advice.dy[Step] and 7) shl 7, Me, uix, nodata^);
     720      Inc(Step);
     721      if RO.Happened and phStealTech <> 0 then StealAdvance;
     722    until False;
     723    if DestinationReached then
     724      if Advice.nStep = 25 then
     725        Result := Unit_Move(uix, ToLoc) // Shinkansen
     726      else if Advice.MoreTurns = 0 then
     727        Result := Result or rLocationReached
     728      else
     729        Result := Result or rMoreTurns;
     730  end;
     731end;
     732
     733function TCustomAI.Unit_Step(uix, ToLoc: Integer): Integer;
     734var
     735  A, B: Integer;
     736begin
     737  Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B);
     738  Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1));
     739  Result := Server(sMoveUnit + ((A - B) and 7) shl 4 + ((A + B) and 7) shl 7, Me, uix, nodata^);
     740  if RO.Happened and phStealTech <> 0 then StealAdvance;
     741end;
     742
     743function TCustomAI.Unit_Attack(uix, ToLoc: Integer): Integer;
     744var
     745  A, B: Integer;
     746begin
     747  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
     748    and ((Map[ToLoc] and (fUnit or fOwned) = fUnit) // is an attack
     749    or (Map[ToLoc] and (fCity or fOwned) = fCity) and
     750    (MyModel[MyUnit[uix].mix].Domain <> dGround))); // is a bombardment
     751  Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B);
     752  Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1));
     753  // attack to adjacent tile
     754  Result := Server(sMoveUnit + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^);
     755end;
     756
     757function TCustomAI.Unit_DoMission(uix, MissionType, ToLoc: Integer): Integer;
     758var
     759  A, B: Integer;
     760begin
     761  Result := Server(sSetSpyMission + MissionType shl 4, Me, 0, nodata^);
     762  if Result >= rExecuted then
     763  begin
     764    Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
     765      and (MyModel[MyUnit[uix].mix].Kind = mkDiplomat)); // is a commando
     766    Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B);
     767    Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1));
     768    // city must be adjacent
     769    Result := Server(sMoveUnit - sExecute + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^);
     770    if Result = eMissionDone then
     771      Result := Server(sMoveUnit + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^)
     772    else if (Result <> eNoTime_Move) and (Result <> eTreaty) and (Result <> eNoTurn) then
     773      Result := eInvalid; // not a special commando mission!
     774  end;
     775end;
     776
     777function TCustomAI.Unit_MoveForecast(uix, ToLoc: Integer;
     778  var RemainingMovement: Integer): Boolean;
     779var
     780  Advice: TMoveAdviceData;
     781begin
     782  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit
     783  Advice.ToLoc := ToLoc;
     784  Advice.MoreTurns := 0;
     785  Advice.MaxHostile_MovementLeft := 100;
     786  if Server(sGetMoveAdvice, Me, uix, Advice) = eOk then
     787  begin
     788    RemainingMovement := Advice.MaxHostile_MovementLeft;
     789    Result := True;
    705790  end
    706 end;
    707 
    708 function TCustomAI.Unit_Step(uix,ToLoc: Integer): Integer;
    709 var
    710 A,B: Integer;
    711 begin
    712 Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B);
    713 Assert(((A<>0) or (B<>0)) and (A>=-1) and (A<=1) and (B>=-1) and (B<=1));
    714 Result:=Server(sMoveUnit+((A-B) and 7) shl 4 +((A+B) and 7) shl 7, Me, uix, nodata^);
    715 if RO.Happened and phStealTech<>0 then StealAdvance;
    716 end;
    717 
    718 function TCustomAI.Unit_Attack(uix,ToLoc: Integer): Integer;
    719 var
    720 A,B: Integer;
    721 begin
    722 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit
    723   and ((Map[ToLoc] and (fUnit or fOwned)=fUnit) // is an attack
    724   or (Map[ToLoc] and (fCity or fOwned)=fCity)
    725   and (MyModel[MyUnit[uix].mix].Domain<>dGround))); // is a bombardment
    726 Loc_to_ab(MyUnit[uix].Loc,ToLoc,A,B);
    727 Assert(((A<>0) or (B<>0)) and (A>=-1) and (A<=1) and (B>=-1) and (B<=1)); // attack to adjacent tile
    728 Result:=Server(sMoveUnit+(A-B) and 7 shl 4 +(A+B) and 7 shl 7,Me,uix,nodata^);
    729 end;
    730 
    731 function TCustomAI.Unit_DoMission(uix,MissionType,ToLoc: Integer): Integer;
    732 var
    733 A,B: Integer;
    734 begin
    735 Result:=Server(sSetSpyMission + MissionType shl 4,Me,0,nodata^);
    736 if Result>=rExecuted then
     791  else
    737792  begin
    738   Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit
    739     and (MyModel[MyUnit[uix].mix].Kind=mkDiplomat)); // is a commando
    740   Loc_to_ab(MyUnit[uix].Loc,ToLoc,A,B);
    741   Assert(((A<>0) or (B<>0)) and (A>=-1) and (A<=1) and (B>=-1) and (B<=1)); // city must be adjacent
    742   Result:=Server(sMoveUnit-sExecute+(A-B) and 7 shl 4 +(A+B) and 7 shl 7,Me,uix,nodata^);
    743   if Result=eMissionDone then
    744     Result:=Server(sMoveUnit+(A-B) and 7 shl 4 +(A+B) and 7 shl 7,Me,uix,nodata^)
    745   else if (Result<>eNoTime_Move) and (Result<>eTreaty) and (Result<>eNoTurn) then
    746     Result:=eInvalid // not a special commando mission!
    747   end
    748 end;
    749 
    750 function TCustomAI.Unit_MoveForecast(uix,ToLoc: Integer;
    751   var RemainingMovement: Integer): Boolean;
    752 var
    753 Advice: TMoveAdviceData;
    754 begin
    755 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit
    756 Advice.ToLoc:=ToLoc;
    757 Advice.MoreTurns:=0;
    758 Advice.MaxHostile_MovementLeft:=100;
    759 if Server(sGetMoveAdvice,Me,uix,Advice)=eOk then
     793    RemainingMovement := -1;
     794    Result := False;
     795  end;
     796end;
     797
     798function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: Integer;
     799  var RemainingHealth: Integer): Boolean;
     800var
     801  BattleForecast: TBattleForecast;
     802begin
     803  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
     804    and (Map[ToLoc] and (fUnit or fOwned) = fUnit)); // is an attack
     805  RemainingHealth := -$100;
     806  Result := False;
     807  if AttackMovement >= 0 then with MyUnit[uix] do
     808    begin
     809      BattleForecast.pAtt := Me;
     810      BattleForecast.mixAtt := mix;
     811      BattleForecast.HealthAtt := Health;
     812      BattleForecast.ExpAtt := Exp;
     813      BattleForecast.FlagsAtt := Flags;
     814      BattleForecast.Movement := AttackMovement;
     815      if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then
     816      begin
     817        if BattleForecast.EndHealthAtt > 0 then
     818          RemainingHealth := BattleForecast.EndHealthAtt
     819        else
     820          RemainingHealth := -BattleForecast.EndHealthDef;
     821        Result := True;
     822      end;
     823    end;
     824end;
     825
     826function TCustomAI.Unit_DefenseForecast(euix, ToLoc: Integer;
     827  var RemainingHealth: Integer): Boolean;
     828var
     829  BattleForecast: TBattleForecast;
     830begin
     831  Assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit
     832    and (Map[ToLoc] and (fUnit or fOwned) = (fUnit or fOwned))); // is an attack
     833  RemainingHealth := $100;
     834  Result := False;
     835  with RO.EnemyUn[euix] do
    760836  begin
    761   RemainingMovement:=Advice.MaxHostile_MovementLeft;
    762   Result:=True
    763   end
    764 else
     837    BattleForecast.pAtt := Owner;
     838    BattleForecast.mixAtt := mix;
     839    BattleForecast.HealthAtt := Health;
     840    BattleForecast.ExpAtt := Exp;
     841    BattleForecast.FlagsAtt := Flags;
     842    BattleForecast.Movement := 100;
     843    if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then
     844    begin
     845      if BattleForecast.EndHealthDef > 0 then
     846        RemainingHealth := BattleForecast.EndHealthDef
     847      else
     848        RemainingHealth := -BattleForecast.EndHealthAtt;
     849      Result := True;
     850    end;
     851  end;
     852end;
     853
     854function TCustomAI.Unit_Disband(uix: Integer): Integer;
     855begin
     856  Result := Server(sRemoveUnit, Me, uix, nodata^);
     857end;
     858
     859function TCustomAI.Unit_StartJob(uix, NewJob: Integer): Integer;
     860begin
     861  Result := Server(sStartJob + NewJob shl 4, Me, uix, nodata^);
     862end;
     863
     864function TCustomAI.Unit_SetHomeHere(uix: Integer): Integer;
     865begin
     866  Result := Server(sSetUnitHome, Me, uix, nodata^);
     867end;
     868
     869function TCustomAI.Unit_Load(uix: Integer): Integer;
     870begin
     871  Result := Server(sLoadUnit, Me, uix, nodata^);
     872end;
     873
     874function TCustomAI.Unit_Unload(uix: Integer): Integer;
     875begin
     876  Result := Server(sUnloadUnit, Me, uix, nodata^);
     877end;
     878
     879function TCustomAI.Unit_AddToCity(uix: Integer): Integer;
     880begin
     881  Result := Server(sAddToCity, Me, uix, nodata^);
     882end;
     883
     884procedure TCustomAI.City_FindMyCity(Loc: Integer; var cix: Integer);
     885begin
     886  if Map[Loc] and (fCity or fOwned) <> fCity or fOwned then
     887    cix := -1
     888  else
    765889  begin
    766   RemainingMovement:=-1;
    767   Result:=False
    768   end
    769 end;
    770 
    771 function TCustomAI.Unit_AttackForecast(uix,ToLoc,AttackMovement: Integer;
    772   var RemainingHealth: Integer): Boolean;
    773 var
    774 BattleForecast: TBattleForecast;
    775 begin
    776 Assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit
    777   and (Map[ToLoc] and (fUnit or fOwned)=fUnit)); // is an attack
    778 RemainingHealth:=-$100;
    779 Result:=False;
    780 if AttackMovement>=0 then with MyUnit[uix] do
     890    cix := RO.nCity - 1;
     891    while (cix >= 0) and (MyCity[cix].Loc <> Loc) do
     892      Dec(cix);
     893  end;
     894end;
     895
     896procedure TCustomAI.City_FindEnemyCity(Loc: Integer; var ecix: Integer);
     897begin
     898  if Map[Loc] and (fCity or fOwned) <> fCity then
     899    ecix := -1
     900  else
    781901  begin
    782   BattleForecast.pAtt:=Me;
    783   BattleForecast.mixAtt:=mix;
    784   BattleForecast.HealthAtt:=Health;
    785   BattleForecast.ExpAtt:=Exp;
    786   BattleForecast.FlagsAtt:=Flags;
    787   BattleForecast.Movement:=AttackMovement;
    788   if Server(sGetBattleForecast,Me,ToLoc,BattleForecast)>=rExecuted then
    789     begin
    790     if BattleForecast.EndHealthAtt>0 then
    791       RemainingHealth:=BattleForecast.EndHealthAtt
    792     else RemainingHealth:=-BattleForecast.EndHealthDef;
    793     Result:=True
    794     end
    795   end
    796 end;
    797 
    798 function TCustomAI.Unit_DefenseForecast(euix,ToLoc: Integer;
    799   var RemainingHealth: Integer): Boolean;
    800 var
    801 BattleForecast: TBattleForecast;
    802 begin
    803 Assert((euix>=0) and (euix<RO.nEnemyUn) and (RO.EnemyUn[euix].Loc>=0) // is an enemy unit
    804   and (Map[ToLoc] and (fUnit or fOwned)=(fUnit or fOwned))); // is an attack
    805 RemainingHealth:=$100;
    806 Result:=False;
    807 with RO.EnemyUn[euix] do
     902    ecix := RO.nEnemyCity - 1;
     903    while (ecix >= 0) and (RO.EnemyCity[ecix].Loc <> Loc) do
     904      Dec(ecix);
     905  end;
     906end;
     907
     908function TCustomAI.City_HasProject(cix: Integer): Boolean;
     909begin
     910  Result := MyCity[cix].Project and (cpImp + cpIndex) <> cpImp + imTrGoods;
     911end;
     912
     913function TCustomAI.City_CurrentImprovementProject(cix: Integer): Integer;
     914begin
     915  if MyCity[cix].Project and cpImp = 0 then Result := -1
     916  else
    808917  begin
    809   BattleForecast.pAtt:=Owner;
    810   BattleForecast.mixAtt:=mix;
    811   BattleForecast.HealthAtt:=Health;
    812   BattleForecast.ExpAtt:=Exp;
    813   BattleForecast.FlagsAtt:=Flags;
    814   BattleForecast.Movement:=100;
    815   if Server(sGetBattleForecast,Me,ToLoc,BattleForecast)>=rExecuted then
    816     begin
    817     if BattleForecast.EndHealthDef>0 then
    818       RemainingHealth:=BattleForecast.EndHealthDef
    819     else RemainingHealth:=-BattleForecast.EndHealthAtt;
    820     Result:=True
    821     end
    822   end
    823 end;
    824 
    825 function TCustomAI.Unit_Disband(uix: Integer): Integer;
    826 begin
    827 Result:=Server(sRemoveUnit,Me,uix,nodata^)
    828 end;
    829 
    830 function TCustomAI.Unit_StartJob(uix,NewJob: Integer): Integer;
    831 begin
    832 Result:=Server(sStartJob+NewJob shl 4,Me,uix,nodata^)
    833 end;
    834 
    835 function TCustomAI.Unit_SetHomeHere(uix: Integer): Integer;
    836 begin
    837 Result:=Server(sSetUnitHome,Me,uix,nodata^)
    838 end;
    839 
    840 function TCustomAI.Unit_Load(uix: Integer): Integer;
    841 begin
    842 Result:=Server(sLoadUnit,Me,uix,nodata^)
    843 end;
    844 
    845 function TCustomAI.Unit_Unload(uix: Integer): Integer;
    846 begin
    847 Result:=Server(sUnloadUnit,Me,uix,nodata^)
    848 end;
    849 
    850 function TCustomAI.Unit_AddToCity(uix: Integer): Integer;
    851 begin
    852 Result:=Server(sAddToCity,Me,uix,nodata^)
    853 end;
    854 
    855 
    856 procedure TCustomAI.City_FindMyCity(Loc: Integer; var cix: Integer);
    857 begin
    858 if Map[Loc] and (fCity or fOwned)<>fCity or fOwned then
    859   cix:=-1
    860 else
    861   begin
    862   cix:=RO.nCity-1;
    863   while (cix>=0) and (MyCity[cix].Loc<>Loc) do
    864     Dec(cix);
    865   end
    866 end;
    867 
    868 procedure TCustomAI.City_FindEnemyCity(Loc: Integer; var ecix: Integer);
    869 begin
    870 if Map[Loc] and (fCity or fOwned)<>fCity then
    871   ecix:=-1
    872 else
    873   begin
    874   ecix:=RO.nEnemyCity-1;
    875   while (ecix>=0) and (RO.EnemyCity[ecix].Loc<>Loc) do
    876     Dec(ecix);
    877   end
    878 end;
    879 
    880 function TCustomAI.City_HasProject(cix: Integer): Boolean;
    881 begin
    882 Result:= MyCity[cix].Project and (cpImp+cpIndex)<>cpImp+imTrGoods
    883 end;
    884 
    885 function TCustomAI.City_CurrentImprovementProject(cix: Integer): Integer;
    886 begin
    887 if MyCity[cix].Project and cpImp=0 then Result:=-1
    888 else
    889   begin
    890   Result:=MyCity[cix].Project and cpIndex;
    891   if Result=imTrGoods then Result:=-1
    892   end
     918    Result := MyCity[cix].Project and cpIndex;
     919    if Result = imTrGoods then Result := -1;
     920  end;
    893921end;
    894922
    895923function TCustomAI.City_CurrentUnitProject(cix: Integer): Integer;
    896924begin
    897 if MyCity[cix].Project and cpImp<>0 then Result:=-1
    898 else Result:=MyCity[cix].Project and cpIndex;
    899 end;
    900 
    901 function TCustomAI.City_GetTileInfo(cix,TileLoc: Integer; var TileInfo: TTileInfo): Integer;
    902 begin
    903 TileInfo.ExplCity:=cix;
    904 Result:=Server(sGetHypoCityTileInfo,Me,TileLoc,TileInfo)
     925  if MyCity[cix].Project and cpImp <> 0 then Result := -1
     926  else
     927    Result := MyCity[cix].Project and cpIndex;
     928end;
     929
     930function TCustomAI.City_GetTileInfo(cix, TileLoc: Integer;
     931  var TileInfo: TTileInfo): Integer;
     932begin
     933  TileInfo.ExplCity := cix;
     934  Result := Server(sGetHypoCityTileInfo, Me, TileLoc, TileInfo);
    905935end;
    906936
    907937function TCustomAI.City_GetReport(cix: Integer; var Report: TCityReport): Integer;
    908938begin
    909 Report.HypoTiles:=-1;
    910 Report.HypoTax:=-1;
    911 Report.HypoLux:=-1;
    912 Result:=Server(sGetCityReport,Me,cix,Report)
     939  Report.HypoTiles := -1;
     940  Report.HypoTax := -1;
     941  Report.HypoLux := -1;
     942  Result := Server(sGetCityReport, Me, cix, Report);
    913943end;
    914944
     
    916946  var Report: TCityReport): Integer;
    917947begin
    918 Report.HypoTiles:=HypoTiles;
    919 Report.HypoTax:=HypoTax;
    920 Report.HypoLux:=HypoLux;
    921 Result:=Server(sGetCityReport,Me,cix,Report)
     948  Report.HypoTiles := HypoTiles;
     949  Report.HypoTax := HypoTax;
     950  Report.HypoLux := HypoLux;
     951  Result := Server(sGetCityReport, Me, cix, Report);
    922952end;
    923953
    924954function TCustomAI.City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer;
    925955begin
    926 Result:=Server(sGetCityAreaInfo,Me,cix,AreaInfo)
    927 end;
    928 
    929 function TCustomAI.City_StartUnitProduction(cix,mix: Integer): Integer;
    930 begin
    931 Result:=Server(sSetCityProject,Me,cix,mix)
    932 end;
    933 
    934 function TCustomAI.City_StartEmigration(cix,mix: Integer;
     956  Result := Server(sGetCityAreaInfo, Me, cix, AreaInfo);
     957end;
     958
     959function TCustomAI.City_StartUnitProduction(cix, mix: Integer): Integer;
     960begin
     961  Result := Server(sSetCityProject, Me, cix, mix);
     962end;
     963
     964function TCustomAI.City_StartEmigration(cix, mix: Integer;
    935965  AllowDisbandCity, AsConscripts: Boolean): Integer;
    936966var
    937 NewProject: Integer;
    938 begin
    939 NewProject:=mix;
    940 if AllowDisbandCity then NewProject:=NewProject or cpDisbandCity;
    941 if AsConscripts then NewProject:=NewProject or cpConscripts;
    942 Result:=Server(sSetCityProject,Me,cix,NewProject)
    943 end;
    944 
    945 function TCustomAI.City_StartImprovement(cix,iix: Integer): Integer;
    946 var
    947 NewProject: Integer;
    948 begin
    949 NewProject:=iix+cpImp;
    950 Result:=Server(sSetCityProject,Me,cix,NewProject)
    951 end;
    952 
    953 function TCustomAI.City_Improvable(cix,iix: Integer): Boolean;
    954 var
    955 NewProject: Integer;
    956 begin
    957 NewProject:=iix+cpImp;
    958 Result:= Server(sSetCityProject-sExecute,Me,cix,NewProject)>=rExecuted;
     967  NewProject: Integer;
     968begin
     969  NewProject := mix;
     970  if AllowDisbandCity then NewProject := NewProject or cpDisbandCity;
     971  if AsConscripts then NewProject := NewProject or cpConscripts;
     972  Result := Server(sSetCityProject, Me, cix, NewProject);
     973end;
     974
     975function TCustomAI.City_StartImprovement(cix, iix: Integer): Integer;
     976var
     977  NewProject: Integer;
     978begin
     979  NewProject := iix + cpImp;
     980  Result := Server(sSetCityProject, Me, cix, NewProject);
     981end;
     982
     983function TCustomAI.City_Improvable(cix, iix: Integer): Boolean;
     984var
     985  NewProject: Integer;
     986begin
     987  NewProject := iix + cpImp;
     988  Result := Server(sSetCityProject - sExecute, Me, cix, NewProject) >= rExecuted;
    959989end;
    960990
    961991function TCustomAI.City_StopProduction(cix: Integer): Integer;
    962992var
    963 NewProject: Integer;
    964 begin
    965 NewProject:=imTrGoods+cpImp;
    966 Result:=Server(sSetCityProject,Me,cix,NewProject)
     993  NewProject: Integer;
     994begin
     995  NewProject := imTrGoods + cpImp;
     996  Result := Server(sSetCityProject, Me, cix, NewProject);
    967997end;
    968998
    969999function TCustomAI.City_BuyProject(cix: Integer): Integer;
    9701000begin
    971 Result:=Server(sBuyCityProject,Me,cix,nodata^)
    972 end;
    973 
    974 function TCustomAI.City_SellImprovement(cix,iix: Integer): Integer;
    975 begin
    976 Result:=Server(sSellCityImprovement,Me,cix,iix)
    977 end;
    978 
    979 function TCustomAI.City_RebuildImprovement(cix,iix: Integer): Integer;
    980 begin
    981 Result:=Server(sRebuildCityImprovement,Me,cix,iix)
    982 end;
    983 
    984 function TCustomAI.City_SetTiles(cix,NewTiles: Integer): Integer;
    985 begin
    986 Result:=Server(sSetCityTiles,Me,cix,NewTiles)
    987 end;
    988 
     1001  Result := Server(sBuyCityProject, Me, cix, nodata^);
     1002end;
     1003
     1004function TCustomAI.City_SellImprovement(cix, iix: Integer): Integer;
     1005begin
     1006  Result := Server(sSellCityImprovement, Me, cix, iix);
     1007end;
     1008
     1009function TCustomAI.City_RebuildImprovement(cix, iix: Integer): Integer;
     1010begin
     1011  Result := Server(sRebuildCityImprovement, Me, cix, iix);
     1012end;
     1013
     1014function TCustomAI.City_SetTiles(cix, NewTiles: Integer): Integer;
     1015begin
     1016  Result := Server(sSetCityTiles, Me, cix, NewTiles);
     1017end;
    9891018
    9901019// negotiation
    9911020function TCustomAI.Nego_CheckMyAction: Integer;
    9921021begin
    993 Assert(Opponent>=0); // only allowed in negotiation mode
    994 Assert((MyAction=scDipNotice) or (MyAction=scDipAccept)
    995   or (MyAction=scDipCancelTreaty) or (MyAction=scDipOffer)
    996   or (MyAction=scDipBreak));
    997 if MyAction=scDipOffer then Result:=Server(MyAction-sExecute, Me, 0, MyOffer)
    998 else Result:=Server(MyAction-sExecute, Me, 0, nodata^);
    999 end;
    1000 
     1022  Assert(Opponent >= 0); // only allowed in negotiation mode
     1023  Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or
     1024    (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak));
     1025  if MyAction = scDipOffer then Result := Server(MyAction - sExecute, Me, 0, MyOffer)
     1026  else
     1027    Result := Server(MyAction - sExecute, Me, 0, nodata^);
     1028end;
    10011029
    10021030initialization
    1003 nodata:=Pointer(0);
    1004 RWDataSize:=0;
     1031  nodata := Pointer(0);
     1032  RWDataSize := 0;
    10051033
    10061034end.
    1007 
  • trunk/AI/StdAI/ToolAI.pas

    r447 r522  
    420420            begin
    421421              Inc(BestCount);
    422               if random(BestCount) = 0 then
     422              if Random(BestCount) = 0 then
    423423              begin
    424424                BestScore := TestScore;
     
    11291129        begin
    11301130          Loc_to_ab(MyUnit[uix].Loc, MyUnit[uixTransportLoad[tuix]].Loc, A, B);
    1131           if (abs(A) <= 1) and (abs(B) <= 1) then
     1131          if (Abs(A) <= 1) and (Abs(B) <= 1) then
    11321132          begin
    11331133            Assert((A <> 0) or (B <> 0));
     
    11461146          begin
    11471147            Loc_to_ab(TransportPlan.LoadLoc, MyUnit[uixTransportLoad[tuix]].Loc, A, B);
    1148             if (abs(A) <= 1) and (abs(B) <= 1) then
     1148            if (Abs(A) <= 1) and (Abs(B) <= 1) then
    11491149            begin
    11501150              TransportPlan.uixLoad[TransportPlan.nLoad] := uixTransportLoad[tuix];
Note: See TracChangeset for help on using the changeset viewer.