Changeset 583 for trunk/AI Template/CustomAI.pas
- Timestamp:
- May 23, 2024, 10:14:11 PM (6 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/AI Template/CustomAI.pas
r582 r583 5 5 6 6 uses 7 7 {$IFDEF DEBUG}SysUtils,{$ENDIF} // necessary for debug exceptions 8 8 Protocol; 9 9 … … 13 13 TCustomAI = class 14 14 public 15 procedure Process(Command: integer; var Data);15 procedure Process(Command: Integer; var Data); 16 16 17 17 // overridables 18 constructor Create(Nation: integer); virtual;18 constructor Create(Nation: Integer); virtual; 19 19 destructor Destroy; override; 20 20 procedure SetDataDefaults; virtual; 21 21 procedure SetDataRandom; virtual; 22 22 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; 25 25 procedure OnAfterEnemyAttack; virtual; 26 26 procedure OnAfterEnemyCapture; virtual; 27 27 28 28 protected 29 me: integer; // index of the controlled nation29 Me: Integer; // index of the controlled nation 30 30 RO: ^TPlayerContext; 31 31 Map: ^TTileList; … … 34 34 MyModel: ^TModelList; 35 35 36 cixStateImp: array[imPalace..imSpacePort] of integer;36 cixStateImp: array[imPalace..imSpacePort] of Integer; 37 37 38 38 // negotiation 39 Opponent: integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode40 MyAction, MyLastAction, OppoAction: integer;39 Opponent: Integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode 40 MyAction, MyLastAction, OppoAction: Integer; 41 41 MyOffer, MyLastOffer, OppoOffer: TOffer; 42 42 … … 44 44 procedure DoTurn; virtual; 45 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;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 51 52 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 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; 65 65 66 66 // 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; 86 86 87 87 // 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); 112 112 113 113 // negotiation 114 function Nego_CheckMyAction: integer;114 function Nego_CheckMyAction: Integer; 115 115 116 116 private 117 HaveTurned: boolean;117 HaveTurned: Boolean; 118 118 UnwantedNego: set of 0..nPl - 1; 119 119 Contacted: set of 0..nPl - 1; … … 125 125 Server: TServerCall; 126 126 G: TNewGameData; 127 RWDataSize, MapSize: integer;128 decompose24: cardinal;129 nodata: pointer;127 RWDataSize, MapSize: Integer; 128 decompose24: Cardinal; 129 nodata: Pointer; 130 130 131 131 const … … 136 136 // Unit_Move: move was not interrupted, location reached 137 137 rMoreTurns = $00020000; 138 138 // Unit_Move: move was not interrupted, location not reached yet 139 139 140 140 type 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; 143 143 144 144 145 145 procedure Init(NewGameData: TNewGameData); 146 146 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); 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); 155 function Distance(Loc0, Loc1: Integer): Integer; 155 156 156 157 … … 158 159 159 160 const 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 166 procedure ab_to_Loc(Loc0, A, B: Integer; var Loc: Integer); 166 167 {relative location from Loc0} 167 168 var 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} 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; 170 begin 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; 176 end; 177 178 procedure Loc_to_ab(Loc0, Loc: Integer; var A, B: Integer); 179 {$IFDEF FPC}// freepascal 180 var 181 dx, dy: Integer; 182 begin 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; 184 185 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; 188 end; 189 190 {$ELSE}// delphi 189 191 register; 190 192 asm 191 192 193 194 195 div byte ptr [G]196 197 198 199 200 201 div byte ptr [G]202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 jl @a 219 220 221 222 @a:223 224 225 226 227 228 229 230 231 232 233 234 235 mov ebx,[b]236 237 238 mov [a],eax239 240 193 push ebx 194 195 // calculate 196 push ecx 197 div Byte ptr [G] 198 xor ebx,ebx 199 mov bl,ah // ebx:=Loc0 mod G.lx 200 mov ecx,eax 201 and ecx,$000000FF // ecx:=Loc0 div G.lx 202 mov eax,edx 203 div Byte ptr [G] 204 xor edx,edx 205 mov dl,ah // edx:=Loc mod G.lx 206 and eax,$000000FF // eax:=Loc div G.lx 207 sub edx,ebx // edx:=Loc mod G.lx-Loc0 mod G.lx 208 mov ebx,eax 209 sub ebx,ecx // ebx:=dy 210 and eax,1 211 and ecx,1 212 add edx,edx 213 add eax,edx 214 sub eax,ecx // eax:=dx, not normalized 215 pop ecx 216 217 // normalize 218 mov edx,dword ptr [G] 219 cmp eax,edx 220 jl @A 221 sub eax,edx 222 sub eax,edx 223 jmp @ok 224 @A: 225 neg edx 226 cmp eax,edx 227 jnl @ok 228 sub eax,edx 229 sub eax,edx 230 231 // return results 232 @ok: 233 mov edx,ebx 234 sub edx,eax 235 add eax,ebx 236 sar edx,1 // edx:=b 237 mov ebx,[B] 238 mov [ebx],edx 239 sar eax,1 // eax:=a 240 mov [A],eax 241 242 pop ebx 241 243 end; 242 244 {$ENDIF} 243 245 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;246 procedure ab_to_V8(A, B: Integer; var V8: Integer); 247 begin 248 Assert((Abs(A) <= 1) and (Abs(B) <= 1) and ((A <> 0) or (B <> 0))); 249 V8 := ab_v8[2 * B + B + A]; 250 end; 251 252 procedure V8_to_ab(V8: Integer; var A, B: Integer); 253 begin 254 A := v8_a[V8]; 255 B := V8_b[V8]; 256 end; 257 258 procedure ab_to_V21(A, B: Integer; var V21: Integer); 259 begin 260 V21 := (A + B + 3) shl 2 + (A - B + 3) shr 1; 261 end; 262 263 procedure V21_to_ab(V21: Integer; var A, B: Integer); 264 var 265 dx, dy: Integer; 264 266 begin 265 267 dy := V21 shr 2 - 3; 266 268 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; 271 end; 272 273 procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc); 274 var 275 x0, y0, lx: Integer; 274 276 begin 275 277 lx := G.lx; 276 y0 := cardinal(Loc0) * decompose24 shr 24;278 y0 := Cardinal(Loc0) * decompose24 shr 24; 277 279 x0 := Loc0 - y0 * lx; // Loc0 mod lx; 278 280 VicinityLoc[1] := Loc0 + lx * 2; … … 321 323 end; 322 324 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;325 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc); 326 var 327 dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: Integer; 328 dst: ^Integer; 329 begin 330 y0 := Cardinal(Loc0) * decompose24 shr 24; 329 331 xComp0 := Loc0 - y0 * G.lx - 1; // Loc0 mod G.lx -1 330 332 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); 333 337 xCompSwitch := xCompSwitch xor xComp0; 334 338 yComp := G.lx * (y0 - 3); … … 342 346 for dx := 0 to 3 do 343 347 begin 344 if bit and $67F7F76 <> 0 then dst^ := xComp + yComp 348 if bit and $67F7F76 <> 0 then 349 dst^ := xComp + yComp 345 350 else 346 351 dst^ := -1; 347 352 Inc(xComp); 348 if xComp >= G.lx then Dec(xComp, G.lx); 353 if xComp >= G.lx then 354 Dec(xComp, G.lx); 349 355 Inc(dst); 350 356 bit := bit shl 1; … … 362 368 end; 363 369 370 function Distance(Loc0, Loc1: Integer): Integer; 371 var 372 A, B, dx, dy: Integer; 373 begin 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; 378 end; 364 379 365 380 procedure Init(NewGameData: TNewGameData); 366 381 {$IFDEF DEBUG}var 367 Loc: integer;368 382 Loc: Integer; 383 {$ENDIF} 369 384 begin 370 385 G := NewGameData; 371 386 MapSize := G.lx * G.ly; 372 387 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} 392 end; 393 394 constructor TCustomAI.Create(Nation: Integer); 381 395 begin 382 396 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); 389 403 Opponent := -1; 390 404 end; … … 392 406 destructor TCustomAI.Destroy; 393 407 begin 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^); 409 end; 410 411 procedure TCustomAI.Process(Command: Integer; var Data); 412 var 413 Nation, NewResearch, NewGov, Count, ad, cix, iix: Integer; 401 414 NegoTime: TNegoTime; 402 415 begin … … 404 417 cTurn, cContinue: 405 418 begin 406 if RO.Alive and (1 shl me) = 0 then419 if RO.Alive and (1 shl Me) = 0 then 407 420 begin // I'm dead, huhu 408 Server(sTurn, me, 0, nodata^);409 exit;421 Server(sTurn, Me, 0, nodata^); 422 Exit; 410 423 end; 411 424 if Command = cTurn then 412 425 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 415 429 for iix := imPalace to imSpacePort do 416 430 if MyCity[cix].Built[iix] > 0 then … … 420 434 NewGov := ChooseGovernment; 421 435 if NewGov > gAnarchy then 422 Server(sSetGovernment, me, NewGov, nodata^);436 Server(sSetGovernment, Me, NewGov, nodata^); 423 437 end; 424 438 HaveTurned := False; … … 429 443 if OnNegoRejected_CancelTreaty then 430 444 if RO.Treaty[Opponent] >= trPeace then 431 if Server(sCancelTreaty, me, 0, nodata^) < rExecuted then432 assert(False);445 if Server(sCancelTreaty, Me, 0, nodata^) < rExecuted then 446 Assert(False); 433 447 end 434 448 else … … 436 450 Opponent := -1; 437 451 repeat 438 if HaveTurned then NegoTime := EndOfTurn 452 if HaveTurned then 453 NegoTime := EndOfTurn 439 454 else 440 455 NegoTime := BeginOfTurn; 441 456 if RO.Government <> gAnarchy then 442 457 for Nation := 0 to nPl - 1 do 443 if (Nation <> me) and (1 shl Nation and RO.Alive <> 0) and458 if (Nation <> Me) and (1 shl Nation and RO.Alive <> 0) and 444 459 (RO.Treaty[Nation] >= trNone) and not (Nation in Contacted) and not 445 460 (Nation in UnwantedNego) and 446 (Server(scContact - sExecute + Nation shl 4, me, 0, nodata^) >= rExecuted) then461 (Server(scContact - sExecute + Nation shl 4, Me, 0, nodata^) >= rExecuted) then 447 462 if WantNegotiation(Nation, NegoTime) then 448 463 begin 449 if Server(scContact + Nation shl 4, me, 0, nodata^) >= rExecuted then464 if Server(scContact + Nation shl 4, Me, 0, nodata^) >= rExecuted then 450 465 begin 451 include(Contacted, Nation);466 Include(Contacted, Nation); 452 467 Opponent := Nation; 453 468 MyAction := scContact; 454 exit;469 Exit; 455 470 end; 456 471 end 457 472 else 458 include(UnwantedNego, Nation);473 Include(UnwantedNego, Nation); 459 474 if NegoTime = BeginOfTurn then 460 475 begin … … 465 480 end 466 481 else 467 break;482 Break; 468 483 until False; 469 484 if RO.Happened and phTech <> 0 then … … 473 488 begin // choose random research 474 489 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 476 492 begin 477 493 Inc(Count); 478 if random(Count) = 0 then NewResearch := ad; 494 if Random(Count) = 0 then 495 NewResearch := ad; 479 496 end; 480 497 end; 481 Server(sSetResearch, me, NewResearch, nodata^);498 Server(sSetResearch, Me, NewResearch, nodata^); 482 499 end; 483 if Server(sTurn, me, 0, nodata^) < rExecuted then484 assert(False);500 if Server(sTurn, Me, 0, nodata^) < rExecuted then 501 Assert(False); 485 502 end; 486 503 scContact: 487 if WantNegotiation( integer(Data), EnemyCalled) then504 if WantNegotiation(Integer(Data), EnemyCalled) then 488 505 begin 489 if Server(scDipStart, me, 0, nodata^) < rExecuted then490 assert(False);491 Opponent := integer(Data);506 if Server(scDipStart, Me, 0, nodata^) < rExecuted then 507 Assert(False); 508 Opponent := Integer(Data); 492 509 MyAction := scDipStart; 493 510 end 494 511 else 495 512 begin 496 if Server(scReject, me, 0, nodata^) < rExecuted then497 assert(False);513 if Server(scReject, Me, 0, nodata^) < rExecuted then 514 Assert(False); 498 515 end; 499 516 scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak: 500 517 begin 501 518 OppoAction := Command; 502 if Command = scDipOffer then OppoOffer := TOffer(Data); 519 if Command = scDipOffer then 520 OppoOffer := TOffer(Data); 503 521 if Command = scDipStart then 504 522 MyLastAction := scContact … … 517 535 end; 518 536 DoNegotiation; 519 assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or537 Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or 520 538 (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) 522 541 else 523 Server(MyAction, me, 0, nodata^);542 Server(MyAction, Me, 0, nodata^); 524 543 end; 525 544 cShowEndContact: … … 546 565 547 566 procedure 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); 568 begin 569 end; 570 571 procedure TCustomAI.OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: Integer); 553 572 begin 554 573 end; … … 562 581 end; 563 582 564 function TCustomAI.ChooseResearchAdvance: integer;583 function TCustomAI.ChooseResearchAdvance: Integer; 565 584 begin 566 585 Result := -1; 567 586 end; 568 587 569 function TCustomAI.ChooseStealAdvance: integer;588 function TCustomAI.ChooseStealAdvance: Integer; 570 589 begin 571 590 Result := -1; 572 591 end; 573 592 574 function TCustomAI.ChooseGovernment: integer;593 function TCustomAI.ChooseGovernment: Integer; 575 594 begin 576 595 Result := gDespotism; 577 596 end; 578 597 579 function TCustomAI.WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean;598 function TCustomAI.WantNegotiation(Nation: Integer; NegoTime: TNegoTime): Boolean; 580 599 begin 581 600 Result := False; 582 601 end; 583 602 584 function TCustomAI.OnNegoRejected_CancelTreaty: boolean;603 function TCustomAI.OnNegoRejected_CancelTreaty: Boolean; 585 604 begin 586 605 Result := False; 587 606 end; 607 588 608 {$HINTS ON} 589 609 590 610 procedure TCustomAI.StealAdvance; 591 611 var 592 Steal, ad, Count: integer;612 Steal, ad, Count: Integer; 593 613 begin 594 614 Steal := ChooseStealAdvance; … … 596 616 begin // choose random advance 597 617 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 599 620 begin 600 621 Inc(Count); 601 if random(Count) = 0 then Steal := ad; 622 if Random(Count) = 0 then 623 Steal := ad; 602 624 end; 603 625 end; 604 if Steal >= 0 then Server(sStealTech, me, Steal, nodata^); 626 if Steal >= 0 then 627 Server(sStealTech, Me, Steal, nodata^); 605 628 RO.Happened := RO.Happened and not phStealTech; 606 629 end; 607 630 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 $fshl 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)^);631 function TCustomAI.IsResearched(Advance: Integer): Boolean; 632 begin 633 Result := (Advance = preNone) or (Advance <> preNA) and (RO.Tech[Advance] >= tsApplicable); 634 end; 635 636 function TCustomAI.ResearchCost: Integer; 637 begin 638 Server(sGetTechCost, Me, 0, Result); 639 end; 640 641 function TCustomAI.ChangeAttitude(Nation, Attitude: Integer): Integer; 642 begin 643 Result := Server(sSetAttitude + Nation shl 4, Me, Attitude, nodata^); 644 end; 645 646 function TCustomAI.Revolution: Integer; 647 begin 648 Result := Server(sRevolution, Me, 0, nodata^); 649 end; 650 651 function TCustomAI.ChangeRates(Tax, Lux: Integer): Integer; 652 begin 653 Result := Server(sSetRates, Me, Tax div 10 and $F + Lux div 10 and $F shl 4, nodata^); 654 end; 655 656 function TCustomAI.PrepareNewModel(Domain: Integer): Integer; 657 begin 658 Result := Server(sCreateDevModel, Me, Domain, nodata^); 659 end; 660 661 function TCustomAI.SetNewModelFeature(F, Count: Integer): Integer; 662 begin 663 Result := Server(sSetDevModelCap + Count shl 4, Me, F, nodata^); 664 end; 665 666 function TCustomAI.AdvanceResearchable(Advance: Integer): Boolean; 667 begin 668 Result := Server(sSetResearch - sExecute, Me, Advance, nodata^) >= rExecuted; 669 end; 670 671 function TCustomAI.AdvanceStealable(Advance: Integer): Boolean; 672 begin 673 Result := Server(sStealTech - sExecute, Me, Advance, nodata^) >= rExecuted; 674 end; 675 676 function TCustomAI.GetJobProgress(Loc: Integer; 677 var JobProgress: TJobProgressData): Boolean; 678 begin 679 Result := Server(sGetJobProgress, Me, Loc, JobProgress) >= rExecuted; 680 end; 681 682 function TCustomAI.DebugMessage(Level: Integer; Text: string): Boolean; 683 begin 684 Text := Copy('P' + Char(48 + Me) + ' ' + Text, 1, 254); 685 Server(sMessage, Me, Level, PChar(Text)^); 663 686 664 687 Result := True; … … 667 690 end; 668 691 669 function TCustomAI.SetDebugMap(var DebugMap): boolean;670 begin 671 Server(sSetDebugMap, me, 0, DebugMap);692 function TCustomAI.SetDebugMap(var DebugMap): Boolean; 693 begin 694 Server(sSetDebugMap, Me, 0, DebugMap); 672 695 673 696 Result := True; … … 676 699 end; 677 700 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); 701 procedure TCustomAI.Unit_FindMyDefender(Loc: Integer; var uix: Integer); 702 begin 703 if Server(sGetDefender, Me, Loc, uix) < rExecuted then 704 uix := -1; 705 end; 706 707 procedure TCustomAI.Unit_FindEnemyDefender(Loc: Integer; var euix: Integer); 684 708 begin 685 709 euix := RO.nEnemyUn - 1; … … 688 712 end; 689 713 690 function TCustomAI.Unit_Move(uix, ToLoc: integer): integer;691 var 692 Step: integer;693 DestinationReached: boolean;714 function TCustomAI.Unit_Move(uix, ToLoc: Integer): Integer; 715 var 716 Step: Integer; 717 DestinationReached: Boolean; 694 718 Advice: TMoveAdviceData; 695 719 begin 696 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit720 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit 697 721 {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) then722 Assert((A<>0) or (B<>0)); 723 if (A>=-1) and (A<=1) and (B>=-1) and (B<=1) then 700 724 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) 702 726 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; 705 729 Advice.MoreTurns:=0; 706 730 Advice.MaxHostile_MovementLeft:=MyUnit[uix].Movement; 707 result:=eOK;731 Result:=eOK; 708 732 end 709 733 else} … … 712 736 Advice.MoreTurns := 9999; 713 737 Advice.MaxHostile_MovementLeft := 100; 714 Result := Server(sGetMoveAdvice, me, uix, Advice);738 Result := Server(sGetMoveAdvice, Me, uix, Advice); 715 739 end; 716 740 if Result = eOk then … … 728 752 begin 729 753 DestinationReached := True; 730 break;754 Break; 731 755 end // stop next to destination 732 756 else if Step = Advice.nStep then … … 734 758 735 759 if (Step = Advice.nStep) or (Result <> eOK) and (Result <> eLoaded) then 736 break;760 Break; 737 761 738 762 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^); 740 764 Inc(Step); 741 if RO.Happened and phStealTech <> 0 then StealAdvance; 765 if RO.Happened and phStealTech <> 0 then 766 StealAdvance; 742 767 until False; 743 768 if DestinationReached then … … 751 776 end; 752 777 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 778 function TCustomAI.Unit_Step(uix, ToLoc: Integer): Integer; 779 var 780 A, B: Integer; 781 begin 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; 787 end; 788 789 function TCustomAI.Unit_Attack(uix, ToLoc: Integer): Integer; 790 var 791 A, B: Integer; 792 begin 793 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 768 794 and ((Map[ToLoc] and (fUnit or fOwned) = fUnit) // is an attack 769 795 or (Map[ToLoc] and (fCity or fOwned) = fCity) and 770 796 (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)); 773 799 // 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^); 801 end; 802 803 function TCustomAI.Unit_DoMission(uix, MissionType, ToLoc: Integer): Integer; 804 var 805 A, B: Integer; 806 begin 807 Result := Server(sSetSpyMission + MissionType shl 4, Me, 0, nodata^); 782 808 if Result >= rExecuted then 783 809 begin 784 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit810 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 785 811 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)); 788 814 // 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^); 790 816 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^) 792 818 else if (Result <> eNoTime_Move) and (Result <> eTreaty) and (Result <> eNoTurn) then 793 819 Result := eInvalid; // not a special commando mission! … … 795 821 end; 796 822 797 function TCustomAI.Unit_MoveForecast(uix, ToLoc: integer;798 var RemainingMovement: integer): boolean;823 function TCustomAI.Unit_MoveForecast(uix, ToLoc: Integer; 824 var RemainingMovement: Integer): Boolean; 799 825 var 800 826 Advice: TMoveAdviceData; 801 827 begin 802 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit828 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit 803 829 Advice.ToLoc := ToLoc; 804 830 Advice.MoreTurns := 0; 805 831 Advice.MaxHostile_MovementLeft := 100; 806 if Server(sGetMoveAdvice, me, uix, Advice) = eOk then832 if Server(sGetMoveAdvice, Me, uix, Advice) = eOk then 807 833 begin 808 834 RemainingMovement := Advice.MaxHostile_MovementLeft; … … 816 842 end; 817 843 818 function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: integer; 819 var RemainingHealth: integer): boolean; 844 // negative RemainingHealth is remaining helth of defender if lost 845 function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: Integer; 846 var RemainingHealth: Integer): Boolean; 820 847 var 821 848 BattleForecast: TBattleForecast; 822 849 begin 823 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit850 Assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 824 851 and (Map[ToLoc] and (fUnit or fOwned) = fUnit)); // is an attack 825 852 RemainingHealth := -$100; 826 853 Result := False; 827 if AttackMovement >= 0 then with MyUnit[uix] do 854 if AttackMovement >= 0 then 855 with MyUnit[uix] do 828 856 begin 829 BattleForecast.pAtt := me;857 BattleForecast.pAtt := Me; 830 858 BattleForecast.mixAtt := mix; 831 859 BattleForecast.HealthAtt := Health; … … 833 861 BattleForecast.FlagsAtt := Flags; 834 862 BattleForecast.Movement := AttackMovement; 835 if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then863 if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then 836 864 begin 837 865 if BattleForecast.EndHealthAtt > 0 then … … 844 872 end; 845 873 846 function TCustomAI.Unit_DefenseForecast(euix, ToLoc: integer;847 var RemainingHealth: integer): boolean;874 function TCustomAI.Unit_DefenseForecast(euix, ToLoc: Integer; 875 var RemainingHealth: Integer): Boolean; 848 876 var 849 877 BattleForecast: TBattleForecast; 850 878 begin 851 assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit879 Assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit 852 880 and (Map[ToLoc] and (fUnit or fOwned) = (fUnit or fOwned))); // is an attack 853 881 RemainingHealth := $100; … … 861 889 BattleForecast.FlagsAtt := Flags; 862 890 BattleForecast.Movement := 100; 863 if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then891 if Server(sGetBattleForecast, Me, ToLoc, BattleForecast) >= rExecuted then 864 892 begin 865 893 if BattleForecast.EndHealthDef > 0 then … … 872 900 end; 873 901 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);902 function TCustomAI.Unit_Disband(uix: Integer): Integer; 903 begin 904 Result := Server(sRemoveUnit, Me, uix, nodata^); 905 end; 906 907 function TCustomAI.Unit_StartJob(uix, NewJob: Integer): Integer; 908 begin 909 Result := Server(sStartJob + NewJob shl 4, Me, uix, nodata^); 910 end; 911 912 function TCustomAI.Unit_SetHomeHere(uix: Integer): Integer; 913 begin 914 Result := Server(sSetUnitHome, Me, uix, nodata^); 915 end; 916 917 function TCustomAI.Unit_Load(uix: Integer): Integer; 918 begin 919 Result := Server(sLoadUnit, Me, uix, nodata^); 920 end; 921 922 function TCustomAI.Unit_Unload(uix: Integer): Integer; 923 begin 924 Result := Server(sUnloadUnit, Me, uix, nodata^); 925 end; 926 927 function TCustomAI.Unit_AddToCity(uix: Integer): Integer; 928 begin 929 Result := Server(sAddToCity, Me, uix, nodata^); 930 end; 931 932 function TCustomAI.Unit_SelectTransport(uix: Integer): Integer; 933 begin 934 Result := Server(sSelectTransport, Me, uix, nodata^); 935 end; 936 937 938 procedure TCustomAI.City_FindMyCity(Loc: Integer; var cix: Integer); 911 939 begin 912 940 if Map[Loc] and (fCity or fOwned) <> fCity or fOwned then … … 920 948 end; 921 949 922 procedure TCustomAI.City_FindEnemyCity(Loc: integer; var ecix: integer);950 procedure TCustomAI.City_FindEnemyCity(Loc: Integer; var ecix: Integer); 923 951 begin 924 952 if Map[Loc] and (fCity or fOwned) <> fCity then … … 932 960 end; 933 961 934 function TCustomAI.City_HasProject(cix: integer): boolean;962 function TCustomAI.City_HasProject(cix: Integer): Boolean; 935 963 begin 936 964 Result := MyCity[cix].Project and (cpImp + cpIndex) <> cpImp + imTrGoods; 937 965 end; 938 966 939 function TCustomAI.City_CurrentImprovementProject(cix: integer): integer; 940 begin 941 if MyCity[cix].Project and cpImp = 0 then Result := -1 967 function TCustomAI.City_CurrentImprovementProject(cix: Integer): Integer; 968 begin 969 if MyCity[cix].Project and cpImp = 0 then 970 Result := -1 942 971 else 943 972 begin 944 973 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; 977 end; 978 979 function TCustomAI.City_CurrentUnitProject(cix: Integer): Integer; 980 begin 981 if MyCity[cix].Project and cpImp <> 0 then 982 Result := -1 952 983 else 953 984 Result := MyCity[cix].Project and cpIndex; 954 985 end; 955 986 956 function TCustomAI.City_GetTileInfo(cix, TileLoc: integer;957 var TileInfo: TTileInfo): integer;987 function TCustomAI.City_GetTileInfo(cix, TileLoc: Integer; 988 var TileInfo: TTileInfo): Integer; 958 989 begin 959 990 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); 992 end; 993 994 function TCustomAI.City_GetReport(cix: Integer; var Report: TCityReport): Integer; 964 995 begin 965 996 Report.HypoTiles := -1; 966 997 Report.HypoTax := -1; 967 998 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); 1000 end; 1001 1002 function TCustomAI.City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: Integer; 1003 var Report: TCityReport): Integer; 973 1004 begin 974 1005 Report.HypoTiles := HypoTiles; 975 1006 Report.HypoTax := HypoTax; 976 1007 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); 1009 end; 1010 1011 function TCustomAI.City_GetReportNew(cix: Integer; var Report: TCityReportNew): Integer; 981 1012 begin 982 1013 Report.HypoTiles := -1; 983 1014 Report.HypoTaxRate := -1; 984 1015 Report.HypoLuxuryRate := -1; 985 Result := Server(sGetCityReportNew, me, cix, Report);1016 Result := Server(sGetCityReportNew, Me, cix, Report); 986 1017 end; 987 1018 988 1019 function TCustomAI.City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, 989 HypoLuxuryRate: integer; var Report: TCityReportNew): integer;1020 HypoLuxuryRate: Integer; var Report: TCityReportNew): Integer; 990 1021 begin 991 1022 Report.HypoTiles := HypoTiles; 992 1023 Report.HypoTaxRate := HypoTaxRate; 993 1024 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); 1026 end; 1027 1028 function TCustomAI.City_GetAreaInfo(cix: Integer; var AreaInfo: TCityAreaInfo): Integer; 1029 begin 1030 Result := Server(sGetCityAreaInfo, Me, cix, AreaInfo); 1031 end; 1032 1033 function TCustomAI.City_StartUnitProduction(cix, mix: Integer): Integer; 1034 begin 1035 if (MyCity[cix].Project and (cpImp + cpIndex) <> mix) then 1036 // not already producing that 1037 Result := Server(sSetCityProject, Me, cix, mix); 1038 end; 1039 1040 function TCustomAI.City_StartEmigration(cix, mix: Integer; 1041 AllowDisbandCity, AsConscripts: Boolean): Integer; 1042 var 1043 NewProject: Integer; 1011 1044 begin 1012 1045 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); 1051 end; 1052 1053 function TCustomAI.City_StartImprovement(cix, iix: Integer): Integer; 1054 var 1055 NewProject: Integer; 1021 1056 begin 1022 1057 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); 1061 end; 1062 1063 function TCustomAI.City_Improvable(cix, iix: Integer): Boolean; 1064 var 1065 NewProject: Integer; 1029 1066 begin 1030 1067 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; 1069 end; 1070 1071 function TCustomAI.City_StopProduction(cix: Integer): Integer; 1072 var 1073 NewProject: Integer; 1037 1074 begin 1038 1075 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); 1077 end; 1078 1079 function TCustomAI.City_BuyProject(cix: Integer): Integer; 1080 begin 1081 Result := Server(sBuyCityProject, Me, cix, nodata^); 1082 end; 1083 1084 function TCustomAI.City_SellImprovement(cix, iix: Integer): Integer; 1085 begin 1086 Result := Server(sSellCityImprovement, Me, cix, iix); 1087 end; 1088 1089 function TCustomAI.City_RebuildImprovement(cix, iix: Integer): Integer; 1090 begin 1091 Result := Server(sRebuildCityImprovement, Me, cix, iix); 1092 end; 1093 1094 function TCustomAI.City_SetTiles(cix, NewTiles: Integer): Integer; 1095 begin 1096 Result := Server(sSetCityTiles, Me, cix, NewTiles); 1097 end; 1098 1099 procedure TCustomAI.City_OptimizeTiles(cix: Integer; ResourceWeights: Cardinal); 1063 1100 var 1064 1101 Advice: TCityTileAdviceData; 1065 1102 begin 1066 1103 Advice.ResourceWeights := ResourceWeights; 1067 Server(sGetCityTileAdvice, me, cix, Advice);1104 Server(sGetCityTileAdvice, Me, cix, Advice); 1068 1105 City_SetTiles(cix, Advice.Tiles); 1069 1106 end; 1070 1107 1071 1072 1108 // negotiation 1073 function TCustomAI.Nego_CheckMyAction: integer;1074 begin 1075 assert(Opponent >= 0); // only allowed in negotiation mode1076 assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or1109 function TCustomAI.Nego_CheckMyAction: Integer; 1110 begin 1111 Assert(Opponent >= 0); // only allowed in negotiation mode 1112 Assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or 1077 1113 (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) 1079 1116 else 1080 Result := Server(MyAction - sExecute, me, 0, nodata^); 1081 end; 1082 1117 Result := Server(MyAction - sExecute, Me, 0, nodata^); 1118 end; 1083 1119 1084 1120 initialization 1085 nodata := pointer(0);1121 nodata := Pointer(0); 1086 1122 RWDataSize := 0; 1087 1123
Note:
See TracChangeset
for help on using the changeset viewer.