Changeset 447 for trunk/UnitProcessing.pas
- Timestamp:
- May 19, 2022, 10:39:34 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UnitProcessing.pas
r442 r447 13 13 TMoveInfo = record 14 14 MoveType: TMoveType; 15 Cost, ToMaster, EndHealth, Defender, Dcix, Duix, EndHealthDef: integer;16 MountainDelay: boolean;15 Cost, ToMaster, EndHealth, Defender, Dcix, Duix, EndHealthDef: Integer; 16 MountainDelay: Boolean; 17 17 end; 18 18 19 19 var 20 uixSelectedTransport: integer;21 Worked: array [0 .. nPl - 1] of integer; { settler work statistics }20 uixSelectedTransport: Integer; 21 Worked: array [0 .. nPl - 1] of Integer; { settler work statistics } 22 22 23 23 // Moving/Combat 24 function HostileDamage( p, mix, Loc, MP: integer): integer;25 function CalculateMove( p, uix, ToLoc, MoveLength: integer; TestOnly: boolean;26 var MoveInfo: TMoveInfo): integer;27 function GetBattleForecast(Loc: integer; var BattleForecast: TBattleForecast;28 var Duix, Dcix, AStr, DStr, ABaseDamage, DBaseDamage: integer): integer;29 function LoadUnit( p, uix: integer; TestOnly: boolean): integer;30 function UnloadUnit( p, uix: integer; TestOnly: boolean): integer;31 procedure Recover( p, uix: integer);32 function GetMoveAdvice( p, uix: integer; var a: TMoveAdviceData): integer;33 function CanPlaneReturn( p, uix: integer;34 PlaneReturnData: TPlaneReturnData): boolean;24 function HostileDamage(P, mix, Loc, MP: Integer): Integer; 25 function CalculateMove(P, uix, ToLoc, MoveLength: Integer; TestOnly: Boolean; 26 var MoveInfo: TMoveInfo): Integer; 27 function GetBattleForecast(Loc: Integer; var BattleForecast: TBattleForecast; 28 var Duix, Dcix, AStr, DStr, ABaseDamage, DBaseDamage: Integer): Integer; 29 function LoadUnit(P, uix: Integer; TestOnly: Boolean): Integer; 30 function UnloadUnit(P, uix: Integer; TestOnly: Boolean): Integer; 31 procedure Recover(P, uix: Integer); 32 function GetMoveAdvice(P, uix: Integer; var A: TMoveAdviceData): Integer; 33 function CanPlaneReturn(P, uix: Integer; 34 PlaneReturnData: TPlaneReturnData): Boolean; 35 35 36 36 // Terrain Improvement 37 function StartJob( p, uix, NewJob: integer; TestOnly: boolean): integer;38 function Work( p, uix: integer): boolean;39 function GetJobProgress( p, Loc: integer;40 var JobProgressData: TJobProgressData): integer;37 function StartJob(P, uix, NewJob: Integer; TestOnly: Boolean): Integer; 38 function Work(P, uix: Integer): Boolean; 39 function GetJobProgress(P, Loc: Integer; 40 var JobProgressData: TJobProgressData): Integer; 41 41 42 42 // Start/End Game … … 74 74 75 75 type 76 TToWorkList = array [0 .. INFIN, 0 .. nJob - 1] of word;76 TToWorkList = array [0 .. INFIN, 0 .. nJob - 1] of Word; 77 77 78 78 var … … 83 83 ____________________________________________________________________ 84 84 } 85 function HostileDamage( p, mix, Loc, MP: integer): integer;86 var 87 Tile: integer;85 function HostileDamage(P, mix, Loc, MP: Integer): Integer; 86 var 87 Tile: Integer; 88 88 begin 89 89 Tile := RealMap[Loc]; 90 if (RW[ p].Model[mix].Domain >= dSea) or (RW[p].Model[mix].Kind = mkSettler)91 and (RW[ p].Model[mix].Speed >= 200) or90 if (RW[P].Model[mix].Domain >= dSea) or (RW[P].Model[mix].Kind = mkSettler) 91 and (RW[P].Model[mix].Speed >= 200) or 92 92 (Tile and (fCity or fRiver or fCanal) <> 0) or (Tile and fTerImp = tiBase) 93 or (GWonder[woGardens].EffectiveOwner = p) then94 result := 093 or (GWonder[woGardens].EffectiveOwner = P) then 94 Result := 0 95 95 else if (Tile and fTerrain = fDesert) and 96 96 (Tile and fSpecial <> fSpecial1 { Oasis } ) then 97 97 begin 98 assert((Tile and fTerImp <> tiIrrigation) and (Tile and fTerImp <> tiFarm));99 result := (DesertThurst * MP - 1) div RW[p].Model[mix].Speed + 198 Assert((Tile and fTerImp <> tiIrrigation) and (Tile and fTerImp <> tiFarm)); 99 Result := (DesertThurst * MP - 1) div RW[P].Model[mix].Speed + 1 100 100 end 101 101 else if Tile and fTerrain = fArctic then 102 102 begin 103 assert((Tile and fTerImp <> tiIrrigation) and (Tile and fTerImp <> tiFarm));104 result := (ArcticThurst * MP - 1) div RW[p].Model[mix].Speed + 1103 Assert((Tile and fTerImp <> tiIrrigation) and (Tile and fTerImp <> tiFarm)); 104 Result := (ArcticThurst * MP - 1) div RW[P].Model[mix].Speed + 1 105 105 end 106 106 else 107 result := 0108 end; 109 110 function Controlled( p, Loc: integer; IsDest: boolean): integer;107 Result := 0; 108 end; 109 110 function Controlled(P, Loc: Integer; IsDest: Boolean): Integer; 111 111 { whether tile at Loc is in control zone of enemy unit 112 112 returns combination of tile control flags } 113 113 var 114 Loc1, V8: integer;114 Loc1, V8: Integer; 115 115 Adjacent: TVicinity8Loc; 116 116 begin 117 result := 0;118 if IsDest and (Occupant[Loc] = p) and (ZoCMap[Loc] > 0) then119 exit;117 Result := 0; 118 if IsDest and (Occupant[Loc] = P) and (ZoCMap[Loc] > 0) then 119 Exit; 120 120 // destination tile, not controlled if already occupied 121 121 122 if (RealMap[Loc] and fCity = 0) or ( integer(RealMap[Loc] shr 27) <> p) and123 (ServerVersion[ p] >= $000EF0) then122 if (RealMap[Loc] and fCity = 0) or (Integer(RealMap[Loc] shr 27) <> P) and 123 (ServerVersion[P] >= $000EF0) then 124 124 begin // not own city 125 125 V8_to_Loc(Loc, Adjacent); … … 128 128 Loc1 := Adjacent[V8]; 129 129 if (Loc1 >= 0) and (Loc1 < MapSize) and (ZoCMap[Loc1] > 0) and 130 (Occupant[Loc1] >= 0) and (Occupant[Loc1] <> p) and131 (RW[ p].Treaty[Occupant[Loc1]] < trAlliance) then132 if ObserveLevel[Loc1] and (3 shl ( p* 2)) > 0 then130 (Occupant[Loc1] >= 0) and (Occupant[Loc1] <> P) and 131 (RW[P].Treaty[Occupant[Loc1]] < trAlliance) then 132 if ObserveLevel[Loc1] and (3 shl (P * 2)) > 0 then 133 133 begin // p observes tile 134 result := coKnown or coTrue;135 exit;134 Result := coKnown or coTrue; 135 Exit; 136 136 end 137 137 else 138 result := coTrue; // p does not observe tile138 Result := coTrue; // p does not observe tile 139 139 end; 140 140 end; 141 141 end; 142 142 143 function GetMoveCost( p, mix, FromLoc, ToLoc, MoveLength: integer;144 var MoveCost: integer): integer;143 function GetMoveCost(P, mix, FromLoc, ToLoc, MoveLength: Integer; 144 var MoveCost: Integer): Integer; 145 145 // MoveLength - 2 for short move, 3 for long move 146 146 var 147 FromTile, ToTile: integer;148 begin 149 result := eOK;147 FromTile, ToTile: Integer; 148 begin 149 Result := eOK; 150 150 FromTile := RealMap[FromLoc]; 151 151 ToTile := RealMap[ToLoc]; 152 with RW[ p].Model[mix] do152 with RW[P].Model[mix] do 153 153 begin 154 154 case Domain of … … 160 160 if (FromTile and (fRR or fCity) <> 0) and 161 161 (ToTile and (fRR or fCity) <> 0) then 162 if GWonder[woShinkansen].EffectiveOwner = pthen162 if GWonder[woShinkansen].EffectiveOwner = P then 163 163 MoveCost := 0 164 164 else … … 174 174 MoveCost := 20 175 175 else if Cap[mcOver] > 0 then 176 result := eNoRoad176 Result := eNoRoad 177 177 else 178 178 case Terrain[ToTile and fTerrain].MoveCost of … … 181 181 2: 182 182 begin 183 assert(Speed - 150 <= 600);183 Assert(Speed - 150 <= 600); 184 184 MoveCost := 50 + (Speed - 150) * 13 shr 7; // heavy terrain 185 185 end; … … 187 187 begin 188 188 MoveCost := Speed; 189 result := eMountains;190 exit;189 Result := eMountains; 190 Exit; 191 191 end; 192 192 end; … … 194 194 end 195 195 else 196 result := eDomainMismatch;196 Result := eDomainMismatch; 197 197 198 198 dSea: … … 202 202 MoveCost := 50 * MoveLength { valid move } 203 203 else 204 result := eNoNav { navigation required for open sea }205 else 206 result := eDomainMismatch;204 Result := eNoNav { navigation required for open sea } 205 else 206 Result := eDomainMismatch; 207 207 208 208 dAir: … … 212 212 end; 213 213 214 function CalculateMove( p, uix, ToLoc, MoveLength: integer; TestOnly: boolean;215 var MoveInfo: TMoveInfo): integer;214 function CalculateMove(P, uix, ToLoc, MoveLength: Integer; TestOnly: Boolean; 215 var MoveInfo: TMoveInfo): Integer; 216 216 var 217 217 uix1, p1, FromLoc, DestControlled, AStr, DStr, ABaseDamage, 218 DBaseDamage: integer;218 DBaseDamage: Integer; 219 219 PModel: ^TModel; 220 220 BattleForecast: TBattleForecast; 221 221 begin 222 with RW[ p], Un[uix] do222 with RW[P], Un[uix] do 223 223 begin 224 224 PModel := @Model[mix]; 225 225 FromLoc := Loc; 226 226 227 BattleForecast.pAtt := p;227 BattleForecast.pAtt := P; 228 228 BattleForecast.mixAtt := mix; 229 229 BattleForecast.HealthAtt := Health; … … 231 231 BattleForecast.FlagsAtt := Flags; 232 232 BattleForecast.Movement := Movement; 233 result := GetBattleForecast(ToLoc, BattleForecast, MoveInfo.Duix,233 Result := GetBattleForecast(ToLoc, BattleForecast, MoveInfo.Duix, 234 234 MoveInfo.Dcix, AStr, DStr, ABaseDamage, DBaseDamage); 235 235 236 if result = eHiddenUnit then236 if Result = eHiddenUnit then 237 237 if TestOnly then 238 result := eOK // behave just like unit was moving238 Result := eOK // behave just like unit was moving 239 239 else if Mode > moLoading_Fast then 240 240 Map[ToLoc] := Map[ToLoc] or fHiddenUnit; 241 if result = eStealthUnit then241 if Result = eStealthUnit then 242 242 if TestOnly then 243 result := eOK // behave just like unit was moving243 Result := eOK // behave just like unit was moving 244 244 else if Mode > moLoading_Fast then 245 245 Map[ToLoc] := Map[ToLoc] or fStealthUnit; 246 if result < rExecuted then247 exit;248 249 case result of246 if Result < rExecuted then 247 Exit; 248 249 case Result of 250 250 eOK: 251 251 MoveInfo.MoveType := mtMove; … … 261 261 begin 262 262 p1 := RealMap[ToLoc] shr 27; 263 if (p1 < nPl) and (p1 <> p) and263 if (p1 < nPl) and (p1 <> P) and 264 264 ((RealMap[Loc] shr 27 <> Cardinal(p1)) and (PModel.Kind <> mkDiplomat) 265 265 and (Treaty[p1] >= trPeace) and (Treaty[p1] < trAlliance) or 266 266 (RealMap[ToLoc] and fCity <> 0) and (Treaty[p1] >= trPeace)) then 267 267 begin 268 result := eTreaty;269 exit;268 Result := eTreaty; 269 Exit; 270 270 end; // keep peace treaty! 271 271 end; 272 272 if (RealMap[ToLoc] and fCity <> 0) and 273 (RealMap[ToLoc] shr 27 <> Cardinal( p)) then // empty enemy city273 (RealMap[ToLoc] shr 27 <> Cardinal(P)) then // empty enemy city 274 274 if PModel.Kind = mkDiplomat then 275 275 begin … … 280 280 if PModel.Flags and mdCivil <> 0 then 281 281 begin 282 result := eNoCapturer;283 exit;282 Result := eNoCapturer; 283 Exit; 284 284 end; 285 285 MoveInfo.MoveType := mtCapture; … … 289 289 if (PModel.Domain = dSea) and (PModel.Cap[mcArtillery] = 0) then 290 290 begin 291 result := eDomainMismatch;292 exit;291 Result := eDomainMismatch; 292 Exit; 293 293 end 294 294 else if (PModel.Attack = 0) and … … 296 296 then 297 297 begin 298 result := eNoBombarder;299 exit;298 Result := eNoBombarder; 299 Exit; 300 300 end 301 301 else if Movement < 100 then 302 302 begin 303 result := eNoTime_Bombard;304 exit;303 Result := eNoTime_Bombard; 304 Exit; 305 305 end; 306 306 MoveInfo.MoveType := mtBombard; 307 result := eBombarded;308 end; 309 end; 310 311 MoveInfo.MountainDelay := false;307 Result := eBombarded; 308 end; 309 end; 310 311 MoveInfo.MountainDelay := False; 312 312 if MoveInfo.MoveType in [mtAttack, mtBombard, mtExpel] then 313 313 begin … … 317 317 then 318 318 begin 319 result := eViolation;320 exit319 Result := eViolation; 320 Exit; 321 321 end; 322 322 if MoveInfo.MoveType = mtBombard then … … 337 337 MoveInfo.Cost := PModel.Speed; 338 338 if RealMap[ToLoc] and fTerrain < fGrass then 339 result := eDomainMismatch;339 Result := eDomainMismatch; 340 340 end 341 341 else 342 342 begin 343 result := GetMoveCost(p, mix, FromLoc, ToLoc, MoveLength,343 Result := GetMoveCost(P, mix, FromLoc, ToLoc, MoveLength, 344 344 MoveInfo.Cost); 345 if result = eMountains then346 begin 347 result := eOK;348 MoveInfo.MountainDelay := true345 if Result = eMountains then 346 begin 347 Result := eOK; 348 MoveInfo.MountainDelay := True 349 349 end; 350 350 end; 351 if ( result >= rExecuted) and (MoveInfo.MoveType = mtSpyMission) then352 result := eMissionDone;351 if (Result >= rExecuted) and (MoveInfo.MoveType = mtSpyMission) then 352 Result := eMissionDone; 353 353 354 354 MoveInfo.ToMaster := -1; 355 if ( result = eDomainMismatch) and (PModel.Domain < dSea) and355 if (Result = eDomainMismatch) and (PModel.Domain < dSea) and 356 356 (PModel.Cap[mcOver] = 0) then 357 357 begin … … 361 361 (TroopLoad < Model[mix].MTrans * Model[mix].Cap[mcSeaTrans]) then 362 362 begin 363 result := eLoaded;363 Result := eLoaded; 364 364 MoveInfo.Cost := PModel.Speed; 365 365 MoveInfo.ToMaster := uix1; … … 378 378 (AirLoad < Model[mix].MTrans * Model[mix].Cap[mcCarrier]) then 379 379 begin // load plane to ship 380 result := eLoaded;380 Result := eLoaded; 381 381 MoveInfo.ToMaster := uix1; 382 382 if (uixSelectedTransport >= 0) and (uix1 = uixSelectedTransport) … … 385 385 end; 386 386 end; 387 if result < rExecuted then388 exit;387 if Result < rExecuted then 388 Exit; 389 389 390 390 if (Master < 0) and (MoveInfo.ToMaster < 0) then 391 MoveInfo.EndHealth := Health - HostileDamage( p, mix, ToLoc,391 MoveInfo.EndHealth := Health - HostileDamage(P, mix, ToLoc, 392 392 MoveInfo.Cost) 393 393 else … … 395 395 396 396 if (Mode = moPlaying) and (PModel.Flags and mdZOC <> 0) and (Master < 0) 397 and (MoveInfo.ToMaster < 0) and (Controlled( p, FromLoc, false) >= coTrue)397 and (MoveInfo.ToMaster < 0) and (Controlled(P, FromLoc, False) >= coTrue) 398 398 then 399 399 begin 400 DestControlled := Controlled( p, ToLoc, true);400 DestControlled := Controlled(P, ToLoc, True); 401 401 if DestControlled >= coTrue + coKnown then 402 402 begin 403 result := eZOC;404 exit;403 Result := eZOC; 404 Exit; 405 405 end 406 406 else if not TestOnly and (DestControlled >= coTrue) then 407 407 begin 408 result := eZOC_EnemySpotted;409 exit;408 Result := eZOC_EnemySpotted; 409 Exit; 410 410 end; 411 411 end; 412 if (Movement = 0) and (ServerVersion[ p] >= $0100F1) or412 if (Movement = 0) and (ServerVersion[P] >= $0100F1) or 413 413 (MoveInfo.Cost > Movement) then 414 414 if (Master >= 0) or (MoveInfo.ToMaster >= 0) then 415 415 begin 416 result := eNoTime_Load;417 exit;416 Result := eNoTime_Load; 417 Exit; 418 418 end 419 419 else 420 420 begin 421 result := eNoTime_Move;422 exit;421 Result := eNoTime_Move; 422 Exit; 423 423 end; 424 424 if (MoveInfo.EndHealth <= 0) or (MoveInfo.MoveType = mtSpyMission) then 425 result := result or rUnitRemoved;425 Result := Result or rUnitRemoved; 426 426 // spy mission or victim of HostileDamage 427 427 … … 438 438 end; 439 439 440 function GetBattleForecast(Loc: integer; var BattleForecast: TBattleForecast;441 var Duix, Dcix, AStr, DStr, ABaseDamage, DBaseDamage: integer): integer;442 var 443 Time, Defender, ABon, DBon, DCnt, MultiDamage: integer;440 function GetBattleForecast(Loc: Integer; var BattleForecast: TBattleForecast; 441 var Duix, Dcix, AStr, DStr, ABaseDamage, DBaseDamage: Integer): Integer; 442 var 443 Time, Defender, ABon, DBon, DCnt, MultiDamage: Integer; 444 444 PModel, DModel: ^TModel; 445 445 begin … … 449 449 if (Defender < 0) or (Defender = pAtt) then 450 450 begin 451 result := eOK;452 exit;451 Result := eOK; 452 Exit; 453 453 end; // no attack, simple move 454 454 … … 459 459 EndHealthAtt := HealthAtt; 460 460 EndHealthDef := RW[Defender].Un[Duix].Health; 461 result := eOK;462 exit;461 Result := eOK; 462 Exit; 463 463 end; 464 464 … … 470 470 (ObserveLevel[Loc] shr (2 * pAtt) and 3 < lObserveAll) then 471 471 begin 472 result := eHiddenUnit;473 exit;472 Result := eHiddenUnit; 473 Exit; 474 474 end; // attacking submarine not allowed 475 475 if (DModel.Cap[mcStealth] > 0) and 476 476 (ObserveLevel[Loc] shr (2 * pAtt) and 3 <> lObserveSuper) then 477 477 begin 478 result := eStealthUnit;479 exit;478 Result := eStealthUnit; 479 Exit; 480 480 end; // attacking stealth aircraft not allowed 481 481 if (DModel.Domain = dAir) and (DModel.Kind <> mkSpecial_Glider) and 482 482 (PModel.Domain <> dAir) then 483 483 begin 484 result := eDomainMismatch;485 exit;484 Result := eDomainMismatch; 485 Exit; 486 486 end; // can't attack plane 487 487 end; … … 492 492 (PModel.Domain = dSea) and (RealMap[Loc] and fTerrain >= fGrass)) then 493 493 begin 494 result := eDomainMismatch;495 exit;494 Result := eDomainMismatch; 495 Exit; 496 496 end; 497 497 if (PModel.Attack = 0) and not((PModel.Cap[mcBombs] > 0) and 498 498 (FlagsAtt and unBombsLoaded <> 0) and (DModel.Domain < dAir)) then 499 499 begin 500 result := eInvalid;501 exit;500 Result := eInvalid; 501 Exit; 502 502 end; 503 503 504 504 if Movement = 0 then 505 505 begin 506 result := eNoTime_Attack;507 exit;508 end; 509 510 {$IFOPT O-} assert(InvalidTreatyMap = 0); {$ENDIF}506 Result := eNoTime_Attack; 507 Exit; 508 end; 509 510 {$IFOPT O-}Assert(InvalidTreatyMap = 0); {$ENDIF} 511 511 if RW[pAtt].Treaty[Defender] >= trPeace then 512 512 begin 513 513 if (PModel.Domain <> dAir) and (PModel.Attack > 0) and 514 ( integer(RealMap[Loc] shr 27) = pAtt) then514 (Integer(RealMap[Loc] shr 27) = pAtt) then 515 515 if Movement >= 100 then 516 516 begin // expel friendly unit 517 517 EndHealthDef := RW[Defender].Un[Duix].Health; 518 518 EndHealthAtt := HealthAtt; 519 result := eExpelled519 Result := eExpelled 520 520 end 521 521 else 522 result := eNoTime_Expel522 Result := eNoTime_Expel 523 523 else 524 result := eTreaty;525 exit;524 Result := eTreaty; 525 Exit; 526 526 end; 527 527 … … 534 534 (Continent[RW[Defender].City[Dcix].Loc] = GrWallContinent[Defender])) 535 535 then 536 inc(DBon, 8)536 Inc(DBon, 8) 537 537 else if (PModel.Domain = dSea) and 538 538 (RW[Defender].City[Dcix].Built[imCoastalFort] = 1) then 539 inc(DBon, 4)539 Inc(DBon, 4) 540 540 else if (PModel.Domain = dAir) and 541 541 (RW[Defender].City[Dcix].Built[imMissileBat] = 1) then 542 inc(DBon, 4);542 Inc(DBon, 4); 543 543 if RW[Defender].City[Dcix].Built[imBunker] = 1 then 544 inc(DBon, 4)544 Inc(DBon, 4) 545 545 end; 546 546 if (PModel.Domain = dAir) and (DModel.Cap[mcAirDef] > 0) then 547 inc(DBon, 4);547 Inc(DBon, 4); 548 548 DStr := DModel.Defense * DBon * 100; 549 549 if (DModel.Domain = dAir) and ((RealMap[Loc] and fCity <> 0) or … … 622 622 623 623 if EndHealthDef > 0 then 624 result := eLost624 Result := eLost 625 625 else if EndHealthAtt > 0 then 626 result := eWon626 Result := eWon 627 627 else 628 result := eBloody;628 Result := eBloody; 629 629 end; 630 630 end; 631 631 632 function LoadUnit( p, uix: integer; TestOnly: boolean): integer;633 var 634 uix1, d, Cost, ToMaster: integer;635 begin 636 result := eOK;637 with RW[ p].Un[uix] do638 begin 639 d := RW[p].Model[mix].Domain;640 if (Master >= 0) or ( d= dSea) or641 (RW[ p].Model[mix].Cap[mcAirTrans] + RW[p].Model[mix].Cap[mcOver] > 0) then642 result := eViolation632 function LoadUnit(P, uix: Integer; TestOnly: Boolean): Integer; 633 var 634 uix1, D, Cost, ToMaster: Integer; 635 begin 636 Result := eOK; 637 with RW[P].Un[uix] do 638 begin 639 D := RW[P].Model[mix].Domain; 640 if (Master >= 0) or (D = dSea) or 641 (RW[P].Model[mix].Cap[mcAirTrans] + RW[P].Model[mix].Cap[mcOver] > 0) then 642 Result := eViolation 643 643 else 644 644 begin 645 645 ToMaster := -1; 646 for uix1 := 0 to RW[ p].nUn - 1 do647 if RW[ p].Un[uix1].Loc = Loc then648 with RW[ p].Un[uix1], RW[p].Model[mix] do649 if ( d< dSea) and646 for uix1 := 0 to RW[P].nUn - 1 do 647 if RW[P].Un[uix1].Loc = Loc then 648 with RW[P].Un[uix1], RW[P].Model[mix] do 649 if (D < dSea) and 650 650 (TroopLoad < MTrans * (Cap[mcSeaTrans] + Cap[mcAirTrans])) or 651 ( d= dAir) and (AirLoad < MTrans * Cap[mcCarrier]) then651 (D = dAir) and (AirLoad < MTrans * Cap[mcCarrier]) then 652 652 begin { load onto unit uix1 } 653 653 if (uixSelectedTransport < 0) or (uix1 = uixSelectedTransport) … … 661 661 end; 662 662 if ToMaster < 0 then 663 result := eNoLoadCapacity663 Result := eNoLoadCapacity 664 664 else 665 665 begin 666 if d= dAir then666 if D = dAir then 667 667 Cost := 100 668 668 else 669 Cost := RW[ p].Model[mix].Speed;669 Cost := RW[P].Model[mix].Speed; 670 670 if Movement < Cost then 671 result := eNoTime_Load671 Result := eNoTime_Load 672 672 else if not TestOnly then 673 673 begin 674 FreeUnit( p, uix);675 dec(Movement, Cost);676 if d= dAir then677 inc(RW[p].Un[ToMaster].AirLoad)674 FreeUnit(P, uix); 675 Dec(Movement, Cost); 676 if D = dAir then 677 Inc(RW[P].Un[ToMaster].AirLoad) 678 678 else 679 inc(RW[p].Un[ToMaster].TroopLoad);679 Inc(RW[P].Un[ToMaster].TroopLoad); 680 680 Master := ToMaster; 681 681 UpdateUnitMap(Loc); … … 686 686 end; 687 687 688 function UnloadUnit( p, uix: integer; TestOnly: boolean): integer;689 var 690 Cost: integer;691 begin 692 result := eOK;693 with RW[ p].Un[uix] do688 function UnloadUnit(P, uix: Integer; TestOnly: Boolean): Integer; 689 var 690 Cost: Integer; 691 begin 692 Result := eOK; 693 with RW[P].Un[uix] do 694 694 if Master < 0 then 695 result := eNotChanged696 else if (RW[ p].Model[mix].Domain < dSea) and695 Result := eNotChanged 696 else if (RW[P].Model[mix].Domain < dSea) and 697 697 (RealMap[Loc] and fTerrain < fGrass) then 698 result := eDomainMismatch698 Result := eDomainMismatch 699 699 // else if (RW[p].Model[mix].Domain<dSea) 700 700 // and (RW[p].Model[mix].Flags and mdCivil<>0) … … 702 702 else 703 703 begin 704 if RW[ p].Model[mix].Domain = dAir then704 if RW[P].Model[mix].Domain = dAir then 705 705 Cost := 100 706 706 else 707 Cost := RW[ p].Model[mix].Speed;707 Cost := RW[P].Model[mix].Speed; 708 708 if Movement < Cost then 709 result := eNoTime_Load709 Result := eNoTime_Load 710 710 else if not TestOnly then 711 711 begin 712 dec(Movement, Cost);713 if RW[ p].Model[mix].Domain = dAir then714 dec(RW[p].Un[Master].AirLoad)715 else 716 begin 717 dec(RW[p].Un[Master].TroopLoad);712 Dec(Movement, Cost); 713 if RW[P].Model[mix].Domain = dAir then 714 Dec(RW[P].Un[Master].AirLoad) 715 else 716 begin 717 Dec(RW[P].Un[Master].TroopLoad); 718 718 // Movement:=0 // no more movement after unload 719 719 end; 720 720 Master := -1; 721 PlaceUnit( p, uix);721 PlaceUnit(P, uix); 722 722 UpdateUnitMap(Loc); 723 723 end; … … 725 725 end; 726 726 727 procedure Recover( p, uix: integer);728 var 729 cix, Recovery: integer;730 begin 731 with RW[ p], Un[uix] do727 procedure Recover(P, uix: Integer); 728 var 729 cix, Recovery: Integer; 730 begin 731 with RW[P], Un[uix] do 732 732 begin 733 733 if (Master >= 0) and (Model[Un[Master].mix].Cap[mcSupplyShip] > 0) then … … 739 739 cix := nCity - 1; 740 740 while (cix >= 0) and (City[cix].Loc <> Loc) do 741 dec(cix);741 Dec(cix); 742 742 if City[cix].Flags and chDisorder <> 0 then 743 743 Recovery := NoCityRecovery … … 762 762 if Recovery > 100 - Health then 763 763 Recovery := 100 - Health; 764 inc(Health, Recovery);764 Inc(Health, Recovery); 765 765 end; 766 766 end; 767 767 768 function GetMoveAdvice( p, uix: integer; var a: TMoveAdviceData): integer;768 function GetMoveAdvice(P, uix: Integer; var A: TMoveAdviceData): Integer; 769 769 const 770 770 // domains … … 778 778 gmaAlpine = 8; 779 779 var 780 i, FromLoc, EndLoc, T, T1, maxmov, initmov, Loc, Loc1, FromTile, ToTile, V8,780 I, FromLoc, EndLoc, T, T1, maxmov, initmov, Loc, Loc1, FromTile, ToTile, V8, 781 781 MoveInfo, HeavyCost, RailCost, MoveCost, AddDamage, MaxDamage, 782 MovementLeft: integer;782 MovementLeft: Integer; 783 783 Map: ^TTileList; 784 784 Q: TIPQ; 785 785 Adjacent: TVicinity8Loc; 786 From: array [0 .. lxmax * lymax - 1] of integer;787 Time: array [0 .. lxmax * lymax - 1] of integer;788 Damage: array [0 .. lxmax * lymax - 1] of integer;789 MountainDelay, Resistant: boolean;786 From: array [0 .. lxmax * lymax - 1] of Integer; 787 Time: array [0 .. lxmax * lymax - 1] of Integer; 788 Damage: array [0 .. lxmax * lymax - 1] of Integer; 789 MountainDelay, Resistant: Boolean; 790 790 // tt,tt0: int64; 791 791 begin 792 792 // QueryPerformanceCounter(tt0); 793 793 794 MaxDamage := RW[ p].Un[uix].Health - 1;795 if MaxDamage > a.MaxHostile_MovementLeft then796 if a.MaxHostile_MovementLeft >= 0 then797 MaxDamage := a.MaxHostile_MovementLeft794 MaxDamage := RW[P].Un[uix].Health - 1; 795 if MaxDamage > A.MaxHostile_MovementLeft then 796 if A.MaxHostile_MovementLeft >= 0 then 797 MaxDamage := A.MaxHostile_MovementLeft 798 798 else 799 799 MaxDamage := 0; 800 800 801 Map := @(RW[ p].Map^);802 if ( a.ToLoc <> maNextCity) and ((a.ToLoc < 0) or (a.ToLoc >= MapSize)) then803 begin 804 result := eInvalid;805 exit;801 Map := @(RW[P].Map^); 802 if (A.ToLoc <> maNextCity) and ((A.ToLoc < 0) or (A.ToLoc >= MapSize)) then 803 begin 804 Result := eInvalid; 805 Exit; 806 806 end; 807 if ( a.ToLoc <> maNextCity) and (Map[a.ToLoc] and fTerrain = fUNKNOWN) then808 begin 809 result := eNoWay;810 exit;807 if (A.ToLoc <> maNextCity) and (Map[A.ToLoc] and fTerrain = fUNKNOWN) then 808 begin 809 Result := eNoWay; 810 Exit; 811 811 end; 812 812 813 with RW[ p].Model[RW[p].Un[uix].mix] do813 with RW[P].Model[RW[P].Un[uix].mix] do 814 814 case Domain of 815 815 dGround: 816 if ( a.ToLoc <> maNextCity) and (Map[a.ToLoc] and fTerrain = fOcean) then817 begin 818 result := eDomainMismatch;819 exit;816 if (A.ToLoc <> maNextCity) and (Map[A.ToLoc] and fTerrain = fOcean) then 817 begin 818 Result := eDomainMismatch; 819 Exit; 820 820 end 821 821 else … … 826 826 MoveInfo := gmaGround_NoZoC; 827 827 if Cap[mcOver] > 0 then 828 inc(MoveInfo, gmaOver);828 Inc(MoveInfo, gmaOver); 829 829 if Cap[mcAlpine] > 0 then 830 inc(MoveInfo, gmaAlpine);830 Inc(MoveInfo, gmaAlpine); 831 831 HeavyCost := 50 + (Speed - 150) * 13 shr 7; 832 if GWonder[woShinkansen].EffectiveOwner = pthen832 if GWonder[woShinkansen].EffectiveOwner = P then 833 833 RailCost := 0 834 834 else … … 836 836 maxmov := Speed; 837 837 initmov := 0; 838 Resistant := (GWonder[woGardens].EffectiveOwner = p) or838 Resistant := (GWonder[woGardens].EffectiveOwner = P) or 839 839 (Kind = mkSettler) and (Speed >= 200); 840 840 end; 841 841 dSea: 842 if ( a.ToLoc <> maNextCity) and (Map[a.ToLoc] and fTerrain >= fGrass) and843 (Map[ a.ToLoc] and (fCity or fUnit or fCanal) = 0) then844 begin 845 result := eDomainMismatch;846 exit;842 if (A.ToLoc <> maNextCity) and (Map[A.ToLoc] and fTerrain >= fGrass) and 843 (Map[A.ToLoc] and (fCity or fUnit or fCanal) = 0) then 844 begin 845 Result := eDomainMismatch; 846 Exit; 847 847 end 848 848 else … … 850 850 MoveInfo := gmaSea; 851 851 if Cap[mcNav] > 0 then 852 inc(MoveInfo, gmaNav);853 maxmov := UnitSpeed( p, RW[p].Un[uix].mix, 100);854 initmov := maxmov - UnitSpeed( p, RW[p].Un[uix].mix,855 RW[ p].Un[uix].Health);852 Inc(MoveInfo, gmaNav); 853 maxmov := UnitSpeed(P, RW[P].Un[uix].mix, 100); 854 initmov := maxmov - UnitSpeed(P, RW[P].Un[uix].mix, 855 RW[P].Un[uix].Health); 856 856 end; 857 857 dAir: … … 863 863 end; 864 864 865 FromLoc := RW[ p].Un[uix].Loc;865 FromLoc := RW[P].Un[uix].Loc; 866 866 FillChar(Time, SizeOf(Time), 255); { -1 } 867 867 Damage[FromLoc] := 0; 868 868 Q := TIPQ.Create(MapSize); 869 Q.Put(FromLoc, (maxmov - RW[ p].Un[uix].Movement) shl 8);869 Q.Put(FromLoc, (maxmov - RW[P].Un[uix].Movement) shl 8); 870 870 while Q.Get(Loc, T) do 871 871 begin 872 872 Time[Loc] := T; 873 if T >= ( a.MoreTurns + 1) shl 20 then873 if T >= (A.MoreTurns + 1) shl 20 then 874 874 begin 875 875 Loc := -1; … … 877 877 end; 878 878 FromTile := Map[Loc]; 879 if (Loc = a.ToLoc) or (a.ToLoc = maNextCity) and (FromTile and fCity <> 0)879 if (Loc = A.ToLoc) or (A.ToLoc = maNextCity) and (FromTile and fCity <> 0) 880 880 then 881 881 Break; 882 882 if T and $FFF00 = $FFF00 then 883 inc(T, $100000); // indicates mountain delay883 Inc(T, $100000); // indicates mountain delay 884 884 V8_to_Loc(Loc, Adjacent); 885 885 for V8 := 0 to 7 do … … 889 889 begin 890 890 ToTile := Map[Loc1]; 891 if (Loc1 = a.ToLoc) and (ToTile and (fUnit or fOwned) = fUnit) and891 if (Loc1 = A.ToLoc) and (ToTile and (fUnit or fOwned) = fUnit) and 892 892 not((MoveInfo and 3 = gmaSea) and (FromTile and fTerrain >= fGrass)) 893 893 and not((MoveInfo and 3 = gmaAir) and ((FromTile and fCity <> 0) or … … 898 898 end 899 899 else if (ToTile and fTerrain <> fUNKNOWN) and 900 ((Loc1 = a.ToLoc) or (ToTile and (fCity or fOwned) <> fCity))900 ((Loc1 = A.ToLoc) or (ToTile and (fCity or fOwned) <> fCity)) 901 901 // don't move through enemy cities 902 and ((Loc1 = a.ToLoc) or (ToTile and (fUnit or fOwned) <> fUnit))902 and ((Loc1 = A.ToLoc) or (ToTile and (fUnit or fOwned) <> fUnit)) 903 903 // way is blocked 904 904 and (ToTile and not FromTile and fPeace = 0) and … … 910 910 // calculate move cost, must be identic to GetMoveCost function 911 911 AddDamage := 0; 912 MountainDelay := false;912 MountainDelay := False; 913 913 case MoveInfo of 914 914 … … 956 956 begin 957 957 MoveCost := maxmov; 958 MountainDelay := true;958 MountainDelay := True; 959 959 end; 960 960 end; … … 990 990 if (MoveCost > 0) and not MountainDelay then 991 991 if V8 and 1 <> 0 then 992 inc(MoveCost, MoveCost * 2)992 Inc(MoveCost, MoveCost * 2) 993 993 else 994 inc(MoveCost, MoveCost);994 Inc(MoveCost, MoveCost); 995 995 996 996 if (MoveInfo and 2 <> 0) // ground unit, check transport load/unload … … 1011 1011 if FromTile and (fTerrain or fCity or fRiver or fCanal or 1012 1012 fSpecial1 { Oasis } ) = fDesert then 1013 inc(AddDamage, (DesertThurst * (maxmov - T shr 8 and $FFF) -1013 Inc(AddDamage, (DesertThurst * (maxmov - T shr 8 and $FFF) - 1014 1014 1) div maxmov + 1) 1015 1015 else if FromTile and (fTerrain or fCity or fRiver or fCanal) = fArctic 1016 1016 then 1017 inc(AddDamage, (ArcticThurst * (maxmov - T shr 8 and $FFF) -1017 Inc(AddDamage, (ArcticThurst * (maxmov - T shr 8 and $FFF) - 1018 1018 1) div maxmov + 1); 1019 1019 … … 1037 1037 end; 1038 1038 FreeAndNil(Q); 1039 if (Loc = a.ToLoc) or (a.ToLoc = maNextCity) and (Loc >= 0) and1039 if (Loc = A.ToLoc) or (A.ToLoc = maNextCity) and (Loc >= 0) and 1040 1040 (Map[Loc] and fCity <> 0) then 1041 1041 begin 1042 a.MoreTurns := T shr 20;1042 A.MoreTurns := T shr 20; 1043 1043 EndLoc := Loc; 1044 a.nStep := 0;1044 A.nStep := 0; 1045 1045 while Loc <> FromLoc do 1046 1046 begin 1047 1047 if Time[Loc] < $100000 then 1048 inc(a.nStep);1048 Inc(A.nStep); 1049 1049 Loc := From[Loc]; 1050 1050 end; 1051 1051 Loc := EndLoc; 1052 i := a.nStep;1052 I := A.nStep; 1053 1053 while Loc <> FromLoc do 1054 1054 begin 1055 1055 if Time[Loc] < $100000 then 1056 1056 begin 1057 dec(i);1058 if i< 25 then1059 begin 1060 a.dx[i] := ((Loc mod lx * 2 + Loc div lx and 1) -1057 Dec(I); 1058 if I < 25 then 1059 begin 1060 A.dx[I] := ((Loc mod lx * 2 + Loc div lx and 1) - 1061 1061 (From[Loc] mod lx * 2 + From[Loc] div lx and 1) + 3 * lx) 1062 1062 mod (2 * lx) - lx; 1063 a.dy[i] := Loc div lx - From[Loc] div lx;1063 A.dy[I] := Loc div lx - From[Loc] div lx; 1064 1064 end 1065 1065 end; 1066 1066 Loc := From[Loc]; 1067 1067 end; 1068 a.MaxHostile_MovementLeft := maxmov - Time[EndLoc] shr 8 and $FFF;1069 if a.nStep > 25 then1070 a.nStep := 25;1071 result := eOK1068 A.MaxHostile_MovementLeft := maxmov - Time[EndLoc] shr 8 and $FFF; 1069 if A.nStep > 25 then 1070 A.nStep := 25; 1071 Result := eOK 1072 1072 end 1073 1073 else 1074 result := eNoWay;1074 Result := eNoWay; 1075 1075 1076 1076 // QueryPerformanceCounter(tt);{time in s is: (tt-tt0)/PerfFreq} 1077 1077 end; 1078 1078 1079 function CanPlaneReturn( p, uix: integer;1080 PlaneReturnData: TPlaneReturnData): boolean;1079 function CanPlaneReturn(P, uix: Integer; 1080 PlaneReturnData: TPlaneReturnData): Boolean; 1081 1081 const 1082 1082 mfEnd = 1; 1083 1083 mfReached = 2; 1084 1084 var 1085 uix1, T, T1, Loc, Loc1, FromTile, ToTile, V8, MoveCost, maxmov: integer;1085 uix1, T, T1, Loc, Loc1, FromTile, ToTile, V8, MoveCost, maxmov: Integer; 1086 1086 Map: ^TTileList; 1087 1087 Q: TIPQ; 1088 1088 Adjacent: TVicinity8Loc; 1089 MapFlags: array [0 .. lxmax * lymax - 1] of byte;1090 begin 1091 Map := @(RW[ p].Map^);1089 MapFlags: array [0 .. lxmax * lymax - 1] of Byte; 1090 begin 1091 Map := @(RW[P].Map^); 1092 1092 1093 1093 // calculate possible return points 1094 1094 FillChar(MapFlags, SizeOf(MapFlags), 0); 1095 if RW[ p].Model[RW[p].Un[uix].mix].Kind = mkSpecial_Glider then1095 if RW[P].Model[RW[P].Un[uix].mix].Kind = mkSpecial_Glider then 1096 1096 begin 1097 1097 for Loc := 0 to MapSize - 1 do … … 1106 1106 (Map[Loc] and (fUnit or fOwned) <> fUnit) then 1107 1107 MapFlags[Loc] := MapFlags[Loc] or mfEnd; 1108 if RW[ p].Model[RW[p].Un[uix].mix].Cap[mcAirTrans] = 0 then1108 if RW[P].Model[RW[P].Un[uix].mix].Cap[mcAirTrans] = 0 then 1109 1109 // plane can land on carriers 1110 for uix1 := 0 to RW[ p].nUn - 1 do1111 with RW[ p].Un[uix1], RW[p].Model[mix] do1110 for uix1 := 0 to RW[P].nUn - 1 do 1111 with RW[P].Un[uix1], RW[P].Model[mix] do 1112 1112 if AirLoad < MTrans * Cap[mcCarrier] then 1113 1113 MapFlags[Loc] := MapFlags[Loc] or mfEnd; 1114 1114 end; 1115 1115 1116 with RW[ p].Un[uix] do1116 with RW[P].Un[uix] do 1117 1117 begin 1118 1118 if Master >= 0 then // can return to same carrier, even if full now 1119 1119 MapFlags[Loc] := MapFlags[Loc] or mfEnd; 1120 maxmov := RW[ p].Model[mix].Speed;1120 maxmov := RW[P].Model[mix].Speed; 1121 1121 end; 1122 1122 1123 result := false;1123 Result := False; 1124 1124 Q := TIPQ.Create(MapSize); 1125 1125 Q.Put(PlaneReturnData.Loc, (maxmov - PlaneReturnData.Movement) shl 8); … … 1129 1129 if T >= (PlaneReturnData.Fuel + 1) shl 20 then 1130 1130 begin 1131 result := false;1131 Result := False; 1132 1132 Break; 1133 1133 end; 1134 1134 if MapFlags[Loc] and mfEnd <> 0 then 1135 1135 begin 1136 result := true;1136 Result := True; 1137 1137 Break; 1138 1138 end; … … 1173 1173 ____________________________________________________________________ 1174 1174 } 1175 function CalculateJobWork( p, Loc, Job: integer; var JobWork: integer): integer;1176 var 1177 TerrType: integer;1178 begin 1179 result := eOK;1175 function CalculateJobWork(P, Loc, Job: Integer; var JobWork: Integer): Integer; 1176 var 1177 TerrType: Integer; 1178 begin 1179 Result := eOK; 1180 1180 TerrType := RealMap[Loc] and fTerrain; 1181 1181 with Terrain[TerrType] do … … 1183 1183 jCity: 1184 1184 if RealMap[Loc] and fCity <> 0 then 1185 result := eInvalid1185 Result := eInvalid 1186 1186 else if IrrEff = 0 then 1187 result := eNoCityTerrain1187 Result := eNoCityTerrain 1188 1188 else 1189 1189 JobWork := CityWork; … … 1193 1193 JobWork := MoveCost * RoadWork; 1194 1194 if RealMap[Loc] and fRiver <> 0 then 1195 if RW[ p].Tech[adBridgeBuilding] >= tsApplicable then1196 inc(JobWork, RoadBridgeWork) { across river }1195 if RW[P].Tech[adBridgeBuilding] >= tsApplicable then 1196 Inc(JobWork, RoadBridgeWork) { across river } 1197 1197 else 1198 result := eNoBridgeBuilding;1198 Result := eNoBridgeBuilding; 1199 1199 end 1200 1200 else 1201 result := eInvalid;1201 Result := eInvalid; 1202 1202 jRR: 1203 1203 if RealMap[Loc] and fRoad = 0 then 1204 result := eNoPreq1204 Result := eNoPreq 1205 1205 else if RealMap[Loc] and fRR <> 0 then 1206 result := eInvalid1206 Result := eInvalid 1207 1207 else 1208 1208 begin 1209 1209 JobWork := MoveCost * RRWork; 1210 1210 if RealMap[Loc] and fRiver <> 0 then 1211 inc(JobWork, RRBridgeWork); { across river }1211 Inc(JobWork, RRBridgeWork); { across river } 1212 1212 end; 1213 1213 jClear: 1214 if (TerrType = fDesert) and (GWonder[woGardens].EffectiveOwner <> p)1214 if (TerrType = fDesert) and (GWonder[woGardens].EffectiveOwner <> P) 1215 1215 then 1216 result := eInvalid1216 Result := eInvalid 1217 1217 else if ClearTerrain >= 0 then 1218 1218 JobWork := IrrClearWork 1219 1219 else 1220 result := eInvalid;1220 Result := eInvalid; 1221 1221 jIrr: 1222 1222 begin … … 1224 1224 if (IrrEff = 0) or (RealMap[Loc] and fTerImp = tiIrrigation) or 1225 1225 (RealMap[Loc] and fTerImp = tiFarm) then 1226 result := eInvalid;1226 Result := eInvalid; 1227 1227 end; 1228 1228 jFarm: 1229 1229 if RealMap[Loc] and fTerImp <> tiIrrigation then 1230 result := eNoPreq1230 Result := eNoPreq 1231 1231 else 1232 1232 begin 1233 1233 JobWork := IrrClearWork * FarmWork; 1234 1234 if (JobWork <= 0) or (RealMap[Loc] and fTerImp = tiFarm) then 1235 result := eInvalid;1235 Result := eInvalid; 1236 1236 end; 1237 1237 jAfforest: … … 1239 1239 JobWork := MineAfforestWork 1240 1240 else 1241 result := eInvalid;1241 Result := eInvalid; 1242 1242 jMine: 1243 1243 begin 1244 1244 JobWork := MineAfforestWork; 1245 1245 if (MineEff = 0) or (RealMap[Loc] and fTerImp = tiMine) then 1246 result := eInvalid;1246 Result := eInvalid; 1247 1247 end; 1248 1248 jFort: … … 1250 1250 JobWork := MoveCost * FortWork 1251 1251 else 1252 result := eInvalid;1252 Result := eInvalid; 1253 1253 jCanal: 1254 1254 if (RealMap[Loc] and fCanal = 0) and (TerrType in TerrType_Canalable) … … 1256 1256 JobWork := CanalWork 1257 1257 else 1258 result := eInvalid;1258 Result := eInvalid; 1259 1259 jTrans: 1260 1260 begin 1261 1261 JobWork := TransWork; 1262 1262 if JobWork <= 0 then 1263 result := eInvalid;1263 Result := eInvalid; 1264 1264 end; 1265 1265 jPoll: … … 1267 1267 JobWork := PollWork 1268 1268 else 1269 result := eInvalid;1269 Result := eInvalid; 1270 1270 jBase: 1271 1271 if RealMap[Loc] and fTerImp <> tiBase then 1272 1272 JobWork := MoveCost * BaseWork 1273 1273 else 1274 result := eInvalid;1274 Result := eInvalid; 1275 1275 jPillage: 1276 1276 if RealMap[Loc] and (fRoad or fRR or fCanal or fTerImp) <> 0 then 1277 1277 JobWork := PillageWork 1278 1278 else 1279 result := eInvalid;1280 end; 1281 end; 1282 1283 function StartJob( p, uix, NewJob: integer; TestOnly: boolean): integer;1284 var 1285 JobWork, Loc0, p1, uix1, TerrType: integer;1286 begin 1287 {$IFOPT O-} assert(1 shl pand InvalidTreatyMap = 0); {$ENDIF}1288 result := eOK;1289 with RW[ p].Un[uix] do1279 Result := eInvalid; 1280 end; 1281 end; 1282 1283 function StartJob(P, uix, NewJob: Integer; TestOnly: Boolean): Integer; 1284 var 1285 JobWork, Loc0, p1, uix1, TerrType: Integer; 1286 begin 1287 {$IFOPT O-}Assert(1 shl P and InvalidTreatyMap = 0); {$ENDIF} 1288 Result := eOK; 1289 with RW[P].Un[uix] do 1290 1290 begin 1291 1291 if NewJob = Job then 1292 1292 begin 1293 result := eNotChanged;1294 exit;1293 Result := eNotChanged; 1294 Exit; 1295 1295 end; 1296 1296 if NewJob = jNone then … … 1298 1298 if not TestOnly then 1299 1299 Job := jNone; 1300 exit;1300 Exit; 1301 1301 end; 1302 1302 Loc0 := Loc; … … 1304 1304 (NewJob <> jRR) then 1305 1305 begin 1306 result := eDeadLands;1307 exit;1306 Result := eDeadLands; 1307 Exit; 1308 1308 end; 1309 1309 TerrType := RealMap[Loc0] and fTerrain; 1310 1310 if (RealMap[Loc0] and fCity <> 0) or (TerrType < fGrass) or (Master >= 0) or 1311 not((NewJob = jPillage) and (RW[ p].Model[mix].Domain = dGround) or1312 (RW[ p].Model[mix].Kind = mkSettler) or (NewJob <> jCity) and1313 (RW[ p].Model[mix].Kind = mkSlaves) and (GWonder[woPyramids].EffectiveOwner1311 not((NewJob = jPillage) and (RW[P].Model[mix].Domain = dGround) or 1312 (RW[P].Model[mix].Kind = mkSettler) or (NewJob <> jCity) and 1313 (RW[P].Model[mix].Kind = mkSlaves) and (GWonder[woPyramids].EffectiveOwner 1314 1314 >= 0)) then 1315 1315 begin 1316 result := eInvalid;1317 exit;1316 Result := eInvalid; 1317 Exit; 1318 1318 end; 1319 1319 if (JobPreq[NewJob] <> preNone) and 1320 (RW[ p].Tech[JobPreq[NewJob]] < tsApplicable) then1321 begin 1322 result := eNoPreq;1323 exit;1324 end; 1325 1326 result := CalculateJobWork(p, Loc0, NewJob, JobWork);1327 if (Mode = moPlaying) and ( result = eOK) and (NewJob <> jPoll) then1320 (RW[P].Tech[JobPreq[NewJob]] < tsApplicable) then 1321 begin 1322 Result := eNoPreq; 1323 Exit; 1324 end; 1325 1326 Result := CalculateJobWork(P, Loc0, NewJob, JobWork); 1327 if (Mode = moPlaying) and (Result = eOK) and (NewJob <> jPoll) then 1328 1328 begin // not allowed in territory of friendly nation 1329 1329 p1 := RealMap[Loc0] shr 27; // owner of territory 1330 if (p1 < nPl) and (p1 <> p) and (RW[p].Treaty[p1] >= trPeace) then1331 result := eTreaty; // keep peace treaty!1332 end; 1333 if TestOnly or ( result < rExecuted) then1334 exit;1330 if (p1 < nPl) and (p1 <> P) and (RW[P].Treaty[p1] >= trPeace) then 1331 Result := eTreaty; // keep peace treaty! 1332 end; 1333 if TestOnly or (Result < rExecuted) then 1334 Exit; 1335 1335 1336 1336 if (ToWork[Loc0, NewJob] = 0) or (ToWork[Loc0, NewJob] > JobWork) then … … 1338 1338 Job := NewJob; 1339 1339 Flags := Flags and not unFortified; 1340 for uix1 := 0 to RW[ p].nUn - 1 do1341 if (RW[ p].Un[uix1].Loc = Loc) and1342 (RW[ p].Un[uix1].Job in ContraJobs[NewJob]) then1343 RW[ p].Un[uix1].Job := jNone; // stop contradictive jobs1344 if ServerVersion[ p] < $000EF0 then1345 if Work( p, uix) then1346 result := eJobDone;1347 if (NewJob = jCity) and ( result = eJobDone) then1348 begin 1349 RemoveUnit_UpdateMap( p, uix);1350 result := eCity;1340 for uix1 := 0 to RW[P].nUn - 1 do 1341 if (RW[P].Un[uix1].Loc = Loc) and 1342 (RW[P].Un[uix1].Job in ContraJobs[NewJob]) then 1343 RW[P].Un[uix1].Job := jNone; // stop contradictive jobs 1344 if ServerVersion[P] < $000EF0 then 1345 if Work(P, uix) then 1346 Result := eJobDone; 1347 if (NewJob = jCity) and (Result = eJobDone) then 1348 begin 1349 RemoveUnit_UpdateMap(P, uix); 1350 Result := eCity; 1351 1351 end 1352 1352 else if Health <= 0 then 1353 1353 begin // victim of HostileDamage 1354 RemoveUnit_UpdateMap( p, uix);1355 result := result or rUnitRemoved;1354 RemoveUnit_UpdateMap(P, uix); 1355 Result := Result or rUnitRemoved; 1356 1356 end; 1357 1357 if Mode > moLoading_Fast then 1358 1358 begin 1359 if result = eCity then1360 begin 1361 ObserveLevel[Loc0] := ObserveLevel[Loc0] and not(3 shl (2 * p));1362 Discover21(Loc0, p, lObserveUnhidden, true, true);1359 if Result = eCity then 1360 begin 1361 ObserveLevel[Loc0] := ObserveLevel[Loc0] and not(3 shl (2 * P)); 1362 Discover21(Loc0, P, lObserveUnhidden, True, True); 1363 1363 // CheckContact; 1364 1364 end; … … 1367 1367 end; 1368 1368 1369 function Work( p, uix: integer): boolean;1370 var 1371 uix1, j0: integer;1372 begin 1373 result := false;1374 with RW[ p].Un[uix] do1369 function Work(P, uix: Integer): Boolean; 1370 var 1371 uix1, j0: Integer; 1372 begin 1373 Result := False; 1374 with RW[P].Un[uix] do 1375 1375 if Movement >= 100 then 1376 1376 begin 1377 assert(ToWork[Loc, Job] < $FFFF); // should have been set by StartJob1377 Assert(ToWork[Loc, Job] < $FFFF); // should have been set by StartJob 1378 1378 if Job >= jRoad then 1379 if integer(Movement) >= integer(ToWork[Loc, Job]) then { work complete }1380 begin 1381 result := true;1379 if Integer(Movement) >= Integer(ToWork[Loc, Job]) then { work complete } 1380 begin 1381 Result := True; 1382 1382 if Job <> jIrr then 1383 Health := Health - HostileDamage( p, mix, Loc, ToWork[Loc, Job]);1384 dec(Movement, ToWork[Loc, Job]);1383 Health := Health - HostileDamage(P, mix, Loc, ToWork[Loc, Job]); 1384 Dec(Movement, ToWork[Loc, Job]); 1385 1385 if not(Job in [jCity, jPillage, jPoll]) then 1386 inc(Worked[p], ToWork[Loc, Job]);1386 Inc(Worked[P], ToWork[Loc, Job]); 1387 1387 if Job = jCity then 1388 1388 begin // found new city 1389 FoundCity( p, Loc);1390 inc(Founded[p]);1391 with RW[ p].City[RW[p].nCity - 1] do1389 FoundCity(P, Loc); 1390 Inc(Founded[P]); 1391 with RW[P].City[RW[P].nCity - 1] do 1392 1392 begin 1393 ID := p shl 12 + Founded[p] - 1;1393 ID := P shl 12 + Founded[P] - 1; 1394 1394 Flags := chFounded; 1395 1395 end; 1396 1396 if Mode = moPlaying then 1397 1397 begin 1398 LogCheckBorders( p, RW[p].nCity - 1);1399 RecalcPeaceMap( p);1398 LogCheckBorders(P, RW[P].nCity - 1); 1399 RecalcPeaceMap(P); 1400 1400 end; 1401 1401 {$IFOPT O-} if Mode < moPlaying then 1402 InvalidTreatyMap := not(1 shl p); {$ENDIF}1402 InvalidTreatyMap := not(1 shl P); {$ENDIF} 1403 1403 // territory should not be considered for the rest of the command 1404 1404 // execution, because during loading a game it's incorrect before 1405 1405 // subsequent sIntExpandTerritory is processed 1406 RW[ p].Un[uix].Health := 0; // causes unit to be removed later1406 RW[P].Un[uix].Health := 0; // causes unit to be removed later 1407 1407 end 1408 1408 else 1409 CompleteJob( p, Loc, Job);1409 CompleteJob(P, Loc, Job); 1410 1410 ToWork[Loc, Job] := 0; 1411 1411 j0 := Job; 1412 for uix1 := 0 to RW[ p].nUn - 1 do1413 if (RW[ p].Un[uix1].Loc = Loc) and (RW[p].Un[uix1].Job = j0) then1414 RW[ p].Un[uix1].Job := jNone1412 for uix1 := 0 to RW[P].nUn - 1 do 1413 if (RW[P].Un[uix1].Loc = Loc) and (RW[P].Un[uix1].Job = j0) then 1414 RW[P].Un[uix1].Job := jNone 1415 1415 end 1416 1416 else 1417 1417 begin 1418 dec(ToWork[Loc, Job], Movement);1418 Dec(ToWork[Loc, Job], Movement); 1419 1419 if not(Job in [jCity, jPillage, jPoll]) then 1420 inc(Worked[p], Movement);1421 Health := Health - HostileDamage( p, mix, Loc, Movement);1420 Inc(Worked[P], Movement); 1421 Health := Health - HostileDamage(P, mix, Loc, Movement); 1422 1422 Movement := 0; 1423 1423 end … … 1425 1425 end; 1426 1426 1427 function GetJobProgress( p, Loc: integer;1428 var JobProgressData: TJobProgressData): integer;1429 var 1430 Job, JobResult, uix: integer;1427 function GetJobProgress(P, Loc: Integer; 1428 var JobProgressData: TJobProgressData): Integer; 1429 var 1430 Job, JobResult, uix: Integer; 1431 1431 begin 1432 1432 for Job := 0 to nJob - 1 do 1433 1433 begin 1434 JobResult := CalculateJobWork( p, Loc, Job, JobProgressData[Job].Required);1434 JobResult := CalculateJobWork(P, Loc, Job, JobProgressData[Job].Required); 1435 1435 if JobResult = eOK then 1436 1436 begin … … 1448 1448 JobProgressData[Job].NextTurnPlus := 0; 1449 1449 end; 1450 for uix := 0 to RW[ p].nUn - 1 do1451 if (RW[ p].Un[uix].Loc = Loc) and (RW[p].Un[uix].Movement >= 100) then1452 inc(JobProgressData[RW[p].Un[uix].Job].NextTurnPlus,1453 RW[ p].Un[uix].Movement);1454 result := eOK;1450 for uix := 0 to RW[P].nUn - 1 do 1451 if (RW[P].Un[uix].Loc = Loc) and (RW[P].Un[uix].Movement >= 100) then 1452 Inc(JobProgressData[RW[P].Un[uix].Job].NextTurnPlus, 1453 RW[P].Un[uix].Movement); 1454 Result := eOK; 1455 1455 end; 1456 1456
Note:
See TracChangeset
for help on using the changeset viewer.