Changeset 303 for branches/highdpi/AI/StdAI/CustomAI.pas
- Timestamp:
- Mar 9, 2021, 9:19:49 AM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/highdpi/AI/StdAI/CustomAI.pas
r210 r303 9 9 10 10 type 11 TNegoTime=(BeginOfTurn, EndOfTurn, EnemyCalled); 12 13 TCustomAI=class 14 public 15 procedure Process(Command: integer; var Data); 16 17 // overridables 18 constructor Create(Nation: integer); virtual; 19 destructor Destroy; override; 20 procedure SetDataDefaults; virtual; 21 procedure SetDataRandom; virtual; 22 procedure OnBeforeEnemyAttack(UnitInfo: TUnitInfo; 23 ToLoc, EndHealth, EndHealthDef: integer); virtual; 24 procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer); virtual; 25 procedure OnAfterEnemyAttack; virtual; 26 procedure OnAfterEnemyCapture; virtual; 27 28 protected 29 me: integer; // index of the controlled nation 30 RO: ^TPlayerContext; 31 Map: ^TTileList; 32 MyUnit: ^TUnList; 33 MyCity: ^TCityList; 34 MyModel: ^TModelList; 35 36 cixStateImp: array[imPalace..imSpacePort] of integer; 37 38 // negotiation 39 Opponent: integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode 40 MyAction, MyLastAction, OppoAction: integer; 41 MyOffer, MyLastOffer, OppoOffer: TOffer; 42 43 // overridables 44 procedure DoTurn; virtual; 45 procedure DoNegotiation; virtual; 46 function ChooseResearchAdvance: integer; virtual; 47 function ChooseStealAdvance: integer; virtual; 48 function ChooseGovernment: integer; virtual; 49 function WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean; virtual; 50 function OnNegoRejected_CancelTreaty: boolean; virtual; 51 52 // general functions 53 function IsResearched(Advance: integer): boolean; 54 function ResearchCost: integer; 55 function ChangeAttitude(Nation, Attitude: integer): integer; 56 function Revolution: integer; 57 function ChangeRates(Tax,Lux: integer): integer; 58 function PrepareNewModel(Domain: integer): integer; 59 function SetNewModelFeature(F, Count: integer): integer; 60 function AdvanceResearchable(Advance: integer): boolean; 61 function AdvanceStealable(Advance: integer): boolean; 62 function GetJobProgress(Loc: integer; var JobProgress: TJobProgressData): boolean; 63 function DebugMessage(Level: integer; Text: string): boolean; 64 function SetDebugMap(var DebugMap): boolean; 65 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; var RemainingMovement: integer): boolean; 74 function Unit_AttackForecast(uix,ToLoc,AttackMovement: integer; var RemainingHealth: integer): boolean; 75 function Unit_DefenseForecast(euix,ToLoc: integer; var RemainingHealth: integer): boolean; 76 function Unit_Disband(uix: integer): integer; 77 function Unit_StartJob(uix,NewJob: integer): integer; 78 function Unit_SetHomeHere(uix: integer): integer; 79 function Unit_Load(uix: integer): integer; 80 function Unit_Unload(uix: integer): integer; 81 function Unit_SelectTransport(uix: integer): integer; 82 function Unit_AddToCity(uix: integer): integer; 83 84 // city functions 85 procedure City_FindMyCity(Loc: integer; var cix: integer); 86 procedure City_FindEnemyCity(Loc: integer; var ecix: integer); 87 function City_HasProject(cix: integer): boolean; 88 function City_CurrentImprovementProject(cix: integer): integer; 89 function City_CurrentUnitProject(cix: integer): integer; 90 function City_GetTileInfo(cix,TileLoc: integer; var TileInfo: TTileInfo): integer; 91 function City_GetReport(cix: integer; var Report: TCityReport): integer; 92 function City_GetHypoReport(cix, HypoTiles, HypoTax, HypoLux: integer; var Report: TCityReport): integer; 93 function City_GetReportNew(cix: integer; var Report: TCityReportNew): integer; 94 function City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, HypoLuxuryRate: integer; var Report: TCityReportNew): integer; 95 function City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer; 96 function City_StartUnitProduction(cix,mix: integer): integer; 97 function City_StartEmigration(cix,mix: integer; AllowDisbandCity, AsConscripts: boolean): integer; 98 function City_StartImprovement(cix,iix: integer): integer; 99 function City_Improvable(cix,iix: integer): boolean; 100 function City_StopProduction(cix: integer): integer; 101 function City_BuyProject(cix: integer): integer; 102 function City_SellImprovement(cix,iix: integer): integer; 103 function City_RebuildImprovement(cix,iix: integer): integer; 104 function City_SetTiles(cix,NewTiles: integer): integer; 105 procedure City_OptimizeTiles(cix: integer; ResourceWeights: cardinal = rwMaxGrowth); 106 107 // negotiation 108 function Nego_CheckMyAction: integer; 109 110 private 111 HaveTurned: boolean; 112 UnwantedNego: set of 0..nPl-1; 113 Contacted: set of 0..nPl-1; 114 procedure StealAdvance; 115 end; 116 117 118 var 119 Server: TServerCall; 120 G: TNewGameData; 121 RWDataSize, MapSize: integer; 122 decompose24: cardinal; 123 nodata: pointer; 11 TNegoTime = (BeginOfTurn, EndOfTurn, EnemyCalled); 12 13 TCustomAI = class 14 public 15 procedure Process(Command: integer; var Data); 16 17 // overridables 18 constructor Create(Nation: integer); virtual; 19 destructor Destroy; override; 20 procedure SetDataDefaults; virtual; 21 procedure SetDataRandom; virtual; 22 procedure OnBeforeEnemyAttack(UnitInfo: TUnitInfo; 23 ToLoc, EndHealth, EndHealthDef: integer); virtual; 24 procedure OnBeforeEnemyCapture(UnitInfo: TUnitInfo; ToLoc: integer); virtual; 25 procedure OnAfterEnemyAttack; virtual; 26 procedure OnAfterEnemyCapture; virtual; 27 28 protected 29 me: integer; // index of the controlled nation 30 RO: ^TPlayerContext; 31 Map: ^TTileList; 32 MyUnit: ^TUnList; 33 MyCity: ^TCityList; 34 MyModel: ^TModelList; 35 36 cixStateImp: array[imPalace..imSpacePort] of integer; 37 38 // negotiation 39 Opponent: integer; // nation i'm in negotiation with, -1 indicates no-negotiation mode 40 MyAction, MyLastAction, OppoAction: integer; 41 MyOffer, MyLastOffer, OppoOffer: TOffer; 42 43 // overridables 44 procedure DoTurn; virtual; 45 procedure DoNegotiation; virtual; 46 function ChooseResearchAdvance: integer; virtual; 47 function ChooseStealAdvance: integer; virtual; 48 function ChooseGovernment: integer; virtual; 49 function WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean; virtual; 50 function OnNegoRejected_CancelTreaty: boolean; virtual; 51 52 // general functions 53 function IsResearched(Advance: integer): boolean; 54 function ResearchCost: integer; 55 function ChangeAttitude(Nation, Attitude: integer): integer; 56 function Revolution: integer; 57 function ChangeRates(Tax, Lux: integer): integer; 58 function PrepareNewModel(Domain: integer): integer; 59 function SetNewModelFeature(F, Count: integer): integer; 60 function AdvanceResearchable(Advance: integer): boolean; 61 function AdvanceStealable(Advance: integer): boolean; 62 function GetJobProgress(Loc: integer; var JobProgress: TJobProgressData): boolean; 63 function DebugMessage(Level: integer; Text: string): boolean; 64 function SetDebugMap(var DebugMap): boolean; 65 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; 86 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: cardinal = rwMaxGrowth); 112 113 // negotiation 114 function Nego_CheckMyAction: integer; 115 116 private 117 HaveTurned: boolean; 118 UnwantedNego: set of 0..nPl - 1; 119 Contacted: set of 0..nPl - 1; 120 procedure StealAdvance; 121 end; 122 123 124 var 125 Server: TServerCall; 126 G: TNewGameData; 127 RWDataSize, MapSize: integer; 128 decompose24: cardinal; 129 nodata: pointer; 124 130 125 131 const 126 CityOwnTile = 13; // = ab_to_V21(0,0) 127 128 // additional return codes 129 rLocationReached= $00010000; // Unit_Move: move was not interrupted, location reached 130 rMoreTurns= $00020000; // Unit_Move: move was not interrupted, location not reached yet 132 CityOwnTile = 13; // = ab_to_V21(0,0) 133 134 // additional return codes 135 rLocationReached = $00010000; 136 // Unit_Move: move was not interrupted, location reached 137 rMoreTurns = $00020000; 138 // Unit_Move: move was not interrupted, location not reached yet 131 139 132 140 type 133 TVicinity8Loc=array[0..7] of integer;134 TVicinity21Loc=array[0..27] of integer;141 TVicinity8Loc = array[0..7] of integer; 142 TVicinity21Loc = array[0..27] of integer; 135 143 136 144 137 145 procedure Init(NewGameData: TNewGameData); 138 146 139 procedure ab_to_Loc(Loc0, a,b: integer; var Loc: integer);140 procedure Loc_to_ab(Loc0, Loc: integer; var a,b: integer);141 procedure ab_to_V8(a, b: integer; var V8: integer);142 procedure V8_to_ab(V8: integer; var a, b: integer);143 procedure ab_to_V21(a, b: integer; var V21: integer);144 procedure V21_to_ab(V21: integer; var a, b: integer);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); 145 153 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc); 146 154 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc); 147 function Distance(Loc0, Loc1: integer): integer;155 function Distance(Loc0, Loc1: integer): integer; 148 156 149 157 … … 151 159 152 160 const 153 ab_v8: array[-4..4] of integer = (5,6,7,4,-1,0,3,2,1);154 v8_a: array[0..7] of integer = (1,1,0,-1,-1,-1,0,1);155 v8_b: array[0..7] of integer = (0,1,1,1,0,-1,-1,-1);156 157 158 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); 159 167 {relative location from Loc0} 160 168 var 161 y0: integer; 162 begin 163 assert((Loc0>=0) and (Loc0<MapSize) and (a-b+G.lx>=0)); 164 y0:=cardinal(Loc0)*decompose24 shr 24; 165 Loc:=(Loc0+(a-b+y0 and 1+G.lx+G.lx) shr 1) mod G.lx +G.lx*(y0+a+b); 166 if Loc>=MapSize then Loc:=-$1000 167 end; 168 169 procedure Loc_to_ab(Loc0,Loc: integer; var a,b: integer); 170 {$IFDEF FPC} // freepascal 171 var 172 dx,dy: integer; 173 begin 174 dx:=((Loc mod G.lx *2 +Loc div G.lx and 1) 175 -(Loc0 mod G.lx *2 +Loc0 div G.lx and 1)+3*G.lx) mod (2*G.lx) -G.lx; 176 dy:=Loc div G.lx-Loc0 div G.lx; 177 a:=(dx+dy) div 2; 178 b:=(dy-dx) div 2; 179 end; 180 {$ELSE} // delphi 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; 185 dy := Loc div G.lx - Loc0 div G.lx; 186 a := (dx + dy) div 2; 187 b := (dy - dx) div 2; 188 end; 189 190 {$ELSE}// delphi 181 191 register; 182 192 asm … … 234 244 {$ENDIF} 235 245 236 procedure ab_to_V8(a,b: integer; var V8: integer); 237 begin 238 assert((abs(a)<=1) and (abs(b)<=1) and ((a<>0) or (b<>0))); 239 V8:=ab_v8[2*b+b+a]; 240 end; 241 242 procedure V8_to_ab(V8: integer; var a,b: integer); 243 begin 244 a:=v8_a[V8]; b:=V8_b[V8]; 245 end; 246 247 procedure ab_to_V21(a,b: integer; var V21: integer); 248 begin 249 V21:=(a+b+3) shl 2+(a-b+3) shr 1; 250 end; 251 252 procedure V21_to_ab(V21: integer; var a,b: integer); 253 var 254 dx,dy: integer; 255 begin 256 dy:=V21 shr 2-3; 257 dx:=V21 and 3 shl 1 -3 + (dy+3) and 1; 258 a:=(dx+dy) div 2; 259 b:=(dy-dx) div 2; 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; 266 begin 267 dy := V21 shr 2 - 3; 268 dx := V21 and 3 shl 1 - 3 + (dy + 3) and 1; 269 a := (dx + dy) div 2; 270 b := (dy - dx) div 2; 260 271 end; 261 272 262 273 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc); 263 274 var 264 x0,y0,lx: integer;265 begin 266 lx:=G.lx;267 y0:=cardinal(Loc0)*decompose24 shr 24;268 x0:=Loc0-y0*lx; // Loc0 mod lx;269 VicinityLoc[1]:=Loc0+lx*2;270 VicinityLoc[3]:=Loc0-1;271 VicinityLoc[5]:=Loc0-lx*2;272 VicinityLoc[7]:=Loc0+1;273 inc(Loc0,y0 and 1);274 VicinityLoc[0]:=Loc0+lx;275 VicinityLoc[2]:=Loc0+lx-1;276 VicinityLoc[4]:=Loc0-lx-1;277 VicinityLoc[6]:=Loc0-lx;278 279 // world is round!280 if x0<lx-1 then275 x0, y0, lx: integer; 276 begin 277 lx := G.lx; 278 y0 := cardinal(Loc0) * decompose24 shr 24; 279 x0 := Loc0 - y0 * lx; // Loc0 mod lx; 280 VicinityLoc[1] := Loc0 + lx * 2; 281 VicinityLoc[3] := Loc0 - 1; 282 VicinityLoc[5] := Loc0 - lx * 2; 283 VicinityLoc[7] := Loc0 + 1; 284 Inc(Loc0, y0 and 1); 285 VicinityLoc[0] := Loc0 + lx; 286 VicinityLoc[2] := Loc0 + lx - 1; 287 VicinityLoc[4] := Loc0 - lx - 1; 288 VicinityLoc[6] := Loc0 - lx; 289 290 // world is round! 291 if x0 < lx - 1 then 281 292 begin 282 if x0=0 then293 if x0 = 0 then 283 294 begin 284 inc(VicinityLoc[3],lx);285 if y0 and 1=0 then295 Inc(VicinityLoc[3], lx); 296 if y0 and 1 = 0 then 286 297 begin 287 inc(VicinityLoc[2],lx); 288 inc(VicinityLoc[4],lx); 298 Inc(VicinityLoc[2], lx); 299 Inc(VicinityLoc[4], lx); 300 end; 301 end; 302 end 303 else 304 begin 305 Dec(VicinityLoc[7], lx); 306 if y0 and 1 = 1 then 307 begin 308 Dec(VicinityLoc[0], lx); 309 Dec(VicinityLoc[6], lx); 310 end; 311 end; 312 313 // check south pole 314 case G.ly - y0 of 315 1: 316 begin 317 VicinityLoc[0] := -$1000; 318 VicinityLoc[1] := -$1000; 319 VicinityLoc[2] := -$1000; 320 end; 321 2: VicinityLoc[1] := -$1000; 322 end; 323 end; 324 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; 331 xComp0 := Loc0 - y0 * G.lx - 1; // Loc0 mod G.lx -1 332 xCompSwitch := xComp0 - 1 + y0 and 1; 333 if xComp0 < 0 then 334 Inc(xComp0, G.lx); 335 if xCompSwitch < 0 then 336 Inc(xCompSwitch, G.lx); 337 xCompSwitch := xCompSwitch xor xComp0; 338 yComp := G.lx * (y0 - 3); 339 dst := @VicinityLoc; 340 bit := 1; 341 for dy := 0 to 6 do 342 if yComp < MapSize then 343 begin 344 xComp0 := xComp0 xor xCompSwitch; 345 xComp := xComp0; 346 for dx := 0 to 3 do 347 begin 348 if bit and $67F7F76 <> 0 then 349 dst^ := xComp + yComp 350 else 351 dst^ := -1; 352 Inc(xComp); 353 if xComp >= G.lx then 354 Dec(xComp, G.lx); 355 Inc(dst); 356 bit := bit shl 1; 357 end; 358 Inc(yComp, G.lx); 359 end 360 else 361 begin 362 for dx := 0 to 3 do 363 begin 364 dst^ := -$1000; 365 Inc(dst); 366 end; 367 end; 368 end; 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; 379 380 381 procedure Init(NewGameData: TNewGameData); 382 {$IFDEF DEBUG}var 383 Loc: integer; 384 {$ENDIF} 385 begin 386 G := NewGameData; 387 MapSize := G.lx * G.ly; 388 decompose24 := (1 shl 24 - 1) div G.lx + 1; 389 {$IFDEF DEBUG} 390 for Loc := 0 to MapSize - 1 do 391 assert(cardinal(Loc) * decompose24 shr 24 = cardinal(Loc div G.lx)); 392 {$ENDIF} 393 end; 394 395 396 constructor TCustomAI.Create(Nation: integer); 397 begin 398 inherited Create; 399 me := Nation; 400 RO := pointer(G.RO[Nation]); 401 Map := pointer(RO.Map); 402 MyUnit := pointer(RO.Un); 403 MyCity := pointer(RO.City); 404 MyModel := pointer(RO.Model); 405 Opponent := -1; 406 end; 407 408 destructor TCustomAI.Destroy; 409 begin 410 Server(sSetDebugMap, me, 0, nodata^); 411 end; 412 413 414 procedure TCustomAI.Process(Command: integer; var Data); 415 var 416 Nation, NewResearch, NewGov, Count, ad, cix, iix: integer; 417 NegoTime: TNegoTime; 418 begin 419 case Command of 420 cTurn, cContinue: 421 begin 422 if RO.Alive and (1 shl me) = 0 then 423 begin // I'm dead, huhu 424 Server(sTurn, me, 0, nodata^); 425 exit; 426 end; 427 if Command = cTurn then 428 begin 429 fillchar(cixStateImp, sizeof(cixStateImp), $FF); 430 for cix := 0 to RO.nCity - 1 do 431 if MyCity[cix].Loc >= 0 then 432 for iix := imPalace to imSpacePort do 433 if MyCity[cix].Built[iix] > 0 then 434 cixStateImp[iix] := cix; 435 if RO.Happened and phChangeGov <> 0 then 436 begin 437 NewGov := ChooseGovernment; 438 if NewGov > gAnarchy then 439 Server(sSetGovernment, me, NewGov, nodata^); 440 end; 441 HaveTurned := False; 442 Contacted := []; 443 end; 444 if (Command = cContinue) and (MyAction = scContact) then 445 begin 446 if OnNegoRejected_CancelTreaty then 447 if RO.Treaty[Opponent] >= trPeace then 448 if Server(sCancelTreaty, me, 0, nodata^) < rExecuted then 449 assert(False); 289 450 end 290 end 291 end 292 else 293 begin 294 dec(VicinityLoc[7],lx); 295 if y0 and 1=1 then 451 else 452 UnwantedNego := []; 453 Opponent := -1; 454 repeat 455 if HaveTurned then 456 NegoTime := EndOfTurn 457 else 458 NegoTime := BeginOfTurn; 459 if RO.Government <> gAnarchy then 460 for Nation := 0 to nPl - 1 do 461 if (Nation <> me) and (1 shl Nation and RO.Alive <> 0) and 462 (RO.Treaty[Nation] >= trNone) and not (Nation in Contacted) and not 463 (Nation in UnwantedNego) and 464 (Server(scContact - sExecute + Nation shl 4, me, 0, nodata^) >= rExecuted) then 465 if WantNegotiation(Nation, NegoTime) then 466 begin 467 if Server(scContact + Nation shl 4, me, 0, nodata^) >= rExecuted then 468 begin 469 include(Contacted, Nation); 470 Opponent := Nation; 471 MyAction := scContact; 472 exit; 473 end; 474 end 475 else 476 include(UnwantedNego, Nation); 477 if NegoTime = BeginOfTurn then 478 begin 479 DoTurn; 480 HaveTurned := True; 481 Contacted := []; 482 UnwantedNego := []; 483 end 484 else 485 break; 486 until False; 487 if RO.Happened and phTech <> 0 then 488 begin 489 NewResearch := ChooseResearchAdvance; 490 if NewResearch < 0 then 491 begin // choose random research 492 Count := 0; 493 for ad := 0 to nAdv - 1 do 494 if AdvanceResearchable(ad) then 495 begin 496 Inc(Count); 497 if random(Count) = 0 then 498 NewResearch := ad; 499 end; 500 end; 501 Server(sSetResearch, me, NewResearch, nodata^); 502 end; 503 if Server(sTurn, me, 0, nodata^) < rExecuted then 504 assert(False); 505 end; 506 scContact: 507 if WantNegotiation(integer(Data), EnemyCalled) then 508 begin 509 if Server(scDipStart, me, 0, nodata^) < rExecuted then 510 assert(False); 511 Opponent := integer(Data); 512 MyAction := scDipStart; 513 end 514 else 515 begin 516 if Server(scReject, me, 0, nodata^) < rExecuted then 517 assert(False); 518 end; 519 scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak: 296 520 begin 297 dec(VicinityLoc[0],lx); 298 dec(VicinityLoc[6],lx); 299 end 300 end; 301 302 // check south pole 303 case G.ly-y0 of 304 1: 305 begin 306 VicinityLoc[0]:=-$1000; 307 VicinityLoc[1]:=-$1000; 308 VicinityLoc[2]:=-$1000; 521 OppoAction := Command; 522 if Command = scDipOffer then 523 OppoOffer := TOffer(Data); 524 if Command = scDipStart then 525 MyLastAction := scContact 526 else 527 begin 528 MyLastAction := MyAction; 529 MyLastOffer := MyOffer; 530 end; 531 if (OppoAction = scDipCancelTreaty) or (OppoAction = scDipBreak) then 532 MyAction := scDipNotice 533 else 534 begin 535 MyAction := scDipOffer; 536 MyOffer.nDeliver := 0; 537 MyOffer.nCost := 0; 538 end; 539 DoNegotiation; 540 assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or 541 (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak)); 542 if MyAction = scDipOffer then 543 Server(MyAction, me, 0, MyOffer) 544 else 545 Server(MyAction, me, 0, nodata^); 309 546 end; 310 2: VicinityLoc[1]:=-$1000; 311 end 312 end; 313 314 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc); 315 var 316 dx,dy,bit,y0,xComp,yComp,xComp0,xCompSwitch: integer; 317 dst: ^integer; 318 begin 319 y0:=cardinal(Loc0)*decompose24 shr 24; 320 xComp0:=Loc0-y0*G.lx-1; // Loc0 mod G.lx -1 321 xCompSwitch:=xComp0-1+y0 and 1; 322 if xComp0<0 then inc(xComp0,G.lx); 323 if xCompSwitch<0 then inc(xCompSwitch,G.lx); 324 xCompSwitch:=xCompSwitch xor xComp0; 325 yComp:=G.lx*(y0-3); 326 dst:=@VicinityLoc; 327 bit:=1; 328 for dy:=0 to 6 do 329 if yComp<MapSize then 330 begin 331 xComp0:=xComp0 xor xCompSwitch; 332 xComp:=xComp0; 333 for dx:=0 to 3 do 334 begin 335 if bit and $67F7F76<>0 then dst^:=xComp+yComp 336 else dst^:=-1; 337 inc(xComp); 338 if xComp>=G.lx then dec(xComp, G.lx); 339 inc(dst); 340 bit:=bit shl 1; 341 end; 342 inc(yComp,G.lx); 343 end 344 else 345 begin 346 for dx:=0 to 3 do 347 begin dst^:=-$1000; inc(dst); end; 348 end 349 end; 350 351 function Distance(Loc0,Loc1: integer): integer; 352 var 353 a,b,dx,dy: integer; 354 begin 355 Loc_to_ab(Loc0,Loc1,a,b); 356 dx:=abs(a-b); 357 dy:=abs(a+b); 358 result:=dx+dy+abs(dx-dy) shr 1; 359 end; 360 361 362 procedure Init(NewGameData: TNewGameData); 363 {$IFDEF DEBUG}var Loc: integer;{$ENDIF} 364 begin 365 G:=NewGameData; 366 MapSize:=G.lx*G.ly; 367 decompose24:=(1 shl 24-1) div G.lx +1; 368 {$IFDEF DEBUG}for Loc:=0 to MapSize-1 do assert(cardinal(Loc)*decompose24 shr 24=cardinal(Loc div G.lx));{$ENDIF} 369 end; 370 371 372 constructor TCustomAI.Create(Nation: integer); 373 begin 374 inherited Create; 375 me:=Nation; 376 RO:=pointer(G.RO[Nation]); 377 Map:=pointer(RO.Map); 378 MyUnit:=pointer(RO.Un); 379 MyCity:=pointer(RO.City); 380 MyModel:=pointer(RO.Model); 381 Opponent:=-1; 382 end; 383 384 destructor TCustomAI.Destroy; 385 begin 386 Server(sSetDebugMap,me,0,nodata^); 387 end; 388 389 390 procedure TCustomAI.Process(Command: integer; var Data); 391 var 392 Nation,NewResearch,NewGov,count,ad,cix,iix: integer; 393 NegoTime: TNegoTime; 394 begin 395 case Command of 396 cTurn, cContinue: 397 begin 398 if RO.Alive and (1 shl me)=0 then 399 begin // I'm dead, huhu 400 Server(sTurn,me,0,nodata^); 401 exit 402 end; 403 if Command=cTurn then 404 begin 405 fillchar(cixStateImp, sizeof(cixStateImp), $FF); 406 for cix:=0 to RO.nCity-1 do if MyCity[cix].Loc>=0 then 407 for iix:=imPalace to imSpacePort do 408 if MyCity[cix].Built[iix]>0 then 409 cixStateImp[iix]:=cix; 410 if RO.Happened and phChangeGov<>0 then 411 begin 412 NewGov:=ChooseGovernment; 413 if NewGov>gAnarchy then 414 Server(sSetGovernment,me,NewGov,nodata^); 415 end; 416 HaveTurned:=false; 417 Contacted:=[]; 418 end; 419 if (Command=cContinue) and (MyAction=scContact) then 420 begin 421 if OnNegoRejected_CancelTreaty then 422 if RO.Treaty[Opponent]>=trPeace then 423 if Server(sCancelTreaty,me,0,nodata^)<rExecuted then 424 assert(false) 425 end 426 else UnwantedNego:=[]; 427 Opponent:=-1; 428 repeat 429 if HaveTurned then NegoTime:=EndOfTurn 430 else NegoTime:=BeginOfTurn; 431 if RO.Government<>gAnarchy then 432 for Nation:=0 to nPl-1 do 433 if (Nation<>me) and (1 shl Nation and RO.Alive<>0) 434 and (RO.Treaty[Nation]>=trNone) 435 and not (Nation in Contacted) and not (Nation in UnwantedNego) 436 and (Server(scContact-sExecute + Nation shl 4, me, 0, nodata^)>=rExecuted) then 437 if WantNegotiation(Nation, NegoTime) then 438 begin 439 if Server(scContact + Nation shl 4, me, 0, nodata^)>=rExecuted then 440 begin 441 include(Contacted, Nation); 442 Opponent:=Nation; 443 MyAction:=scContact; 444 exit; 445 end; 446 end 447 else include(UnwantedNego,Nation); 448 if NegoTime=BeginOfTurn then 449 begin 450 DoTurn; 451 HaveTurned:=true; 452 Contacted:=[]; 453 UnwantedNego:=[]; 454 end 455 else break; 456 until false; 457 if RO.Happened and phTech<>0 then 458 begin 459 NewResearch:=ChooseResearchAdvance; 460 if NewResearch<0 then 461 begin // choose random research 462 count:=0; 463 for ad:=0 to nAdv-1 do if AdvanceResearchable(ad) then 464 begin inc(count); if random(count)=0 then NewResearch:=ad end 465 end; 466 Server(sSetResearch,me,NewResearch,nodata^) 467 end; 468 if Server(sTurn,me,0,nodata^)<rExecuted then 469 assert(false); 470 end; 471 scContact: 472 if WantNegotiation(integer(Data), EnemyCalled) then 473 begin 474 if Server(scDipStart, me, 0, nodata^)<rExecuted then 475 assert(false); 476 Opponent:=integer(Data); 477 MyAction:=scDipStart; 478 end 479 else 480 begin 481 if Server(scReject, me, 0, nodata^)<rExecuted then 482 assert(false); 483 end; 484 scDipStart, scDipNotice, scDipAccept, scDipCancelTreaty, scDipOffer, scDipBreak: 485 begin 486 OppoAction:=Command; 487 if Command=scDipOffer then OppoOffer:=TOffer(Data); 488 if Command=scDipStart then 489 MyLastAction:=scContact 490 else 491 begin 492 MyLastAction:=MyAction; 493 MyLastOffer:=MyOffer; 494 end; 495 if (OppoAction=scDipCancelTreaty) or (OppoAction=scDipBreak) then 496 MyAction:=scDipNotice 497 else begin MyAction:=scDipOffer; MyOffer.nDeliver:=0; MyOffer.nCost:=0; end; 498 DoNegotiation; 499 assert((MyAction=scDipNotice) or (MyAction=scDipAccept) 500 or (MyAction=scDipCancelTreaty) or (MyAction=scDipOffer) 501 or (MyAction=scDipBreak)); 502 if MyAction=scDipOffer then Server(MyAction, me, 0, MyOffer) 503 else Server(MyAction, me, 0, nodata^); 504 end; 505 cShowEndContact: 506 Opponent:=-1; 547 cShowEndContact: 548 Opponent := -1; 507 549 end; 508 550 end; … … 525 567 end; 526 568 527 procedure TCustomAI.OnBeforeEnemyAttack(UnitInfo: TUnitInfo; ToLoc, EndHealth,528 EndHealthDef: integer);569 procedure TCustomAI.OnBeforeEnemyAttack(UnitInfo: TUnitInfo; 570 ToLoc, EndHealth, EndHealthDef: integer); 529 571 begin 530 572 end; … … 544 586 function TCustomAI.ChooseResearchAdvance: integer; 545 587 begin 546 result:=-1 588 Result := -1; 547 589 end; 548 590 549 591 function TCustomAI.ChooseStealAdvance: integer; 550 592 begin 551 result:=-1 593 Result := -1; 552 594 end; 553 595 554 596 function TCustomAI.ChooseGovernment: integer; 555 597 begin 556 result:=gDespotism 598 Result := gDespotism; 557 599 end; 558 600 559 601 function TCustomAI.WantNegotiation(Nation: integer; NegoTime: TNegoTime): boolean; 560 602 begin 561 result:=false;603 Result := False; 562 604 end; 563 605 564 606 function TCustomAI.OnNegoRejected_CancelTreaty: boolean; 565 607 begin 566 result:=false; 567 end; 608 Result := False; 609 end; 610 568 611 {$HINTS ON} 569 612 570 613 procedure TCustomAI.StealAdvance; 571 614 var 572 Steal, ad, count: integer;573 begin 574 Steal:=ChooseStealAdvance;575 if Steal<0 then615 Steal, ad, Count: integer; 616 begin 617 Steal := ChooseStealAdvance; 618 if Steal < 0 then 576 619 begin // choose random advance 577 count:=0; 578 for ad:=0 to nAdv-1 do if AdvanceStealable(ad) then 579 begin inc(count); if random(count)=0 then Steal:=ad end 580 end; 581 if Steal>=0 then Server(sStealTech,me,Steal,nodata^); 582 RO.Happened:=RO.Happened and not phStealTech 620 Count := 0; 621 for ad := 0 to nAdv - 1 do 622 if AdvanceStealable(ad) then 623 begin 624 Inc(Count); 625 if random(Count) = 0 then 626 Steal := ad; 627 end; 628 end; 629 if Steal >= 0 then 630 Server(sStealTech, me, Steal, nodata^); 631 RO.Happened := RO.Happened and not phStealTech; 583 632 end; 584 633 585 634 function TCustomAI.IsResearched(Advance: integer): boolean; 586 635 begin 587 result:= (Advance=preNone) 588 or (Advance<>preNA) and (RO.Tech[Advance]>=tsApplicable) 636 Result := (Advance = preNone) or (Advance <> preNA) and (RO.Tech[Advance] >= tsApplicable); 589 637 end; 590 638 591 639 function TCustomAI.ResearchCost: integer; 592 640 begin 593 Server(sGetTechCost,me,0,result) 641 Server(sGetTechCost, me, 0, Result); 594 642 end; 595 643 596 644 function TCustomAI.ChangeAttitude(Nation, Attitude: integer): integer; 597 645 begin 598 result:=Server(sSetAttitude+Nation shl 4,me,Attitude,nodata^) 646 Result := Server(sSetAttitude + Nation shl 4, me, Attitude, nodata^); 599 647 end; 600 648 601 649 function TCustomAI.Revolution: integer; 602 650 begin 603 result:=Server(sRevolution,me,0,nodata^);604 end; 605 606 function TCustomAI.ChangeRates(Tax, Lux: integer): integer;607 begin 608 result:=Server(sSetRates,me,Tax div 10 and $f+Lux div 10 and $f shl 4,nodata^) 651 Result := Server(sRevolution, me, 0, nodata^); 652 end; 653 654 function TCustomAI.ChangeRates(Tax, Lux: integer): integer; 655 begin 656 Result := Server(sSetRates, me, Tax div 10 and $f + Lux div 10 and $f shl 4, nodata^); 609 657 end; 610 658 611 659 function TCustomAI.PrepareNewModel(Domain: integer): integer; 612 660 begin 613 result:=Server(sCreateDevModel,me,Domain,nodata^);661 Result := Server(sCreateDevModel, me, Domain, nodata^); 614 662 end; 615 663 616 664 function TCustomAI.SetNewModelFeature(F, Count: integer): integer; 617 665 begin 618 result:=Server(sSetDevModelCap+Count shl 4,me,F,nodata^) 666 Result := Server(sSetDevModelCap + Count shl 4, me, F, nodata^); 619 667 end; 620 668 621 669 function TCustomAI.AdvanceResearchable(Advance: integer): boolean; 622 670 begin 623 result:= Server(sSetResearch-sExecute,me,Advance,nodata^)>=rExecuted;671 Result := Server(sSetResearch - sExecute, me, Advance, nodata^) >= rExecuted; 624 672 end; 625 673 626 674 function TCustomAI.AdvanceStealable(Advance: integer): boolean; 627 675 begin 628 result:= Server(sStealTech-sExecute,me,Advance,nodata^)>=rExecuted; 629 end; 630 631 function TCustomAI.GetJobProgress(Loc: integer; var JobProgress: TJobProgressData): boolean; 632 begin 633 result:= Server(sGetJobProgress,me,Loc,JobProgress)>=rExecuted; 676 Result := Server(sStealTech - sExecute, me, Advance, nodata^) >= rExecuted; 677 end; 678 679 function TCustomAI.GetJobProgress(Loc: integer; 680 var JobProgress: TJobProgressData): boolean; 681 begin 682 Result := Server(sGetJobProgress, me, Loc, JobProgress) >= rExecuted; 634 683 end; 635 684 636 685 function TCustomAI.DebugMessage(Level: integer; Text: string): boolean; 637 686 begin 638 Text:=copy('P'+char(48+me)+' '+Text,1,254);639 Server(sMessage,me,Level,pchar(Text)^);640 641 result:=true;687 Text := copy('P' + char(48 + me) + ' ' + Text, 1, 254); 688 Server(sMessage, me, Level, PChar(Text)^); 689 690 Result := True; 642 691 // always returns true so that it can be used like 643 692 // "assert(DebugMessage(...));" -> not compiled in release build … … 646 695 function TCustomAI.SetDebugMap(var DebugMap): boolean; 647 696 begin 648 Server(sSetDebugMap, me, 0, DebugMap);649 650 result:=true;697 Server(sSetDebugMap, me, 0, DebugMap); 698 699 Result := True; 651 700 // always returns true so that it can be used like 652 701 // "assert(SetDebugMap(...));" -> not compiled in release build … … 655 704 procedure TCustomAI.Unit_FindMyDefender(Loc: integer; var uix: integer); 656 705 begin 657 if Server(sGetDefender,me,Loc,uix)<rExecuted then uix:=-1 706 if Server(sGetDefender, me, Loc, uix) < rExecuted then 707 uix := -1; 658 708 end; 659 709 660 710 procedure TCustomAI.Unit_FindEnemyDefender(Loc: integer; var euix: integer); 661 711 begin 662 euix:=RO.nEnemyUn-1;663 while (euix>=0) and (RO.EnemyUn[euix].Loc<>Loc) do664 dec(euix);665 end; 666 667 function TCustomAI.Unit_Move(uix, ToLoc: integer): integer;668 var 669 Step: integer;670 DestinationReached: boolean;671 Advice: TMoveAdviceData;672 begin 673 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit712 euix := RO.nEnemyUn - 1; 713 while (euix >= 0) and (RO.EnemyUn[euix].Loc <> Loc) do 714 Dec(euix); 715 end; 716 717 function TCustomAI.Unit_Move(uix, ToLoc: integer): integer; 718 var 719 Step: integer; 720 DestinationReached: boolean; 721 Advice: TMoveAdviceData; 722 begin 723 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit 674 724 {Loc_to_ab(MyUnit[uix].Loc,ToLoc,a,b); 675 725 assert((a<>0) or (b<>0)); … … 686 736 else} 687 737 begin // move to non-adjacent tile, find shortest path 688 Advice.ToLoc:=ToLoc;689 Advice.MoreTurns:=9999;690 Advice.MaxHostile_MovementLeft:=100;691 result:=Server(sGetMoveAdvice,me,uix,Advice);692 end; 693 if result=eOk then738 Advice.ToLoc := ToLoc; 739 Advice.MoreTurns := 9999; 740 Advice.MaxHostile_MovementLeft := 100; 741 Result := Server(sGetMoveAdvice, me, uix, Advice); 742 end; 743 if Result = eOk then 694 744 begin 695 DestinationReached:=false; 696 Step:=0; 697 repeat 698 if result and (rExecuted or rUnitRemoved)=rExecuted then // check if destination reached 699 if (ToLoc>=0) and (Advice.MoreTurns=0) and (Step=Advice.nStep-1) 700 and ((Map[ToLoc] and (fUnit or fOwned)=fUnit) // attack 701 or (Map[ToLoc] and (fCity or fOwned)=fCity) 702 and ((MyModel[MyUnit[uix].mix].Domain<>dGround) // bombardment 703 or (MyModel[MyUnit[uix].mix].Flags and mdCivil<>0))) then // can't capture 704 begin DestinationReached:=true; break end // stop next to destination 705 else if Step=Advice.nStep then 706 DestinationReached:=true; // normal move -- stop at destination 707 708 if (Step=Advice.nStep) or (result<>eOK) and (result<>eLoaded) then 709 break; 710 711 result:=Server(sMoveUnit+(Advice.dx[Step] and 7) shl 4 +(Advice.dy[Step] and 7) shl 7, 712 me,uix,nodata^); 713 inc(Step); 714 if RO.Happened and phStealTech<>0 then StealAdvance; 715 until false; 716 if DestinationReached then 717 if Advice.nStep=25 then 718 result:=Unit_Move(uix,ToLoc) // Shinkansen 719 else if Advice.MoreTurns=0 then 720 result:=result or rLocationReached 721 else result:=result or rMoreTurns; 745 DestinationReached := False; 746 Step := 0; 747 repeat 748 if Result and (rExecuted or rUnitRemoved) = rExecuted then 749 // check if destination reached 750 if (ToLoc >= 0) and (Advice.MoreTurns = 0) and (Step = Advice.nStep - 1) and 751 ((Map[ToLoc] and (fUnit or fOwned) = fUnit) // attack 752 or (Map[ToLoc] and (fCity or fOwned) = fCity) and 753 ((MyModel[MyUnit[uix].mix].Domain <> dGround) // bombardment 754 or (MyModel[MyUnit[uix].mix].Flags and mdCivil <> 0))) then // can't capture 755 begin 756 DestinationReached := True; 757 break; 758 end // stop next to destination 759 else if Step = Advice.nStep then 760 DestinationReached := True; // normal move -- stop at destination 761 762 if (Step = Advice.nStep) or (Result <> eOK) and (Result <> eLoaded) then 763 break; 764 765 Result := Server(sMoveUnit + (Advice.dx[Step] and 7) shl 4 + 766 (Advice.dy[Step] and 7) shl 7, me, uix, nodata^); 767 Inc(Step); 768 if RO.Happened and phStealTech <> 0 then 769 StealAdvance; 770 until False; 771 if DestinationReached then 772 if Advice.nStep = 25 then 773 Result := Unit_Move(uix, ToLoc) // Shinkansen 774 else if Advice.MoreTurns = 0 then 775 Result := Result or rLocationReached 776 else 777 Result := Result or rMoreTurns; 778 end; 779 end; 780 781 function TCustomAI.Unit_Step(uix, ToLoc: integer): integer; 782 var 783 a, b: integer; 784 begin 785 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b); 786 assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b <= 1)); 787 Result := Server(sMoveUnit + ((a - b) and 7) shl 4 + ((a + b) and 7) shl 7, me, uix, nodata^); 788 if RO.Happened and phStealTech <> 0 then 789 StealAdvance; 790 end; 791 792 function TCustomAI.Unit_Attack(uix, ToLoc: integer): integer; 793 var 794 a, b: integer; 795 begin 796 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 797 and ((Map[ToLoc] and (fUnit or fOwned) = fUnit) // is an attack 798 or (Map[ToLoc] and (fCity or fOwned) = fCity) and 799 (MyModel[MyUnit[uix].mix].Domain <> dGround))); // is a bombardment 800 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b); 801 assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b <= 1)); 802 // attack to adjacent tile 803 Result := Server(sMoveUnit + (a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^); 804 end; 805 806 function TCustomAI.Unit_DoMission(uix, MissionType, ToLoc: integer): integer; 807 var 808 a, b: integer; 809 begin 810 Result := Server(sSetSpyMission + MissionType shl 4, me, 0, nodata^); 811 if Result >= rExecuted then 812 begin 813 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 814 and (MyModel[MyUnit[uix].mix].Kind = mkDiplomat)); // is a commando 815 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b); 816 assert(((a <> 0) or (b <> 0)) and (a >= -1) and (a <= 1) and (b >= -1) and (b <= 1)); 817 // city must be adjacent 818 Result := Server(sMoveUnit - sExecute + (a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^); 819 if Result = eMissionDone then 820 Result := Server(sMoveUnit + (a - b) and 7 shl 4 + (a + b) and 7 shl 7, me, uix, nodata^) 821 else if (Result <> eNoTime_Move) and (Result <> eTreaty) and (Result <> eNoTurn) then 822 Result := eInvalid; // not a special commando mission! 823 end; 824 end; 825 826 function TCustomAI.Unit_MoveForecast(uix, ToLoc: integer; 827 var RemainingMovement: integer): boolean; 828 var 829 Advice: TMoveAdviceData; 830 begin 831 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0)); // is a unit 832 Advice.ToLoc := ToLoc; 833 Advice.MoreTurns := 0; 834 Advice.MaxHostile_MovementLeft := 100; 835 if Server(sGetMoveAdvice, me, uix, Advice) = eOk then 836 begin 837 RemainingMovement := Advice.MaxHostile_MovementLeft; 838 Result := True; 722 839 end 723 end; 724 725 function TCustomAI.Unit_Step(uix,ToLoc: integer): integer; 726 var 727 a,b: integer; 728 begin 729 Loc_to_ab(MyUnit[uix].Loc, ToLoc, a, b); 730 assert(((a<>0) or (b<>0)) and (a>=-1) and (a<=1) and (b>=-1) and (b<=1)); 731 result:=Server(sMoveUnit+((a-b) and 7) shl 4 +((a+b) and 7) shl 7, me, uix, nodata^); 732 if RO.Happened and phStealTech<>0 then StealAdvance; 733 end; 734 735 function TCustomAI.Unit_Attack(uix,ToLoc: integer): integer; 736 var 737 a,b: integer; 738 begin 739 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit 740 and ((Map[ToLoc] and (fUnit or fOwned)=fUnit) // is an attack 741 or (Map[ToLoc] and (fCity or fOwned)=fCity) 742 and (MyModel[MyUnit[uix].mix].Domain<>dGround))); // is a bombardment 743 Loc_to_ab(MyUnit[uix].Loc,ToLoc,a,b); 744 assert(((a<>0) or (b<>0)) and (a>=-1) and (a<=1) and (b>=-1) and (b<=1)); // attack to adjacent tile 745 result:=Server(sMoveUnit+(a-b) and 7 shl 4 +(a+b) and 7 shl 7,me,uix,nodata^); 746 end; 747 748 function TCustomAI.Unit_DoMission(uix,MissionType,ToLoc: integer): integer; 749 var 750 a,b: integer; 751 begin 752 result:=Server(sSetSpyMission + MissionType shl 4,me,0,nodata^); 753 if result>=rExecuted then 840 else 754 841 begin 755 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit 756 and (MyModel[MyUnit[uix].mix].Kind=mkDiplomat)); // is a commando 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)); // city must be adjacent 759 result:=Server(sMoveUnit-sExecute+(a-b) and 7 shl 4 +(a+b) and 7 shl 7,me,uix,nodata^); 760 if result=eMissionDone then 761 result:=Server(sMoveUnit+(a-b) and 7 shl 4 +(a+b) and 7 shl 7,me,uix,nodata^) 762 else if (result<>eNoTime_Move) and (result<>eTreaty) and (result<>eNoTurn) then 763 result:=eInvalid // not a special commando mission! 764 end 765 end; 766 767 function TCustomAI.Unit_MoveForecast(uix,ToLoc: integer; 768 var RemainingMovement: integer): boolean; 769 var 770 Advice: TMoveAdviceData; 771 begin 772 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0)); // is a unit 773 Advice.ToLoc:=ToLoc; 774 Advice.MoreTurns:=0; 775 Advice.MaxHostile_MovementLeft:=100; 776 if Server(sGetMoveAdvice,me,uix,Advice)=eOk then 842 RemainingMovement := -1; 843 Result := False; 844 end; 845 end; 846 847 // negative RemainingHealth is remaining helth of defender if lost 848 function TCustomAI.Unit_AttackForecast(uix, ToLoc, AttackMovement: integer; 849 var RemainingHealth: integer): boolean; 850 var 851 BattleForecast: TBattleForecast; 852 begin 853 assert((uix >= 0) and (uix < RO.nUn) and (MyUnit[uix].Loc >= 0) // is a unit 854 and (Map[ToLoc] and (fUnit or fOwned) = fUnit)); // is an attack 855 RemainingHealth := -$100; 856 Result := False; 857 if AttackMovement >= 0 then 858 with MyUnit[uix] do 859 begin 860 BattleForecast.pAtt := me; 861 BattleForecast.mixAtt := mix; 862 BattleForecast.HealthAtt := Health; 863 BattleForecast.ExpAtt := Exp; 864 BattleForecast.FlagsAtt := Flags; 865 BattleForecast.Movement := AttackMovement; 866 if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then 867 begin 868 if BattleForecast.EndHealthAtt > 0 then 869 RemainingHealth := BattleForecast.EndHealthAtt 870 else 871 RemainingHealth := -BattleForecast.EndHealthDef; 872 Result := True; 873 end; 874 end; 875 end; 876 877 function TCustomAI.Unit_DefenseForecast(euix, ToLoc: integer; 878 var RemainingHealth: integer): boolean; 879 var 880 BattleForecast: TBattleForecast; 881 begin 882 assert((euix >= 0) and (euix < RO.nEnemyUn) and (RO.EnemyUn[euix].Loc >= 0) // is an enemy unit 883 and (Map[ToLoc] and (fUnit or fOwned) = (fUnit or fOwned))); // is an attack 884 RemainingHealth := $100; 885 Result := False; 886 with RO.EnemyUn[euix] do 777 887 begin 778 RemainingMovement:=Advice.MaxHostile_MovementLeft; 779 result:=true 780 end 781 else 888 BattleForecast.pAtt := Owner; 889 BattleForecast.mixAtt := mix; 890 BattleForecast.HealthAtt := Health; 891 BattleForecast.ExpAtt := Exp; 892 BattleForecast.FlagsAtt := Flags; 893 BattleForecast.Movement := 100; 894 if Server(sGetBattleForecast, me, ToLoc, BattleForecast) >= rExecuted then 895 begin 896 if BattleForecast.EndHealthDef > 0 then 897 RemainingHealth := BattleForecast.EndHealthDef 898 else 899 RemainingHealth := -BattleForecast.EndHealthAtt; 900 Result := True; 901 end; 902 end; 903 end; 904 905 function TCustomAI.Unit_Disband(uix: integer): integer; 906 begin 907 Result := Server(sRemoveUnit, me, uix, nodata^); 908 end; 909 910 function TCustomAI.Unit_StartJob(uix, NewJob: integer): integer; 911 begin 912 Result := Server(sStartJob + NewJob shl 4, me, uix, nodata^); 913 end; 914 915 function TCustomAI.Unit_SetHomeHere(uix: integer): integer; 916 begin 917 Result := Server(sSetUnitHome, me, uix, nodata^); 918 end; 919 920 function TCustomAI.Unit_Load(uix: integer): integer; 921 begin 922 Result := Server(sLoadUnit, me, uix, nodata^); 923 end; 924 925 function TCustomAI.Unit_Unload(uix: integer): integer; 926 begin 927 Result := Server(sUnloadUnit, me, uix, nodata^); 928 end; 929 930 function TCustomAI.Unit_AddToCity(uix: integer): integer; 931 begin 932 Result := Server(sAddToCity, me, uix, nodata^); 933 end; 934 935 function TCustomAI.Unit_SelectTransport(uix: integer): integer; 936 begin 937 Result := Server(sSelectTransport, me, uix, nodata^); 938 end; 939 940 941 procedure TCustomAI.City_FindMyCity(Loc: integer; var cix: integer); 942 begin 943 if Map[Loc] and (fCity or fOwned) <> fCity or fOwned then 944 cix := -1 945 else 782 946 begin 783 RemainingMovement:=-1; 784 result:=false 785 end 786 end; 787 788 // negative RemainingHealth is remaining helth of defender if lost 789 function TCustomAI.Unit_AttackForecast(uix,ToLoc,AttackMovement: integer; 790 var RemainingHealth: integer): boolean; 791 var 792 BattleForecast: TBattleForecast; 793 begin 794 assert((uix>=0) and (uix<RO.nUn) and (MyUnit[uix].Loc>=0) // is a unit 795 and (Map[ToLoc] and (fUnit or fOwned)=fUnit)); // is an attack 796 RemainingHealth:=-$100; 797 result:=false; 798 if AttackMovement>=0 then with MyUnit[uix] do 947 cix := RO.nCity - 1; 948 while (cix >= 0) and (MyCity[cix].Loc <> Loc) do 949 Dec(cix); 950 end; 951 end; 952 953 procedure TCustomAI.City_FindEnemyCity(Loc: integer; var ecix: integer); 954 begin 955 if Map[Loc] and (fCity or fOwned) <> fCity then 956 ecix := -1 957 else 799 958 begin 800 BattleForecast.pAtt:=me; 801 BattleForecast.mixAtt:=mix; 802 BattleForecast.HealthAtt:=Health; 803 BattleForecast.ExpAtt:=Exp; 804 BattleForecast.FlagsAtt:=Flags; 805 BattleForecast.Movement:=AttackMovement; 806 if Server(sGetBattleForecast,me,ToLoc,BattleForecast)>=rExecuted then 807 begin 808 if BattleForecast.EndHealthAtt>0 then 809 RemainingHealth:=BattleForecast.EndHealthAtt 810 else RemainingHealth:=-BattleForecast.EndHealthDef; 811 result:=true 812 end 813 end 814 end; 815 816 function TCustomAI.Unit_DefenseForecast(euix,ToLoc: integer; 817 var RemainingHealth: integer): boolean; 818 var 819 BattleForecast: TBattleForecast; 820 begin 821 assert((euix>=0) and (euix<RO.nEnemyUn) and (RO.EnemyUn[euix].Loc>=0) // is an enemy unit 822 and (Map[ToLoc] and (fUnit or fOwned)=(fUnit or fOwned))); // is an attack 823 RemainingHealth:=$100; 824 result:=false; 825 with RO.EnemyUn[euix] do 959 ecix := RO.nEnemyCity - 1; 960 while (ecix >= 0) and (RO.EnemyCity[ecix].Loc <> Loc) do 961 Dec(ecix); 962 end; 963 end; 964 965 function TCustomAI.City_HasProject(cix: integer): boolean; 966 begin 967 Result := MyCity[cix].Project and (cpImp + cpIndex) <> cpImp + imTrGoods; 968 end; 969 970 function TCustomAI.City_CurrentImprovementProject(cix: integer): integer; 971 begin 972 if MyCity[cix].Project and cpImp = 0 then 973 Result := -1 974 else 826 975 begin 827 BattleForecast.pAtt:=Owner; 828 BattleForecast.mixAtt:=mix; 829 BattleForecast.HealthAtt:=Health; 830 BattleForecast.ExpAtt:=Exp; 831 BattleForecast.FlagsAtt:=Flags; 832 BattleForecast.Movement:=100; 833 if Server(sGetBattleForecast,me,ToLoc,BattleForecast)>=rExecuted then 834 begin 835 if BattleForecast.EndHealthDef>0 then 836 RemainingHealth:=BattleForecast.EndHealthDef 837 else RemainingHealth:=-BattleForecast.EndHealthAtt; 838 result:=true 839 end 840 end 841 end; 842 843 function TCustomAI.Unit_Disband(uix: integer): integer; 844 begin 845 result:=Server(sRemoveUnit,me,uix,nodata^) 846 end; 847 848 function TCustomAI.Unit_StartJob(uix,NewJob: integer): integer; 849 begin 850 result:=Server(sStartJob+NewJob shl 4,me,uix,nodata^) 851 end; 852 853 function TCustomAI.Unit_SetHomeHere(uix: integer): integer; 854 begin 855 result:=Server(sSetUnitHome,me,uix,nodata^) 856 end; 857 858 function TCustomAI.Unit_Load(uix: integer): integer; 859 begin 860 result:=Server(sLoadUnit,me,uix,nodata^) 861 end; 862 863 function TCustomAI.Unit_Unload(uix: integer): integer; 864 begin 865 result:=Server(sUnloadUnit,me,uix,nodata^) 866 end; 867 868 function TCustomAI.Unit_AddToCity(uix: integer): integer; 869 begin 870 result:=Server(sAddToCity,me,uix,nodata^) 871 end; 872 873 function TCustomAI.Unit_SelectTransport(uix: integer): integer; 874 begin 875 result:=Server(sSelectTransport,me,uix,nodata^) 876 end; 877 878 879 procedure TCustomAI.City_FindMyCity(Loc: integer; var cix: integer); 880 begin 881 if Map[Loc] and (fCity or fOwned)<>fCity or fOwned then 882 cix:=-1 883 else 884 begin 885 cix:=RO.nCity-1; 886 while (cix>=0) and (MyCity[cix].Loc<>Loc) do 887 dec(cix); 888 end 889 end; 890 891 procedure TCustomAI.City_FindEnemyCity(Loc: integer; var ecix: integer); 892 begin 893 if Map[Loc] and (fCity or fOwned)<>fCity then 894 ecix:=-1 895 else 896 begin 897 ecix:=RO.nEnemyCity-1; 898 while (ecix>=0) and (RO.EnemyCity[ecix].Loc<>Loc) do 899 dec(ecix); 900 end 901 end; 902 903 function TCustomAI.City_HasProject(cix: integer): boolean; 904 begin 905 result:= MyCity[cix].Project and (cpImp+cpIndex)<>cpImp+imTrGoods 906 end; 907 908 function TCustomAI.City_CurrentImprovementProject(cix: integer): integer; 909 begin 910 if MyCity[cix].Project and cpImp=0 then result:=-1 911 else 912 begin 913 result:=MyCity[cix].Project and cpIndex; 914 if result=imTrGoods then result:=-1 915 end 976 Result := MyCity[cix].Project and cpIndex; 977 if Result = imTrGoods then 978 Result := -1; 979 end; 916 980 end; 917 981 918 982 function TCustomAI.City_CurrentUnitProject(cix: integer): integer; 919 983 begin 920 if MyCity[cix].Project and cpImp<>0 then result:=-1 921 else result:=MyCity[cix].Project and cpIndex; 922 end; 923 924 function TCustomAI.City_GetTileInfo(cix,TileLoc: integer; var TileInfo: TTileInfo): integer; 925 begin 926 TileInfo.ExplCity:=cix; 927 result:=Server(sGetHypoCityTileInfo,me,TileLoc,TileInfo) 984 if MyCity[cix].Project and cpImp <> 0 then 985 Result := -1 986 else 987 Result := MyCity[cix].Project and cpIndex; 988 end; 989 990 function TCustomAI.City_GetTileInfo(cix, TileLoc: integer; 991 var TileInfo: TTileInfo): integer; 992 begin 993 TileInfo.ExplCity := cix; 994 Result := Server(sGetHypoCityTileInfo, me, TileLoc, TileInfo); 928 995 end; 929 996 930 997 function TCustomAI.City_GetReport(cix: integer; var Report: TCityReport): integer; 931 998 begin 932 Report.HypoTiles:=-1;933 Report.HypoTax:=-1;934 Report.HypoLux:=-1;935 result:=Server(sGetCityReport,me,cix,Report) 999 Report.HypoTiles := -1; 1000 Report.HypoTax := -1; 1001 Report.HypoLux := -1; 1002 Result := Server(sGetCityReport, me, cix, Report); 936 1003 end; 937 1004 … … 939 1006 var Report: TCityReport): integer; 940 1007 begin 941 Report.HypoTiles:=HypoTiles;942 Report.HypoTax:=HypoTax;943 Report.HypoLux:=HypoLux;944 result:=Server(sGetCityReport,me,cix,Report) 1008 Report.HypoTiles := HypoTiles; 1009 Report.HypoTax := HypoTax; 1010 Report.HypoLux := HypoLux; 1011 Result := Server(sGetCityReport, me, cix, Report); 945 1012 end; 946 1013 947 1014 function TCustomAI.City_GetReportNew(cix: integer; var Report: TCityReportNew): integer; 948 1015 begin 949 Report.HypoTiles:=-1;950 Report.HypoTaxRate:=-1;951 Report.HypoLuxuryRate:=-1;952 result:=Server(sGetCityReportNew,me,cix,Report) 953 end; 954 955 function TCustomAI.City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, HypoLuxuryRate: integer;956 var Report: TCityReportNew): integer;957 begin 958 Report.HypoTiles:=HypoTiles;959 Report.HypoTaxRate:=HypoTaxRate;960 Report.HypoLuxuryRate:=HypoLuxuryRate;961 result:=Server(sGetCityReportNew,me,cix,Report) 1016 Report.HypoTiles := -1; 1017 Report.HypoTaxRate := -1; 1018 Report.HypoLuxuryRate := -1; 1019 Result := Server(sGetCityReportNew, me, cix, Report); 1020 end; 1021 1022 function TCustomAI.City_GetHypoReportNew(cix, HypoTiles, HypoTaxRate, 1023 HypoLuxuryRate: integer; var Report: TCityReportNew): integer; 1024 begin 1025 Report.HypoTiles := HypoTiles; 1026 Report.HypoTaxRate := HypoTaxRate; 1027 Report.HypoLuxuryRate := HypoLuxuryRate; 1028 Result := Server(sGetCityReportNew, me, cix, Report); 962 1029 end; 963 1030 964 1031 function TCustomAI.City_GetAreaInfo(cix: integer; var AreaInfo: TCityAreaInfo): integer; 965 1032 begin 966 result:=Server(sGetCityAreaInfo,me,cix,AreaInfo) 967 end; 968 969 function TCustomAI.City_StartUnitProduction(cix, mix: integer): integer;970 begin 971 if (MyCity[cix].Project and (cpImp+cpIndex)<>mix) then972 // not already producing that973 result:=Server(sSetCityProject,me,cix,mix)974 end; 975 976 function TCustomAI.City_StartEmigration(cix, mix: integer;1033 Result := Server(sGetCityAreaInfo, me, cix, AreaInfo); 1034 end; 1035 1036 function TCustomAI.City_StartUnitProduction(cix, mix: integer): integer; 1037 begin 1038 if (MyCity[cix].Project and (cpImp + cpIndex) <> mix) then 1039 // not already producing that 1040 Result := Server(sSetCityProject, me, cix, mix); 1041 end; 1042 1043 function TCustomAI.City_StartEmigration(cix, mix: integer; 977 1044 AllowDisbandCity, AsConscripts: boolean): integer; 978 1045 var 979 NewProject: integer; 980 begin 981 NewProject:=mix; 982 if AllowDisbandCity then NewProject:=NewProject or cpDisbandCity; 983 if AsConscripts then NewProject:=NewProject or cpConscripts; 984 result:=Server(sSetCityProject,me,cix,NewProject) 985 end; 986 987 function TCustomAI.City_StartImprovement(cix,iix: integer): integer; 988 var 989 NewProject: integer; 990 begin 991 NewProject:=iix+cpImp; 992 if (MyCity[cix].Project and (cpImp+cpIndex)<>NewProject) then 993 // not already producing that 994 result:=Server(sSetCityProject,me,cix,NewProject) 995 end; 996 997 function TCustomAI.City_Improvable(cix,iix: integer): boolean; 998 var 999 NewProject: integer; 1000 begin 1001 NewProject:=iix+cpImp; 1002 result:= Server(sSetCityProject-sExecute,me,cix,NewProject)>=rExecuted; 1046 NewProject: integer; 1047 begin 1048 NewProject := mix; 1049 if AllowDisbandCity then 1050 NewProject := NewProject or cpDisbandCity; 1051 if AsConscripts then 1052 NewProject := NewProject or cpConscripts; 1053 Result := Server(sSetCityProject, me, cix, NewProject); 1054 end; 1055 1056 function TCustomAI.City_StartImprovement(cix, iix: integer): integer; 1057 var 1058 NewProject: integer; 1059 begin 1060 NewProject := iix + cpImp; 1061 if (MyCity[cix].Project and (cpImp + cpIndex) <> NewProject) then 1062 // not already producing that 1063 Result := Server(sSetCityProject, me, cix, NewProject); 1064 end; 1065 1066 function TCustomAI.City_Improvable(cix, iix: integer): boolean; 1067 var 1068 NewProject: integer; 1069 begin 1070 NewProject := iix + cpImp; 1071 Result := Server(sSetCityProject - sExecute, me, cix, NewProject) >= rExecuted; 1003 1072 end; 1004 1073 1005 1074 function TCustomAI.City_StopProduction(cix: integer): integer; 1006 1075 var 1007 NewProject: integer;1008 begin 1009 NewProject:=imTrGoods+cpImp;1010 result:=Server(sSetCityProject,me,cix,NewProject) 1076 NewProject: integer; 1077 begin 1078 NewProject := imTrGoods + cpImp; 1079 Result := Server(sSetCityProject, me, cix, NewProject); 1011 1080 end; 1012 1081 1013 1082 function TCustomAI.City_BuyProject(cix: integer): integer; 1014 1083 begin 1015 result:=Server(sBuyCityProject,me,cix,nodata^) 1016 end; 1017 1018 function TCustomAI.City_SellImprovement(cix, iix: integer): integer;1019 begin 1020 result:=Server(sSellCityImprovement,me,cix,iix) 1021 end; 1022 1023 function TCustomAI.City_RebuildImprovement(cix, iix: integer): integer;1024 begin 1025 result:=Server(sRebuildCityImprovement,me,cix,iix) 1026 end; 1027 1028 function TCustomAI.City_SetTiles(cix, NewTiles: integer): integer;1029 begin 1030 result:=Server(sSetCityTiles,me,cix,NewTiles) 1084 Result := Server(sBuyCityProject, me, cix, nodata^); 1085 end; 1086 1087 function TCustomAI.City_SellImprovement(cix, iix: integer): integer; 1088 begin 1089 Result := Server(sSellCityImprovement, me, cix, iix); 1090 end; 1091 1092 function TCustomAI.City_RebuildImprovement(cix, iix: integer): integer; 1093 begin 1094 Result := Server(sRebuildCityImprovement, me, cix, iix); 1095 end; 1096 1097 function TCustomAI.City_SetTiles(cix, NewTiles: integer): integer; 1098 begin 1099 Result := Server(sSetCityTiles, me, cix, NewTiles); 1031 1100 end; 1032 1101 1033 1102 procedure TCustomAI.City_OptimizeTiles(cix: integer; ResourceWeights: cardinal); 1034 1103 var 1035 Advice: TCityTileAdviceData;1036 begin 1037 Advice.ResourceWeights:=ResourceWeights;1038 Server(sGetCityTileAdvice, me, cix, Advice);1039 City_SetTiles(cix, Advice.Tiles);1104 Advice: TCityTileAdviceData; 1105 begin 1106 Advice.ResourceWeights := ResourceWeights; 1107 Server(sGetCityTileAdvice, me, cix, Advice); 1108 City_SetTiles(cix, Advice.Tiles); 1040 1109 end; 1041 1110 … … 1044 1113 function TCustomAI.Nego_CheckMyAction: integer; 1045 1114 begin 1046 assert(Opponent>=0); // only allowed in negotiation mode 1047 assert((MyAction=scDipNotice) or (MyAction=scDipAccept) 1048 or (MyAction=scDipCancelTreaty) or (MyAction=scDipOffer) 1049 or (MyAction=scDipBreak)); 1050 if MyAction=scDipOffer then result:=Server(MyAction-sExecute, me, 0, MyOffer) 1051 else result:=Server(MyAction-sExecute, me, 0, nodata^); 1115 assert(Opponent >= 0); // only allowed in negotiation mode 1116 assert((MyAction = scDipNotice) or (MyAction = scDipAccept) or 1117 (MyAction = scDipCancelTreaty) or (MyAction = scDipOffer) or (MyAction = scDipBreak)); 1118 if MyAction = scDipOffer then 1119 Result := Server(MyAction - sExecute, me, 0, MyOffer) 1120 else 1121 Result := Server(MyAction - sExecute, me, 0, nodata^); 1052 1122 end; 1053 1123 1054 1124 1055 1125 initialization 1056 nodata:=pointer(0);1057 RWDataSize:=0;1126 nodata := pointer(0); 1127 RWDataSize := 0; 1058 1128 1059 1129 end. 1060
Note:
See TracChangeset
for help on using the changeset viewer.