Ignore:
Timestamp:
May 23, 2024, 10:14:11 PM (6 weeks ago)
Author:
chronos
Message:
  • Modified: Code cleanup.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/AI Template/CustomAI.pas

    r582 r583  
    55
    66uses
    7   {$IFDEF DEBUG}SysUtils,{$ENDIF} // necessary for debug exceptions
     7{$IFDEF DEBUG}SysUtils,{$ENDIF} // necessary for debug exceptions
    88  Protocol;
    99
     
    1313  TCustomAI = class
    1414  public
    15     procedure Process(Command: integer; var Data);
     15    procedure Process(Command: Integer; var Data);
    1616
    1717    // overridables
    18     constructor Create(Nation: integer); virtual;
     18    constructor Create(Nation: Integer); virtual;
    1919    destructor Destroy; override;
    2020    procedure SetDataDefaults; virtual;
    2121    procedure SetDataRandom; virtual;
    2222    procedure OnBeforeEnemyAttack(UnitInfo: TUnitInfo;
    23       ToLoc, EndHealth, EndHealthDef: integer); virtual;
    24     procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer); virtual;
     23      ToLoc, EndHealth, EndHealthDef: Integer); virtual;
     24    procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); virtual;
    2525    procedure OnAfterEnemyAttack; virtual;
    2626    procedure OnAfterEnemyCapture; virtual;
    2727
    2828  protected
    29     me: integer; // index of the controlled nation
     29    Me: Integer; // index of the controlled nation
    3030    RO: ^TPlayerContext;
    3131    Map: ^TTileList;
     
    3434    MyModel: ^TModelList;
    3535
    36     cixStateImp: array[imPalace..imSpacePort] of integer;
     36    cixStateImp: array[imPalace..imSpacePort] of Integer;
    3737
    3838    // negotiation
    39     Opponent: integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode
    40     MyAction, MyLastAction, OppoAction: integer;
     39    Opponent: Integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode
     40    MyAction, MyLastAction, OppoAction: Integer;
    4141    MyOffer, MyLastOffer, OppoOffer: TOffer;
    4242
     
    4444    procedure DoTurn; virtual;
    4545    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;
     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;
    5151
    5252    // 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 GetJobProgress(Loc: integer; var JobProgress: TJobProgressData): boolean;
    63     function DebugMessage(Level: integer; Text: string): boolean;
    64     function SetDebugMap(var DebugMap): boolean;
     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 GetJobProgress(Loc: Integer; var JobProgress: TJobProgressData): Boolean;
     63    function DebugMessage(Level: Integer; Text: string): Boolean;
     64    function SetDebugMap(var DebugMap): Boolean;
    6565
    6666    // unit functions
    67     procedure Unit_FindMyDefender(Loc: integer; var uix: integer);
    68     procedure Unit_FindEnemyDefender(Loc: integer; var euix: integer);
    69     function Unit_Move(uix, ToLoc: integer): integer;
    70     function Unit_Step(uix, ToLoc: integer): integer;
    71     function Unit_Attack(uix, ToLoc: integer): integer;
    72     function Unit_DoMission(uix, MissionType, ToLoc: integer): integer;
    73     function Unit_MoveForecast(uix, ToLoc: integer;
    74       var RemainingMovement: integer): boolean;
    75     function Unit_AttackForecast(uix, ToLoc, AttackMovement: integer;
    76       var RemainingHealth: integer): boolean;
    77     function Unit_DefenseForecast(euix, ToLoc: integer;
    78       var RemainingHealth: integer): boolean;
    79     function Unit_Disband(uix: integer): integer;
    80     function Unit_StartJob(uix, NewJob: integer): integer;
    81     function Unit_SetHomeHere(uix: integer): integer;
    82     function Unit_Load(uix: integer): integer;
    83     function Unit_Unload(uix: integer): integer;
    84     function Unit_SelectTransport(uix: integer): integer;
    85     function Unit_AddToCity(uix: integer): integer;
     67    procedure Unit_FindMyDefender(Loc: Integer; var uix: Integer);
     68    procedure Unit_FindEnemyDefender(Loc: Integer; var euix: Integer);
     69    function Unit_Move(uix, ToLoc: Integer): Integer;
     70    function Unit_Step(uix, ToLoc: Integer): Integer;
     71    function Unit_Attack(uix, ToLoc: Integer): Integer;
     72    function Unit_DoMission(uix, MissionType, ToLoc: Integer): Integer;
     73    function Unit_MoveForecast(uix, ToLoc: Integer;
     74      var RemainingMovement: Integer): Boolean;
     75    function Unit_AttackForecast(uix, ToLoc, AttackMovement: Integer;
     76      var RemainingHealth: Integer): Boolean;
     77    function Unit_DefenseForecast(euix, ToLoc: Integer;
     78      var RemainingHealth: Integer): Boolean;
     79    function Unit_Disband(uix: Integer): Integer;
     80    function Unit_StartJob(uix, NewJob: Integer): Integer;
     81    function Unit_SetHomeHere(uix: Integer): Integer;
     82    function Unit_Load(uix: Integer): Integer;
     83    function Unit_Unload(uix: Integer): Integer;
     84    function Unit_SelectTransport(uix: Integer): Integer;
     85    function Unit_AddToCity(uix: Integer): Integer;
    8686
    8787    // city functions
    88     procedure City_FindMyCity(Loc: integer; var cix: integer);
    89     procedure City_FindEnemyCity(Loc: integer; var ecix: integer);
    90     function City_HasProject(cix: integer): boolean;
    91     function City_CurrentImprovementProject(cix: integer): integer;
    92     function City_CurrentUnitProject(cix: integer): integer;
    93     function City_GetTileInfo(cix, TileLoc: integer; var TileInfo: TTileInfo): integer;
    94     function City_GetReport(cix: integer; var Report: TCityReport): integer;
    95     function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: integer;
    96       var Report: TCityReport): integer;
    97     function City_GetReportNew(cix: integer; var Report: TCityReportNew): integer;
    98     function City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, HypoLuxuryRate: integer;
    99       var Report: TCityReportNew): integer;
    100     function City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer;
    101     function City_StartUnitProduction(cix, mix: integer): integer;
    102     function City_StartEmigration(cix, mix: integer;
    103       AllowDisbandCity, AsConscripts: boolean): integer;
    104     function City_StartImprovement(cix, iix: integer): integer;
    105     function City_Improvable(cix, iix: integer): boolean;
    106     function City_StopProduction(cix: integer): integer;
    107     function City_BuyProject(cix: integer): integer;
    108     function City_SellImprovement(cix, iix: integer): integer;
    109     function City_RebuildImprovement(cix, iix: integer): integer;
    110     function City_SetTiles(cix, NewTiles: integer): integer;
    111     procedure City_OptimizeTiles(cix: integer; ResourceWeights: integer = rwMaxGrowth);
     88    procedure City_FindMyCity(Loc: Integer; var cix: Integer);
     89    procedure City_FindEnemyCity(Loc: Integer; var ecix: Integer);
     90    function City_HasProject(cix: Integer): Boolean;
     91    function City_CurrentImprovementProject(cix: Integer): Integer;
     92    function City_CurrentUnitProject(cix: Integer): Integer;
     93    function City_GetTileInfo(cix, TileLoc: Integer; var TileInfo: TTileInfo): Integer;
     94    function City_GetReport(cix: Integer; var Report: TCityReport): Integer;
     95    function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer;
     96      var Report: TCityReport): Integer;
     97    function City_GetReportNew(cix: Integer; var Report: TCityReportNew): Integer;
     98    function City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, HypoLuxuryRate: Integer;
     99      var Report: TCityReportNew): Integer;
     100    function City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer;
     101    function City_StartUnitProduction(cix, mix: Integer): Integer;
     102    function City_StartEmigration(cix, mix: Integer;
     103      AllowDisbandCity, AsConscripts: Boolean): Integer;
     104    function City_StartImprovement(cix, iix: Integer): Integer;
     105    function City_Improvable(cix, iix: Integer): Boolean;
     106    function City_StopProduction(cix: Integer): Integer;
     107    function City_BuyProject(cix: Integer): Integer;
     108    function City_SellImprovement(cix, iix: Integer): Integer;
     109    function City_RebuildImprovement(cix, iix: Integer): Integer;
     110    function City_SetTiles(cix, NewTiles: Integer): Integer;
     111    procedure City_OptimizeTiles(cix: Integer; ResourceWeights: Cardinal = rwMaxGrowth);
    112112
    113113    // negotiation
    114     function Nego_CheckMyAction: integer;
     114    function Nego_CheckMyAction: Integer;
    115115
    116116  private
    117     HaveTurned: boolean;
     117    HaveTurned: Boolean;
    118118    UnwantedNego: set of 0..nPl - 1;
    119119    Contacted: set of 0..nPl - 1;
     
    125125  Server: TServerCall;
    126126  G: TNewGameData;
    127   RWDataSize, MapSize: integer;
    128   decompose24: cardinal;
    129   nodata: pointer;
     127  RWDataSize, MapSize: Integer;
     128  decompose24: Cardinal;
     129  nodata: Pointer;
    130130
    131131const
     
    136136  // Unit_Move: move was not interrupted, location reached
    137137  rMoreTurns = $00020000;
    138   // Unit_Move: move was not interrupted, location not reached yet
     138// Unit_Move: move was not interrupted, location not reached yet
    139139
    140140type
    141   TVicinity8Loc = array[0..7] of integer;
    142   TVicinity21Loc = array[0..27] of integer;
     141  TVicinity8Loc = array[0..7] of Integer;
     142  TVicinity21Loc = array[0..27] of Integer;
    143143
    144144
    145145procedure Init(NewGameData: TNewGameData);
    146146
    147 procedure ab_to_Loc(Loc0, a, b: integer; var Loc: integer);
    148 procedure Loc_to_ab(Loc0, Loc: integer; var a, b: integer);
    149 procedure ab_to_V8(a, b: integer; var V8: integer);
    150 procedure V8_to_ab(V8: integer; var a, b: integer);
    151 procedure ab_to_V21(a, b: integer; var V21: integer);
    152 procedure V21_to_ab(V21: integer; var a, b: integer);
    153 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);
    154 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);
     147procedure ab_to_Loc(Loc0, A, B: Integer; var Loc: Integer);
     148procedure Loc_to_ab(Loc0, Loc: Integer; var A, B: Integer);
     149procedure ab_to_V8(A, B: Integer; var V8: Integer);
     150procedure V8_to_ab(V8: Integer; var A, B: Integer);
     151procedure ab_to_V21(A, B: Integer; var V21: Integer);
     152procedure V21_to_ab(V21: Integer; var A, B: Integer);
     153procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc);
     154procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc);
     155function Distance(Loc0, Loc1: Integer): Integer;
    155156
    156157
     
    158159
    159160const
    160   ab_v8: array[-4..4] of integer = (5, 6, 7, 4, -1, 0, 3, 2, 1);
    161   v8_a: array[0..7] of integer = (1, 1, 0, -1, -1, -1, 0, 1);
    162   v8_b: array[0..7] of integer = (0, 1, 1, 1, 0, -1, -1, -1);
    163 
    164 
    165 procedure ab_to_Loc(Loc0, a, b: integer; var Loc: integer);
     161  ab_v8: array[-4..4] of Integer = (5, 6, 7, 4, -1, 0, 3, 2, 1);
     162  v8_a: array[0..7] of Integer = (1, 1, 0, -1, -1, -1, 0, 1);
     163  v8_b: array[0..7] of Integer = (0, 1, 1, 1, 0, -1, -1, -1);
     164
     165
     166procedure ab_to_Loc(Loc0, A, B: Integer; var Loc: Integer);
    166167{relative location from Loc0}
    167168var
    168   y0: integer;
    169 begin
    170   assert((Loc0 >= 0) and (Loc0 < MapSize) and (a - b + G.lx >= 0));
    171   y0 := cardinal(Loc0) * decompose24 shr 24;
    172   Loc := (Loc0 + (a - b + y0 and 1 + G.lx + G.lx) shr 1) mod G.lx + G.lx * (y0 + a + b);
    173   if Loc >= MapSize then Loc := -$1000;
    174 end;
    175 
    176 
    177 procedure Loc_to_ab(Loc0,Loc: integer; var a,b: integer);
    178 {$IFDEF FPC} // freepascal
    179 var
    180   dx, dy: integer;
    181 begin
    182   dx := ((Loc mod G.lx * 2 + Loc div G.lx and 1)
    183     -(Loc0 mod G.lx *2 +Loc0 div G.lx and 1) + 3 * G.lx) mod (2 * G.lx) -G.lx;
     169  y0: Integer;
     170begin
     171  Assert((Loc0 >= 0) and (Loc0 < MapSize) and (A - B + G.lx >= 0));
     172  y0 := Cardinal(Loc0) * decompose24 shr 24;
     173  Loc := (Loc0 + (A - B + y0 and 1 + G.lx + G.lx) shr 1) mod G.lx + G.lx * (y0 + A + B);
     174  if Loc >= MapSize then
     175    Loc := -$1000;
     176end;
     177
     178procedure Loc_to_ab(Loc0, Loc: Integer; var A, B: Integer);
     179{$IFDEF FPC}// freepascal
     180var
     181  dx, dy: Integer;
     182begin
     183  dx := ((Loc mod G.lx * 2 + Loc div G.lx and 1) - (Loc0 mod G.lx * 2 + Loc0 div
     184    G.lx and 1) + 3 * G.lx) mod (2 * G.lx) - G.lx;
    184185  dy := Loc div G.lx - Loc0 div G.lx;
    185   a := (dx + dy) div 2;
    186   b := (dy - dx) div 2;
    187 end;
    188 {$ELSE} // delphi
     186  A := (dx + dy) div 2;
     187  B := (dy - dx) div 2;
     188end;
     189
     190{$ELSE}// delphi
    189191register;
    190192asm
    191   push ebx
    192 
    193   // calculate
    194   push ecx
    195   div byte ptr [G]
    196   xor ebx,ebx
    197   mov bl,ah  // ebx:=Loc0 mod G.lx
    198   mov ecx,eax
    199   and ecx,$000000FF // ecx:=Loc0 div G.lx
    200   mov eax,edx
    201   div byte ptr [G]
    202   xor edx,edx
    203   mov dl,ah // edx:=Loc mod G.lx
    204   and eax,$000000FF // eax:=Loc div G.lx
    205   sub edx,ebx // edx:=Loc mod G.lx-Loc0 mod G.lx
    206   mov ebx,eax
    207   sub ebx,ecx // ebx:=dy
    208   and eax,1
    209   and ecx,1
    210   add edx,edx
    211   add eax,edx
    212   sub eax,ecx // eax:=dx, not normalized
    213   pop ecx
    214 
    215   // normalize
    216   mov edx,dword ptr [G]
    217   cmp eax,edx
    218   jl @a
    219     sub eax,edx
    220     sub eax,edx
    221     jmp @ok
    222   @a:
    223   neg edx
    224   cmp eax,edx
    225   jnl @ok
    226     sub eax,edx
    227     sub eax,edx
    228 
    229   // return results
    230   @ok:
    231   mov edx,ebx
    232   sub edx,eax
    233   add eax,ebx
    234   sar edx,1 // edx:=b
    235   mov ebx,[b]
    236   mov [ebx],edx
    237   sar eax,1 // eax:=a
    238   mov [a],eax
    239 
    240   pop ebx
     193push ebx
     194
     195// calculate
     196push ecx
     197div Byte ptr [G]
     198xor ebx,ebx
     199mov bl,ah  // ebx:=Loc0 mod G.lx
     200mov ecx,eax
     201and ecx,$000000FF // ecx:=Loc0 div G.lx
     202mov eax,edx
     203div Byte ptr [G]
     204xor edx,edx
     205mov dl,ah // edx:=Loc mod G.lx
     206and eax,$000000FF // eax:=Loc div G.lx
     207sub edx,ebx // edx:=Loc mod G.lx-Loc0 mod G.lx
     208mov ebx,eax
     209sub ebx,ecx // ebx:=dy
     210and eax,1
     211and ecx,1
     212add edx,edx
     213add eax,edx
     214sub eax,ecx // eax:=dx, not normalized
     215pop ecx
     216
     217// normalize
     218mov edx,dword ptr [G]
     219cmp eax,edx
     220jl @A
     221  sub eax,edx
     222  sub eax,edx
     223  jmp @ok
     224@A:
     225neg edx
     226cmp eax,edx
     227jnl @ok
     228  sub eax,edx
     229  sub eax,edx
     230
     231// return results
     232@ok:
     233mov edx,ebx
     234sub edx,eax
     235add eax,ebx
     236sar edx,1 // edx:=b
     237mov ebx,[B]
     238mov [ebx],edx
     239sar eax,1 // eax:=a
     240mov [A],eax
     241
     242pop ebx
    241243end;
    242244{$ENDIF}
    243245
    244 procedure ab_to_V8(a, b: integer; var V8: integer);
    245 begin
    246   assert((abs(a) <= 1) and (abs(b) <= 1) and ((a <> 0) or (b <> 0)));
    247   V8 := ab_v8[2 * b + b + a];
    248 end;
    249 
    250 procedure V8_to_ab(V8: integer; var a, b: integer);
    251 begin
    252   a := v8_a[V8];
    253   b := V8_b[V8];
    254 end;
    255 
    256 procedure ab_to_V21(a, b: integer; var V21: integer);
    257 begin
    258   V21 := (a + b + 3) shl 2 + (a - b + 3) shr 1;
    259 end;
    260 
    261 procedure V21_to_ab(V21: integer; var a, b: integer);
    262 var
    263   dx, dy: integer;
     246procedure ab_to_V8(A, B: Integer; var V8: Integer);
     247begin
     248  Assert((Abs(A) <= 1) and (Abs(B) <= 1) and ((A <> 0) or (B <> 0)));
     249  V8 := ab_v8[2 * B + B + A];
     250end;
     251
     252procedure V8_to_ab(V8: Integer; var A, B: Integer);
     253begin
     254  A := v8_a[V8];
     255  B := V8_b[V8];
     256end;
     257
     258procedure ab_to_V21(A, B: Integer; var V21: Integer);
     259begin
     260  V21 := (A + B + 3) shl 2 + (A - B + 3) shr 1;
     261end;
     262
     263procedure V21_to_ab(V21: Integer; var A, B: Integer);
     264var
     265  dx, dy: Integer;
    264266begin
    265267  dy := V21 shr 2 - 3;
    266268  dx := V21 and 3 shl 1 - 3 + (dy + 3) and 1;
    267   a := (dx + dy) div 2;
    268   b := (dy - dx) div 2;
    269 end;
    270 
    271 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);
    272 var
    273   x0, y0, lx: integer;
     269  A := (dx + dy) div 2;
     270  B := (dy - dx) div 2;
     271end;
     272
     273procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc);
     274var
     275  x0, y0, lx: Integer;
    274276begin
    275277  lx := G.lx;
    276   y0 := cardinal(Loc0) * decompose24 shr 24;
     278  y0 := Cardinal(Loc0) * decompose24 shr 24;
    277279  x0 := Loc0 - y0 * lx; // Loc0 mod lx;
    278280  VicinityLoc[1] := Loc0 + lx * 2;
     
    321323end;
    322324
    323 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);
    324 var
    325   dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: integer;
    326   dst: ^integer;
    327 begin
    328   y0 := cardinal(Loc0) * decompose24 shr 24;
     325procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc);
     326var
     327  dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: Integer;
     328  dst: ^Integer;
     329begin
     330  y0 := Cardinal(Loc0) * decompose24 shr 24;
    329331  xComp0 := Loc0 - y0 * G.lx - 1; // Loc0 mod G.lx -1
    330332  xCompSwitch := xComp0 - 1 + y0 and 1;
    331   if xComp0 < 0 then Inc(xComp0, G.lx);
    332   if xCompSwitch < 0 then Inc(xCompSwitch, G.lx);
     333  if xComp0 < 0 then
     334    Inc(xComp0, G.lx);
     335  if xCompSwitch < 0 then
     336    Inc(xCompSwitch, G.lx);
    333337  xCompSwitch := xCompSwitch xor xComp0;
    334338  yComp := G.lx * (y0 - 3);
     
    342346      for dx := 0 to 3 do
    343347      begin
    344         if bit and $67F7F76 <> 0 then dst^ := xComp + yComp
     348        if bit and $67F7F76 <> 0 then
     349          dst^ := xComp + yComp
    345350        else
    346351          dst^ := -1;
    347352        Inc(xComp);
    348         if xComp >= G.lx then Dec(xComp, G.lx);
     353        if xComp >= G.lx then
     354          Dec(xComp, G.lx);
    349355        Inc(dst);
    350356        bit := bit shl 1;
     
    362368end;
    363369
     370function Distance(Loc0, Loc1: Integer): Integer;
     371var
     372  A, B, dx, dy: Integer;
     373begin
     374  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;
     378end;
    364379
    365380procedure Init(NewGameData: TNewGameData);
    366381{$IFDEF DEBUG}var
    367   Loc: integer;
    368   {$ENDIF}
     382  Loc: Integer;
     383{$ENDIF}
    369384begin
    370385  G := NewGameData;
    371386  MapSize := G.lx * G.ly;
    372387  decompose24 := (1 shl 24 - 1) div G.lx + 1;
    373   {$IFDEF DEBUG}
    374   for Loc := 0 to MapSize - 1 do assert(cardinal(Loc) * decompose24 shr
    375       24 = cardinal(Loc div G.lx));
    376   {$ENDIF}
    377 end;
    378 
    379 
    380 constructor TCustomAI.Create(Nation: integer);
     388{$IFDEF DEBUG}
     389  for Loc := 0 to MapSize - 1 do
     390    Assert(Cardinal(Loc) * decompose24 shr 24 = Cardinal(Loc div G.lx));
     391{$ENDIF}
     392end;
     393
     394constructor TCustomAI.Create(Nation: Integer);
    381395begin
    382396  inherited Create;
    383   me := Nation;
    384   RO := pointer(G.RO[Nation]);
    385   Map := pointer(RO.Map);
    386   MyUnit := pointer(RO.Un);
    387   MyCity := pointer(RO.City);
    388   MyModel := pointer(RO.Model);
     397  Me := Nation;
     398  RO := Pointer(G.RO[Nation]);
     399  Map := Pointer(RO.Map);
     400  MyUnit := Pointer(RO.Un);
     401  MyCity := Pointer(RO.City);
     402  MyModel := Pointer(RO.Model);
    389403  Opponent := -1;
    390404end;
     
    392406destructor TCustomAI.Destroy;
    393407begin
    394   Server(sSetDebugMap, me, 0, nodata^);
    395 end;
    396 
    397 
    398 procedure TCustomAI.Process(Command: integer; var Data);
    399 var
    400   Nation, NewResearch, NewGov, Count, ad, cix, iix: integer;
     408  Server(sSetDebugMap, Me, 0, nodata^);
     409end;
     410
     411procedure TCustomAI.Process(Command: Integer; var Data);
     412var
     413  Nation, NewResearch, NewGov, Count, ad, cix, iix: Integer;
    401414  NegoTime: TNegoTime;
    402415begin
     
    404417    cTurn, cContinue:
    405418    begin
    406       if RO.Alive and (1 shl me) = 0 then
     419      if RO.Alive and (1 shl Me) = 0 then
    407420      begin // I'm dead, huhu
    408         Server(sTurn, me, 0, nodata^);
    409         exit;
     421        Server(sTurn, Me, 0, nodata^);
     422        Exit;
    410423      end;
    411424      if Command = cTurn then
    412425      begin
    413         fillchar(cixStateImp, sizeof(cixStateImp), $FF);
    414         for cix := 0 to RO.nCity - 1 do if MyCity[cix].Loc >= 0 then
     426        FillChar(cixStateImp, SizeOf(cixStateImp), $FF);
     427        for cix := 0 to RO.nCity - 1 do
     428          if MyCity[cix].Loc >= 0 then
    415429            for iix := imPalace to imSpacePort do
    416430              if MyCity[cix].Built[iix] > 0 then
     
    420434          NewGov := ChooseGovernment;
    421435          if NewGov > gAnarchy then
    422             Server(sSetGovernment, me, NewGov, nodata^);
     436            Server(sSetGovernment, Me, NewGov, nodata^);
    423437        end;
    424438        HaveTurned := False;
     
    429443        if OnNegoRejected_CancelTreaty then
    430444          if RO.Treaty[Opponent] >= trPeace then
    431             if Server(sCancelTreaty, me, 0, nodata^) < rExecuted then
    432               assert(False);
     445            if Server(sCancelTreaty, Me, 0, nodata^) < rExecuted then
     446              Assert(False);
    433447      end
    434448      else
     
    436450      Opponent := -1;
    437451      repeat
    438         if HaveTurned then NegoTime := EndOfTurn
     452        if HaveTurned then
     453          NegoTime := EndOfTurn
    439454        else
    440455          NegoTime := BeginOfTurn;
    441456        if RO.Government <> gAnarchy then
    442457          for Nation := 0 to nPl - 1 do
    443             if (Nation <> me) and (1 shl Nation and RO.Alive <> 0) and
     458            if (Nation <> Me) and (1 shl Nation and RO.Alive <> 0) and
    444459              (RO.Treaty[Nation] >= trNone) and not (Nation in Contacted) and not
    445460              (Nation in UnwantedNego) and
    446               (Server(scContact - sExecute + Nation shl 4, me, 0, nodata^) >= rExecuted) then
     461              (Server(scContact - sExecute + Nation shl 4, Me, 0, nodata^) >= rExecuted) then
    447462              if WantNegotiation(Nation, NegoTime) then
    448463              begin
    449                 if Server(scContact + Nation shl 4, me, 0, nodata^) >= rExecuted then
     464                if Server(scContact + Nation shl 4, Me, 0, nodata^) >= rExecuted then
    450465                begin
    451                   include(Contacted, Nation);
     466                  Include(Contacted, Nation);
    452467                  Opponent := Nation;
    453468                  MyAction := scContact;
    454                   exit;
     469                  Exit;
    455470                end;
    456471              end
    457472              else
    458                 include(UnwantedNego, Nation);
     473                Include(UnwantedNego, Nation);
    459474        if NegoTime = BeginOfTurn then
    460475        begin
     
    465480        end
    466481        else
    467           break;
     482          Break;
    468483      until False;
    469484      if RO.Happened and phTech <> 0 then
     
    473488        begin // choose random research
    474489          Count := 0;
    475           for ad := 0 to nAdv - 1 do if AdvanceResearchable(ad) then
     490          for ad := 0 to nAdv - 1 do
     491            if AdvanceResearchable(ad) then
    476492            begin
    477493              Inc(Count);
    478               if random(Count) = 0 then NewResearch := ad;
     494              if Random(Count) = 0 then
     495                NewResearch := ad;
    479496            end;
    480497        end;
    481         Server(sSetResearch, me, NewResearch, nodata^);
     498        Server(sSetResearch, Me, NewResearch, nodata^);
    482499      end;
    483       if Server(sTurn, me, 0, nodata^) < rExecuted then
    484         assert(False);
     500      if Server(sTurn, Me, 0, nodata^) < rExecuted then
     501        Assert(False);
    485502    end;
    486503    scContact:
    487       if WantNegotiation(integer(Data), EnemyCalled) then
     504      if WantNegotiation(Integer(Data), EnemyCalled) then
    488505      begin
    489         if Server(scDipStart, me, 0, nodata^) < rExecuted then
    490           assert(False);
    491         Opponent := integer(Data);
     506        if Server(scDipStart, Me, 0, nodata^) < rExecuted then
     507          Assert(False);
     508        Opponent := Integer(Data);
    492509        MyAction := scDipStart;
    493510      end
    494511      else
    495512      begin
    496         if Server(scReject, me, 0, nodata^) < rExecuted then
    497           assert(False);
     513        if Server(scReject, Me, 0, nodata^) < rExecuted then
     514          Assert(False);
    498515      end;
    499516    scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak:
    500517    begin
    501518      OppoAction := Command;
    502       if Command = scDipOffer then OppoOffer := TOffer(Data);
     519      if Command = scDipOffer then
     520        OppoOffer := TOffer(Data);
    503521      if Command = scDipStart then
    504522        MyLastAction := scContact
     
    517535      end;
    518536      DoNegotiation;
    519       assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or
     537      Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or
    520538        (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak));
    521       if MyAction = scDipOffer then Server(MyAction, me, 0, MyOffer)
     539      if MyAction = scDipOffer then
     540        Server(MyAction, Me, 0, MyOffer)
    522541      else
    523         Server(MyAction, me, 0, nodata^);
     542        Server(MyAction, Me, 0, nodata^);
    524543    end;
    525544    cShowEndContact:
     
    546565
    547566procedure TCustomAI.OnBeforeEnemyAttack(UnitInfo: TUnitInfo;
    548   ToLoc, EndHealth, EndHealthDef: integer);
    549 begin
    550 end;
    551 
    552 procedure TCustomAI.OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer);
     567  ToLoc, EndHealth, EndHealthDef: Integer);
     568begin
     569end;
     570
     571procedure TCustomAI.OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer);
    553572begin
    554573end;
     
    562581end;
    563582
    564 function TCustomAI.ChooseResearchAdvance: integer;
     583function TCustomAI.ChooseResearchAdvance: Integer;
    565584begin
    566585  Result := -1;
    567586end;
    568587
    569 function TCustomAI.ChooseStealAdvance: integer;
     588function TCustomAI.ChooseStealAdvance: Integer;
    570589begin
    571590  Result := -1;
    572591end;
    573592
    574 function TCustomAI.ChooseGovernment: integer;
     593function TCustomAI.ChooseGovernment: Integer;
    575594begin
    576595  Result := gDespotism;
    577596end;
    578597
    579 function TCustomAI.WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean;
     598function TCustomAI.WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean;
    580599begin
    581600  Result := False;
    582601end;
    583602
    584 function TCustomAI.OnNegoRejected_CancelTreaty: boolean;
     603function TCustomAI.OnNegoRejected_CancelTreaty: Boolean;
    585604begin
    586605  Result := False;
    587606end;
     607
    588608{$HINTS ON}
    589609
    590610procedure TCustomAI.StealAdvance;
    591611var
    592   Steal, ad, Count: integer;
     612  Steal, ad, Count: Integer;
    593613begin
    594614  Steal := ChooseStealAdvance;
     
    596616  begin // choose random advance
    597617    Count := 0;
    598     for ad := 0 to nAdv - 1 do if AdvanceStealable(ad) then
     618    for ad := 0 to nAdv - 1 do
     619      if AdvanceStealable(ad) then
    599620      begin
    600621        Inc(Count);
    601         if random(Count) = 0 then Steal := ad;
     622        if Random(Count) = 0 then
     623          Steal := ad;
    602624      end;
    603625  end;
    604   if Steal >= 0 then Server(sStealTech, me, Steal, nodata^);
     626  if Steal >= 0 then
     627    Server(sStealTech, Me, Steal, nodata^);
    605628  RO.Happened := RO.Happened and not phStealTech;
    606629end;
    607630
    608 function TCustomAI.IsResearched(Advance: integer): boolean;
    609 begin
    610   Result := RO.Tech[Advance] >= tsApplicable;
    611 end;
    612 
    613 function TCustomAI.ResearchCost: integer;
    614 begin
    615   Server(sGetTechCost, me, 0, Result);
    616 end;
    617 
    618 function TCustomAI.ChangeAttitude(Nation, Attitude: integer): integer;
    619 begin
    620   Result := Server(sSetAttitude + Nation shl 4, me, Attitude, nodata^);
    621 end;
    622 
    623 function TCustomAI.Revolution: integer;
    624 begin
    625   Result := Server(sRevolution, me, 0, nodata^);
    626 end;
    627 
    628 function TCustomAI.ChangeRates(Tax, Lux: integer): integer;
    629 begin
    630   Result := Server(sSetRates, me, Tax div 10 and $f + Lux div 10 and $f shl 4, nodata^);
    631 end;
    632 
    633 function TCustomAI.PrepareNewModel(Domain: integer): integer;
    634 begin
    635   Result := Server(sCreateDevModel, me, Domain, nodata^);
    636 end;
    637 
    638 function TCustomAI.SetNewModelFeature(F, Count: integer): integer;
    639 begin
    640   Result := Server(sSetDevModelCap + Count shl 4, me, F, nodata^);
    641 end;
    642 
    643 function TCustomAI.AdvanceResearchable(Advance: integer): boolean;
    644 begin
    645   Result := Server(sSetResearch - sExecute, me, Advance, nodata^) >= rExecuted;
    646 end;
    647 
    648 function TCustomAI.AdvanceStealable(Advance: integer): boolean;
    649 begin
    650   Result := Server(sStealTech - sExecute, me, Advance, nodata^) >= rExecuted;
    651 end;
    652 
    653 function TCustomAI.GetJobProgress(Loc: integer;
    654   var JobProgress: TJobProgressData): boolean;
    655 begin
    656   Result := Server(sGetJobProgress, me, Loc, JobProgress) >= rExecuted;
    657 end;
    658 
    659 function TCustomAI.DebugMessage(Level: integer; Text: string): boolean;
    660 begin
    661   Text := copy('P' + char(48 + me) + ' ' + Text, 1, 254);
    662   Server(sMessage, me, Level, PChar(Text)^);
     631function TCustomAI.IsResearched(Advance: Integer): Boolean;
     632begin
     633  Result := (Advance = preNone) or (Advance <> preNA) and (RO.Tech[Advance] >= tsApplicable);
     634end;
     635
     636function TCustomAI.ResearchCost: Integer;
     637begin
     638  Server(sGetTechCost, Me, 0, Result);
     639end;
     640
     641function TCustomAI.ChangeAttitude(Nation, Attitude: Integer): Integer;
     642begin
     643  Result := Server(sSetAttitude + Nation shl 4, Me, Attitude, nodata^);
     644end;
     645
     646function TCustomAI.Revolution: Integer;
     647begin
     648  Result := Server(sRevolution, Me, 0, nodata^);
     649end;
     650
     651function TCustomAI.ChangeRates(Tax, Lux: Integer): Integer;
     652begin
     653  Result := Server(sSetRates, Me, Tax div 10 and $F + Lux div 10 and $F shl 4, nodata^);
     654end;
     655
     656function TCustomAI.PrepareNewModel(Domain: Integer): Integer;
     657begin
     658  Result := Server(sCreateDevModel, Me, Domain, nodata^);
     659end;
     660
     661function TCustomAI.SetNewModelFeature(F, Count: Integer): Integer;
     662begin
     663  Result := Server(sSetDevModelCap + Count shl 4, Me, F, nodata^);
     664end;
     665
     666function TCustomAI.AdvanceResearchable(Advance: Integer): Boolean;
     667begin
     668  Result := Server(sSetResearch - sExecute, Me, Advance, nodata^) >= rExecuted;
     669end;
     670
     671function TCustomAI.AdvanceStealable(Advance: Integer): Boolean;
     672begin
     673  Result := Server(sStealTech - sExecute, Me, Advance, nodata^) >= rExecuted;
     674end;
     675
     676function TCustomAI.GetJobProgress(Loc: Integer;
     677  var JobProgress: TJobProgressData): Boolean;
     678begin
     679  Result := Server(sGetJobProgress, Me, Loc, JobProgress) >= rExecuted;
     680end;
     681
     682function TCustomAI.DebugMessage(Level: Integer; Text: string): Boolean;
     683begin
     684  Text := Copy('P' + Char(48 + Me) + ' ' + Text, 1, 254);
     685  Server(sMessage, Me, Level, PChar(Text)^);
    663686
    664687  Result := True;
     
    667690end;
    668691
    669 function TCustomAI.SetDebugMap(var DebugMap): boolean;
    670 begin
    671   Server(sSetDebugMap, me, 0, DebugMap);
     692function TCustomAI.SetDebugMap(var DebugMap): Boolean;
     693begin
     694  Server(sSetDebugMap, Me, 0, DebugMap);
    672695
    673696  Result := True;
     
    676699end;
    677700
    678 procedure TCustomAI.Unit_FindMyDefender(Loc: integer; var uix: integer);
    679 begin
    680   if Server(sGetDefender, me, Loc, uix) < rExecuted then uix := -1;
    681 end;
    682 
    683 procedure TCustomAI.Unit_FindEnemyDefender(Loc: integer; var euix: integer);
     701procedure TCustomAI.Unit_FindMyDefender(Loc: Integer; var uix: Integer);
     702begin
     703  if Server(sGetDefender, Me, Loc, uix) < rExecuted then
     704    uix := -1;
     705end;
     706
     707procedure TCustomAI.Unit_FindEnemyDefender(Loc: Integer; var euix: Integer);
    684708begin
    685709  euix := RO.nEnemyUn - 1;
     
    688712end;
    689713
    690 function TCustomAI.Unit_Move(uix, ToLoc: integer): integer;
    691 var
    692   Step: integer;
    693   DestinationReached: boolean;
     714function TCustomAI.Unit_Move(uix, ToLoc: Integer): Integer;
     715var
     716  Step: Integer;
     717  DestinationReached: Boolean;
    694718  Advice: TMoveAdviceData;
    695719begin
    696   assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit
     720  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit
    697721{Loc_to_ab(MyUnit[uix].Loc,ToLoc,a,b);
    698 assert((a<>0) or (b<>0));
    699 if (a>=-1) and (a<=1) and (b>=-1) and (b<=1) then
     722Assert((A<>0) or (B<>0));
     723if (A>=-1) and (A<=1) and (B>=-1) and (B<=1) then
    700724  begin // move to adjacent tile
    701   !!!problem: if move is invalid, return codes are not consistent with other branch (eNoWay)
     725  !!!problem: if Move is invalid, return codes are not consistent with other branch (eNoWay)
    702726  Advice.nStep:=1;
    703   Advice.dx[0]:=a-b;
    704   Advice.dy[0]:=a+b;
     727  Advice.dx[0]:=A-B;
     728  Advice.dy[0]:=A+B;
    705729  Advice.MoreTurns:=0;
    706730  Advice.MaxHostile_MovementLeft:=MyUnit[uix].Movement;
    707   result:=eOK;
     731  Result:=eOK;
    708732  end
    709733else}
     
    712736    Advice.MoreTurns := 9999;
    713737    Advice.MaxHostile_MovementLeft := 100;
    714     Result := Server(sGetMoveAdvice, me, uix, Advice);
     738    Result := Server(sGetMoveAdvice, Me, uix, Advice);
    715739  end;
    716740  if Result = eOk then
     
    728752        begin
    729753          DestinationReached := True;
    730           break;
     754          Break;
    731755        end // stop next to destination
    732756        else if Step = Advice.nStep then
     
    734758
    735759      if (Step = Advice.nStep) or (Result <> eOK) and (Result <> eLoaded) then
    736         break;
     760        Break;
    737761
    738762      Result := Server(sMoveUnit + (Advice.dx[Step] and 7) shl 4 +
    739         (Advice.dy[Step] and 7) shl 7, me, uix, nodata^);
     763        (Advice.dy[Step] and 7) shl 7, Me, uix, nodata^);
    740764      Inc(Step);
    741       if RO.Happened and phStealTech <> 0 then StealAdvance;
     765      if RO.Happened and phStealTech <> 0 then
     766        StealAdvance;
    742767    until False;
    743768    if DestinationReached then
     
    751776end;
    752777
    753 function TCustomAI.Unit_Step(uix, ToLoc: integer): integer;
    754 var
    755   a, b: integer;
    756 begin
    757   Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b);
    758   assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b <= 1));
    759   Result := Server(sMoveUnit + ((a - b) and 7) shl 4 + ((a + b) and 7) shl 7, me, uix, nodata^);
    760   if RO.Happened and phStealTech <> 0 then StealAdvance;
    761 end;
    762 
    763 function TCustomAI.Unit_Attack(uix, ToLoc: integer): integer;
    764 var
    765   a, b: integer;
    766 begin
    767   assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
     778function TCustomAI.Unit_Step(uix, ToLoc: Integer): Integer;
     779var
     780  A, B: Integer;
     781begin
     782  Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B);
     783  Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1));
     784  Result := Server(sMoveUnit + ((A - B) and 7) shl 4 + ((A + B) and 7) shl 7, Me, uix, nodata^);
     785  if RO.Happened and phStealTech <> 0 then
     786    StealAdvance;
     787end;
     788
     789function TCustomAI.Unit_Attack(uix, ToLoc: Integer): Integer;
     790var
     791  A, B: Integer;
     792begin
     793  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
    768794    and ((Map[ToLoc] and (fUnit or fOwned) = fUnit) // is an attack
    769795    or (Map[ToLoc] and (fCity or fOwned) = fCity) and
    770796    (MyModel[MyUnit[uix].mix].Domain <> dGround))); // is a bombardment
    771   Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b);
    772   assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b <= 1));
     797  Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B);
     798  Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1));
    773799  // attack to adjacent tile
    774   Result := Server(sMoveUnit + (a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^);
    775 end;
    776 
    777 function TCustomAI.Unit_DoMission(uix, MissionType, ToLoc: integer): integer;
    778 var
    779   a, b: integer;
    780 begin
    781   Result := Server(sSetSpyMission + MissionType shl 4, me, 0, nodata^);
     800  Result := Server(sMoveUnit + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^);
     801end;
     802
     803function TCustomAI.Unit_DoMission(uix, MissionType, ToLoc: Integer): Integer;
     804var
     805  A, B: Integer;
     806begin
     807  Result := Server(sSetSpyMission + MissionType shl 4, Me, 0, nodata^);
    782808  if Result >= rExecuted then
    783809  begin
    784     assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
     810    Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
    785811      and (MyModel[MyUnit[uix].mix].Kind = mkDiplomat)); // is a commando
    786     Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b);
    787     assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b <= 1));
     812    Loc_to_ab(MyUnit[uix].Loc, ToLoc, A, B);
     813    Assert(((A <> 0) or (B <> 0)) and (A >= -1) and (A <= 1) and (B >= -1) and (B <= 1));
    788814    // city must be adjacent
    789     Result := Server(sMoveUnit - sExecute + (a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^);
     815    Result := Server(sMoveUnit - sExecute + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^);
    790816    if Result = eMissionDone then
    791       Result := Server(sMoveUnit + (a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^)
     817      Result := Server(sMoveUnit + (A - B) and 7 shl 4 + (A + B) and 7 shl 7, Me, uix, nodata^)
    792818    else if (Result <> eNoTime_Move) and (Result <> eTreaty) and (Result <> eNoTurn) then
    793819      Result := eInvalid; // not a special commando mission!
     
    795821end;
    796822
    797 function TCustomAI.Unit_MoveForecast(uix, ToLoc: integer;
    798   var RemainingMovement: integer): boolean;
     823function TCustomAI.Unit_MoveForecast(uix, ToLoc: Integer;
     824  var RemainingMovement: Integer): Boolean;
    799825var
    800826  Advice: TMoveAdviceData;
    801827begin
    802   assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit
     828  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit
    803829  Advice.ToLoc := ToLoc;
    804830  Advice.MoreTurns := 0;
    805831  Advice.MaxHostile_MovementLeft := 100;
    806   if Server(sGetMoveAdvice, me, uix, Advice) = eOk then
     832  if Server(sGetMoveAdvice, Me, uix, Advice) = eOk then
    807833  begin
    808834    RemainingMovement := Advice.MaxHostile_MovementLeft;
     
    816842end;
    817843
    818 function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: integer;
    819   var RemainingHealth: integer): boolean;
     844// negative RemainingHealth is remaining helth of defender if lost
     845function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: Integer;
     846  var RemainingHealth: Integer): Boolean;
    820847var
    821848  BattleForecast: TBattleForecast;
    822849begin
    823   assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
     850  Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit
    824851    and (Map[ToLoc] and (fUnit or fOwned) = fUnit)); // is an attack
    825852  RemainingHealth := -$100;
    826853  Result := False;
    827   if AttackMovement >= 0 then with MyUnit[uix] do
     854  if AttackMovement >= 0 then
     855    with MyUnit[uix] do
    828856    begin
    829       BattleForecast.pAtt := me;
     857      BattleForecast.pAtt := Me;
    830858      BattleForecast.mixAtt := mix;
    831859      BattleForecast.HealthAtt := Health;
     
    833861      BattleForecast.FlagsAtt := Flags;
    834862      BattleForecast.Movement := AttackMovement;
    835       if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then
     863      if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then
    836864      begin
    837865        if BattleForecast.EndHealthAtt > 0 then
     
    844872end;
    845873
    846 function TCustomAI.Unit_DefenseForecast(euix, ToLoc: integer;
    847   var RemainingHealth: integer): boolean;
     874function TCustomAI.Unit_DefenseForecast(euix, ToLoc: Integer;
     875  var RemainingHealth: Integer): Boolean;
    848876var
    849877  BattleForecast: TBattleForecast;
    850878begin
    851   assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit
     879  Assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit
    852880    and (Map[ToLoc] and (fUnit or fOwned) = (fUnit or fOwned))); // is an attack
    853881  RemainingHealth := $100;
     
    861889    BattleForecast.FlagsAtt := Flags;
    862890    BattleForecast.Movement := 100;
    863     if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then
     891    if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then
    864892    begin
    865893      if BattleForecast.EndHealthDef > 0 then
     
    872900end;
    873901
    874 function TCustomAI.Unit_Disband(uix: integer): integer;
    875 begin
    876   Result := Server(sRemoveUnit, me, uix, nodata^);
    877 end;
    878 
    879 function TCustomAI.Unit_StartJob(uix, NewJob: integer): integer;
    880 begin
    881   Result := Server(sStartJob + NewJob shl 4, me, uix, nodata^);
    882 end;
    883 
    884 function TCustomAI.Unit_SetHomeHere(uix: integer): integer;
    885 begin
    886   Result := Server(sSetUnitHome, me, uix, nodata^);
    887 end;
    888 
    889 function TCustomAI.Unit_Load(uix: integer): integer;
    890 begin
    891   Result := Server(sLoadUnit, me, uix, nodata^);
    892 end;
    893 
    894 function TCustomAI.Unit_Unload(uix: integer): integer;
    895 begin
    896   Result := Server(sUnloadUnit, me, uix, nodata^);
    897 end;
    898 
    899 function TCustomAI.Unit_AddToCity(uix: integer): integer;
    900 begin
    901   Result := Server(sAddToCity, me, uix, nodata^);
    902 end;
    903 
    904 function TCustomAI.Unit_SelectTransport(uix: integer): integer;
    905 begin
    906   Result := Server(sSelectTransport, me, uix, nodata^);
    907 end;
    908 
    909 
    910 procedure TCustomAI.City_FindMyCity(Loc: integer; var cix: integer);
     902function TCustomAI.Unit_Disband(uix: Integer): Integer;
     903begin
     904  Result := Server(sRemoveUnit, Me, uix, nodata^);
     905end;
     906
     907function TCustomAI.Unit_StartJob(uix, NewJob: Integer): Integer;
     908begin
     909  Result := Server(sStartJob + NewJob shl 4, Me, uix, nodata^);
     910end;
     911
     912function TCustomAI.Unit_SetHomeHere(uix: Integer): Integer;
     913begin
     914  Result := Server(sSetUnitHome, Me, uix, nodata^);
     915end;
     916
     917function TCustomAI.Unit_Load(uix: Integer): Integer;
     918begin
     919  Result := Server(sLoadUnit, Me, uix, nodata^);
     920end;
     921
     922function TCustomAI.Unit_Unload(uix: Integer): Integer;
     923begin
     924  Result := Server(sUnloadUnit, Me, uix, nodata^);
     925end;
     926
     927function TCustomAI.Unit_AddToCity(uix: Integer): Integer;
     928begin
     929  Result := Server(sAddToCity, Me, uix, nodata^);
     930end;
     931
     932function TCustomAI.Unit_SelectTransport(uix: Integer): Integer;
     933begin
     934  Result := Server(sSelectTransport, Me, uix, nodata^);
     935end;
     936
     937
     938procedure TCustomAI.City_FindMyCity(Loc: Integer; var cix: Integer);
    911939begin
    912940  if Map[Loc] and (fCity or fOwned) <> fCity or fOwned then
     
    920948end;
    921949
    922 procedure TCustomAI.City_FindEnemyCity(Loc: integer; var ecix: integer);
     950procedure TCustomAI.City_FindEnemyCity(Loc: Integer; var ecix: Integer);
    923951begin
    924952  if Map[Loc] and (fCity or fOwned) <> fCity then
     
    932960end;
    933961
    934 function TCustomAI.City_HasProject(cix: integer): boolean;
     962function TCustomAI.City_HasProject(cix: Integer): Boolean;
    935963begin
    936964  Result := MyCity[cix].Project and (cpImp + cpIndex) <> cpImp + imTrGoods;
    937965end;
    938966
    939 function TCustomAI.City_CurrentImprovementProject(cix: integer): integer;
    940 begin
    941   if MyCity[cix].Project and cpImp = 0 then Result := -1
     967function TCustomAI.City_CurrentImprovementProject(cix: Integer): Integer;
     968begin
     969  if MyCity[cix].Project and cpImp = 0 then
     970    Result := -1
    942971  else
    943972  begin
    944973    Result := MyCity[cix].Project and cpIndex;
    945     if Result = imTrGoods then Result := -1;
    946   end;
    947 end;
    948 
    949 function TCustomAI.City_CurrentUnitProject(cix: integer): integer;
    950 begin
    951   if MyCity[cix].Project and cpImp <> 0 then Result := -1
     974    if Result = imTrGoods then
     975      Result := -1;
     976  end;
     977end;
     978
     979function TCustomAI.City_CurrentUnitProject(cix: Integer): Integer;
     980begin
     981  if MyCity[cix].Project and cpImp <> 0 then
     982    Result := -1
    952983  else
    953984    Result := MyCity[cix].Project and cpIndex;
    954985end;
    955986
    956 function TCustomAI.City_GetTileInfo(cix, TileLoc: integer;
    957   var TileInfo: TTileInfo): integer;
     987function TCustomAI.City_GetTileInfo(cix, TileLoc: Integer;
     988  var TileInfo: TTileInfo): Integer;
    958989begin
    959990  TileInfo.ExplCity := cix;
    960   Result := Server(sGetHypoCityTileInfo, me, TileLoc, TileInfo);
    961 end;
    962 
    963 function TCustomAI.City_GetReport(cix: integer; var Report: TCityReport): integer;
     991  Result := Server(sGetHypoCityTileInfo, Me, TileLoc, TileInfo);
     992end;
     993
     994function TCustomAI.City_GetReport(cix: Integer; var Report: TCityReport): Integer;
    964995begin
    965996  Report.HypoTiles := -1;
    966997  Report.HypoTax := -1;
    967998  Report.HypoLux := -1;
    968   Result := Server(sGetCityReport, me, cix, Report);
    969 end;
    970 
    971 function TCustomAI.City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: integer;
    972   var Report: TCityReport): integer;
     999  Result := Server(sGetCityReport, Me, cix, Report);
     1000end;
     1001
     1002function TCustomAI.City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer;
     1003  var Report: TCityReport): Integer;
    9731004begin
    9741005  Report.HypoTiles := HypoTiles;
    9751006  Report.HypoTax := HypoTax;
    9761007  Report.HypoLux := HypoLux;
    977   Result := Server(sGetCityReport, me, cix, Report);
    978 end;
    979 
    980 function TCustomAI.City_GetReportNew(cix: integer; var Report: TCityReportNew): integer;
     1008  Result := Server(sGetCityReport, Me, cix, Report);
     1009end;
     1010
     1011function TCustomAI.City_GetReportNew(cix: Integer; var Report: TCityReportNew): Integer;
    9811012begin
    9821013  Report.HypoTiles := -1;
    9831014  Report.HypoTaxRate := -1;
    9841015  Report.HypoLuxuryRate := -1;
    985   Result := Server(sGetCityReportNew, me, cix, Report);
     1016  Result := Server(sGetCityReportNew, Me, cix, Report);
    9861017end;
    9871018
    9881019function TCustomAI.City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate,
    989   HypoLuxuryRate: integer; var Report: TCityReportNew): integer;
     1020  HypoLuxuryRate: Integer; var Report: TCityReportNew): Integer;
    9901021begin
    9911022  Report.HypoTiles := HypoTiles;
    9921023  Report.HypoTaxRate := HypoTaxRate;
    9931024  Report.HypoLuxuryRate := HypoLuxuryRate;
    994   Result := Server(sGetCityReportNew, me, cix, Report);
    995 end;
    996 
    997 function TCustomAI.City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer;
    998 begin
    999   Result := Server(sGetCityAreaInfo, me, cix, AreaInfo);
    1000 end;
    1001 
    1002 function TCustomAI.City_StartUnitProduction(cix, mix: integer): integer;
    1003 begin
    1004   Result := Server(sSetCityProject, me, cix, mix);
    1005 end;
    1006 
    1007 function TCustomAI.City_StartEmigration(cix, mix: integer;
    1008   AllowDisbandCity, AsConscripts: boolean): integer;
    1009 var
    1010   NewProject: integer;
     1025  Result := Server(sGetCityReportNew, Me, cix, Report);
     1026end;
     1027
     1028function TCustomAI.City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer;
     1029begin
     1030  Result := Server(sGetCityAreaInfo, Me, cix, AreaInfo);
     1031end;
     1032
     1033function TCustomAI.City_StartUnitProduction(cix, mix: Integer): Integer;
     1034begin
     1035  if (MyCity[cix].Project and (cpImp + cpIndex) <> mix) then
     1036    // not already producing that
     1037    Result := Server(sSetCityProject, Me, cix, mix);
     1038end;
     1039
     1040function TCustomAI.City_StartEmigration(cix, mix: Integer;
     1041  AllowDisbandCity, AsConscripts: Boolean): Integer;
     1042var
     1043  NewProject: Integer;
    10111044begin
    10121045  NewProject := mix;
    1013   if AllowDisbandCity then NewProject := NewProject or cpDisbandCity;
    1014   if AsConscripts then NewProject := NewProject or cpConscripts;
    1015   Result := Server(sSetCityProject, me, cix, NewProject);
    1016 end;
    1017 
    1018 function TCustomAI.City_StartImprovement(cix, iix: integer): integer;
    1019 var
    1020   NewProject: integer;
     1046  if AllowDisbandCity then
     1047    NewProject := NewProject or cpDisbandCity;
     1048  if AsConscripts then
     1049    NewProject := NewProject or cpConscripts;
     1050  Result := Server(sSetCityProject, Me, cix, NewProject);
     1051end;
     1052
     1053function TCustomAI.City_StartImprovement(cix, iix: Integer): Integer;
     1054var
     1055  NewProject: Integer;
    10211056begin
    10221057  NewProject := iix + cpImp;
    1023   Result := Server(sSetCityProject, me, cix, NewProject);
    1024 end;
    1025 
    1026 function TCustomAI.City_Improvable(cix, iix: integer): boolean;
    1027 var
    1028   NewProject: integer;
     1058  if (MyCity[cix].Project and (cpImp + cpIndex) <> NewProject) then
     1059    // not already producing that
     1060    Result := Server(sSetCityProject, Me, cix, NewProject);
     1061end;
     1062
     1063function TCustomAI.City_Improvable(cix, iix: Integer): Boolean;
     1064var
     1065  NewProject: Integer;
    10291066begin
    10301067  NewProject := iix + cpImp;
    1031   Result := Server(sSetCityProject - sExecute, me, cix, NewProject) >= rExecuted;
    1032 end;
    1033 
    1034 function TCustomAI.City_StopProduction(cix: integer): integer;
    1035 var
    1036   NewProject: integer;
     1068  Result := Server(sSetCityProject - sExecute, Me, cix, NewProject) >= rExecuted;
     1069end;
     1070
     1071function TCustomAI.City_StopProduction(cix: Integer): Integer;
     1072var
     1073  NewProject: Integer;
    10371074begin
    10381075  NewProject := imTrGoods + cpImp;
    1039   Result := Server(sSetCityProject, me, cix, NewProject);
    1040 end;
    1041 
    1042 function TCustomAI.City_BuyProject(cix: integer): integer;
    1043 begin
    1044   Result := Server(sBuyCityProject, me, cix, nodata^);
    1045 end;
    1046 
    1047 function TCustomAI.City_SellImprovement(cix, iix: integer): integer;
    1048 begin
    1049   Result := Server(sSellCityImprovement, me, cix, iix);
    1050 end;
    1051 
    1052 function TCustomAI.City_RebuildImprovement(cix, iix: integer): integer;
    1053 begin
    1054   Result := Server(sRebuildCityImprovement, me, cix, iix);
    1055 end;
    1056 
    1057 function TCustomAI.City_SetTiles(cix, NewTiles: integer): integer;
    1058 begin
    1059   Result := Server(sSetCityTiles, me, cix, NewTiles);
    1060 end;
    1061 
    1062 procedure TCustomAI.City_OptimizeTiles(cix: integer; ResourceWeights: integer);
     1076  Result := Server(sSetCityProject, Me, cix, NewProject);
     1077end;
     1078
     1079function TCustomAI.City_BuyProject(cix: Integer): Integer;
     1080begin
     1081  Result := Server(sBuyCityProject, Me, cix, nodata^);
     1082end;
     1083
     1084function TCustomAI.City_SellImprovement(cix, iix: Integer): Integer;
     1085begin
     1086  Result := Server(sSellCityImprovement, Me, cix, iix);
     1087end;
     1088
     1089function TCustomAI.City_RebuildImprovement(cix, iix: Integer): Integer;
     1090begin
     1091  Result := Server(sRebuildCityImprovement, Me, cix, iix);
     1092end;
     1093
     1094function TCustomAI.City_SetTiles(cix, NewTiles: Integer): Integer;
     1095begin
     1096  Result := Server(sSetCityTiles, Me, cix, NewTiles);
     1097end;
     1098
     1099procedure TCustomAI.City_OptimizeTiles(cix: Integer; ResourceWeights: Cardinal);
    10631100var
    10641101  Advice: TCityTileAdviceData;
    10651102begin
    10661103  Advice.ResourceWeights := ResourceWeights;
    1067   Server(sGetCityTileAdvice, me, cix, Advice);
     1104  Server(sGetCityTileAdvice, Me, cix, Advice);
    10681105  City_SetTiles(cix, Advice.Tiles);
    10691106end;
    10701107
    1071 
    10721108// negotiation
    1073 function TCustomAI.Nego_CheckMyAction: integer;
    1074 begin
    1075   assert(Opponent >= 0); // only allowed in negotiation mode
    1076   assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or
     1109function TCustomAI.Nego_CheckMyAction: Integer;
     1110begin
     1111  Assert(Opponent >= 0); // only allowed in negotiation mode
     1112  Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or
    10771113    (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak));
    1078   if MyAction = scDipOffer then Result := Server(MyAction - sExecute, me, 0, MyOffer)
     1114  if MyAction = scDipOffer then
     1115    Result := Server(MyAction - sExecute, Me, 0, MyOffer)
    10791116  else
    1080     Result := Server(MyAction - sExecute, me, 0, nodata^);
    1081 end;
    1082 
     1117    Result := Server(MyAction - sExecute, Me, 0, nodata^);
     1118end;
    10831119
    10841120initialization
    1085   nodata := pointer(0);
     1121  nodata := Pointer(0);
    10861122  RWDataSize := 0;
    10871123
Note: See TracChangeset for help on using the changeset viewer.