Changeset 465 for branches/highdpi/Database.pas
- Timestamp:
- Nov 30, 2023, 10:16:14 PM (12 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/highdpi/Database.pas
r349 r465 26 26 27 27 nStartUn = 1; 28 StartUn: array [0 .. nStartUn - 1] of integer = (0); // mix of start units28 StartUn: array [0 .. nStartUn - 1] of Integer = (0); // mix of start units 29 29 30 30 CityOwnTile = 13; … … 50 50 Mode: TGameMode; 51 51 GWonder: array [0 .. nWonder - 1] of TWonderInfo; 52 ServerVersion: array [0 .. nPl - 1] of integer;53 ProcessClientData: array [0 .. nPl - 1] of boolean;52 ServerVersion: array [0 .. nPl - 1] of Integer; 53 ProcessClientData: array [0 .. nPl - 1] of Boolean; 54 54 CL: TCmdList; 55 55 {$IFDEF TEXTLOG}CmdInfo: string; … … 58 58 // map data 59 59 RealMap: array [0 .. lxmax * lymax - 1] of Cardinal; 60 Continent: array [0 .. lxmax * lymax - 1] of integer;60 Continent: array [0 .. lxmax * lymax - 1] of Integer; 61 61 { continent id for each tile } 62 62 Occupant: array [0 .. lxmax * lymax - 1] of ShortInt; … … 65 65 ObserveLevel: array [0 .. lxmax * lymax - 1] of Cardinal; 66 66 { Observe Level of player p in bits 2*p and 2*p+1 } 67 UsedByCity: array [0 .. lxmax * lymax - 1] of integer;67 UsedByCity: array [0 .. lxmax * lymax - 1] of Integer; 68 68 { location of exploiting city for 69 69 each tile, =-1 if not exploited } … … 71 71 // player data 72 72 RW: array [0 .. nPl - 1] of TPlayerContext; { player data } 73 Difficulty: array [0 .. nPl - 1] of integer;73 Difficulty: array [0 .. nPl - 1] of Integer; 74 74 GShip: array [0 .. nPl - 1] of TShipInfo; 75 75 ResourceMask: array [0 .. nPl - 1] of Cardinal; 76 Founded: array [0 .. nPl - 1] of integer; { number of cities founded }77 TerritoryCount: array [0 .. nPl] of integer;76 Founded: array [0 .. nPl - 1] of Integer; { number of cities founded } 77 TerritoryCount: array [0 .. nPl] of Integer; 78 78 LastValidStat, Researched, Discovered, // number of tiles discovered 79 GrWallContinent: array [0 .. nPl - 1] of integer;79 GrWallContinent: array [0 .. nPl - 1] of Integer; 80 80 RWemix: array [0 .. nPl - 1, 0 .. nPl - 1, 0 .. nmmax - 1] of SmallInt; 81 81 // [p1,p2,mix] -> index of p2's model mix in p1's enemy model list 82 82 Destroyed: array [0 .. nPl - 1, 0 .. nPl - 1, 0 .. nmmax - 1] of SmallInt; 83 83 // [p1,p2,mix] -> number of p2's units with model mix that p1 has destroyed 84 nTech: array [0 .. nPl - 1] of integer; { number of known techs }84 nTech: array [0 .. nPl - 1] of Integer; { number of known techs } 85 85 // NewContact: array[0..nPl-1,0..nPl-1] of boolean; 86 86 87 87 type 88 TVicinity8Loc = array [0 .. 7] of integer;89 TVicinity21Loc = array [0 .. 27] of integer;90 91 procedure MaskD(var x: array of Cardinal; Count, Mask: Cardinal);92 procedure IntServer(Command, Player, Subject: integer; var Data);93 procedure CompactLists( p: integer);94 procedure ClearTestFlags(ClearFlags: integer);95 procedure SetTestFlags( p, SetFlags: integer);88 TVicinity8Loc = array [0 .. 7] of Integer; 89 TVicinity21Loc = array [0 .. 27] of Integer; 90 91 procedure MaskD(var X: array of Cardinal; Count, Mask: Cardinal); 92 procedure IntServer(Command, Player, Subject: Integer; var Data); 93 procedure CompactLists(P: Integer); 94 procedure ClearTestFlags(ClearFlags: Integer); 95 procedure SetTestFlags(P, SetFlags: Integer); 96 96 97 97 // Tech Related Functions 98 function TechBaseCost(nTech, diff: integer): integer;99 function TechCost( p: integer): integer;100 procedure CalculateModel(var m: TModel);101 procedure CheckSpecialModels( p, pre: integer);102 procedure EnableDevModel( p: integer);103 procedure SeeTech( p, ad: integer);104 procedure DiscoverTech( p, ad: integer);105 procedure CheckExpiration(Wonder: integer);98 function TechBaseCost(nTech, diff: Integer): Integer; 99 function TechCost(P: Integer): Integer; 100 procedure CalculateModel(var M: TModel); 101 procedure CheckSpecialModels(P, pre: Integer); 102 procedure EnableDevModel(P: Integer); 103 procedure SeeTech(P, ad: Integer); 104 procedure DiscoverTech(P, ad: Integer); 105 procedure CheckExpiration(Wonder: Integer); 106 106 107 107 // Location Navigation 108 function dLoc(Loc, dx, dy: integer): integer;109 procedure dxdy(Loc0, Loc1: integer; var dx, dy: integer);110 function Distance(Loc0, Loc1: integer): integer;111 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);112 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);108 function dLoc(Loc, dx, dy: Integer): Integer; 109 procedure dxdy(Loc0, Loc1: Integer; var dx, dy: Integer); 110 function Distance(Loc0, Loc1: Integer): Integer; 111 procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc); 112 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc); 113 113 114 114 // Game Initialization 115 115 procedure InitRandomGame; 116 procedure InitMapGame(Human: integer);116 procedure InitMapGame(Human: Integer); 117 117 procedure ReleaseGame; 118 118 119 119 // Map Editor 120 function MapGeneratorAvailable: boolean;120 function MapGeneratorAvailable: Boolean; 121 121 procedure CreateElevation; 122 procedure CreateMap(preview: boolean);122 procedure CreateMap(preview: Boolean); 123 123 procedure InitMapEditor; 124 124 procedure ReleaseMapEditor; 125 procedure EditTile(Loc, NewTile: integer);125 procedure EditTile(Loc, NewTile: Integer); 126 126 127 127 // Map Revealing 128 function GetTileInfo( p, cix, Loc: integer; var Info: TTileInfo): integer;129 procedure Strongest(Loc: integer; var uix, Strength, Bonus, Cnt: integer);130 function UnitSpeed( p, mix, Health: integer): integer;131 procedure GetUnitReport( p, uix: integer; var UnitReport: TUnitReport);132 procedure SearchCity(Loc: integer; var p, cix: integer);133 procedure TellAboutModel( p, taOwner, tamix: integer);134 function emixSafe( p, taOwner, tamix: integer): integer;135 function Discover9(Loc, p, Level: integer;136 TellAllied, EnableContact: boolean): boolean;137 function Discover21(Loc, p, AdjacentLevel: integer;138 TellAllied, EnableContact: boolean): boolean;139 procedure DiscoverAll( p, Level: integer);140 procedure DiscoverViewAreas( p: integer);141 function GetUnitStack( p, Loc: integer): integer;142 procedure UpdateUnitMap(Loc: integer; CityChange: boolean = false);143 procedure RecalcV8ZoC( p, Loc: integer);144 procedure RecalcMapZoC( p: integer);145 procedure RecalcPeaceMap( p: integer);128 function GetTileInfo(P, cix, Loc: Integer; var Info: TTileInfo): Integer; 129 procedure Strongest(Loc: Integer; var uix, Strength, Bonus, Cnt: Integer); 130 function UnitSpeed(P, mix, Health: Integer): Integer; 131 procedure GetUnitReport(P, uix: Integer; var UnitReport: TUnitReport); 132 procedure SearchCity(Loc: Integer; var P, cix: Integer); 133 procedure TellAboutModel(P, taOwner, tamix: Integer); 134 function emixSafe(P, taOwner, tamix: Integer): Integer; 135 function Discover9(Loc, P, Level: Integer; 136 TellAllied, EnableContact: Boolean): Boolean; 137 function Discover21(Loc, P, AdjacentLevel: Integer; 138 TellAllied, EnableContact: Boolean): Boolean; 139 procedure DiscoverAll(P, Level: Integer); 140 procedure DiscoverViewAreas(P: Integer); 141 function GetUnitStack(P, Loc: Integer): Integer; 142 procedure UpdateUnitMap(Loc: Integer; CityChange: Boolean = False); 143 procedure RecalcV8ZoC(P, Loc: Integer); 144 procedure RecalcMapZoC(P: Integer); 145 procedure RecalcPeaceMap(P: Integer); 146 146 147 147 // Territory Calculation 148 procedure CheckBorders(OriginLoc: integer; PlayerLosingCity: integer = -1);149 procedure LogCheckBorders( p, cix: integer; PlayerLosingCity: integer = -1);148 procedure CheckBorders(OriginLoc: Integer; PlayerLosingCity: Integer = -1); 149 procedure LogCheckBorders(P, cix: Integer; PlayerLosingCity: Integer = -1); 150 150 151 151 // Map Processing 152 procedure CreateUnit( p, mix: integer);153 procedure FreeUnit( p, uix: integer);154 procedure PlaceUnit( p, uix: integer);155 procedure RemoveUnit( p, uix: integer; Enemy: integer = -1);156 procedure RemoveUnit_UpdateMap( p, uix: integer);157 procedure RemoveAllUnits( p, Loc: integer; Enemy: integer = -1);158 procedure RemoveDomainUnits( d, p, Loc: integer);159 procedure FoundCity( p, FoundLoc: integer);160 procedure DestroyCity( p, cix: integer; SaveUnits: boolean);161 procedure ChangeCityOwner(pOld, cixOld, pNew: integer);162 procedure CompleteJob( p, Loc, Job: integer);152 procedure CreateUnit(P, mix: Integer); 153 procedure FreeUnit(P, uix: Integer); 154 procedure PlaceUnit(P, uix: Integer); 155 procedure RemoveUnit(P, uix: Integer; Enemy: Integer = -1); 156 procedure RemoveUnit_UpdateMap(P, uix: Integer); 157 procedure RemoveAllUnits(P, Loc: Integer; Enemy: Integer = -1); 158 procedure RemoveDomainUnits(D, P, Loc: Integer); 159 procedure FoundCity(P, FoundLoc: Integer); 160 procedure DestroyCity(P, cix: Integer; SaveUnits: Boolean); 161 procedure ChangeCityOwner(pOld, cixOld, pNew: Integer); 162 procedure CompleteJob(P, Loc, Job: Integer); 163 163 164 164 // Diplomacy 165 procedure IntroduceEnemy(p1, p2: integer); 166 procedure GiveCivilReport(p, pAbout: integer); 167 procedure GiveMilReport(p, pAbout: integer); 168 procedure ShowPrice(pSender, pTarget, Price: integer); 169 function PayPrice(pSender, pTarget, Price: integer; execute: boolean): boolean; 170 procedure CancelTreaty(p, pWith: integer; DecreaseCredibility: boolean = true); 171 function DoSpyMission(p, pCity, cix, Mission: integer): Cardinal; 165 procedure IntroduceEnemy(p1, p2: Integer); 166 procedure GiveCivilReport(P, pAbout: Integer); 167 procedure GiveMilReport(P, pAbout: Integer); 168 procedure ShowPrice(pSender, pTarget, Price: Integer); 169 function PayPrice(pSender, pTarget, Price: Integer; execute: Boolean): Boolean; 170 procedure CancelTreaty(P, pWith: Integer; DecreaseCredibility: Boolean = True); 171 function DoSpyMission(P, pCity, cix, Mission: Integer): Cardinal; 172 172 173 173 174 implementation … … 179 180 180 181 var 181 UnBuilt: array [0 .. nPl - 1] of integer; { number of units built }182 183 procedure MaskD(var x: array of Cardinal; Count, Mask: Cardinal);182 UnBuilt: array [0 .. nPl - 1] of Integer; { number of units built } 183 184 procedure MaskD(var X: array of Cardinal; Count, Mask: Cardinal); 184 185 var 185 186 I: Integer; 186 187 begin 187 188 for I := 0 to Count - 1 do 188 x[I] := x[I] and Mask;189 end; 190 191 procedure CompactLists( p: integer);192 var 193 uix, uix1, cix: integer;194 {$IFOPT O-}V21: integer;189 X[I] := X[I] and Mask; 190 end; 191 192 procedure CompactLists(P: Integer); 193 var 194 uix, uix1, cix: Integer; 195 {$IFOPT O-}V21: Integer; 195 196 Radius: TVicinity21Loc; {$ENDIF} 196 197 begin 197 with RW[ p] do198 with RW[P] do 198 199 begin 199 200 // compact unit list … … 202 203 if Un[uix].Loc < 0 then 203 204 begin 204 dec(nUn);205 Dec(nUn); 205 206 Un[uix] := Un[nUn]; { replace removed unit by last } 206 207 if (Un[uix].TroopLoad > 0) or (Un[uix].AirLoad > 0) then … … 211 212 end 212 213 else 213 inc(uix);214 Inc(uix); 214 215 215 216 // compact city list … … 218 219 if City[cix].Loc < 0 then 219 220 begin 220 dec(nCity);221 Dec(nCity); 221 222 City[cix] := City[nCity]; { replace city by last } 222 223 for uix1 := 0 to nUn - 1 do … … 226 227 end 227 228 else 228 inc(cix);229 Inc(cix); 229 230 230 231 // compact enemy city list … … 233 234 if EnemyCity[cix].Loc < 0 then 234 235 begin 235 dec(nEnemyCity);236 Dec(nEnemyCity); 236 237 EnemyCity[cix] := EnemyCity[nEnemyCity]; { replace city by last } 237 238 end 238 239 else 239 inc(cix);240 Inc(cix); 240 241 241 242 {$IFOPT O-} … … 246 247 for V21 := 1 to 26 do 247 248 if Tiles and (1 shl V21) <> 0 then 248 assert(UsedByCity[Radius[V21]] = Loc);249 end 249 Assert(UsedByCity[Radius[V21]] = Loc); 250 end; 250 251 {$ENDIF} 251 252 end; 252 end; // CompactLists253 end; 253 254 254 255 { … … 256 257 ____________________________________________________________________ 257 258 } 258 function TechBaseCost(nTech, diff: integer): integer;259 var 260 c0: single;259 function TechBaseCost(nTech, diff: Integer): Integer; 260 var 261 c0: Single; 261 262 begin 262 263 c0 := TechFormula_M[diff] * (nTech + 4) * 263 264 exp((nTech + 4) / TechFormula_D[diff]); 264 265 if c0 >= $10000000 then 265 result := $10000000266 Result := $10000000 266 267 else 267 result := trunc(c0)268 end; 269 270 function TechCost( p: integer): integer;271 begin 272 with RW[ p] do273 begin 274 result := TechBaseCost(nTech[p], Difficulty[p]);268 Result := trunc(c0); 269 end; 270 271 function TechCost(P: Integer): Integer; 272 begin 273 with RW[P] do 274 begin 275 Result := TechBaseCost(nTech[P], Difficulty[P]); 275 276 if ResearchTech >= 0 then 276 277 if (ResearchTech = adMilitary) or (Tech[ResearchTech] = tsSeen) then 277 result := result shr 1278 Result := Result shr 1 278 279 else if ResearchTech in FutureTech then 279 280 if Government = gFuture then 280 result := result * 2281 Result := Result * 2 281 282 else 282 result := result * 4;283 end 284 end; 285 286 procedure SetModelFlags(var m: TModel);287 begin 288 m.Flags := 0;289 if ( m.Domain = dGround) and (m.Kind <> mkDiplomat) then290 m.Flags := m.Flags or mdZOC;291 if ( m.Kind = mkDiplomat) or (m.Attack + m.Cap[mcBombs] = 0) then292 m.Flags := m.Flags or mdCivil;293 if ( m.Cap[mcOver] > 0) or (m.Domain = dSea) and (m.Weight >= 6) then294 m.Flags := m.Flags or mdDoubleSupport;295 end; 296 297 procedure CalculateModel(var m: TModel);283 Result := Result * 4; 284 end; 285 end; 286 287 procedure SetModelFlags(var M: TModel); 288 begin 289 M.Flags := 0; 290 if (M.Domain = dGround) and (M.Kind <> mkDiplomat) then 291 M.Flags := M.Flags or mdZOC; 292 if (M.Kind = mkDiplomat) or (M.Attack + M.Cap[mcBombs] = 0) then 293 M.Flags := M.Flags or mdCivil; 294 if (M.Cap[mcOver] > 0) or (M.Domain = dSea) and (M.Weight >= 6) then 295 M.Flags := M.Flags or mdDoubleSupport; 296 end; 297 298 procedure CalculateModel(var M: TModel); 298 299 { calculate attack, defense, cost... of a model by features } 299 300 var 300 i: integer;301 begin 302 with mdo301 I: Integer; 302 begin 303 with M do 303 304 begin 304 305 Attack := (Cap[mcOffense] + Cap[mcOver]) * MStrength; … … 311 312 Speed := 350 + 200 * Cap[mcNP] + 200 * Cap[mcTurbines]; 312 313 if Cap[mcNP] = 0 then 313 inc(Speed, 100 * Cap[mcSE]);314 Inc(Speed, 100 * Cap[mcSE]); 314 315 end; 315 316 dAir: … … 317 318 end; 318 319 Cost := 0; 319 for i:= 0 to nFeature - 1 do320 if 1 shl Domain and Feature[ i].Domains <> 0 then321 inc(Cost, Cap[i] * Feature[i].Cost);320 for I := 0 to nFeature - 1 do 321 if 1 shl Domain and Feature[I].Domains <> 0 then 322 Inc(Cost, Cap[I] * Feature[I].Cost); 322 323 Cost := Cost * MCost; 323 324 Weight := 0; 324 for i:= 0 to nFeature - 1 do325 if 1 shl Domain and Feature[ i].Domains <> 0 then326 if (Domain = dGround) and ( i= mcDefense) then327 inc(Weight, Cap[i] * 2)325 for I := 0 to nFeature - 1 do 326 if 1 shl Domain and Feature[I].Domains <> 0 then 327 if (Domain = dGround) and (I = mcDefense) then 328 Inc(Weight, Cap[I] * 2) 328 329 else 329 inc(Weight, Cap[i] * Feature[i].Weight);330 end; 331 SetModelFlags( m);332 end; 333 334 procedure CheckSpecialModels( p, pre: integer);335 var 336 i, mix1: integer;337 HasAlready: boolean;338 begin 339 for i:= 0 to nSpecialModel -330 Inc(Weight, Cap[I] * Feature[I].Weight); 331 end; 332 SetModelFlags(M); 333 end; 334 335 procedure CheckSpecialModels(P, pre: Integer); 336 var 337 I, mix1: Integer; 338 HasAlready: Boolean; 339 begin 340 for I := 0 to nSpecialModel - 340 341 1 do { check whether new special model available } 341 if (SpecialModelPreq[ i] = pre) and (RW[p].nModel < nmmax) then342 begin 343 HasAlready := false;344 for mix1 := 0 to RW[ p].nModel - 1 do345 if (RW[ p].Model[mix1].Kind = SpecialModel[i].Kind) and346 (RW[ p].Model[mix1].Attack = SpecialModel[i].Attack) and347 (RW[ p].Model[mix1].Speed = SpecialModel[i].Speed) then348 HasAlready := true;342 if (SpecialModelPreq[I] = pre) and (RW[P].nModel < nmmax) then 343 begin 344 HasAlready := False; 345 for mix1 := 0 to RW[P].nModel - 1 do 346 if (RW[P].Model[mix1].Kind = SpecialModel[I].Kind) and 347 (RW[P].Model[mix1].Attack = SpecialModel[I].Attack) and 348 (RW[P].Model[mix1].Speed = SpecialModel[I].Speed) then 349 HasAlready := True; 349 350 if not HasAlready then 350 351 begin 351 RW[ p].Model[RW[p].nModel] := SpecialModel[i];352 SetModelFlags(RW[ p].Model[RW[p].nModel]);353 with RW[ p].Model[RW[p].nModel] do352 RW[P].Model[RW[P].nModel] := SpecialModel[I]; 353 SetModelFlags(RW[P].Model[RW[P].nModel]); 354 with RW[P].Model[RW[P].nModel] do 354 355 begin 355 356 Status := 0; … … 358 359 Built := 0; 359 360 Lost := 0; 360 ID := p shl 12 + RW[p].nModel;361 if (Kind = mkSpecial_Boat) and (ServerVersion[ p] < $000EF0) then361 ID := P shl 12 + RW[P].nModel; 362 if (Kind = mkSpecial_Boat) and (ServerVersion[P] < $000EF0) then 362 363 Speed := 350; // old longboat 363 364 end; 364 inc(RW[p].nModel);365 end 366 end; 367 end; 368 369 procedure EnableDevModel( p: integer);370 begin 371 with RW[ p] do365 Inc(RW[P].nModel); 366 end; 367 end; 368 end; 369 370 procedure EnableDevModel(P: Integer); 371 begin 372 with RW[P] do 372 373 if nModel < nmmax then 373 374 begin … … 380 381 Built := 0; 381 382 Lost := 0; 382 ID := p shl 12 + nModel383 end; 384 inc(nModel);385 inc(Researched[p])386 end 387 end; 388 389 procedure SeeTech( p, ad: integer);390 begin 391 {$IFDEF TEXTLOG}CmdInfo := CmdInfo + Format(' P%d:A%d', [ p, ad]); {$ENDIF}392 RW[ p].Tech[ad] := tsSeen;383 ID := P shl 12 + nModel; 384 end; 385 Inc(nModel); 386 Inc(Researched[P]); 387 end; 388 end; 389 390 procedure SeeTech(P, ad: Integer); 391 begin 392 {$IFDEF TEXTLOG}CmdInfo := CmdInfo + Format(' P%d:A%d', [P, ad]); {$ENDIF} 393 RW[P].Tech[ad] := tsSeen; 393 394 // inc(nTech[p]); 394 inc(Researched[p])395 Inc(Researched[P]); 395 396 end; 396 397 397 398 procedure FreeSlaves; 398 399 var 399 p1, uix: integer;400 p1, uix: Integer; 400 401 begin 401 402 for p1 := 0 to nPl - 1 do … … 403 404 for uix := 0 to RW[p1].nUn - 1 do 404 405 if RW[p1].Model[RW[p1].Un[uix].mix].Kind = mkSlaves then 405 RW[p1].Un[uix].Job := jNone 406 end; 407 408 procedure DiscoverTech( p, ad: integer);409 410 procedure TellAboutKeyTech( p, Source: integer);406 RW[p1].Un[uix].Job := jNone; 407 end; 408 409 procedure DiscoverTech(P, ad: Integer); 410 411 procedure TellAboutKeyTech(P, Source: Integer); 411 412 var 412 i, p1: integer;413 begin 414 for i:= 1 to 3 do415 if ad = AgePreq[ i] then413 I, p1: Integer; 414 begin 415 for I := 1 to 3 do 416 if ad = AgePreq[I] then 416 417 for p1 := 0 to nPl - 1 do 417 if (p1 <> p) and ((GAlive or GWatching) and (1 shl p1) <> 0) then418 RW[p1].EnemyReport[ p].Tech[ad] := Source;419 end; 420 421 var 422 i: integer;418 if (p1 <> P) and ((GAlive or GWatching) and (1 shl p1) <> 0) then 419 RW[p1].EnemyReport[P].Tech[ad] := Source; 420 end; 421 422 var 423 I: Integer; 423 424 begin 424 425 if ad in FutureTech then 425 426 begin 426 if RW[ p].Tech[ad] < tsApplicable then427 RW[ p].Tech[ad] := 1427 if RW[P].Tech[ad] < tsApplicable then 428 RW[P].Tech[ad] := 1 428 429 else 429 inc(RW[p].Tech[ad]);430 Inc(RW[P].Tech[ad]); 430 431 if ad <> futResearchTechnology then 431 inc(nTech[p], 2);432 inc(Researched[p], 8);433 exit;434 end; 435 436 if RW[ p].Tech[ad] = tsSeen then437 begin 438 inc(nTech[p]);439 inc(Researched[p]);432 Inc(nTech[P], 2); 433 Inc(Researched[P], 8); 434 Exit; 435 end; 436 437 if RW[P].Tech[ad] = tsSeen then 438 begin 439 Inc(nTech[P]); 440 Inc(Researched[P]); 440 441 end 441 442 else 442 443 begin 443 inc(nTech[p], 2);444 inc(Researched[p], 2);445 end; 446 RW[ p].Tech[ad] := tsResearched;447 TellAboutKeyTech( p, tsResearched);448 CheckSpecialModels( p, ad);444 Inc(nTech[P], 2); 445 Inc(Researched[P], 2); 446 end; 447 RW[P].Tech[ad] := tsResearched; 448 TellAboutKeyTech(P, tsResearched); 449 CheckSpecialModels(P, ad); 449 450 if ad = adScience then 450 ResourceMask[ p] := ResourceMask[p] or fSpecial2;451 ResourceMask[P] := ResourceMask[P] or fSpecial2; 451 452 if ad = adMassProduction then 452 ResourceMask[ p] := ResourceMask[p] or fModern;453 454 for i:= 0 to nWonder - 1 do { check whether wonders expired }455 if (GWonder[ i].EffectiveOwner <> GWonder[woEiffel].EffectiveOwner) and456 (Imp[ i].Expiration = ad) then457 begin 458 GWonder[ i].EffectiveOwner := -1;459 if i= woPyramids then453 ResourceMask[P] := ResourceMask[P] or fModern; 454 455 for I := 0 to nWonder - 1 do { check whether wonders expired } 456 if (GWonder[I].EffectiveOwner <> GWonder[woEiffel].EffectiveOwner) and 457 (Imp[I].Expiration = ad) then 458 begin 459 GWonder[I].EffectiveOwner := -1; 460 if I = woPyramids then 460 461 FreeSlaves; 461 462 end; 462 463 end; 463 464 464 procedure CheckExpiration(Wonder: integer);465 procedure CheckExpiration(Wonder: Integer); 465 466 // GWonder[Wonder].EffectiveOwner must be set before! 466 467 var 467 p: integer;468 P: Integer; 468 469 begin 469 470 if (Imp[Wonder].Expiration >= 0) and 470 471 (GWonder[woEiffel].EffectiveOwner <> GWonder[Wonder].EffectiveOwner) then 471 for p:= 0 to nPl - 1 do // check if already expired472 if (1 shl pand GAlive <> 0) and473 (RW[ p].Tech[Imp[Wonder].Expiration] >= tsApplicable) then472 for P := 0 to nPl - 1 do // check if already expired 473 if (1 shl P and GAlive <> 0) and 474 (RW[P].Tech[Imp[Wonder].Expiration] >= tsApplicable) then 474 475 begin 475 476 GWonder[Wonder].EffectiveOwner := -1; 476 477 if Wonder = woPyramids then 477 FreeSlaves 478 end 478 FreeSlaves; 479 end; 479 480 end; 480 481 … … 483 484 ____________________________________________________________________ 484 485 } 485 function dLoc(Loc, dx, dy: integer): integer;486 function dLoc(Loc, dx, dy: Integer): Integer; 486 487 { relative location, dx in hor and dy in ver direction from Loc } 487 488 var 488 y0: integer;489 y0: Integer; 489 490 begin 490 491 if not (Loc >= 0) and (Loc < MapSize) and (dx + lx >= 0) then 491 492 raise Exception.Create('Relative location error'); 492 assert((Loc >= 0) and (Loc < MapSize) and (dx + lx >= 0));493 Assert((Loc >= 0) and (Loc < MapSize) and (dx + lx >= 0)); 493 494 y0 := Loc div lx; 494 result := (Loc + (dx + y0 and 1 + lx + lx) shr 1) mod lx + lx * (y0 + dy);495 if ( result < 0) or (result >= MapSize) then496 result := -1;497 end; 498 499 procedure dxdy(Loc0, Loc1: integer; var dx, dy: integer);495 Result := (Loc + (dx + y0 and 1 + lx + lx) shr 1) mod lx + lx * (y0 + dy); 496 if (Result < 0) or (Result >= MapSize) then 497 Result := -1; 498 end; 499 500 procedure dxdy(Loc0, Loc1: Integer; var dx, dy: Integer); 500 501 begin 501 502 dx := ((Loc1 mod lx * 2 + Loc1 div lx and 1) - … … 504 505 end; 505 506 506 function Distance(Loc0, Loc1: integer): integer;507 var 508 dx, dy: integer;507 function Distance(Loc0, Loc1: Integer): Integer; 508 var 509 dx, dy: Integer; 509 510 begin 510 511 dxdy(Loc0, Loc1, dx, dy); 511 512 dx := abs(dx); 512 513 dy := abs(dy); 513 result := dx + dy + abs(dx - dy) shr 1;514 end; 515 516 procedure V8_to_Loc(Loc0: integer; var VicinityLoc: TVicinity8Loc);517 var 518 x0, y0, lx0: integer;514 Result := dx + dy + abs(dx - dy) shr 1; 515 end; 516 517 procedure V8_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity8Loc); 518 var 519 x0, y0, lx0: Integer; 519 520 begin 520 521 lx0 := lx; // put in register! … … 526 527 VicinityLoc[5] := Loc0 - lx0 * 2; 527 528 VicinityLoc[7] := Loc0 + 1; 528 inc(Loc0, y0);529 Inc(Loc0, y0); 529 530 VicinityLoc[0] := Loc0 + lx0; 530 531 VicinityLoc[2] := Loc0 + lx0 - 1; … … 537 538 if x0 = 0 then 538 539 begin 539 inc(VicinityLoc[3], lx0);540 Inc(VicinityLoc[3], lx0); 540 541 if y0 = 0 then 541 542 begin 542 inc(VicinityLoc[2], lx0);543 inc(VicinityLoc[4], lx0);544 end 545 end 543 Inc(VicinityLoc[2], lx0); 544 Inc(VicinityLoc[4], lx0); 545 end; 546 end; 546 547 end 547 548 else 548 549 begin 549 dec(VicinityLoc[7], lx0);550 Dec(VicinityLoc[7], lx0); 550 551 if y0 = 1 then 551 552 begin 552 dec(VicinityLoc[0], lx0);553 dec(VicinityLoc[6], lx0);554 end 555 end; 556 end; 557 558 procedure V21_to_Loc(Loc0: integer; var VicinityLoc: TVicinity21Loc);559 var 560 dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: integer;561 dst: ^ integer;553 Dec(VicinityLoc[0], lx0); 554 Dec(VicinityLoc[6], lx0); 555 end; 556 end; 557 end; 558 559 procedure V21_to_Loc(Loc0: Integer; var VicinityLoc: TVicinity21Loc); 560 var 561 dx, dy, bit, y0, xComp, yComp, xComp0, xCompSwitch: Integer; 562 dst: ^Integer; 562 563 begin 563 564 y0 := Loc0 div lx; … … 565 566 xCompSwitch := xComp0 - 1 + y0 and 1; 566 567 if xComp0 < 0 then 567 inc(xComp0, lx);568 Inc(xComp0, lx); 568 569 if xCompSwitch < 0 then 569 inc(xCompSwitch, lx);570 Inc(xCompSwitch, lx); 570 571 xCompSwitch := xCompSwitch xor xComp0; 571 572 yComp := lx * (y0 - 3); … … 582 583 else 583 584 dst^ := -1; 584 inc(xComp);585 Inc(xComp); 585 586 if xComp >= lx then 586 dec(xComp, lx);587 inc(dst);587 Dec(xComp, lx); 588 Inc(dst); 588 589 bit := bit shl 1; 589 590 end; 590 inc(yComp, lx);591 Inc(yComp, lx); 591 592 end; 592 593 end; … … 597 598 } 598 599 var 599 primitive: integer;600 StartLoc, StartLoc2: array [0 .. nPl - 1] of integer; { starting coordinates }600 primitive: Integer; 601 StartLoc, StartLoc2: array [0 .. nPl - 1] of Integer; { starting coordinates } 601 602 Elevation: array [0 .. lxmax * lymax - 1] of Byte; { map elevation } 602 ElCount: array [Byte] of integer; { count of elevation occurance }603 ElCount: array [Byte] of Integer; { count of elevation occurance } 603 604 604 605 procedure CalculatePrimitive; 605 606 var 606 i, j: integer;607 I, J: Integer; 607 608 begin 608 609 primitive := 1; 609 i:= 2;610 while i * i<= MapSize + 1 do // test whether prime611 begin 612 if (MapSize + 1) mod i= 0 then610 I := 2; 611 while I * I <= MapSize + 1 do // test whether prime 612 begin 613 if (MapSize + 1) mod I = 0 then 613 614 primitive := 0; 614 inc(i)615 Inc(I); 615 616 end; 616 617 617 618 if primitive > 0 then 618 619 repeat 619 inc(primitive);620 i:= 1;621 j:= 0;620 Inc(primitive); 621 I := 1; 622 J := 0; 622 623 repeat 623 inc(j);624 i := i * primitive mod (MapSize + 1)625 until ( i = 1) or (j= MapSize + 1);626 until j= MapSize;627 end; 628 629 function MapGeneratorAvailable: boolean;630 begin 631 result := (primitive > 0) and (lx >= 20) and (ly >= 40)624 Inc(J); 625 I := I * primitive mod (MapSize + 1); 626 until (I = 1) or (J = MapSize + 1); 627 until J = MapSize; 628 end; 629 630 function MapGeneratorAvailable: Boolean; 631 begin 632 Result := (primitive > 0) and (lx >= 20) and (ly >= 40); 632 633 end; 633 634 634 635 procedure CreateElevation; 635 636 const 636 d= 64;637 D = 64; 637 638 Smooth = 0.049; { causes low amplitude of short waves } 638 639 Detail = 0.095; { causes short period of short waves } … … 641 642 642 643 var 643 sa, ca, f1, f2: array [1 .. d] of single;644 imerge, x, y: integer;645 v, maxv: single;646 647 function Value( x, y: integer): single; { elevation formula }644 sa, ca, f1, f2: array [1 .. D] of Single; 645 imerge, X, Y: Integer; 646 V, maxv: Single; 647 648 function Value(X, Y: Integer): Single; { elevation formula } 648 649 var 649 i: integer;650 begin 651 result := 0;652 for i := 1 to ddo653 result := result + sin(f1[i] * ((x * 2 + y and 1) * sa[i] + y* 1.5 *654 ca[ i])) * f2[i];650 I: Integer; 651 begin 652 Result := 0; 653 for I := 1 to D do 654 Result := Result + sin(f1[I] * ((X * 2 + Y and 1) * sa[I] + Y * 1.5 * 655 ca[I])) * f2[I]; 655 656 { x values effectively multiplied with 2 to get 2 horizantal periods 656 657 of the prime waves } … … 658 659 659 660 begin 660 for x := 1 to ddo { prepare formula parameters }661 begin 662 {$IFNDEF SCR} if x= 1 then663 v:= pi / 2 { first wave goes horizontal }664 else {$ENDIF} v:= DelphiRandom * 2 * pi;665 sa[ x] := sin(v) / lx;666 ca[ x] := cos(v) / ly;667 f1[ x] := 2 * pi * exp(Detail * (x- 1));668 f2[ x] := exp(-x * Smooth)661 for X := 1 to D do { prepare formula parameters } 662 begin 663 {$IFNDEF SCR} if X = 1 then 664 V := pi / 2 { first wave goes horizontal } 665 else {$ENDIF} V := DelphiRandom * 2 * pi; 666 sa[X] := sin(V) / lx; 667 ca[X] := cos(V) / ly; 668 f1[X] := 2 * pi * exp(Detail * (X - 1)); 669 f2[X] := exp(-X * Smooth); 669 670 end; 670 671 … … 672 673 FillChar(ElCount, SizeOf(ElCount), 0); 673 674 maxv := 0; 674 for x:= 0 to lx - 1 do675 for y:= 0 to ly - 1 do676 begin 677 v := Value(x, y);678 if x* 2 < imerge then679 v := (x * 2 * v + (imerge - x * 2) * Value(x + lx, y)) / imerge;680 v := v - sqr(sqr(2 * y/ ly - 1)); { soft cut at poles }681 if v> maxv then682 maxv := v;683 684 if v< -4 then685 Elevation[ x + lx * y] := 0686 else if v> 8.75 then687 Elevation[ x + lx * y] := 255675 for X := 0 to lx - 1 do 676 for Y := 0 to ly - 1 do 677 begin 678 V := Value(X, Y); 679 if X * 2 < imerge then 680 V := (X * 2 * V + (imerge - X * 2) * Value(X + lx, Y)) / imerge; 681 V := V - sqr(sqr(2 * Y / ly - 1)); { soft cut at poles } 682 if V > maxv then 683 maxv := V; 684 685 if V < -4 then 686 Elevation[X + lx * Y] := 0 687 else if V > 8.75 then 688 Elevation[X + lx * Y] := 255 688 689 else 689 Elevation[ x + lx * y] := Round((v+ 4) * 20);690 inc(ElCount[Elevation[x + lx * y]])690 Elevation[X + lx * Y] := Round((V + 4) * 20); 691 Inc(ElCount[Elevation[X + lx * Y]]); 691 692 end; 692 693 end; … … 694 695 procedure FindContinents; 695 696 696 procedure ReplaceCont( a, b, Stop: integer);697 procedure ReplaceCont(A, B, Stop: Integer); 697 698 { replace continent name a by b } 698 699 // make sure always continent[loc]<=loc 699 700 var 700 i: integer;701 begin 702 if a < bthen703 begin 704 i := a;705 a := b;706 b := i707 end; 708 if a > bthen709 for i := ato Stop do710 if Continent[ i] = athen711 Continent[ i] := b712 end; 713 714 var 715 x, y, Loc, Wrong: integer;716 begin 717 for y:= 1 to ly - 2 do718 for x:= 0 to lx - 1 do719 begin 720 Loc := x + lx * y;701 I: Integer; 702 begin 703 if A < B then 704 begin 705 I := A; 706 A := B; 707 B := I 708 end; 709 if A > B then 710 for I := A to Stop do 711 if Continent[I] = A then 712 Continent[I] := B; 713 end; 714 715 var 716 X, Y, Loc, Wrong: Integer; 717 begin 718 for Y := 1 to ly - 2 do 719 for X := 0 to lx - 1 do 720 begin 721 Loc := X + lx * Y; 721 722 Continent[Loc] := -1; 722 723 if RealMap[Loc] and fTerrain >= fGrass then 723 724 begin 724 if ( y- 2 >= 1) and (RealMap[Loc - 2 * lx] and fTerrain >= fGrass) then725 if (Y - 2 >= 1) and (RealMap[Loc - 2 * lx] and fTerrain >= fGrass) then 725 726 Continent[Loc] := Continent[Loc - 2 * lx]; 726 if ( x - 1 + y and 1 >= 0) and (y- 1 >= 1) and727 (RealMap[Loc - 1 + yand 1 - lx] and fTerrain >= fGrass) then728 Continent[Loc] := Continent[Loc - 1 + yand 1 - lx];729 if ( x + y and 1 < lx) and (y- 1 >= 1) and730 (RealMap[Loc + yand 1 - lx] and fTerrain >= fGrass) then731 Continent[Loc] := Continent[Loc + yand 1 - lx];732 if ( x- 1 >= 0) and (RealMap[Loc - 1] and fTerrain >= fGrass) then727 if (X - 1 + Y and 1 >= 0) and (Y - 1 >= 1) and 728 (RealMap[Loc - 1 + Y and 1 - lx] and fTerrain >= fGrass) then 729 Continent[Loc] := Continent[Loc - 1 + Y and 1 - lx]; 730 if (X + Y and 1 < lx) and (Y - 1 >= 1) and 731 (RealMap[Loc + Y and 1 - lx] and fTerrain >= fGrass) then 732 Continent[Loc] := Continent[Loc + Y and 1 - lx]; 733 if (X - 1 >= 0) and (RealMap[Loc - 1] and fTerrain >= fGrass) then 733 734 if Continent[Loc] = -1 then 734 735 Continent[Loc] := Continent[Loc - 1] … … 736 737 ReplaceCont(Continent[Loc - 1], Continent[Loc], Loc); 737 738 if Continent[Loc] = -1 then 738 Continent[Loc] := Loc 739 end 739 Continent[Loc] := Loc; 740 end; 740 741 end; 741 742 742 743 { connect continents due to round earth } 743 for y:= 1 to ly - 2 do744 if RealMap[lx * y] and fTerrain >= fGrass then744 for Y := 1 to ly - 2 do 745 if RealMap[lx * Y] and fTerrain >= fGrass then 745 746 begin 746 747 Wrong := -1; 747 if RealMap[lx - 1 + lx * y] and fTerrain >= fGrass then748 Wrong := Continent[lx - 1 + lx * y];749 if ( y and 1 = 0) and (y- 1 >= 1) and750 (RealMap[lx - 1 + lx * ( y- 1)] and fTerrain >= fGrass) then751 Wrong := Continent[lx - 1 + lx * ( y- 1)];752 if ( y and 1 = 0) and (y+ 1 < ly - 1) and753 (RealMap[lx - 1 + lx * ( y+ 1)] and fTerrain >= fGrass) then754 Wrong := Continent[lx - 1 + lx * ( y+ 1)];748 if RealMap[lx - 1 + lx * Y] and fTerrain >= fGrass then 749 Wrong := Continent[lx - 1 + lx * Y]; 750 if (Y and 1 = 0) and (Y - 1 >= 1) and 751 (RealMap[lx - 1 + lx * (Y - 1)] and fTerrain >= fGrass) then 752 Wrong := Continent[lx - 1 + lx * (Y - 1)]; 753 if (Y and 1 = 0) and (Y + 1 < ly - 1) and 754 (RealMap[lx - 1 + lx * (Y + 1)] and fTerrain >= fGrass) then 755 Wrong := Continent[lx - 1 + lx * (Y + 1)]; 755 756 if Wrong >= 0 then 756 ReplaceCont(Wrong, Continent[lx * y], MapSize - 1)757 ReplaceCont(Wrong, Continent[lx * Y], MapSize - 1); 757 758 end; 758 759 end; … … 762 763 // must be done after FindContinents 763 764 var 764 i, j, Cnt, x, y, dx, dy, Loc0, Loc1, xworst, yworst, totalrare, RareMaxWater,765 RareType, iBest, jbest, MinDist, xBlock, yBlock, V8: integer;766 AreaCount, RareByArea, RareAdjacent: array [0 .. 7, 0 .. 4] of integer;767 RareLoc: array [0 .. 11] of integer;768 Dist: array [0 .. 11, 0 .. 11] of integer;765 I, J, Cnt, X, Y, dx, dy, Loc0, Loc1, xworst, yworst, totalrare, RareMaxWater, 766 RareType, iBest, jbest, MinDist, xBlock, yBlock, V8: Integer; 767 AreaCount, RareByArea, RareAdjacent: array [0 .. 7, 0 .. 4] of Integer; 768 RareLoc: array [0 .. 11] of Integer; 769 Dist: array [0 .. 11, 0 .. 11] of Integer; 769 770 Adjacent: TVicinity8Loc; 770 771 begin … … 772 773 repeat 773 774 FillChar(AreaCount, SizeOf(AreaCount), 0); 774 for y:= 1 to ly - 2 do775 begin 776 yBlock := y* 5 div ly;777 if yBlock = ( y+ 1) * 5 div ly then778 for x:= 0 to lx - 1 do779 begin 780 xBlock := x* 8 div lx;781 if xBlock = ( x+ 1) * 8 div lx then775 for Y := 1 to ly - 2 do 776 begin 777 yBlock := Y * 5 div ly; 778 if yBlock = (Y + 1) * 5 div ly then 779 for X := 0 to lx - 1 do 780 begin 781 xBlock := X * 8 div lx; 782 if xBlock = (X + 1) * 8 div lx then 782 783 begin 783 Loc0 := x + lx * y;784 Loc0 := X + lx * Y; 784 785 if RealMap[Loc0] and fTerrain >= fGrass then 785 786 begin … … 791 792 if (Loc1 >= 0) and (Loc1 < MapSize) and 792 793 (RealMap[Loc1] and fTerrain < fGrass) then 793 inc(Cnt); // count adjacent water794 Inc(Cnt); // count adjacent water 794 795 end; 795 796 if Cnt <= RareMaxWater then // inner land 796 797 begin 797 inc(AreaCount[xBlock, yBlock]);798 Inc(AreaCount[xBlock, yBlock]); 798 799 if DelphiRandom(AreaCount[xBlock, yBlock]) = 0 then 799 RareByArea[xBlock, yBlock] := Loc0 800 end 800 RareByArea[xBlock, yBlock] := Loc0; 801 end; 801 802 end; 802 803 end; 803 end 804 end; 804 805 end; 805 806 totalrare := 0; 806 for x:= 0 to 7 do807 for y:= 0 to 4 do808 if AreaCount[ x, y] > 0 then809 inc(totalrare);810 inc(RareMaxWater);807 for X := 0 to 7 do 808 for Y := 0 to 4 do 809 if AreaCount[X, Y] > 0 then 810 Inc(totalrare); 811 Inc(RareMaxWater); 811 812 until totalrare >= 12; 812 813 … … 814 815 begin // remove rarebyarea resources too close to each other 815 816 FillChar(RareAdjacent, SizeOf(RareAdjacent), 0); 816 for x:= 0 to 7 do817 for y:= 0 to 4 do818 if AreaCount[ x, y] > 0 then819 begin 820 if (AreaCount[( x + 1) mod 8, y] > 0) and821 (Continent[RareByArea[ x, y]] = Continent822 [RareByArea[( x + 1) mod 8, y]]) then817 for X := 0 to 7 do 818 for Y := 0 to 4 do 819 if AreaCount[X, Y] > 0 then 820 begin 821 if (AreaCount[(X + 1) mod 8, Y] > 0) and 822 (Continent[RareByArea[X, Y]] = Continent 823 [RareByArea[(X + 1) mod 8, Y]]) then 823 824 begin 824 inc(RareAdjacent[x, y]);825 inc(RareAdjacent[(x + 1) mod 8, y]);825 Inc(RareAdjacent[X, Y]); 826 Inc(RareAdjacent[(X + 1) mod 8, Y]); 826 827 end; 827 if y< 4 then828 if Y < 4 then 828 829 begin 829 if (AreaCount[ x, y+ 1] > 0) and830 (Continent[RareByArea[ x, y]] = Continent[RareByArea[x, y+ 1]])830 if (AreaCount[X, Y + 1] > 0) and 831 (Continent[RareByArea[X, Y]] = Continent[RareByArea[X, Y + 1]]) 831 832 then 832 833 begin 833 inc(RareAdjacent[x, y]);834 inc(RareAdjacent[x, y+ 1]);834 Inc(RareAdjacent[X, Y]); 835 Inc(RareAdjacent[X, Y + 1]); 835 836 end; 836 if (AreaCount[( x + 1) mod 8, y+ 1] > 0) and837 (Continent[RareByArea[ x, y]] = Continent[RareByArea[(x+ 1) mod 8,838 y+ 1]]) then837 if (AreaCount[(X + 1) mod 8, Y + 1] > 0) and 838 (Continent[RareByArea[X, Y]] = Continent[RareByArea[(X + 1) mod 8, 839 Y + 1]]) then 839 840 begin 840 inc(RareAdjacent[x, y]);841 inc(RareAdjacent[(x + 1) mod 8, y+ 1]);841 Inc(RareAdjacent[X, Y]); 842 Inc(RareAdjacent[(X + 1) mod 8, Y + 1]); 842 843 end; 843 if (AreaCount[( x + 7) mod 8, y+ 1] > 0) and844 (Continent[RareByArea[ x, y]] = Continent[RareByArea[(x+ 7) mod 8,845 y+ 1]]) then844 if (AreaCount[(X + 7) mod 8, Y + 1] > 0) and 845 (Continent[RareByArea[X, Y]] = Continent[RareByArea[(X + 7) mod 8, 846 Y + 1]]) then 846 847 begin 847 inc(RareAdjacent[x, y]);848 inc(RareAdjacent[(x + 7) mod 8, y+ 1]);848 Inc(RareAdjacent[X, Y]); 849 Inc(RareAdjacent[(X + 7) mod 8, Y + 1]); 849 850 end; 850 end 851 end; 851 852 end; 852 853 xworst := 0; 853 854 yworst := 0; 854 855 Cnt := 0; 855 for x:= 0 to 7 do856 for y:= 0 to 4 do857 if AreaCount[ x, y] > 0 then858 begin 859 if (Cnt = 0) or (RareAdjacent[ x, y] > RareAdjacent[xworst, yworst])856 for X := 0 to 7 do 857 for Y := 0 to 4 do 858 if AreaCount[X, Y] > 0 then 859 begin 860 if (Cnt = 0) or (RareAdjacent[X, Y] > RareAdjacent[xworst, yworst]) 860 861 then 861 862 begin 862 xworst := x;863 yworst := y;864 Cnt := 1 863 xworst := X; 864 yworst := Y; 865 Cnt := 1; 865 866 end 866 else if (RareAdjacent[ x, y] = RareAdjacent[xworst, yworst]) then867 else if (RareAdjacent[X, Y] = RareAdjacent[xworst, yworst]) then 867 868 begin 868 inc(Cnt);869 Inc(Cnt); 869 870 if DelphiRandom(Cnt) = 0 then 870 871 begin 871 xworst := x;872 yworst := y;873 end 872 xworst := X; 873 yworst := Y; 874 end; 874 875 end; 875 876 end; 876 877 AreaCount[xworst, yworst] := 0; 877 dec(totalrare)878 Dec(totalrare); 878 879 end; 879 880 880 881 Cnt := 0; 881 for x:= 0 to 7 do882 for y:= 0 to 4 do883 if AreaCount[ x, y] > 0 then884 begin 885 RareLoc[Cnt] := RareByArea[ x, y];886 inc(Cnt)887 end; 888 for i:= 0 to 11 do889 begin 890 RealMap[RareLoc[ i]] := RealMap[RareLoc[i]] and not(fTerrain or fSpecial) or882 for X := 0 to 7 do 883 for Y := 0 to 4 do 884 if AreaCount[X, Y] > 0 then 885 begin 886 RareLoc[Cnt] := RareByArea[X, Y]; 887 Inc(Cnt); 888 end; 889 for I := 0 to 11 do 890 begin 891 RealMap[RareLoc[I]] := RealMap[RareLoc[I]] and not(fTerrain or fSpecial) or 891 892 (fDesert or fDeadLands); 892 893 for dy := -1 to 1 do … … 894 895 if (dx + dy) and 1 = 0 then 895 896 begin 896 Loc1 := dLoc(RareLoc[ i], dx, dy);897 Loc1 := dLoc(RareLoc[I], dx, dy); 897 898 if (Loc1 >= 0) and (RealMap[Loc1] and fTerrain = fMountains) then 898 899 RealMap[Loc1] := RealMap[Loc1] and not fTerrain or fHills; 899 end 900 end; 901 for i:= 0 to 11 do902 for j:= 0 to 11 do903 Dist[ i, j] := Distance(RareLoc[i], RareLoc[j]);900 end; 901 end; 902 for I := 0 to 11 do 903 for J := 0 to 11 do 904 Dist[I, J] := Distance(RareLoc[I], RareLoc[J]); 904 905 905 906 ibest := 0; … … 909 910 begin 910 911 Cnt := 0; 911 for i:= 0 to 11 do912 if RareLoc[ i] >= 0 then913 for j:= 0 to 11 do914 if RareLoc[ j] >= 0 then912 for I := 0 to 11 do 913 if RareLoc[I] >= 0 then 914 for J := 0 to 11 do 915 if RareLoc[J] >= 0 then 915 916 if (Cnt > 0) and (Dist[iBest, jbest] >= MinDist) then 916 917 begin 917 if Dist[ i, j] >= MinDist then918 if Dist[I, J] >= MinDist then 918 919 begin 919 inc(Cnt);920 Inc(Cnt); 920 921 if DelphiRandom(Cnt) = 0 then 921 922 begin 922 iBest := i;923 jbest := j924 end 925 end 923 iBest := I; 924 jbest := J; 925 end; 926 end; 926 927 end 927 else if (Cnt = 0) or (Dist[ i, j] > Dist[iBest, jbest]) then928 else if (Cnt = 0) or (Dist[I, J] > Dist[iBest, jbest]) then 928 929 begin 929 iBest := i;930 jbest := j;930 iBest := I; 931 jbest := J; 931 932 Cnt := 1; 932 933 end; … … 938 939 RareLoc[jbest] := -1; 939 940 end; 940 end; // RarePositions941 942 function CheckShore(Loc: integer): boolean;943 var 944 Loc1, OldTile, V21: integer;941 end; 942 943 function CheckShore(Loc: Integer): Boolean; 944 var 945 Loc1, OldTile, V21: Integer; 945 946 Radius: TVicinity21Loc; 946 947 begin 947 result := false;948 Result := False; 948 949 OldTile := RealMap[Loc]; 949 950 if OldTile and fTerrain < fGrass then … … 960 961 end; 961 962 if (RealMap[Loc] xor Cardinal(OldTile)) and fTerrain <> 0 then 962 result := true;963 end; 964 end; 965 966 function ActualSpecialTile(Loc: integer): Cardinal;967 begin 968 result := SpecialTile(Loc, RealMap[Loc] and fTerrain, lx);969 end; 970 971 procedure CreateMap(preview: boolean);963 Result := True; 964 end; 965 end; 966 967 function ActualSpecialTile(Loc: Integer): Cardinal; 968 begin 969 Result := SpecialTile(Loc, RealMap[Loc] and fTerrain, lx); 970 end; 971 972 procedure CreateMap(preview: Boolean); 972 973 const 973 974 ShHiHills = 6; { of land } … … 980 981 hotunification = 50; // min. 25 981 982 982 Zone: array [0 .. 3, 2 .. 9] of single = { terrain distribution }983 Zone: array [0 .. 3, 2 .. 9] of Single = { terrain distribution } 983 984 ((0.25, 0, 0, 0.4, 0, 0, 0, 0.35), (0.55, 0, 0.1, 0, 0, 0, 0, 0.35), 984 985 (0.4, 0, 0.35, 0, 0, 0, 0, 0.25), (0, 0.7, 0, 0, 0, 0, 0, 0.3)); 985 986 { Grs Dst Pra Tun - - - For } 986 987 987 function RndLow( y: integer): Cardinal;988 function RndLow(Y: Integer): Cardinal; 988 989 { random lowland appropriate to climate } 989 990 var 990 z0, i: integer;991 p, p0, ZPlus: single;992 begin 993 if ly - 1 - y > ythen994 begin 995 z0 := 6 * ydiv ly;996 ZPlus := 6 * y/ ly - z0;991 z0, I: Integer; 992 P, p0, ZPlus: Single; 993 begin 994 if ly - 1 - Y > Y then 995 begin 996 z0 := 6 * Y div ly; 997 ZPlus := 6 * Y / ly - z0; 997 998 end 998 999 else 999 1000 begin 1000 z0 := 6 * (ly - 1 - y) div ly;1001 ZPlus := 6 * (ly - 1 - y) / ly - z0;1001 z0 := 6 * (ly - 1 - Y) div ly; 1002 ZPlus := 6 * (ly - 1 - Y) / ly - z0; 1002 1003 end; 1003 1004 p0 := 1; 1004 for i:= 2 to 9 do1005 begin 1006 p := Zone[z0, i] * (1 - ZPlus) + Zone[z0 + 1, i] * ZPlus;1005 for I := 2 to 9 do 1006 begin 1007 P := Zone[z0, I] * (1 - ZPlus) + Zone[z0 + 1, I] * ZPlus; 1007 1008 { weight between zones z0 and z0+1 } 1008 if DelphiRandom * p0 < pthen1009 begin 1010 RndLow := i;1009 if DelphiRandom * p0 < P then 1010 begin 1011 RndLow := I; 1011 1012 Break; 1012 1013 end; 1013 p0 := p0 - p;1014 end; 1015 end; 1016 1017 function RunRiver(Loc0: integer): integer;1014 p0 := p0 - P; 1015 end; 1016 end; 1017 1018 function RunRiver(Loc0: Integer): Integer; 1018 1019 { runs river from start point Loc0; return value: length } 1019 1020 var 1020 Dir, T, Loc, Loc1, Cost: integer;1021 Dir, T, Loc, Loc1, Cost: Integer; 1021 1022 Q: TIPQ; 1022 From: array [0 .. lxmax * lymax - 1] of integer;1023 Time: array [0 .. lxmax * lymax - 1] of integer;1024 OneTileLake: boolean;1023 From: array [0 .. lxmax * lymax - 1] of Integer; 1024 Time: array [0 .. lxmax * lymax - 1] of Integer; 1025 OneTileLake: Boolean; 1025 1026 begin 1026 1027 FillChar(Time, SizeOf(Time), 255); { -1 } … … 1031 1032 if (RealMap[Loc] and fTerrain < fGrass) then 1032 1033 begin 1033 OneTileLake := true;1034 OneTileLake := True; 1034 1035 for Dir := 0 to 3 do 1035 1036 begin 1036 1037 Loc1 := dLoc(Loc, Dir and 1 * 2 - 1, Dir shr 1 * 2 - 1); 1037 1038 if (Loc1 >= 0) and (RealMap[Loc1] and fTerrain < fGrass) then 1038 OneTileLake := false;1039 OneTileLake := False; 1039 1040 end; 1040 1041 if not OneTileLake then … … 1061 1062 end; 1062 1063 Loc1 := Loc; 1063 result := 0;1064 Result := 0; 1064 1065 while Loc <> Loc0 do 1065 1066 begin 1066 1067 Loc := From[Loc]; 1067 inc(result);1068 end; 1069 if ( result > 1) and ((result >= MinRivLen) or1068 Inc(Result); 1069 end; 1070 if (Result > 1) and ((Result >= MinRivLen) or 1070 1071 (RealMap[Loc1] and fTerrain >= fGrass)) then 1071 1072 begin … … 1081 1082 end 1082 1083 else 1083 result := 0;1084 Result := 0; 1084 1085 FreeAndNil(Q); 1085 1086 end; 1086 1087 1087 1088 var 1088 x, y, n, Dir, plus, Count, Loc0, Loc1, bLand, bHills, bMountains, V8: integer;1089 CopyFrom: array [0 .. lxmax * lymax - 1] of integer;1089 X, Y, N, Dir, plus, Count, Loc0, Loc1, bLand, bHills, bMountains, V8: Integer; 1090 CopyFrom: array [0 .. lxmax * lymax - 1] of Integer; 1090 1091 Adjacent: TVicinity8Loc; 1091 1092 … … 1096 1097 while plus < MapSize * LandMass * ShMountains div 10000 do 1097 1098 begin 1098 dec(bMountains);1099 inc(plus, ElCount[bMountains])1099 Dec(bMountains); 1100 Inc(plus, ElCount[bMountains]); 1100 1101 end; 1101 1102 Count := plus; … … 1104 1105 while plus < MapSize * LandMass * ShHiHills div 10000 do 1105 1106 begin 1106 dec(bHills);1107 inc(plus, ElCount[bHills])1108 end; 1109 inc(Count, plus);1107 Dec(bHills); 1108 Inc(plus, ElCount[bHills]); 1109 end; 1110 Inc(Count, plus); 1110 1111 bLand := bHills; 1111 1112 while Count < MapSize * LandMass div 100 do 1112 1113 begin 1113 dec(bLand);1114 inc(Count, ElCount[bLand])1114 Dec(bLand); 1115 Inc(Count, ElCount[bLand]); 1115 1116 end; 1116 1117 … … 1135 1136 (RealMap[Loc1] and fTerrain < fGrass) or 1136 1137 (RealMap[Loc1] and fTerrain = fArctic) then 1137 inc(Count); // count adjacent water1138 Inc(Count); // count adjacent water 1138 1139 end; 1139 1140 if Count = 8 then 1140 RealMap[Loc0] := fOcean 1141 RealMap[Loc0] := fOcean; 1141 1142 end; 1142 1143 … … 1147 1148 plus := MapSize; 1148 1149 Loc0 := DelphiRandom(MapSize); 1149 for n:= 0 to plus - 1 do1150 for N := 0 to plus - 1 do 1150 1151 begin 1151 1152 if (RealMap[Loc0] and fTerrain >= fGrass) and (Loc0 >= lx) and … … 1164 1165 CopyFrom[Loc0] := Loc0; 1165 1166 1166 for n:= 0 to unification * MapSize div 100 do1167 begin 1168 y:= DelphiRandom(ly);1169 if abs( y- (ly shr 1)) > ly div 4 + DelphiRandom(ly * hotunification div 100) then1170 if y< ly shr 1 then1171 y := ly shr 1 - y1167 for N := 0 to unification * MapSize div 100 do 1168 begin 1169 Y := DelphiRandom(ly); 1170 if abs(Y - (ly shr 1)) > ly div 4 + DelphiRandom(ly * hotunification div 100) then 1171 if Y < ly shr 1 then 1172 Y := ly shr 1 - Y 1172 1173 else 1173 y := 3 * ly shr 1 - y;1174 Loc0 := lx * y+ DelphiRandom(lx);1174 Y := 3 * ly shr 1 - Y; 1175 Loc0 := lx * Y + DelphiRandom(lx); 1175 1176 if RealMap[Loc0] and fTerrain = fGrass then 1176 1177 begin … … 1202 1203 Loc1 := CopyFrom[Loc1]; 1203 1204 RealMap[Loc0] := RealMap[Loc0] and not fTerrain or 1204 RealMap[Loc1] and fTerrain 1205 RealMap[Loc1] and fTerrain; 1205 1206 end; 1206 1207 … … 1225 1226 if Loc1 >= 0 then 1226 1227 if RealMap[Loc1] and fTerrain < fGrass then 1227 inc(Count, 2)1228 Inc(Count, 2); 1228 1229 end; 1229 1230 end; 1230 1231 if Count >= 4 then 1231 RealMap[Loc0] := RealMap[Loc0] and not fTerrain or fPrairie 1232 RealMap[Loc0] := RealMap[Loc0] and not fTerrain or fPrairie; 1232 1233 end; 1233 1234 … … 1241 1242 if Loc1 >= 0 then 1242 1243 if RealMap[Loc1] and fTerrain <> fDesert then 1243 inc(Count)1244 Inc(Count); 1244 1245 end; 1245 1246 if Count >= 4 then 1246 RealMap[Loc0] := RealMap[Loc0] and not fTerrain or fPrairie 1247 RealMap[Loc0] := RealMap[Loc0] and not fTerrain or fPrairie; 1247 1248 end; 1248 1249 1249 1250 for Loc0 := 0 to MapSize - 1 do 1250 1251 CheckShore(Loc0); // change ocean to shore 1251 for x:= 0 to lx - 1 do1252 begin 1253 RealMap[ x+ lx * 0] := fArctic;1254 if RealMap[ x+ lx * 1] >= fGrass then1255 RealMap[ x + lx * 1] := RealMap[x+ lx * 1] and not fTerrain or fTundra;1256 if RealMap[ x+ lx * (ly - 2)] >= fGrass then1257 RealMap[ x + lx * (ly - 2)] := RealMap[x+ lx * (ly - 2)] and1252 for X := 0 to lx - 1 do 1253 begin 1254 RealMap[X + lx * 0] := fArctic; 1255 if RealMap[X + lx * 1] >= fGrass then 1256 RealMap[X + lx * 1] := RealMap[X + lx * 1] and not fTerrain or fTundra; 1257 if RealMap[X + lx * (ly - 2)] >= fGrass then 1258 RealMap[X + lx * (ly - 2)] := RealMap[X + lx * (ly - 2)] and 1258 1259 not fTerrain or fTundra; 1259 RealMap[ x + lx * (ly - 1)] := fArctic1260 RealMap[X + lx * (ly - 1)] := fArctic; 1260 1261 end; 1261 1262 … … 1278 1279 CountGood: (cgBest, cgFlat, cgLand); 1279 1280 1280 function IsGoodTile(Loc: integer): boolean;1281 function IsGoodTile(Loc: Integer): Boolean; 1281 1282 var 1282 xLoc, yLoc: integer;1283 xLoc, yLoc: Integer; 1283 1284 begin 1284 1285 xLoc := Loc mod lx; 1285 1286 yLoc := Loc div lx; 1286 1287 if RealMap[Loc] and fDeadLands <> 0 then 1287 result := false1288 Result := False 1288 1289 else 1289 1290 case CountGood of 1290 1291 cgBest: 1291 result := (RealMap[Loc] and fTerrain in [fGrass, fPrairie, fTundra,1292 Result := (RealMap[Loc] and fTerrain in [fGrass, fPrairie, fTundra, 1292 1293 fSwamp, fForest]) and Odd((lymax + xLoc - yLoc shr 1) shr 1 + xLoc + 1293 1294 (yLoc + 1) shr 1); 1294 1295 cgFlat: 1295 result := (RealMap[Loc] and fTerrain in [fGrass, fPrairie, fTundra,1296 Result := (RealMap[Loc] and fTerrain in [fGrass, fPrairie, fTundra, 1296 1297 fSwamp, fForest]); 1297 1298 cgLand: 1298 result := RealMap[Loc] and fTerrain >= fGrass;1299 Result := RealMap[Loc] and fTerrain >= fGrass; 1299 1300 end; 1300 1301 end; … … 1304 1305 1305 1306 var 1306 p1, p2, nAlive, c, Loc, Loc1, CntGood, CntGoodGrass, MinDist, i, j, n,1307 p1, p2, nAlive, C, Loc, Loc1, CntGood, CntGoodGrass, MinDist, I, J, N, 1307 1308 nsc, V21, V8, BestDist, TestDist, MinGood, nIrrLoc, 1308 FineDistSQR, nRest: integer;1309 ccount: array [0 .. lxmax * lymax - 1] of word;1310 sc, StartLoc0, sccount: array [1 .. nPl] of integer;1311 TestStartLoc: array [0 .. nPl - 1] of integer;1312 CityLoc: array [1 .. nPl, 0 .. MaxCityLoc - 1] of integer;1313 nCityLoc: array [1 .. nPl] of integer;1314 RestLoc: array [0 .. MaxCityLoc - 1] of integer;1315 IrrLoc: array [0 .. 20] of integer;1309 FineDistSQR, nRest: Integer; 1310 ccount: array [0 .. lxmax * lymax - 1] of Word; 1311 sc, StartLoc0, sccount: array [1 .. nPl] of Integer; 1312 TestStartLoc: array [0 .. nPl - 1] of Integer; 1313 CityLoc: array [1 .. nPl, 0 .. MaxCityLoc - 1] of Integer; 1314 nCityLoc: array [1 .. nPl] of Integer; 1315 RestLoc: array [0 .. MaxCityLoc - 1] of Integer; 1316 IrrLoc: array [0 .. 20] of Integer; 1316 1317 Radius: TVicinity21Loc; 1317 1318 Adjacent: TVicinity8Loc; 1318 ok: boolean;1319 ok: Boolean; 1319 1320 1320 1321 begin … … 1322 1323 for p1 := 0 to nPl - 1 do 1323 1324 if 1 shl p1 and GAlive <> 0 then 1324 inc(nAlive);1325 Inc(nAlive); 1325 1326 if nAlive = 0 then 1326 exit;1327 Exit; 1327 1328 1328 1329 { count good tiles } … … 1331 1332 if RealMap[Loc] and fTerrain = fGrass then 1332 1333 if ActualSpecialTile(Loc) = 1 then 1333 inc(ccount[Continent[Loc]], 3)1334 Inc(ccount[Continent[Loc]], 3) 1334 1335 else 1335 inc(ccount[Continent[Loc]], 2)1336 Inc(ccount[Continent[Loc]], 2) 1336 1337 else if RealMap[Loc] and fTerrain in [fPrairie, fSwamp, fForest, fHills] 1337 1338 then 1338 inc(ccount[Continent[Loc]]);1339 Inc(ccount[Continent[Loc]]); 1339 1340 1340 1341 Loc := 0; 1341 1342 while ccount[Loc] > 0 do 1342 inc(Loc);1343 for i:= 1 to nAlive do1344 begin 1345 sc[ i] := Loc;1346 sccount[ i] := 11343 Inc(Loc); 1344 for I := 1 to nAlive do 1345 begin 1346 sc[I] := Loc; 1347 sccount[I] := 1 1347 1348 end; 1348 1349 { init with zero size start continents, then search bigger ones } … … 1355 1356 if p1 < nAlive + 1 then 1356 1357 sc[p1] := sc[p1 - 1]; 1357 dec(p1)1358 Dec(p1); 1358 1359 end; 1359 1360 if p1 < nAlive + 1 then … … 1362 1363 nsc := nAlive; 1363 1364 repeat 1364 c:= 1; // search least crowded continent after smallest1365 for i:= 2 to nsc - 1 do1366 if ccount[sc[ i]] * (2 * sccount[c] + 1) > ccount[sc[c]] *1367 (2 * sccount[ i] + 1) then1368 c := i;1369 if ccount[sc[nsc]] * (2 * sccount[ c] + 1) > ccount[sc[c]] then1365 C := 1; // search least crowded continent after smallest 1366 for I := 2 to nsc - 1 do 1367 if ccount[sc[I]] * (2 * sccount[C] + 1) > ccount[sc[C]] * 1368 (2 * sccount[I] + 1) then 1369 C := I; 1370 if ccount[sc[nsc]] * (2 * sccount[C] + 1) > ccount[sc[C]] then 1370 1371 Break; // even least crowded continent is more crowded than smallest 1371 inc(sccount[c]);1372 dec(nsc)1372 Inc(sccount[C]); 1373 Dec(nsc); 1373 1374 until sccount[nsc] > 1; 1374 1375 … … 1376 1377 CountGood := cgBest; 1377 1378 repeat 1378 dec(MinGood);1379 Dec(MinGood); 1379 1380 if (MinGood = 3) and (CountGood < cgLand) then // too demanding! 1380 1381 begin 1381 inc(CountGood);1382 MinGood := 6 1382 Inc(CountGood); 1383 MinGood := 6; 1383 1384 end; 1384 1385 FillChar(nCityLoc, SizeOf(nCityLoc), 0); 1385 1386 Loc := DelphiRandom(MapSize); 1386 for i:= 0 to MapSize - 1 do1387 for I := 0 to MapSize - 1 do 1387 1388 begin 1388 1389 if ((Loc >= 4 * lx) and (Loc < MapSize - 4 * lx) or (CountGood >= cgLand)) 1389 1390 and IsGoodTile(Loc) then 1390 1391 begin 1391 c:= nsc;1392 while ( c > 0) and (Continent[Loc] <> sc[c]) do1393 dec(c);1394 if ( c > 0) and (nCityLoc[c] < MaxCityLoc) then1392 C := nsc; 1393 while (C > 0) and (Continent[Loc] <> sc[C]) do 1394 Dec(C); 1395 if (C > 0) and (nCityLoc[C] < MaxCityLoc) then 1395 1396 begin 1396 1397 CntGood := 1; … … 1401 1402 Loc1 := Radius[V21]; 1402 1403 if (Loc1 >= 0) and (Loc1 < MapSize) and IsGoodTile(Loc1) then 1403 inc(CntGood)1404 Inc(CntGood); 1404 1405 end; 1405 1406 if CntGood >= MinGood then 1406 1407 begin 1407 CityLoc[ c, nCityLoc[c]] := Loc;1408 inc(nCityLoc[c])1408 CityLoc[C, nCityLoc[C]] := Loc; 1409 Inc(nCityLoc[C]); 1409 1410 end; 1410 1411 end; … … 1413 1414 end; 1414 1415 1415 ok := true;1416 for c:= 1 to nsc do1417 if nCityLoc[ c] < sccount[c] * (8 - MinGood) div (7 - MinGood) then1418 ok := false;1416 ok := True; 1417 for C := 1 to nsc do 1418 if nCityLoc[C] < sccount[C] * (8 - MinGood) div (7 - MinGood) then 1419 ok := False; 1419 1420 until ok; 1420 1421 1421 1422 FineDistSQR := MapSize * LandMass * 9 div (nAlive * 100); 1422 1423 p1 := 1; 1423 for c:= 1 to nsc do1424 for C := 1 to nsc do 1424 1425 begin // for all start continents 1425 if sccount[ c] = 1 then1426 StartLoc0[p1] := CityLoc[ c, DelphiRandom(nCityLoc[c])]1426 if sccount[C] = 1 then 1427 StartLoc0[p1] := CityLoc[C, DelphiRandom(nCityLoc[C])] 1427 1428 else 1428 1429 begin 1429 1430 BestDist := 0; 1430 n := 1 shl sccount[c] * 32; // number of tries to find good distribution1431 if n> 1 shl 12 then1432 n:= 1 shl 12;1433 while ( n> 0) and (BestDist * BestDist < FineDistSQR) do1431 N := 1 shl sccount[C] * 32; // number of tries to find good distribution 1432 if N > 1 shl 12 then 1433 N := 1 shl 12; 1434 while (N > 0) and (BestDist * BestDist < FineDistSQR) do 1434 1435 begin 1435 1436 MinDist := MaxInt; 1436 nRest := nCityLoc[ c];1437 for i:= 0 to nRest - 1 do1438 RestLoc[ i] := CityLoc[c, i];1439 for i := 0 to sccount[c] - 1 do1437 nRest := nCityLoc[C]; 1438 for I := 0 to nRest - 1 do 1439 RestLoc[I] := CityLoc[C, I]; 1440 for I := 0 to sccount[C] - 1 do 1440 1441 begin 1441 1442 if nRest = 0 then 1442 1443 Break; 1443 j:= DelphiRandom(nRest);1444 TestStartLoc[ i] := RestLoc[j];1445 RestLoc[ j] := RestLoc[nRest - 1];1446 dec(nRest);1447 for j := 0 to i- 1 do1444 J := DelphiRandom(nRest); 1445 TestStartLoc[I] := RestLoc[J]; 1446 RestLoc[J] := RestLoc[nRest - 1]; 1447 Dec(nRest); 1448 for J := 0 to I - 1 do 1448 1449 begin 1449 TestDist := Distance(TestStartLoc[ i], TestStartLoc[j]);1450 TestDist := Distance(TestStartLoc[I], TestStartLoc[J]); 1450 1451 if TestDist < MinDist then 1451 MinDist := TestDist 1452 MinDist := TestDist; 1452 1453 end; 1453 if i = sccount[c] - 1 then1454 if I = sccount[C] - 1 then 1454 1455 begin 1455 assert(MinDist > BestDist);1456 Assert(MinDist > BestDist); 1456 1457 BestDist := MinDist; 1457 for j := 0 to sccount[c] - 1 do1458 StartLoc0[p1 + j] := TestStartLoc[j];1458 for J := 0 to sccount[C] - 1 do 1459 StartLoc0[p1 + J] := TestStartLoc[J]; 1459 1460 end 1460 1461 else if BestDist > 0 then 1461 1462 begin 1462 j:= 0;1463 while j< nRest do1463 J := 0; 1464 while J < nRest do 1464 1465 begin // remove all locs from rest which have too little distance to this one 1465 TestDist := Distance(TestStartLoc[ i], RestLoc[j]);1466 TestDist := Distance(TestStartLoc[I], RestLoc[J]); 1466 1467 if TestDist <= BestDist then 1467 1468 begin 1468 RestLoc[ j] := RestLoc[nRest - 1];1469 dec(nRest);1469 RestLoc[J] := RestLoc[nRest - 1]; 1470 Dec(nRest); 1470 1471 end 1471 1472 else 1472 inc(j);1473 Inc(J); 1473 1474 end; 1474 1475 end; 1475 1476 end; 1476 dec(n)1477 end; 1478 end; 1479 p1 := p1 + sccount[ c]1477 Dec(N) 1478 end; 1479 end; 1480 p1 := p1 + sccount[C] 1480 1481 end; 1481 1482 … … 1494 1495 if (Loc1 >= 0) and (Loc1 < MapSize) and IsGoodTile(Loc1) then 1495 1496 if RealMap[Loc1] and fTerrain = fGrass then 1496 inc(CntGoodGrass)1497 Inc(CntGoodGrass) 1497 1498 else 1498 inc(CntGood);1499 Inc(CntGood); 1499 1500 end; 1500 1501 for V21 := 1 to 26 do … … 1528 1529 begin 1529 1530 IrrLoc[nIrrLoc] := Loc1; 1530 inc(nIrrLoc);1531 end; 1532 end; 1533 i:= 2;1534 if i> nIrrLoc then1535 i:= nIrrLoc;1536 while i> 0 do1537 begin 1538 j:= DelphiRandom(nIrrLoc);1539 RealMap[IrrLoc[ j]] := RealMap[IrrLoc[j]] or tiIrrigation;1540 IrrLoc[ j] := IrrLoc[nIrrLoc - 1];1541 dec(nIrrLoc);1542 dec(i);1531 Inc(nIrrLoc); 1532 end; 1533 end; 1534 I := 2; 1535 if I > nIrrLoc then 1536 I := nIrrLoc; 1537 while I > 0 do 1538 begin 1539 J := DelphiRandom(nIrrLoc); 1540 RealMap[IrrLoc[J]] := RealMap[IrrLoc[J]] or tiIrrigation; 1541 IrrLoc[J] := IrrLoc[nIrrLoc - 1]; 1542 Dec(nIrrLoc); 1543 Dec(I); 1543 1544 end; 1544 1545 end; … … 1549 1550 begin 1550 1551 repeat 1551 i:= DelphiRandom(nAlive) + 11552 until StartLoc0[ i] >= 0;1553 StartLoc[p1] := StartLoc0[ i];1554 StartLoc0[ i] := -11552 I := DelphiRandom(nAlive) + 1 1553 until StartLoc0[I] >= 0; 1554 StartLoc[p1] := StartLoc0[I]; 1555 StartLoc0[I] := -1 1555 1556 end; 1556 1557 SaveMapCenterLoc := StartLoc[0]; … … 1585 1586 StartLoc2[p1] := Loc1; 1586 1587 BestDist := TestDist; 1587 n:= 1;1588 N := 1; 1588 1589 end 1589 1590 else if TestDist = BestDist then 1590 1591 begin 1591 inc(n);1592 if DelphiRandom( n) = 0 then1592 Inc(N); 1593 if DelphiRandom(N) = 0 then 1593 1594 StartLoc2[p1] := Loc1; 1594 1595 end; 1595 1596 end; 1596 1597 end; 1597 end; { StartPositions }1598 1599 procedure PredefinedStartPositions(Human: integer);1598 end; 1599 1600 procedure PredefinedStartPositions(Human: Integer); 1600 1601 // use predefined nation start positions 1601 1602 var 1602 i, p1, Loc1, nAlive, nStartLoc0, nPrefStartLoc0, imax: integer;1603 StartLoc0: array [0 .. lxmax * lymax - 1] of integer;1604 ishuman: boolean;1603 I, p1, Loc1, nAlive, nStartLoc0, nPrefStartLoc0, imax: Integer; 1604 StartLoc0: array [0 .. lxmax * lymax - 1] of Integer; 1605 ishuman: Boolean; 1605 1606 begin 1606 1607 nAlive := 0; 1607 1608 for p1 := 0 to nPl - 1 do 1608 1609 if 1 shl p1 and GAlive <> 0 then 1609 inc(nAlive);1610 Inc(nAlive); 1610 1611 if nAlive = 0 then 1611 exit;1612 Exit; 1612 1613 1613 1614 for I := 0 to Length(StartLoc0) - 1 do … … 1622 1623 StartLoc0[nStartLoc0] := StartLoc0[nPrefStartLoc0]; 1623 1624 StartLoc0[nPrefStartLoc0] := Loc1; 1624 inc(nPrefStartLoc0);1625 inc(nStartLoc0);1625 Inc(nPrefStartLoc0); 1626 Inc(nStartLoc0); 1626 1627 RealMap[Loc1] := RealMap[Loc1] and not fPrefStartPos; 1627 1628 end … … 1629 1630 begin 1630 1631 StartLoc0[nStartLoc0] := Loc1; 1631 inc(nStartLoc0);1632 Inc(nStartLoc0); 1632 1633 RealMap[Loc1] := RealMap[Loc1] and not fStartPos; 1633 1634 end; 1634 assert(nStartLoc0 >= nAlive);1635 Assert(nStartLoc0 >= nAlive); 1635 1636 1636 1637 StartLoc[0] := 0; 1637 for ishuman := true downto false do1638 for ishuman := True downto False do 1638 1639 for p1 := 0 to nPl - 1 do 1639 1640 if (1 shl p1 and GAlive <> 0) and ((1 shl p1 and Human <> 0) = ishuman) 1640 1641 then 1641 1642 begin 1642 dec(nStartLoc0);1643 Dec(nStartLoc0); 1643 1644 imax := nStartLoc0; 1644 1645 if nPrefStartLoc0 > 0 then 1645 1646 begin 1646 dec(nPrefStartLoc0);1647 Dec(nPrefStartLoc0); 1647 1648 imax := nPrefStartLoc0; 1648 1649 end; 1649 i:= DelphiRandom(imax + 1);1650 StartLoc[p1] := StartLoc0[ i];1651 StartLoc2[p1] := StartLoc0[ i];1652 StartLoc0[ i] := StartLoc0[imax];1650 I := DelphiRandom(imax + 1); 1651 StartLoc[p1] := StartLoc0[I]; 1652 StartLoc2[p1] := StartLoc0[I]; 1653 StartLoc0[I] := StartLoc0[imax]; 1653 1654 StartLoc0[imax] := StartLoc0[nStartLoc0]; 1654 1655 end; 1655 1656 SaveMapCenterLoc := StartLoc[0]; 1656 end; { PredefinedStartPositions }1657 end; 1657 1658 1658 1659 procedure InitGame; 1659 1660 var 1660 i, p, p1, uix, Loc1: integer;1661 I, P, p1, uix, Loc1: Integer; 1661 1662 begin 1662 1663 {$IFDEF FastContact} … … 1670 1671 if RealMap[Loc1] and fterrain>=fGrass then 1671 1672 if Delphirandom(3)=0 then RealMap[Loc1]:=RealMap[Loc1] or fRoad 1672 else if Delphirandom(3)=0 then RealMap[Loc1]:=RealMap[Loc1] or fRR; 1673 else if Delphirandom(3)=0 then RealMap[Loc1]:=RealMap[Loc1] or fRR;} 1673 1674 {random Road and Railroad } 1674 1675 { !!!for Loc1:=0 to MapSize-1 do … … 1682 1683 GTestFlags := 0; 1683 1684 GInitialized := GAlive or GWatching; 1684 for p:= 0 to nPl - 1 do1685 if 1 shl pand GInitialized <> 0 then1686 with RW[ p] do1687 begin 1688 Researched[ p] := 0;1689 Discovered[ p] := 0;1690 TerritoryCount[ p] := 0;1691 nTech[ p] := 0;1692 if Difficulty[ p] = 0 then1693 ResourceMask[ p] := $FFFFFFFF1685 for P := 0 to nPl - 1 do 1686 if 1 shl P and GInitialized <> 0 then 1687 with RW[P] do 1688 begin 1689 Researched[P] := 0; 1690 Discovered[P] := 0; 1691 TerritoryCount[P] := 0; 1692 nTech[P] := 0; 1693 if Difficulty[P] = 0 then 1694 ResourceMask[P] := $FFFFFFFF 1694 1695 else 1695 ResourceMask[ p] := $FFFFFFFF and not(fSpecial2 or fModern);1696 GrWallContinent[ p] := -1;1696 ResourceMask[P] := $FFFFFFFF and not(fSpecial2 or fModern); 1697 GrWallContinent[P] := -1; 1697 1698 1698 1699 GetMem(Map, 4 * MapSize); … … 1712 1713 if 1 shl p1 and GInitialized <> 0 then 1713 1714 begin 1714 FillChar(RWemix[ p, p1], SizeOf(RWemix[p, p1]), 255); { -1 }1715 FillChar(Destroyed[ p, p1], SizeOf(Destroyed[p, p1]), 0);1715 FillChar(RWemix[P, p1], SizeOf(RWemix[P, p1]), 255); { -1 } 1716 FillChar(Destroyed[P, p1], SizeOf(Destroyed[P, p1]), 0); 1716 1717 end; 1717 1718 Attitude[p1] := atNeutral; … … 1721 1722 Tribute[p1] := 0; 1722 1723 TributePaid[p1] := 0; 1723 if (p1 <> p) and (1 shl p1 and GAlive <> 0) then1724 if (p1 <> P) and (1 shl p1 and GAlive <> 0) then 1724 1725 begin // initialize enemy report 1725 1726 GetMem(EnemyReport[p1], SizeOf(TEnemyReport) - 2 * … … 1731 1732 EnemyReport[p1].Attitude := atNeutral; 1732 1733 EnemyReport[p1].Government := gDespotism; 1733 if 1 shl pand GAlive = 0 then1734 if 1 shl P and GAlive = 0 then 1734 1735 Treaty[p1] := trNone // supervisor 1735 1736 end … … 1753 1754 1754 1755 // create initial models and units 1755 for p:= 0 to nPl - 1 do1756 if (1 shl pand GAlive <> 0) then1757 with RW[ p] do1756 for P := 0 to nPl - 1 do 1757 if (1 shl P and GAlive <> 0) then 1758 with RW[P] do 1758 1759 begin 1759 1760 nModel := 0; 1760 for i:= 0 to nSpecialModel - 1 do1761 if SpecialModelPreq[ i] = preNone then1761 for I := 0 to nSpecialModel - 1 do 1762 if SpecialModelPreq[I] = preNone then 1762 1763 begin 1763 Model[nModel] := SpecialModel[ i];1764 Model[nModel] := SpecialModel[I]; 1764 1765 Model[nModel].Status := 0; 1765 1766 Model[nModel].IntroTurn := 0; 1766 1767 Model[nModel].Built := 0; 1767 1768 Model[nModel].Lost := 0; 1768 Model[nModel].ID := pshl 12 + nModel;1769 Model[nModel].ID := P shl 12 + nModel; 1769 1770 SetModelFlags(Model[nModel]); 1770 inc(nModel)1771 Inc(nModel); 1771 1772 end; 1772 1773 nUn := 0; 1773 UnBuilt[ p] := 0;1774 UnBuilt[P] := 0; 1774 1775 for uix := 0 to nStartUn - 1 do 1775 1776 begin 1776 CreateUnit( p, StartUn[uix]);1777 dec(Model[StartUn[uix]].Built);1778 Un[uix].Loc := StartLoc2[ p];1779 PlaceUnit( p, uix);1780 end; 1781 FoundCity( p, StartLoc[p]); // capital1782 Founded[ p] := 1;1777 CreateUnit(P, StartUn[uix]); 1778 Dec(Model[StartUn[uix]].Built); 1779 Un[uix].Loc := StartLoc2[P]; 1780 PlaceUnit(P, uix); 1781 end; 1782 FoundCity(P, StartLoc[P]); // capital 1783 Founded[P] := 1; 1783 1784 with City[0] do 1784 1785 begin 1785 ID := pshl 12;1786 ID := P shl 12; 1786 1787 Flags := chFounded; 1787 1788 end; … … 1790 1791 TerritoryCount[nPl] := MapSize; 1791 1792 // fillchar(NewContact, sizeof(NewContact), false); 1792 end; // InitGame1793 end; 1793 1794 1794 1795 procedure InitRandomGame; … … 1797 1798 CalculatePrimitive; 1798 1799 CreateElevation; 1799 CreateMap( false);1800 CreateMap(False); 1800 1801 StartPositions; 1801 1802 InitGame; 1802 1803 end; 1803 1804 1804 procedure InitMapGame(Human: integer);1805 procedure InitMapGame(Human: Integer); 1805 1806 begin 1806 1807 DelphiRandSeed := RND; … … 1812 1813 procedure ReleaseGame; 1813 1814 var 1814 p1, p2: integer;1815 p1, p2: Integer; 1815 1816 begin 1816 1817 for p1 := 0 to nPl - 1 do … … 1834 1835 procedure InitMapEditor; 1835 1836 var 1836 p1: integer;1837 p1: Integer; 1837 1838 begin 1838 1839 CalculatePrimitive; … … 1871 1872 end; 1872 1873 1873 procedure EditTile(Loc, NewTile: integer);1874 var 1875 Loc1, V21: integer;1874 procedure EditTile(Loc, NewTile: Integer); 1875 var 1876 Loc1, V21: Integer; 1876 1877 Radius: TVicinity21Loc; 1877 1878 begin … … 1897 1898 if (NewTile and fTerImp = tiIrrigation) or (NewTile and fTerImp = tiFarm) 1898 1899 then 1899 NewTile := NewTile and not fTerImp 1900 NewTile := NewTile and not fTerImp; 1900 1901 end; 1901 1902 if (Terrain[NewTile and fTerrain].MineEff = 0) and … … 1921 1922 RealMap[Loc1] := RealMap[Loc1] or ($F shl 27); 1922 1923 RW[0].Map[Loc1] := RealMap[Loc1] and $07FFFFFF or fObserved; 1923 end 1924 end; 1924 1925 end; 1925 1926 // RealMap[Loc]:=RealMap[Loc] and not fSpecial; … … 1931 1932 ____________________________________________________________________ 1932 1933 } 1933 function GetTileInfo( p, cix, Loc: integer; var Info: TTileInfo): integer;1934 function GetTileInfo(P, cix, Loc: Integer; var Info: TTileInfo): Integer; 1934 1935 // cix>=0 - known city index of player p -- only core internal! 1935 1936 // cix=-1 - search city, player unknown, only if permission for p 1936 1937 // cix=-2 - don't search city, don't calculate city benefits, just government of player p 1937 1938 var 1938 p0, Tile, special: integer;1939 p0, Tile, special: Integer; 1939 1940 begin 1940 1941 with Info do 1941 1942 begin 1942 p0 := p;1943 p0 := P; 1943 1944 if cix >= 0 then 1944 1945 Tile := RealMap[Loc] 1945 1946 else 1946 1947 begin 1947 Tile := RW[ p].Map[Loc];1948 Tile := RW[P].Map[Loc]; 1948 1949 if Tile and fTerrain = fUNKNOWN then 1949 1950 begin 1950 result := eNoPreq;1951 exit;1951 Result := eNoPreq; 1952 Exit; 1952 1953 end; 1953 1954 end; … … 1955 1956 if (cix = -1) and (UsedByCity[Loc] >= 0) then 1956 1957 begin // search exploiting player and city 1957 SearchCity(UsedByCity[Loc], p, cix);1958 if not(( p= p0) or (ObserveLevel[UsedByCity[Loc]] shr (2 * p0) and1958 SearchCity(UsedByCity[Loc], P, cix); 1959 if not((P = p0) or (ObserveLevel[UsedByCity[Loc]] shr (2 * p0) and 1959 1960 3 = lObserveSuper)) then 1960 1961 cix := -1 … … 1962 1963 if cix = -1 then 1963 1964 begin 1964 result := eInvalid;1965 exit;1965 Result := eInvalid; 1966 Exit; 1966 1967 end; // no city found here 1967 1968 1968 special := Tile and fSpecial and ResourceMask[ p] shr 5;1969 special := Tile and fSpecial and ResourceMask[P] shr 5; 1969 1970 with Terrain[Tile and fTerrain] do 1970 1971 begin … … 1973 1974 Trade := TradeRes[special]; 1974 1975 if (special > 0) and (Tile and fTerrain <> fGrass) and 1975 (RW[ p].NatBuilt[imSpacePort] > 0) then1976 (RW[P].NatBuilt[imSpacePort] > 0) then 1976 1977 begin // GeoSat effect 1977 1978 Food := 2 * Food - FoodRes[0]; … … 1982 1983 if (Tile and fTerImp = tiIrrigation) or (Tile and fTerImp = tiFarm) or 1983 1984 (Tile and fCity <> 0) then 1984 inc(Food, IrrEff); { irrigation effect }1985 Inc(Food, IrrEff); { irrigation effect } 1985 1986 if Tile and fTerImp = tiMine then 1986 inc(Prod, MineEff); { mining effect }1987 if (Tile and fRiver <> 0) and (RW[ p].Tech[adMapMaking] >= tsApplicable)1987 Inc(Prod, MineEff); { mining effect } 1988 if (Tile and fRiver <> 0) and (RW[P].Tech[adMapMaking] >= tsApplicable) 1988 1989 then 1989 inc(Trade); { river effect }1990 Inc(Trade); { river effect } 1990 1991 if (Tile and (fRoad or fRR) <> 0) and (MoveCost = 1) and 1991 (RW[ p].Tech[adWheel] >= tsApplicable) then1992 inc(Trade); { road effect }1992 (RW[P].Tech[adWheel] >= tsApplicable) then 1993 Inc(Trade); { road effect } 1993 1994 if (Tile and (fRR or fCity) <> 0) and 1994 (RW[ p].Tech[adRailroad] >= tsApplicable) then1995 inc(Prod, Prod shr 1); { railroad effect }1995 (RW[P].Tech[adRailroad] >= tsApplicable) then 1996 Inc(Prod, Prod shr 1); { railroad effect } 1996 1997 1997 1998 ExplCity := -1; 1998 if (cix >= 0) and ( p= p0) then1999 if (cix >= 0) and (P = p0) then 1999 2000 ExplCity := cix; 2000 2001 if cix >= 0 then … … 2002 2003 begin 2003 2004 if ((Tile and fTerImp = tiFarm) or (Tile and fCity <> 0)) and 2004 (RW[ p].City[cix].Built[imSupermarket] > 0) then2005 inc(Food, Food shr 1); { farmland effect }2005 (RW[P].City[cix].Built[imSupermarket] > 0) then 2006 Inc(Food, Food shr 1); { farmland effect } 2006 2007 if (Tile and (fRoad or fRR) <> 0) and (MoveCost = 1) and 2007 (RW[ p].City[cix].Built[imHighways] > 0) then2008 inc(Trade, 1); { superhighway effect }2008 (RW[P].City[cix].Built[imHighways] > 0) then 2009 Inc(Trade, 1); { superhighway effect } 2009 2010 end 2010 2011 else 2011 2012 begin 2012 if RW[ p].City[cix].Built[imHarbor] > 0 then2013 inc(Food); { harbour effect }2014 if RW[ p].City[cix].Built[imPlatform] > 0 then2015 inc(Prod); { oil platform effect }2016 if GWonder[woLighthouse].EffectiveOwner = pthen2017 inc(Prod);2013 if RW[P].City[cix].Built[imHarbor] > 0 then 2014 Inc(Food); { harbour effect } 2015 if RW[P].City[cix].Built[imPlatform] > 0 then 2016 Inc(Prod); { oil platform effect } 2017 if GWonder[woLighthouse].EffectiveOwner = P then 2018 Inc(Prod); 2018 2019 end; 2019 2020 end; 2020 2021 2021 2022 { good government influence } 2022 if (RW[ p].Government in [gRepublic, gDemocracy, gFuture]) and (Trade > 0)2023 if (RW[P].Government in [gRepublic, gDemocracy, gFuture]) and (Trade > 0) 2023 2024 then 2024 inc(Trade);2025 if (RW[ p].Government = gCommunism) and (Prod > 1) then2026 inc(Prod);2027 2028 if RW[ p].Government in [gAnarchy, gDespotism] then2025 Inc(Trade); 2026 if (RW[P].Government = gCommunism) and (Prod > 1) then 2027 Inc(Prod); 2028 2029 if RW[P].Government in [gAnarchy, gDespotism] then 2029 2030 begin { bad government influence } 2030 2031 if Food > 3 then … … 2038 2039 if Tile and (fTerrain or fPoll) > fPoll then 2039 2040 begin { pollution - decrease ressources } 2040 dec(Food, Food shr 1);2041 dec(Prod, Prod shr 1);2042 dec(Trade, Trade shr 1);2041 Dec(Food, Food shr 1); 2042 Dec(Prod, Prod shr 1); 2043 Dec(Trade, Trade shr 1); 2043 2044 end; 2044 2045 2045 2046 if Tile and fCity <> 0 then 2046 2047 Trade := 0 2047 else if (cix >= 0) and (RW[ p].City[cix].Built[imCourt] + RW[p].City[cix]2048 else if (cix >= 0) and (RW[P].City[cix].Built[imCourt] + RW[P].City[cix] 2048 2049 .Built[imPalace] = 0) then 2049 if RW[ p].City[cix].Built[imTownHall] = 0 then2050 if RW[P].City[cix].Built[imTownHall] = 0 then 2050 2051 Trade := 0 2051 2052 else if Trade > 3 then 2052 2053 Trade := 3; 2053 2054 end; 2054 result := eOK;2055 end; { GetTileInfo }2056 2057 procedure Strongest(Loc: integer; var uix, Strength, Bonus, Cnt: integer);2055 Result := eOK; 2056 end; 2057 2058 procedure Strongest(Loc: Integer; var uix, Strength, Bonus, Cnt: Integer); 2058 2059 { find strongest defender at Loc } 2059 2060 var 2060 2061 Defender, uix1, Det, Cost, TestStrength, TestBonus, TestDet, TestCost, 2061 Domain: integer;2062 Domain: Integer; 2062 2063 PUn: ^TUn; 2063 2064 PModel: ^TModel; … … 2077 2078 if PUn.Loc = Loc then 2078 2079 begin 2079 inc(Cnt);2080 Inc(Cnt); 2080 2081 if PUn.Master < 0 then 2081 2082 begin … … 2084 2085 TestBonus := Terrain[RealMap[Loc] and fTerrain].Defense; 2085 2086 if RealMap[Loc] and fTerImp = tiFort then 2086 inc(TestBonus, 4);2087 Inc(TestBonus, 4); 2087 2088 if PUn.Flags and unFortified <> 0 then 2088 inc(TestBonus, 2);2089 Inc(TestBonus, 2); 2089 2090 if (PModel.Kind = mkSpecial_TownGuard) and 2090 2091 (RealMap[Loc] and fCity <> 0) then 2091 inc(TestBonus, 4);2092 Inc(TestBonus, 4); 2092 2093 end 2093 2094 else 2094 2095 TestBonus := 4; 2095 inc(TestBonus, PUn.exp div ExpCost);2096 Inc(TestBonus, PUn.exp div ExpCost); 2096 2097 TestStrength := PModel.Defense * TestBonus * PUn.Health; 2097 2098 if (Domain = dAir) and ((RealMap[Loc] and fCity <> 0) or … … 2103 2104 if PModel.Cap[mcStealth] > 0 then 2104 2105 else if PModel.Cap[mcSub] > 0 then 2105 inc(TestDet, 1 shl 28)2106 Inc(TestDet, 1 shl 28) 2106 2107 else if (Domain = dGround) and (PModel.Cap[mcFanatic] > 0) and 2107 2108 not(RW[Defender].Government in [gRepublic, gDemocracy, gFuture]) then 2108 inc(TestDet, 4 shl 28) // fanatic ground units always defend2109 Inc(TestDet, 4 shl 28) // fanatic ground units always defend 2109 2110 else if PModel.Flags and mdZOC <> 0 then 2110 inc(TestDet, 3 shl 28)2111 Inc(TestDet, 3 shl 28) 2111 2112 else 2112 inc(TestDet, 2 shl 28);2113 Inc(TestDet, 2 shl 28); 2113 2114 TestCost := RW[Defender].Model[PUn.mix].Cost; 2114 2115 if (TestDet > Det) or (TestDet = Det) and (TestCost < Cost) then … … 2125 2126 end; 2126 2127 2127 function UnitSpeed( p, mix, Health: integer): integer;2128 begin 2129 with RW[ p].Model[mix] do2130 begin 2131 result := Speed;2128 function UnitSpeed(P, mix, Health: Integer): Integer; 2129 begin 2130 with RW[P].Model[mix] do 2131 begin 2132 Result := Speed; 2132 2133 if Domain = dSea then 2133 2134 begin 2134 if GWonder[woMagellan].EffectiveOwner = pthen2135 inc(result, 200);2135 if GWonder[woMagellan].EffectiveOwner = P then 2136 Inc(Result, 200); 2136 2137 if Health < 100 then 2137 result := ((result - 250) * Health div 5000) * 50 + 250;2138 end 2139 end 2140 end; 2141 2142 procedure GetUnitReport( p, uix: integer; var UnitReport: TUnitReport);2143 var 2144 TerrOwner: integer;2138 Result := ((Result - 250) * Health div 5000) * 50 + 250; 2139 end; 2140 end; 2141 end; 2142 2143 procedure GetUnitReport(P, uix: Integer; var UnitReport: TUnitReport); 2144 var 2145 TerrOwner: Integer; 2145 2146 PModel: ^TModel; 2146 2147 begin … … 2148 2149 UnitReport.ProdSupport := 0; 2149 2150 UnitReport.ReportFlags := 0; 2150 if RW[ p].Government <> gAnarchy then2151 with RW[ p].Un[uix] do2152 begin 2153 PModel := @RW[ p].Model[mix];2151 if RW[P].Government <> gAnarchy then 2152 with RW[P].Un[uix] do 2153 begin 2154 PModel := @RW[P].Model[mix]; 2154 2155 if (PModel.Kind = mkSettler) 2155 2156 { and (GWonder[woFreeSettlers].EffectiveOwner<>p) } then 2156 UnitReport.FoodSupport := SettlerFood[RW[ p].Government]2157 UnitReport.FoodSupport := SettlerFood[RW[P].Government] 2157 2158 else if Flags and unConscripts <> 0 then 2158 2159 UnitReport.FoodSupport := 1; 2159 2160 2160 if RW[ p].Government <> gFundamentalism then2161 if RW[P].Government <> gFundamentalism then 2161 2162 begin 2162 2163 if GTestFlags and tfImmImprove = 0 then … … 2173 2174 begin 2174 2175 TerrOwner := RealMap[Loc] shr 27; 2175 case RW[ p].Government of2176 case RW[P].Government of 2176 2177 gRepublic, gFuture: 2177 if (TerrOwner <> p) and (TerrOwner < nPl) and2178 (RW[ p].Treaty[TerrOwner] < trAlliance) then2178 if (TerrOwner <> P) and (TerrOwner < nPl) and 2179 (RW[P].Treaty[TerrOwner] < trAlliance) then 2179 2180 UnitReport.ReportFlags := UnitReport.ReportFlags or urfDeployed; 2180 2181 gDemocracy: 2181 if (TerrOwner >= nPl) or (TerrOwner <> p) and2182 (RW[ p].Treaty[TerrOwner] < trAlliance) then2182 if (TerrOwner >= nPl) or (TerrOwner <> P) and 2183 (RW[P].Treaty[TerrOwner] < trAlliance) then 2183 2184 UnitReport.ReportFlags := UnitReport.ReportFlags or urfDeployed; 2184 2185 end; … … 2188 2189 end; 2189 2190 2190 procedure SearchCity(Loc: integer; var p, cix: integer);2191 procedure SearchCity(Loc: Integer; var P, cix: Integer); 2191 2192 // set p to supposed owner before call 2192 2193 var 2193 i: integer;2194 I: Integer; 2194 2195 begin 2195 2196 if RealMap[Loc] < nPl shl 27 then 2196 p:= RealMap[Loc] shr 27;2197 for i:= 0 to nPl - 1 do2198 begin 2199 if 1 shl pand GAlive <> 0 then2200 with RW[ p] do2197 P := RealMap[Loc] shr 27; 2198 for I := 0 to nPl - 1 do 2199 begin 2200 if 1 shl P and GAlive <> 0 then 2201 with RW[P] do 2201 2202 begin 2202 2203 cix := nCity - 1; 2203 2204 while (cix >= 0) and (City[cix].Loc <> Loc) do 2204 dec(cix);2205 Dec(cix); 2205 2206 if cix >= 0 then 2206 exit;2207 end; 2208 assert(i< nPl - 1);2209 p := (p+ 1) mod nPl;2210 end; 2211 end; 2212 2213 procedure MakeCityInfo( p, cix: integer; var ci: TCityInfo);2214 begin 2215 assert((p >= 0) and (p< nPl));2216 assert((cix >= 0) and (cix < RW[p].nCity));2217 with RW[ p].City[cix] do2207 Exit; 2208 end; 2209 Assert(I < nPl - 1); 2210 P := (P + 1) mod nPl; 2211 end; 2212 end; 2213 2214 procedure MakeCityInfo(P, cix: Integer; var ci: TCityInfo); 2215 begin 2216 Assert((P >= 0) and (P < nPl)); 2217 Assert((cix >= 0) and (cix < RW[P].nCity)); 2218 with RW[P].City[cix] do 2218 2219 begin 2219 2220 ci.Loc := Loc; 2220 2221 ci.ID := ID; 2221 ci.Owner := p;2222 ci.Owner := P; 2222 2223 ci.Size := Size; 2223 2224 ci.Flags := 0; 2224 2225 if Built[imPalace] > 0 then 2225 inc(ci.Flags, ciCapital);2226 if (Built[imWalls] > 0) or (Continent[Loc] = GrWallContinent[ p]) then2227 inc(ci.Flags, ciWalled);2226 Inc(ci.Flags, ciCapital); 2227 if (Built[imWalls] > 0) or (Continent[Loc] = GrWallContinent[P]) then 2228 Inc(ci.Flags, ciWalled); 2228 2229 if Built[imCoastalFort] > 0 then 2229 inc(ci.Flags, ciCoastalFort);2230 Inc(ci.Flags, ciCoastalFort); 2230 2231 if Built[imMissileBat] > 0 then 2231 inc(ci.Flags, ciMissileBat);2232 Inc(ci.Flags, ciMissileBat); 2232 2233 if Built[imBunker] > 0 then 2233 inc(ci.Flags, ciBunker);2234 Inc(ci.Flags, ciBunker); 2234 2235 if Built[imSpacePort] > 0 then 2235 inc(ci.Flags, ciSpacePort);2236 end; 2237 end; 2238 2239 procedure TellAboutModel( p, taOwner, tamix: integer);2240 var 2241 i: integer;2242 begin 2243 if ( p= taOwner) or (Mode < moPlaying) then2244 exit;2245 i:= 0;2246 while ( i < RW[p].nEnemyModel) and ((RW[p].EnemyModel[i].Owner <> taOwner) or2247 (RW[ p].EnemyModel[i].mix <> tamix)) do2248 inc(i);2249 if i = RW[p].nEnemyModel then2250 IntServer(sIntTellAboutModel + pshl 4, taOwner, tamix, nil^);2251 end; 2252 2253 function emixSafe( p, taOwner, tamix: integer): integer;2254 begin 2255 result := RWemix[p, taOwner, tamix];2256 if result < 0 then2236 Inc(ci.Flags, ciSpacePort); 2237 end; 2238 end; 2239 2240 procedure TellAboutModel(P, taOwner, tamix: Integer); 2241 var 2242 I: Integer; 2243 begin 2244 if (P = taOwner) or (Mode < moPlaying) then 2245 Exit; 2246 I := 0; 2247 while (I < RW[P].nEnemyModel) and ((RW[P].EnemyModel[I].Owner <> taOwner) or 2248 (RW[P].EnemyModel[I].mix <> tamix)) do 2249 Inc(I); 2250 if I = RW[P].nEnemyModel then 2251 IntServer(sIntTellAboutModel + P shl 4, taOwner, tamix, nil^); 2252 end; 2253 2254 function emixSafe(P, taOwner, tamix: Integer): Integer; 2255 begin 2256 Result := RWemix[P, taOwner, tamix]; 2257 if Result < 0 then 2257 2258 begin // sIntTellAboutModel comes too late 2258 assert(Mode = moMovie);2259 result := $FFFF;2260 end; 2261 end; 2262 2263 procedure IntroduceEnemy(p1, p2: integer);2259 Assert(Mode = moMovie); 2260 Result := $FFFF; 2261 end; 2262 end; 2263 2264 procedure IntroduceEnemy(p1, p2: Integer); 2264 2265 begin 2265 2266 RW[p1].Treaty[p2] := trNone; … … 2267 2268 end; 2268 2269 2269 function DiscoverTile(Loc, p, pTell, Level: integer; EnableContact: boolean;2270 euix: integer = -2): boolean;2270 function DiscoverTile(Loc, P, pTell, Level: Integer; EnableContact: Boolean; 2271 euix: Integer = -2): Boolean; 2271 2272 // euix = -2: full discover 2272 2273 // euix = -1: unit and city only, append units in EnemyUn 2273 2274 // euix >= 0: unit and city only, replace EnemyUn[euix] 2274 2275 2275 procedure SetContact(p1, p2: integer);2276 procedure SetContact(p1, p2: Integer); 2276 2277 begin 2277 2278 if (Mode < moPlaying) or (p1 = p2) or (RW[p1].Treaty[p2] > trNoContact) then 2278 exit;2279 Exit; 2279 2280 IntServer(sIntTellAboutNation, p1, p2, nil^); 2280 2281 // NewContact[p1,p2]:=true … … 2282 2283 2283 2284 var 2284 i, uix, cix, TerrOwner, TerrOwnerTreaty, Strength, Bonus, Cnt, pFoundCity,2285 cixFoundCity, MinLevel, Loc1, V8: integer;2285 I, uix, cix, TerrOwner, TerrOwnerTreaty, Strength, Bonus, Cnt, pFoundCity, 2286 cixFoundCity, MinLevel, Loc1, V8: Integer; 2286 2287 Tile, AddFlags: Cardinal; 2287 2288 Adjacent: TVicinity8Loc; … … 2289 2290 mox: ^TModel; 2290 2291 begin 2291 result := false;2292 Result := False; 2292 2293 with RW[pTell] do 2293 2294 begin … … 2305 2306 AddFlags := AddFlags or fGrWall; 2306 2307 if (Mode = moPlaying) and ((Tile and (nPl shl 27) <> nPl shl 27) and 2307 (pTell = p)) then2308 (pTell = P)) then 2308 2309 begin // set fPeace flag? 2309 2310 TerrOwner := Tile shr 27; … … 2314 2315 (1 shl trPeace or 1 shl TrFriendlyContact) <> 0 then 2315 2316 AddFlags := AddFlags or fPeace; 2316 end 2317 end; 2317 2318 end; 2318 2319 … … 2332 2333 unx := @RW[Occupant[Loc]].Un[uix]; 2333 2334 mox := @RW[Occupant[Loc]].Model[unx.mix]; 2334 assert((ZoCMap[Loc] <> 0) = (mox.Flags and mdZOC <> 0));2335 Assert((ZoCMap[Loc] <> 0) = (mox.Flags and mdZOC <> 0)); 2335 2336 if (mox.Cap[mcStealth] > 0) and (Tile and fCity = 0) and 2336 2337 (Tile and fTerImp <> tiBase) then … … 2348 2349 begin 2349 2350 uix := nEnemyUn; 2350 inc(nEnemyUn);2351 assert(nEnemyUn < neumax);2351 Inc(nEnemyUn); 2352 Assert(nEnemyUn < neumax); 2352 2353 end; 2353 2354 MakeUnitInfo(Occupant[Loc], unx^, EnemyUn[uix]); 2354 2355 if Cnt > 1 then 2355 2356 EnemyUn[uix].Flags := EnemyUn[uix].Flags or unMulti; 2356 if (mox.Flags and mdZOC <> 0) and (pTell = p) and2357 if (mox.Flags and mdZOC <> 0) and (pTell = P) and 2357 2358 (Treaty[Occupant[Loc]] < trAlliance) then 2358 2359 begin // set fInEnemyZoC flags of surrounding tiles … … 2363 2364 if (Loc1 >= 0) and (Loc1 < MapSize) then 2364 2365 Map[Loc1] := Map[Loc1] or fInEnemyZoC 2365 end 2366 end; 2366 2367 end; 2367 2368 if EnableContact and (mox.Domain = dGround) then … … 2373 2374 end; 2374 2375 // Level:=lObserveSuper; // don't discover unit twice 2375 if (pTell = p) and2376 if (pTell = P) and 2376 2377 ((Tile and fCity = 0) or (1 shl pTell and GAI <> 0)) then 2377 result := true;2378 Result := True; 2378 2379 end 2379 2380 else … … 2397 2398 while (cixFoundCity >= 0) and 2398 2399 (RW[pFoundCity].City[cixFoundCity].Loc <> Loc) do 2399 dec(cixFoundCity);2400 assert(cixFoundCity >= 0);2401 i:= 0;2402 while ( i < nEnemyCity) and (EnemyCity[i].Loc <> Loc) do2403 inc(i);2404 if i= nEnemyCity then2400 Dec(cixFoundCity); 2401 Assert(cixFoundCity >= 0); 2402 I := 0; 2403 while (I < nEnemyCity) and (EnemyCity[I].Loc <> Loc) do 2404 Inc(I); 2405 if I = nEnemyCity then 2405 2406 begin 2406 inc(nEnemyCity);2407 assert(nEnemyCity < necmax);2408 EnemyCity[ i].Status := 0;2409 EnemyCity[ i].SavedStatus := 0;2410 if pTell = pthen2411 result := true;2407 Inc(nEnemyCity); 2408 Assert(nEnemyCity < necmax); 2409 EnemyCity[I].Status := 0; 2410 EnemyCity[I].SavedStatus := 0; 2411 if pTell = P then 2412 Result := True; 2412 2413 end; 2413 MakeCityInfo(pFoundCity, cixFoundCity, EnemyCity[ i]);2414 MakeCityInfo(pFoundCity, cixFoundCity, EnemyCity[I]); 2414 2415 end; 2415 2416 end … … 2420 2421 2421 2422 if Map[Loc] and fTerrain = fUNKNOWN then 2422 inc(Discovered[pTell]);2423 Inc(Discovered[pTell]); 2423 2424 if euix >= -1 then 2424 2425 Map[Loc] := Map[Loc] and not(fUnit or fCity or fOwned or fOwnZoCUnit) or … … 2437 2438 Cardinal(Level) shl (2 * pTell); 2438 2439 end; 2439 end; // DiscoverTile2440 2441 function Discover9(Loc, p, Level: integer;2442 TellAllied, EnableContact: boolean): boolean;2443 var 2444 V9, Loc1, pTell, OldLevel: integer;2440 end; 2441 2442 function Discover9(Loc, P, Level: Integer; 2443 TellAllied, EnableContact: Boolean): Boolean; 2444 var 2445 V9, Loc1, pTell, OldLevel: Integer; 2445 2446 Radius: TVicinity8Loc; 2446 2447 begin 2447 assert((Mode > moLoading_Fast) or (RW[p].nEnemyUn = 0));2448 result := false;2448 Assert((Mode > moLoading_Fast) or (RW[P].nEnemyUn = 0)); 2449 Result := False; 2449 2450 V8_to_Loc(Loc, Radius); 2450 2451 for V9 := 0 to 8 do … … 2458 2459 begin 2459 2460 for pTell := 0 to nPl - 1 do 2460 if (pTell = p) or (1 shl pTell and GAlive <> 0) and2461 (RW[ p].Treaty[pTell] = trAlliance) then2461 if (pTell = P) or (1 shl pTell and GAlive <> 0) and 2462 (RW[P].Treaty[pTell] = trAlliance) then 2462 2463 begin 2463 2464 OldLevel := ObserveLevel[Loc1] shr (2 * pTell) and 3; 2464 2465 if Level > OldLevel then 2465 result := DiscoverTile(Loc1, p, pTell, Level, EnableContact)2466 or result;2466 Result := DiscoverTile(Loc1, P, pTell, Level, EnableContact) 2467 or Result; 2467 2468 end; 2468 2469 end 2469 2470 else 2470 2471 begin 2471 OldLevel := ObserveLevel[Loc1] shr (2 * p) and 3;2472 OldLevel := ObserveLevel[Loc1] shr (2 * P) and 3; 2472 2473 if Level > OldLevel then 2473 result := DiscoverTile(Loc1, p, p, Level, EnableContact) or result;2474 end; 2475 end; 2476 end; 2477 2478 function Discover21(Loc, p, AdjacentLevel: integer;2479 TellAllied, EnableContact: boolean): boolean;2480 var 2481 V21, Loc1, pTell, Level, OldLevel, AdjacentFlags: integer;2474 Result := DiscoverTile(Loc1, P, P, Level, EnableContact) or Result; 2475 end; 2476 end; 2477 end; 2478 2479 function Discover21(Loc, P, AdjacentLevel: Integer; 2480 TellAllied, EnableContact: Boolean): Boolean; 2481 var 2482 V21, Loc1, pTell, Level, OldLevel, AdjacentFlags: Integer; 2482 2483 Radius: TVicinity21Loc; 2483 2484 begin 2484 assert((Mode > moLoading_Fast) or (RW[p].nEnemyUn = 0));2485 result := false;2485 Assert((Mode > moLoading_Fast) or (RW[P].nEnemyUn = 0)); 2486 Result := False; 2486 2487 AdjacentFlags := $00267620 shr 1; 2487 2488 V21_to_Loc(Loc, Radius); … … 2498 2499 begin 2499 2500 for pTell := 0 to nPl - 1 do 2500 if (pTell = p) or (1 shl pTell and GAlive <> 0) and2501 (RW[ p].Treaty[pTell] = trAlliance) then2501 if (pTell = P) or (1 shl pTell and GAlive <> 0) and 2502 (RW[P].Treaty[pTell] = trAlliance) then 2502 2503 begin 2503 2504 OldLevel := ObserveLevel[Loc1] shr (2 * pTell) and 3; 2504 2505 if Level > OldLevel then 2505 result := DiscoverTile(Loc1, p, pTell, Level, EnableContact)2506 or result;2506 Result := DiscoverTile(Loc1, P, pTell, Level, EnableContact) 2507 or Result; 2507 2508 end; 2508 2509 end 2509 2510 else 2510 2511 begin 2511 OldLevel := ObserveLevel[Loc1] shr (2 * p) and 3;2512 OldLevel := ObserveLevel[Loc1] shr (2 * P) and 3; 2512 2513 if Level > OldLevel then 2513 result := DiscoverTile(Loc1, p, p, Level, EnableContact) or result;2514 Result := DiscoverTile(Loc1, P, P, Level, EnableContact) or Result; 2514 2515 end; 2515 2516 end; … … 2518 2519 end; 2519 2520 2520 procedure DiscoverAll( p, Level: integer);2521 procedure DiscoverAll(P, Level: Integer); 2521 2522 { player p discovers complete playground (for supervisor) } 2522 2523 var 2523 Loc, OldLevel: integer;2524 begin 2525 assert((Mode > moLoading_Fast) or (RW[p].nEnemyUn = 0));2524 Loc, OldLevel: Integer; 2525 begin 2526 Assert((Mode > moLoading_Fast) or (RW[P].nEnemyUn = 0)); 2526 2527 for Loc := 0 to MapSize - 1 do 2527 2528 begin 2528 OldLevel := ObserveLevel[Loc] shr (2 * p) and 3;2529 OldLevel := ObserveLevel[Loc] shr (2 * P) and 3; 2529 2530 if Level > OldLevel then 2530 DiscoverTile(Loc, p, p, Level, false);2531 end; 2532 end; 2533 2534 procedure DiscoverViewAreas( p: integer);2535 var 2536 pTell, uix, cix, ecix, Loc, RealOwner: integer;2531 DiscoverTile(Loc, P, P, Level, False); 2532 end; 2533 end; 2534 2535 procedure DiscoverViewAreas(P: Integer); 2536 var 2537 pTell, uix, cix, ecix, Loc, RealOwner: Integer; 2537 2538 PModel: ^TModel; 2538 2539 begin // discover unit and city view areas 2539 2540 for pTell := 0 to nPl - 1 do 2540 if (pTell = p) or (RW[p].Treaty[pTell] = trAlliance) then2541 if (pTell = P) or (RW[P].Treaty[pTell] = trAlliance) then 2541 2542 begin 2542 2543 for uix := 0 to RW[pTell].nUn - 1 do … … 2546 2547 PModel := @RW[pTell].Model[mix]; 2547 2548 if (PModel.Kind = mkDiplomat) or (PModel.Cap[mcSpy] > 0) then 2548 Discover21(Loc, p, lObserveSuper, false, true)2549 Discover21(Loc, P, lObserveSuper, False, True) 2549 2550 else if (PModel.Cap[mcRadar] + PModel.Cap[mcCarrier] > 0) or 2550 2551 (PModel.Domain = dAir) then 2551 Discover21(Loc, p, lObserveAll, false, false)2552 Discover21(Loc, P, lObserveAll, False, False) 2552 2553 else if (RealMap[Loc] and fTerrain = fMountains) or 2553 2554 (RealMap[Loc] and fTerImp = tiFort) or 2554 2555 (RealMap[Loc] and fTerImp = tiBase) or (PModel.Cap[mcAcademy] > 0) 2555 2556 then 2556 Discover21(Loc, p, lObserveUnhidden, false,2557 Discover21(Loc, P, lObserveUnhidden, False, 2557 2558 PModel.Domain = dGround) 2558 2559 else 2559 Discover9(Loc, p, lObserveUnhidden, false,2560 Discover9(Loc, P, lObserveUnhidden, False, 2560 2561 PModel.Domain = dGround); 2561 2562 end; 2562 2563 for cix := 0 to RW[pTell].nCity - 1 do 2563 2564 if RW[pTell].City[cix].Loc >= 0 then 2564 Discover21(RW[pTell].City[cix].Loc, p, lObserveUnhidden, false, true);2565 Discover21(RW[pTell].City[cix].Loc, P, lObserveUnhidden, False, True); 2565 2566 for ecix := 0 to RW[pTell].nEnemyCity - 1 do 2566 2567 begin // players know territory, so no use in hiding city owner … … 2574 2575 begin 2575 2576 RW[pTell].EnemyCity[ecix].Loc := -1; 2576 RW[pTell].Map[Loc] := RW[pTell].Map[Loc] and not fCity 2577 RW[pTell].Map[Loc] := RW[pTell].Map[Loc] and not fCity; 2577 2578 end; 2578 2579 end; … … 2581 2582 end; 2582 2583 2583 function GetUnitStack( p, Loc: integer): integer;2584 var 2585 uix: integer;2584 function GetUnitStack(P, Loc: Integer): Integer; 2585 var 2586 uix: Integer; 2586 2587 unx: ^TUn; 2587 2588 begin 2588 result := 0;2589 Result := 0; 2589 2590 if Occupant[Loc] < 0 then 2590 exit;2591 Exit; 2591 2592 for uix := 0 to RW[Occupant[Loc]].nUn - 1 do 2592 2593 begin … … 2594 2595 if unx.Loc = Loc then 2595 2596 begin 2596 MakeUnitInfo(Occupant[Loc], unx^, RW[ p].EnemyUn[RW[p].nEnemyUn + result]);2597 TellAboutModel( p, Occupant[Loc], unx.mix);2598 RW[ p].EnemyUn[RW[p].nEnemyUn + result].emix :=2599 RWemix[ p, Occupant[Loc], unx.mix];2600 inc(result);2601 end; 2602 end; 2603 end; 2604 2605 procedure UpdateUnitMap(Loc: integer; CityChange: boolean = false);2597 MakeUnitInfo(Occupant[Loc], unx^, RW[P].EnemyUn[RW[P].nEnemyUn + Result]); 2598 TellAboutModel(P, Occupant[Loc], unx.mix); 2599 RW[P].EnemyUn[RW[P].nEnemyUn + Result].emix := 2600 RWemix[P, Occupant[Loc], unx.mix]; 2601 Inc(Result); 2602 end; 2603 end; 2604 end; 2605 2606 procedure UpdateUnitMap(Loc: Integer; CityChange: Boolean = False); 2606 2607 // update maps and enemy units of all players after unit change 2607 2608 var 2608 p, euix, OldLevel: integer;2609 P, euix, OldLevel: Integer; 2609 2610 AddFlags, ClearFlags: Cardinal; 2610 2611 begin 2611 2612 if (Mode = moLoading_Fast) and not CityChange then 2612 exit;2613 for p:= 0 to nPl - 1 do2614 if 1 shl pand (GAlive or GWatching) <> 0 then2615 begin 2616 OldLevel := ObserveLevel[Loc] shr (2 * p) and 3;2613 Exit; 2614 for P := 0 to nPl - 1 do 2615 if 1 shl P and (GAlive or GWatching) <> 0 then 2616 begin 2617 OldLevel := ObserveLevel[Loc] shr (2 * P) and 3; 2617 2618 if OldLevel > lNoObserve then 2618 2619 begin 2619 if RW[ p].Map[Loc] and (fUnit or fOwned) = fUnit then2620 if RW[P].Map[Loc] and (fUnit or fOwned) = fUnit then 2620 2621 begin 2621 2622 // replace unit located here in EnemyUn 2622 2623 // do not just set loc:=-1 because total number would be unlimited 2623 euix := RW[ p].nEnemyUn - 1;2624 euix := RW[P].nEnemyUn - 1; 2624 2625 while euix >= 0 do 2625 2626 begin 2626 if RW[ p].EnemyUn[euix].Loc = Loc then2627 if RW[P].EnemyUn[euix].Loc = Loc then 2627 2628 begin 2628 RW[ p].EnemyUn[euix].Loc := -1;2629 RW[P].EnemyUn[euix].Loc := -1; 2629 2630 Break; 2630 2631 end; 2631 dec(euix);2632 Dec(euix); 2632 2633 end; 2633 RW[ p].Map[Loc] := RW[p].Map[Loc] and not fUnit2634 RW[P].Map[Loc] := RW[P].Map[Loc] and not fUnit 2634 2635 end 2635 2636 else 2636 2637 begin // look for empty slot in EnemyUn 2637 euix := RW[ p].nEnemyUn - 1;2638 while (euix >= 0) and (RW[ p].EnemyUn[euix].Loc >= 0) do2639 dec(euix);2638 euix := RW[P].nEnemyUn - 1; 2639 while (euix >= 0) and (RW[P].EnemyUn[euix].Loc >= 0) do 2640 Dec(euix); 2640 2641 end; 2641 2642 if (Occupant[Loc] < 0) and not CityChange then … … 2644 2645 if RealMap[Loc] and fCity = 0 then 2645 2646 ClearFlags := ClearFlags or fOwned; 2646 RW[ p].Map[Loc] := RW[p].Map[Loc] and not ClearFlags;2647 RW[P].Map[Loc] := RW[P].Map[Loc] and not ClearFlags; 2647 2648 end 2648 else if (Occupant[Loc] <> p) or CityChange then2649 else if (Occupant[Loc] <> P) or CityChange then 2649 2650 begin // city or enemy unit update necessary, call DiscoverTile 2650 ObserveLevel[Loc] := ObserveLevel[Loc] and not(3 shl (2 * p));2651 DiscoverTile(Loc, p, p, OldLevel, false, euix);2651 ObserveLevel[Loc] := ObserveLevel[Loc] and not(3 shl (2 * P)); 2652 DiscoverTile(Loc, P, P, OldLevel, False, euix); 2652 2653 end 2653 2654 else { if (Occupant[Loc]=p) and not CityChange then } … … 2659 2660 else 2660 2661 ClearFlags := ClearFlags or fOwnZoCUnit; 2661 RW[ p].Map[Loc] := RW[p].Map[Loc] and not ClearFlags or AddFlags;2662 end; 2663 end; 2664 end; 2665 end; 2666 2667 procedure RecalcV8ZoC( p, Loc: integer);2662 RW[P].Map[Loc] := RW[P].Map[Loc] and not ClearFlags or AddFlags; 2663 end; 2664 end; 2665 end; 2666 end; 2667 2668 procedure RecalcV8ZoC(P, Loc: Integer); 2668 2669 // recalculate fInEnemyZoC flags around single tile 2669 2670 var 2670 V8, V8V8, Loc1, Loc2, p1, ObserveMask: integer;2671 V8, V8V8, Loc1, Loc2, p1, ObserveMask: Integer; 2671 2672 Tile1: ^Cardinal; 2672 2673 Adjacent, AdjacentAdjacent: TVicinity8Loc; 2673 2674 begin 2674 2675 if Mode = moLoading_Fast then 2675 exit;2676 ObserveMask := 3 shl (2 * p);2676 Exit; 2677 ObserveMask := 3 shl (2 * P); 2677 2678 V8_to_Loc(Loc, Adjacent); 2678 2679 for V8 := 0 to 7 do … … 2681 2682 if (Loc1 >= 0) and (Loc1 < MapSize) then 2682 2683 begin 2683 Tile1 := @RW[ p].Map[Loc1];2684 Tile1 := @RW[P].Map[Loc1]; 2684 2685 Tile1^ := Tile1^ and not fInEnemyZoC; 2685 2686 V8_to_Loc(Loc1, AdjacentAdjacent); … … 2691 2692 begin 2692 2693 p1 := Occupant[Loc2]; 2693 assert(p1 <> nPl);2694 if (p1 <> p) and (RW[p].Treaty[p1] < trAlliance) then2694 Assert(p1 <> nPl); 2695 if (p1 <> P) and (RW[P].Treaty[p1] < trAlliance) then 2695 2696 begin 2696 2697 Tile1^ := Tile1^ or fInEnemyZoC; 2697 Break 2698 Break; 2698 2699 end; 2699 2700 end; … … 2703 2704 end; 2704 2705 2705 procedure RecalcMapZoC( p: integer);2706 procedure RecalcMapZoC(P: Integer); 2706 2707 // recalculate fInEnemyZoC flags for the whole map 2707 2708 var 2708 Loc, Loc1, V8, p1, ObserveMask: integer;2709 Loc, Loc1, V8, p1, ObserveMask: Integer; 2709 2710 Adjacent: TVicinity8Loc; 2710 2711 begin 2711 2712 if Mode = moLoading_Fast then 2712 exit;2713 MaskD(RW[ p].Map^, MapSize, Cardinal(not Cardinal(fInEnemyZoC)));2714 ObserveMask := 3 shl (2 * p);2713 Exit; 2714 MaskD(RW[P].Map^, MapSize, Cardinal(not Cardinal(fInEnemyZoC))); 2715 ObserveMask := 3 shl (2 * P); 2715 2716 for Loc := 0 to MapSize - 1 do 2716 2717 if (ZoCMap[Loc] > 0) and (ObserveLevel[Loc] and ObserveMask <> 0) then 2717 2718 begin 2718 2719 p1 := Occupant[Loc]; 2719 assert(p1 <> nPl);2720 if (p1 <> p) and (RW[p].Treaty[p1] < trAlliance) then2720 Assert(p1 <> nPl); 2721 if (p1 <> P) and (RW[P].Treaty[p1] < trAlliance) then 2721 2722 begin // this non-allied enemy ZoC unit is known to this player -- set flags! 2722 2723 V8_to_Loc(Loc, Adjacent); … … 2725 2726 Loc1 := Adjacent[V8]; 2726 2727 if (Loc1 >= 0) and (Loc1 < MapSize) then 2727 RW[ p].Map[Loc1] := RW[p].Map[Loc1] or fInEnemyZoC2728 end; 2729 end; 2730 end; 2731 end; 2732 2733 procedure RecalcPeaceMap( p: integer);2728 RW[P].Map[Loc1] := RW[P].Map[Loc1] or fInEnemyZoC; 2729 end; 2730 end; 2731 end; 2732 end; 2733 2734 procedure RecalcPeaceMap(P: Integer); 2734 2735 // recalculate fPeace flags for the whole map 2735 2736 var 2736 Loc, p1: integer;2737 PeacePlayer: array [-1 .. nPl - 1] of boolean;2737 Loc, p1: Integer; 2738 PeacePlayer: array [-1 .. nPl - 1] of Boolean; 2738 2739 begin 2739 2740 if Mode <> moPlaying then 2740 exit;2741 MaskD(RW[ p].Map^, MapSize, Cardinal(not Cardinal(fPeace)));2741 Exit; 2742 MaskD(RW[P].Map^, MapSize, Cardinal(not Cardinal(fPeace))); 2742 2743 for p1 := -1 to nPl - 1 do 2743 PeacePlayer[p1] := (p1 >= 0) and (p1 <> p) and (1 shl p1 and GAlive <> 0)2744 and (RW[ p].Treaty[p1] in [trPeace, TrFriendlyContact]);2744 PeacePlayer[p1] := (p1 >= 0) and (p1 <> P) and (1 shl p1 and GAlive <> 0) 2745 and (RW[P].Treaty[p1] in [trPeace, TrFriendlyContact]); 2745 2746 for Loc := 0 to MapSize - 1 do 2746 if PeacePlayer[RW[ p].Territory[Loc]] then2747 RW[ p].Map[Loc] := RW[p].Map[Loc] or fPeace;2747 if PeacePlayer[RW[P].Territory[Loc]] then 2748 RW[P].Map[Loc] := RW[P].Map[Loc] or fPeace; 2748 2749 end; 2749 2750 … … 2755 2756 BorderChanges: array [0 .. sIntExpandTerritory and $F - 1] of Cardinal; 2756 2757 2757 procedure ChangeTerritory(Loc, p: integer);2758 var 2759 p1: integer;2760 begin 2761 Assert( p>= 0); // no player's territory indicated by p=nPl2758 procedure ChangeTerritory(Loc, P: Integer); 2759 var 2760 p1: Integer; 2761 begin 2762 Assert(P >= 0); // no player's territory indicated by p=nPl 2762 2763 Dec(TerritoryCount[RealMap[Loc] shr 27]); 2763 Inc(TerritoryCount[ p]);2764 RealMap[Loc] := RealMap[Loc] and not($F shl 27) or Cardinal( p) shl 27;2765 if p= $F then2766 p:= -1;2764 Inc(TerritoryCount[P]); 2765 RealMap[Loc] := RealMap[Loc] and not($F shl 27) or Cardinal(P) shl 27; 2766 if P = $F then 2767 P := -1; 2767 2768 for p1 := 0 to nPl - 1 do 2768 2769 if 1 shl p1 and (GAlive or GWatching) <> 0 then 2769 2770 if RW[p1].Map[Loc] and fTerrain <> fUNKNOWN then 2770 2771 begin 2771 RW[p1].Territory[Loc] := p;2772 if ( p < nPl) and (p <> p1) and (1 shl pand GAlive <> 0) and2773 (RW[p1].Treaty[ p] in [trPeace, TrFriendlyContact]) then2772 RW[p1].Territory[Loc] := P; 2773 if (P < nPl) and (P <> p1) and (1 shl P and GAlive <> 0) and 2774 (RW[p1].Treaty[P] in [trPeace, TrFriendlyContact]) then 2774 2775 RW[p1].Map[Loc] := RW[p1].Map[Loc] or fPeace 2775 2776 else … … 2778 2779 end; 2779 2780 2780 procedure ExpandTerritory(OriginLoc: integer);2781 var 2782 i, dx, dy, dxMax, dyMax, Loc, NewOwner: integer;2781 procedure ExpandTerritory(OriginLoc: Integer); 2782 var 2783 I, dx, dy, dxMax, dyMax, Loc, NewOwner: Integer; 2783 2784 begin 2784 2785 if OriginLoc = -1 then 2785 2786 raise Exception.Create('Location error'); 2786 i:= 0;2787 I := 0; 2787 2788 dyMax := 0; 2788 2789 while (dyMax + 1) + (dyMax + 1) shr 1 <= CountryRadius do 2789 inc(dyMax);2790 Inc(dyMax); 2790 2791 for dy := -dyMax to dyMax do 2791 2792 begin … … 2793 2794 while abs(dy) + (dxMax + 2) + abs(abs(dy) - (dxMax + 2)) shr 1 <= 2794 2795 CountryRadius do 2795 inc(dxMax, 2);2796 Inc(dxMax, 2); 2796 2797 for dx := -dxMax to dxMax do 2797 2798 if (dy + dx) and 1 = 0 then 2798 2799 begin 2799 NewOwner := BorderChanges[ i div 8] shr (imod 8 * 4) and $F;2800 NewOwner := BorderChanges[I div 8] shr (I mod 8 * 4) and $F; 2800 2801 Loc := dLoc(OriginLoc, dx, dy); 2801 2802 if (Loc >= 0) and (Cardinal(NewOwner) <> RealMap[Loc] shr 27) then 2802 2803 ChangeTerritory(Loc, NewOwner); 2803 inc(i);2804 end; 2805 end; 2806 end; 2807 2808 procedure CheckBorders(OriginLoc, PlayerLosingCity: integer);2804 Inc(I); 2805 end; 2806 end; 2807 end; 2808 2809 procedure CheckBorders(OriginLoc, PlayerLosingCity: Integer); 2809 2810 // OriginLoc: only changes in CountryRadius around this location possible, 2810 2811 // -1 for complete map, -2 for double-check (no more changes allowed) … … 2812 2813 // player's territory, -1 for full border recalculation 2813 2814 var 2814 i, r, Loc, Loc1, dx, dy, p1, p2, cix, NewDist, dxMax, dyMax, OldOwner, V8: Integer;2815 I, R, Loc, Loc1, dx, dy, p1, p2, cix, NewDist, dxMax, dyMax, OldOwner, V8: Integer; 2815 2816 NewOwner: Cardinal; 2816 2817 Adjacent: TVicinity8Loc; 2817 AtPeace: array [0 .. nPl, 0 .. nPl] of boolean;2818 AtPeace: array [0 .. nPl, 0 .. nPl] of Boolean; 2818 2819 Country, FormerCountry, { to who's country a tile belongs } 2819 2820 Dist, FormerDist, StolenDist: array [0 .. lxmax * lymax - 1] of ShortInt; … … 2827 2828 StolenDist[RW[PlayerLosingCity].City[cix].Loc] := 0; 2828 2829 2829 for r:= 1 to CountryRadius shr 1 do2830 begin 2831 move(StolenDist, FormerDist, MapSize);2830 for R := 1 to CountryRadius shr 1 do 2831 begin 2832 Move(StolenDist, FormerDist, MapSize); 2832 2833 for Loc := 0 to MapSize - 1 do 2833 2834 if (FormerDist[Loc] <= CountryRadius - 2) … … 2861 2862 end; 2862 2863 2863 for r:= 1 to CountryRadius shr 1 do2864 begin 2865 move(Country, FormerCountry, MapSize);2866 move(Dist, FormerDist, MapSize);2864 for R := 1 to CountryRadius shr 1 do 2865 begin 2866 Move(Country, FormerCountry, MapSize); 2867 Move(Dist, FormerDist, MapSize); 2867 2868 for Loc := 0 to MapSize - 1 do 2868 2869 if (FormerDist[Loc] <= CountryRadius - 2) // use same conditions as above! … … 2870 2871 (1 shl fShore + 1 shl fMountains + 1 shl fArctic) = 0) then 2871 2872 begin 2872 assert(FormerCountry[Loc] >= 0);2873 Assert(FormerCountry[Loc] >= 0); 2873 2874 V8_to_Loc(Loc, Adjacent); 2874 2875 for V8 := 0 to 7 do … … 2885 2886 end; 2886 2887 2887 FillChar(AtPeace, SizeOf(AtPeace), false);2888 FillChar(AtPeace, SizeOf(AtPeace), False); 2888 2889 for p1 := 0 to nPl - 1 do 2889 2890 if 1 shl p1 and GAlive <> 0 then … … 2891 2892 if (p2 <> p1) and (1 shl p2 and GAlive <> 0) and 2892 2893 (RW[p1].Treaty[p2] >= trPeace) then 2893 AtPeace[p1, p2] := true;2894 AtPeace[p1, p2] := True; 2894 2895 2895 2896 if OriginLoc >= 0 then 2896 2897 begin // update area only 2897 i:= 0;2898 I := 0; 2898 2899 FillChar(BorderChanges, SizeOf(BorderChanges), 0); 2899 2900 dyMax := 0; 2900 2901 while (dyMax + 1) + (dyMax + 1) shr 1 <= CountryRadius do 2901 inc(dyMax);2902 Inc(dyMax); 2902 2903 for dy := -dyMax to dyMax do 2903 2904 begin … … 2905 2906 while abs(dy) + (dxMax + 2) + abs(abs(dy) - (dxMax + 2)) shr 1 <= 2906 2907 CountryRadius do 2907 inc(dxMax, 2);2908 Inc(dxMax, 2); 2908 2909 for dx := -dxMax to dxMax do 2909 2910 if (dy + dx) and 1 = 0 then … … 2921 2922 else 2922 2923 ChangeTerritory(Loc, NewOwner); 2923 BorderChanges[ i shr 3] := BorderChanges[ishr 3] or2924 ((NewOwner shl (( iand 7) * 4)) and $ffffffff);2924 BorderChanges[I shr 3] := BorderChanges[I shr 3] or 2925 ((NewOwner shl ((I and 7) * 4)) and $ffffffff); 2925 2926 end; 2926 inc(i);2927 Inc(I); 2927 2928 end; 2928 2929 end; … … 2937 2938 then 2938 2939 begin 2939 assert(OriginLoc <> -2); // test if border saving works2940 Assert(OriginLoc <> -2); // test if border saving works 2940 2941 ChangeTerritory(Loc, NewOwner); 2941 2942 end; … … 2944 2945 {$IFOPT O-} if OriginLoc <> -2 then 2945 2946 CheckBorders(-2); {$ENDIF} // check: single pass should do! 2946 end; // CheckBorders2947 2948 procedure LogCheckBorders( p, cix, PlayerLosingCity: integer);2949 begin 2950 CheckBorders(RW[ p].City[cix].Loc, PlayerLosingCity);2951 IntServer(sIntExpandTerritory, p, cix, BorderChanges);2947 end; 2948 2949 procedure LogCheckBorders(P, cix, PlayerLosingCity: Integer); 2950 begin 2951 CheckBorders(RW[P].City[cix].Loc, PlayerLosingCity); 2952 IntServer(sIntExpandTerritory, P, cix, BorderChanges); 2952 2953 end; 2953 2954 … … 2957 2958 } 2958 2959 2959 procedure CreateUnit( p, mix: integer);2960 begin 2961 with RW[ p] do2960 procedure CreateUnit(P, mix: Integer); 2961 begin 2962 with RW[P] do 2962 2963 begin 2963 2964 Un[nUn].mix := mix; 2964 2965 with Un[nUn] do 2965 2966 begin 2966 ID := UnBuilt[ p];2967 inc(UnBuilt[p]);2967 ID := UnBuilt[P]; 2968 Inc(UnBuilt[P]); 2968 2969 Status := 0; 2969 2970 SavedStatus := 0; 2970 inc(Model[mix].Built);2971 Inc(Model[mix].Built); 2971 2972 Home := -1; 2972 2973 Health := 100; … … 2976 2977 begin 2977 2978 Fuel := Model[mix].Cap[mcFuel]; 2978 Flags := Flags or unBombsLoaded 2979 Flags := Flags or unBombsLoaded; 2979 2980 end; 2980 2981 Job := jNone; … … 2984 2985 Master := -1; 2985 2986 end; 2986 inc(nUn);2987 Inc(nUn); 2987 2988 end 2988 2989 end; 2989 2990 2990 procedure FreeUnit( p, uix: integer);2991 procedure FreeUnit(P, uix: Integer); 2991 2992 // loc or master should be set after call 2992 2993 // implementation is critical for loading performance, change carefully 2993 2994 var 2994 Loc0, uix1: integer;2995 Occ, ZoC: boolean;2996 begin 2997 with RW[ p].Un[uix] do2995 Loc0, uix1: Integer; 2996 Occ, ZoC: Boolean; 2997 begin 2998 with RW[P].Un[uix] do 2998 2999 begin 2999 3000 Job := jNone; 3000 3001 Flags := Flags and not(unFortified or unMountainDelay); 3001 Loc0 := Loc 3002 Loc0 := Loc; 3002 3003 end; 3003 3004 if Occupant[Loc0] >= 0 then 3004 3005 begin 3005 assert(Occupant[Loc0] = p);3006 Occ := false;3007 ZoC := false;3008 for uix1 := 0 to RW[ p].nUn - 1 do3009 with RW[ p].Un[uix1] do3006 Assert(Occupant[Loc0] = P); 3007 Occ := False; 3008 ZoC := False; 3009 for uix1 := 0 to RW[P].nUn - 1 do 3010 with RW[P].Un[uix1] do 3010 3011 if (Loc = Loc0) and (Master < 0) and (uix1 <> uix) then 3011 3012 begin 3012 Occ := true;3013 if RW[ p].Model[mix].Flags and mdZOC <> 0 then3013 Occ := True; 3014 if RW[P].Model[mix].Flags and mdZOC <> 0 then 3014 3015 begin 3015 ZoC := true;3016 Break 3017 end 3016 ZoC := True; 3017 Break; 3018 end; 3018 3019 end; 3019 3020 if not Occ then … … 3024 3025 end; 3025 3026 3026 procedure PlaceUnit( p, uix: integer);3027 begin 3028 with RW[ p].Un[uix] do3029 begin 3030 Occupant[Loc] := p;3031 if RW[ p].Model[mix].Flags and mdZOC <> 0 then3027 procedure PlaceUnit(P, uix: Integer); 3028 begin 3029 with RW[P].Un[uix] do 3030 begin 3031 Occupant[Loc] := P; 3032 if RW[P].Model[mix].Flags and mdZOC <> 0 then 3032 3033 ZoCMap[Loc] := 1; 3033 3034 end; 3034 3035 end; 3035 3036 3036 procedure CountLost( p, mix, Enemy: integer);3037 begin 3038 Inc(RW[ p].Model[mix].Lost);3039 TellAboutModel(Enemy, p, mix);3040 Inc(Destroyed[Enemy, p, mix]);3041 end; 3042 3043 procedure RemoveUnit( p, uix: integer; Enemy: integer = -1);3037 procedure CountLost(P, mix, Enemy: Integer); 3038 begin 3039 Inc(RW[P].Model[mix].Lost); 3040 TellAboutModel(Enemy, P, mix); 3041 Inc(Destroyed[Enemy, P, mix]); 3042 end; 3043 3044 procedure RemoveUnit(P, uix: Integer; Enemy: Integer = -1); 3044 3045 // use enemy only from inside sMoveUnit if attack 3045 3046 var 3046 uix1: integer;3047 begin 3048 with RW[ p].Un[uix] do3049 begin 3050 assert((Loc >= 0) or (RW[p].Model[mix].Kind = mkDiplomat));3047 uix1: Integer; 3048 begin 3049 with RW[P].Un[uix] do 3050 begin 3051 Assert((Loc >= 0) or (RW[P].Model[mix].Kind = mkDiplomat)); 3051 3052 // already freed when spy mission 3052 3053 if Loc >= 0 then 3053 FreeUnit( p, uix);3054 FreeUnit(P, uix); 3054 3055 if Master >= 0 then 3055 if RW[ p].Model[mix].Domain = dAir then3056 dec(RW[p].Un[Master].AirLoad)3056 if RW[P].Model[mix].Domain = dAir then 3057 Dec(RW[P].Un[Master].AirLoad) 3057 3058 else 3058 dec(RW[p].Un[Master].TroopLoad);3059 Dec(RW[P].Un[Master].TroopLoad); 3059 3060 if (TroopLoad > 0) or (AirLoad > 0) then 3060 for uix1 := 0 to RW[ p].nUn - 1 do3061 if (RW[ p].Un[uix1].Loc >= 0) and (RW[p].Un[uix1].Master = uix) then3061 for uix1 := 0 to RW[P].nUn - 1 do 3062 if (RW[P].Un[uix1].Loc >= 0) and (RW[P].Un[uix1].Master = uix) then 3062 3063 { unit mastered by removed unit -- remove too } 3063 3064 begin 3064 RW[ p].Un[uix1].Loc := -1;3065 RW[P].Un[uix1].Loc := -1; 3065 3066 if Enemy >= 0 then 3066 CountLost( p, RW[p].Un[uix1].mix, Enemy);3067 CountLost(P, RW[P].Un[uix1].mix, Enemy); 3067 3068 end; 3068 3069 Loc := -1; 3069 3070 if Enemy >= 0 then 3070 CountLost( p, mix, Enemy);3071 end; 3072 end; 3073 3074 procedure RemoveUnit_UpdateMap( p, uix: integer);3071 CountLost(P, mix, Enemy); 3072 end; 3073 end; 3074 3075 procedure RemoveUnit_UpdateMap(P, uix: Integer); 3075 3076 var 3076 3077 Loc0: Integer; 3077 3078 begin 3078 Loc0 := RW[ p].Un[uix].Loc;3079 RemoveUnit( p, uix);3079 Loc0 := RW[P].Un[uix].Loc; 3080 RemoveUnit(P, uix); 3080 3081 if Mode > moLoading_Fast then 3081 3082 UpdateUnitMap(Loc0); 3082 3083 end; 3083 3084 3084 procedure RemoveAllUnits( p, Loc: integer; Enemy: integer = -1);3085 var 3086 uix: integer;3087 begin 3088 for uix := 0 to RW[ p].nUn - 1 do3089 if RW[ p].Un[uix].Loc = Loc then3085 procedure RemoveAllUnits(P, Loc: Integer; Enemy: Integer = -1); 3086 var 3087 uix: Integer; 3088 begin 3089 for uix := 0 to RW[P].nUn - 1 do 3090 if RW[P].Un[uix].Loc = Loc then 3090 3091 begin 3091 3092 if Enemy >= 0 then 3092 CountLost( p, RW[p].Un[uix].mix, Enemy);3093 RW[ p].Un[uix].Loc := -13093 CountLost(P, RW[P].Un[uix].mix, Enemy); 3094 RW[P].Un[uix].Loc := -1; 3094 3095 end; 3095 3096 Occupant[Loc] := -1; … … 3097 3098 end; 3098 3099 3099 procedure RemoveDomainUnits( d, p, Loc: integer);3100 var 3101 uix: integer;3102 begin 3103 for uix := 0 to RW[ p].nUn - 1 do3104 if (RW[ p].Model[RW[p].Un[uix].mix].Domain = d) and (RW[p].Un[uix].Loc = Loc)3100 procedure RemoveDomainUnits(D, P, Loc: Integer); 3101 var 3102 uix: Integer; 3103 begin 3104 for uix := 0 to RW[P].nUn - 1 do 3105 if (RW[P].Model[RW[P].Un[uix].mix].Domain = D) and (RW[P].Un[uix].Loc = Loc) 3105 3106 then 3106 RemoveUnit( p, uix);3107 end; 3108 3109 procedure FoundCity( p, FoundLoc: integer);3110 var 3111 p1, cix1, V21, dx, dy: integer;3112 begin 3113 if RW[ p].nCity = ncmax then3114 exit;3115 inc(RW[p].nCity);3116 with RW[ p].City[RW[p].nCity - 1] do3107 RemoveUnit(P, uix); 3108 end; 3109 3110 procedure FoundCity(P, FoundLoc: Integer); 3111 var 3112 p1, cix1, V21, dx, dy: Integer; 3113 begin 3114 if RW[P].nCity = ncmax then 3115 Exit; 3116 Inc(RW[P].nCity); 3117 with RW[P].City[RW[P].nCity - 1] do 3117 3118 begin 3118 3119 Size := 2; … … 3130 3131 if UsedByCity[FoundLoc] >= 0 then 3131 3132 begin { central tile is exploited - toggle in exploiting city } 3132 p1 := p;3133 p1 := P; 3133 3134 SearchCity(UsedByCity[FoundLoc], p1, cix1); 3134 3135 dxdy(UsedByCity[FoundLoc], FoundLoc, dx, dy); … … 3141 3142 (fTerrain or fSpecial or fRiver or nPl shl 27) or fCity; 3142 3143 3143 ChangeTerritory(Loc, p)3144 end; 3145 end; 3146 3147 procedure StealCity( p, cix: integer; SaveUnits: boolean);3148 var 3149 i, j, uix1, cix1, nearest: integer;3150 begin 3151 for i:= 0 to nWonder - 1 do3152 if RW[ p].City[cix].Built[i] = 1 then3153 begin 3154 GWonder[ i].EffectiveOwner := -1;3155 if i= woPyramids then3144 ChangeTerritory(Loc, P); 3145 end; 3146 end; 3147 3148 procedure StealCity(P, cix: Integer; SaveUnits: Boolean); 3149 var 3150 I, J, uix1, cix1, nearest: Integer; 3151 begin 3152 for I := 0 to nWonder - 1 do 3153 if RW[P].City[cix].Built[I] = 1 then 3154 begin 3155 GWonder[I].EffectiveOwner := -1; 3156 if I = woPyramids then 3156 3157 FreeSlaves; 3157 if i= woEiffel then // deactivate expired wonders3158 for j:= 0 to nWonder - 1 do3159 if GWonder[ j].EffectiveOwner = pthen3160 CheckExpiration( j);3161 end; 3162 for i:= nWonder to nImp - 1 do3163 if (Imp[ i].Kind <> ikCommon) and (RW[p].City[cix].Built[i] > 0) then3158 if I = woEiffel then // deactivate expired wonders 3159 for J := 0 to nWonder - 1 do 3160 if GWonder[J].EffectiveOwner = P then 3161 CheckExpiration(J); 3162 end; 3163 for I := nWonder to nImp - 1 do 3164 if (Imp[I].Kind <> ikCommon) and (RW[P].City[cix].Built[I] > 0) then 3164 3165 begin { destroy national projects } 3165 RW[ p].NatBuilt[i] := 0;3166 if i= imGrWall then3167 GrWallContinent[ p] := -1;3168 end; 3169 3170 for uix1 := 0 to RW[ p].nUn - 1 do3171 with RW[ p].Un[uix1] do3166 RW[P].NatBuilt[I] := 0; 3167 if I = imGrWall then 3168 GrWallContinent[P] := -1; 3169 end; 3170 3171 for uix1 := 0 to RW[P].nUn - 1 do 3172 with RW[P].Un[uix1] do 3172 3173 if (Loc >= 0) and (Home = cix) then 3173 3174 if SaveUnits then 3174 3175 begin // support units by nearest other city 3175 3176 nearest := -1; 3176 for cix1 := 0 to RW[ p].nCity - 1 do3177 if (cix1 <> cix) and (RW[ p].City[cix1].Loc >= 0) and3178 ((nearest < 0) or (Distance(RW[ p].City[cix1].Loc, Loc) <3179 Distance(RW[ p].City[nearest].Loc, Loc))) then3177 for cix1 := 0 to RW[P].nCity - 1 do 3178 if (cix1 <> cix) and (RW[P].City[cix1].Loc >= 0) and 3179 ((nearest < 0) or (Distance(RW[P].City[cix1].Loc, Loc) < 3180 Distance(RW[P].City[nearest].Loc, Loc))) then 3180 3181 nearest := cix1; 3181 Home := nearest 3182 Home := nearest; 3182 3183 end 3183 3184 else 3184 RemoveUnit( p, uix1); // destroy supported units3185 end; 3186 3187 procedure DestroyCity( p, cix: integer; SaveUnits: boolean);3188 var 3189 i, V21: integer;3185 RemoveUnit(P, uix1); // destroy supported units 3186 end; 3187 3188 procedure DestroyCity(P, cix: Integer; SaveUnits: Boolean); 3189 var 3190 I, V21: Integer; 3190 3191 Radius: TVicinity21Loc; 3191 3192 begin 3192 StealCity( p, cix, SaveUnits);3193 with RW[ p].City[cix] do begin3194 for i:= 0 to nWonder - 1 do3195 if Built[ i] > 0 then3196 GWonder[ i].CityID := WonderDestroyed;3193 StealCity(P, cix, SaveUnits); 3194 with RW[P].City[cix] do begin 3195 for I := 0 to nWonder - 1 do 3196 if Built[I] > 0 then 3197 GWonder[I].CityID := WonderDestroyed; 3197 3198 V21_to_Loc(Loc, Radius); 3198 3199 for V21 := 1 to 26 do … … 3200 3201 UsedByCity[Radius[V21]] := -1; 3201 3202 RealMap[Loc] := RealMap[Loc] and not fCity; 3202 Loc := -1 3203 end; 3204 end; 3205 3206 procedure ChangeCityOwner(pOld, cixOld, pNew: integer);3207 var 3208 i, j, cix1, Loc1, V21: integer;3203 Loc := -1; 3204 end; 3205 end; 3206 3207 procedure ChangeCityOwner(pOld, cixOld, pNew: Integer); 3208 var 3209 I, J, cix1, Loc1, V21: Integer; 3209 3210 Radius: TVicinity21Loc; 3210 3211 begin 3211 inc(RW[pNew].nCity);3212 Inc(RW[pNew].nCity); 3212 3213 RW[pNew].City[RW[pNew].nCity - 1] := RW[pOld].City[cixOld]; 3213 StealCity(pOld, cixOld, false);3214 StealCity(pOld, cixOld, False); 3214 3215 RW[pOld].City[cixOld].Loc := -1; 3215 3216 with RW[pNew].City[(RW[pNew].nCity - 1)] do … … 3230 3231 begin 3231 3232 Loc1 := Radius[V21]; 3232 assert((Loc1 >= 0) and (Loc1 < MapSize) and (UsedByCity[Loc1] = Loc));3233 Assert((Loc1 >= 0) and (Loc1 < MapSize) and (UsedByCity[Loc1] = Loc)); 3233 3234 if (ZoCMap[Loc1] > 0) and (Occupant[Loc1] <> pNew) and 3234 3235 (RW[pNew].Treaty[Occupant[Loc1]] < trAlliance) then … … 3242 3243 Built[imTownHall] := 0; 3243 3244 Built[imCourt] := 0; 3244 for i:= nWonder to nImp - 1 do3245 if Imp[ i].Kind <> ikCommon then3246 Built[ i] := 0; { destroy national projects }3247 for i:= 0 to nWonder - 1 do3248 if Built[ i] = 1 then3245 for I := nWonder to nImp - 1 do 3246 if Imp[I].Kind <> ikCommon then 3247 Built[I] := 0; { destroy national projects } 3248 for I := 0 to nWonder - 1 do 3249 if Built[I] = 1 then 3249 3250 begin // new wonder owner! 3250 GWonder[ i].EffectiveOwner := pNew;3251 if i= woEiffel then // reactivate expired wonders3252 begin 3253 for j:= 0 to nWonder - 1 do3254 if Imp[ j].Expiration >= 0 then3251 GWonder[I].EffectiveOwner := pNew; 3252 if I = woEiffel then // reactivate expired wonders 3253 begin 3254 for J := 0 to nWonder - 1 do 3255 if Imp[J].Expiration >= 0 then 3255 3256 for cix1 := 0 to (RW[pNew].nCity - 1) do 3256 if RW[pNew].City[cix1].Built[ j] = 1 then3257 GWonder[ j].EffectiveOwner := pNew;3257 if RW[pNew].City[cix1].Built[J] = 1 then 3258 GWonder[J].EffectiveOwner := pNew; 3258 3259 end 3259 3260 else 3260 CheckExpiration( i);3261 case iof3261 CheckExpiration(I); 3262 case I of 3262 3263 woLighthouse: 3263 3264 CheckSpecialModels(pNew, preLighthouse); … … 3273 3274 cix1 := RW[pNew].nEnemyCity - 1; 3274 3275 while (cix1 >= 0) and (RW[pNew].EnemyCity[cix1].Loc <> Loc) do 3275 dec(cix1);3276 assert(cix1 >= 0);3276 Dec(cix1); 3277 Assert(cix1 >= 0); 3277 3278 RW[pNew].EnemyCity[cix1].Loc := -1; 3278 3279 … … 3281 3282 end; 3282 3283 3283 procedure CompleteJob( p, Loc, Job: integer);3284 var 3285 ChangedTerrain, p1: integer;3286 begin 3287 assert(Job <> jCity);3284 procedure CompleteJob(P, Loc, Job: Integer); 3285 var 3286 ChangedTerrain, p1: Integer; 3287 begin 3288 Assert(Job <> jCity); 3288 3289 ChangedTerrain := -1; 3289 3290 case Job of … … 3327 3328 if not(RealMap[Loc] and fTerrain in TerrType_Canalable) then 3328 3329 begin 3329 RemoveDomainUnits(dSea, p, Loc);3330 RemoveDomainUnits(dSea, P, Loc); 3330 3331 RealMap[Loc] := RealMap[Loc] and not fCanal; 3331 3332 end; … … 3339 3340 begin 3340 3341 if RealMap[Loc] and fTerImp = tiBase then 3341 RemoveDomainUnits(dAir, p, Loc);3342 RemoveDomainUnits(dAir, P, Loc); 3342 3343 RealMap[Loc] := RealMap[Loc] and not fTerImp 3343 3344 end 3344 3345 else if RealMap[Loc] and fCanal <> 0 then 3345 3346 begin 3346 RemoveDomainUnits(dSea, p, Loc);3347 RemoveDomainUnits(dSea, P, Loc); 3347 3348 RealMap[Loc] := RealMap[Loc] and not fCanal 3348 3349 end … … 3374 3375 fPoll) or RealMap[Loc] and (fTerrain or fSpecial or fTerImp or 3375 3376 fRoad or fRR or fCanal or fPoll); 3376 end; // CompleteJob3377 end; 3377 3378 3378 3379 { … … 3380 3381 ____________________________________________________________________ 3381 3382 } 3382 procedure GiveCivilReport( p, pAbout: integer);3383 begin 3384 with RW[ p].EnemyReport[pAbout]^ do3383 procedure GiveCivilReport(P, pAbout: Integer); 3384 begin 3385 with RW[P].EnemyReport[pAbout]^ do 3385 3386 begin 3386 3387 // general info 3387 3388 TurnOfCivilReport := LastValidStat[pAbout]; 3388 move(RW[pAbout].Treaty, Treaty, SizeOf(Treaty));3389 Move(RW[pAbout].Treaty, Treaty, SizeOf(Treaty)); 3389 3390 Government := RW[pAbout].Government; 3390 3391 Money := RW[pAbout].Money; … … 3395 3396 if ResearchDone > 100 then 3396 3397 ResearchDone := 100; 3397 move(RW[pAbout].Tech, Tech, nAdv);3398 end; 3399 end; 3400 3401 procedure GiveMilReport( p, pAbout: integer);3402 var 3403 uix, mix: integer;3404 begin 3405 with RW[ p].EnemyReport[pAbout]^ do3398 Move(RW[pAbout].Tech, Tech, nAdv); 3399 end; 3400 end; 3401 3402 procedure GiveMilReport(P, pAbout: Integer); 3403 var 3404 uix, mix: Integer; 3405 begin 3406 with RW[P].EnemyReport[pAbout]^ do 3406 3407 begin 3407 3408 TurnOfMilReport := LastValidStat[pAbout]; … … 3409 3410 for mix := 0 to RW[pAbout].nModel - 1 do 3410 3411 begin 3411 TellAboutModel( p, pAbout, mix);3412 TellAboutModel(P, pAbout, mix); 3412 3413 UnCount[mix] := 0 3413 3414 end; 3414 3415 for uix := 0 to RW[pAbout].nUn - 1 do 3415 3416 if RW[pAbout].Un[uix].Loc >= 0 then 3416 inc(UnCount[RW[pAbout].Un[uix].mix]);3417 end; 3418 end; 3419 3420 procedure ShowPrice(pSender, pTarget, Price: integer);3417 Inc(UnCount[RW[pAbout].Un[uix].mix]); 3418 end; 3419 end; 3420 3421 procedure ShowPrice(pSender, pTarget, Price: Integer); 3421 3422 begin 3422 3423 case Price and opMask of … … 3433 3434 end; 3434 3435 3435 function CopyCivilReport(pSender, pTarget, pAbout: integer): boolean;3436 var 3437 i: integer;3436 function CopyCivilReport(pSender, pTarget, pAbout: Integer): Boolean; 3437 var 3438 I: Integer; 3438 3439 rSender, rTarget: ^TEnemyReport; 3439 3440 begin // copy third nation civil report 3440 result := false;3441 Result := False; 3441 3442 if RW[pTarget].Treaty[pAbout] = trNoContact then 3442 3443 IntroduceEnemy(pTarget, pAbout); 3443 rSender := pointer(RW[pSender].EnemyReport[pAbout]);3444 rTarget := pointer(RW[pTarget].EnemyReport[pAbout]);3444 rSender := Pointer(RW[pSender].EnemyReport[pAbout]); 3445 rTarget := Pointer(RW[pTarget].EnemyReport[pAbout]); 3445 3446 if rSender.TurnOfCivilReport > rTarget.TurnOfCivilReport then 3446 3447 begin // only if newer than current information … … 3451 3452 rTarget.ResearchTech := rSender.ResearchTech; 3452 3453 rTarget.ResearchDone := rSender.ResearchDone; 3453 result := true;3454 end; 3455 for i:= 0 to nAdv - 1 do3456 if rTarget.Tech[ i] < rSender.Tech[i] then3457 begin 3458 rTarget.Tech[ i] := rSender.Tech[i];3459 result := true;3460 end; 3461 end; 3462 3463 function CopyMilReport(pSender, pTarget, pAbout: integer): boolean;3464 var 3465 mix: integer;3454 Result := True; 3455 end; 3456 for I := 0 to nAdv - 1 do 3457 if rTarget.Tech[I] < rSender.Tech[I] then 3458 begin 3459 rTarget.Tech[I] := rSender.Tech[I]; 3460 Result := True; 3461 end; 3462 end; 3463 3464 function CopyMilReport(pSender, pTarget, pAbout: Integer): Boolean; 3465 var 3466 mix: Integer; 3466 3467 rSender, rTarget: ^TEnemyReport; 3467 3468 begin // copy third nation military report 3468 result := false;3469 Result := False; 3469 3470 if RW[pTarget].Treaty[pAbout] = trNoContact then 3470 3471 IntroduceEnemy(pTarget, pAbout); 3471 rSender := pointer(RW[pSender].EnemyReport[pAbout]);3472 rTarget := pointer(RW[pTarget].EnemyReport[pAbout]);3472 rSender := Pointer(RW[pSender].EnemyReport[pAbout]); 3473 rTarget := Pointer(RW[pTarget].EnemyReport[pAbout]); 3473 3474 if rSender.TurnOfMilReport > rTarget.TurnOfMilReport then 3474 3475 begin // only if newer than current information 3475 3476 rTarget.TurnOfMilReport := rSender.TurnOfMilReport; 3476 3477 rTarget.nModelCounted := rSender.nModelCounted; 3477 move(rSender.UnCount, rTarget.UnCount, 2 * rSender.nModelCounted);3478 Move(rSender.UnCount, rTarget.UnCount, 2 * rSender.nModelCounted); 3478 3479 for mix := 0 to rTarget.nModelCounted - 1 do 3479 3480 TellAboutModel(pTarget, pAbout, mix); 3480 result := true;3481 end; 3482 end; 3483 3484 procedure CopyModel(pSender, pTarget, mix: integer);3485 var 3486 i: integer;3481 Result := True; 3482 end; 3483 end; 3484 3485 procedure CopyModel(pSender, pTarget, mix: Integer); 3486 var 3487 I: Integer; 3487 3488 miSender, miTarget: TModelInfo; 3488 ok: boolean;3489 ok: Boolean; 3489 3490 begin 3490 3491 // only if target doesn't already have a model like this 3491 3492 ok := RW[pTarget].nModel < nmmax; 3492 3493 MakeModelInfo(pSender, mix, RW[pSender].Model[mix], miSender); 3493 for i:= 0 to RW[pTarget].nModel - 1 do3494 begin 3495 MakeModelInfo(pTarget, i, RW[pTarget].Model[i], miTarget);3494 for I := 0 to RW[pTarget].nModel - 1 do 3495 begin 3496 MakeModelInfo(pTarget, I, RW[pTarget].Model[I], miTarget); 3496 3497 if IsSameModel(miSender, miTarget) then 3497 ok := false;3498 ok := False; 3498 3499 end; 3499 3500 if ok then … … 3510 3511 Lost := 0; 3511 3512 end; 3512 inc(RW[pTarget].nModel);3513 inc(Researched[pTarget]);3513 Inc(RW[pTarget].nModel); 3514 Inc(Researched[pTarget]); 3514 3515 TellAboutModel(pSender, pTarget, RW[pTarget].nModel - 1); 3515 3516 end; 3516 3517 end; 3517 3518 3518 procedure CopyMap(pSender, pTarget: integer);3519 var 3520 Loc, i, cix: integer;3519 procedure CopyMap(pSender, pTarget: Integer); 3520 var 3521 Loc, I, cix: Integer; 3521 3522 Tile: Cardinal; 3522 3523 begin … … 3528 3529 if Tile and fCity <> 0 then 3529 3530 begin 3530 i:= 0;3531 while ( i< RW[pTarget].nEnemyCity) and3532 (RW[pTarget].EnemyCity[ i].Loc <> Loc) do3533 inc(i);3534 if i= RW[pTarget].nEnemyCity then3535 begin 3536 inc(RW[pTarget].nEnemyCity);3537 assert(RW[pTarget].nEnemyCity < necmax);3538 RW[pTarget].EnemyCity[ i].Status := 0;3539 RW[pTarget].EnemyCity[ i].SavedStatus := 0;3531 I := 0; 3532 while (I < RW[pTarget].nEnemyCity) and 3533 (RW[pTarget].EnemyCity[I].Loc <> Loc) do 3534 Inc(I); 3535 if I = RW[pTarget].nEnemyCity then 3536 begin 3537 Inc(RW[pTarget].nEnemyCity); 3538 Assert(RW[pTarget].nEnemyCity < necmax); 3539 RW[pTarget].EnemyCity[I].Status := 0; 3540 RW[pTarget].EnemyCity[I].SavedStatus := 0; 3540 3541 end; 3541 3542 if Tile and fOwned <> 0 then … … 3543 3544 cix := RW[pSender].nCity - 1; 3544 3545 while (cix >= 0) and (RW[pSender].City[cix].Loc <> Loc) do 3545 dec(cix);3546 MakeCityInfo(pSender, cix, RW[pTarget].EnemyCity[ i]);3546 Dec(cix); 3547 MakeCityInfo(pSender, cix, RW[pTarget].EnemyCity[I]); 3547 3548 end 3548 3549 else // city not owned by sender -- copy old info … … 3550 3551 cix := RW[pSender].nEnemyCity - 1; 3551 3552 while (cix >= 0) and (RW[pSender].EnemyCity[cix].Loc <> Loc) do 3552 dec(cix);3553 RW[pTarget].EnemyCity[ i] := RW[pSender].EnemyCity[cix];3553 Dec(cix); 3554 RW[pTarget].EnemyCity[I] := RW[pSender].EnemyCity[cix]; 3554 3555 end; 3555 3556 end … … 3565 3566 3566 3567 if RW[pTarget].Map[Loc] and fTerrain = fUNKNOWN then 3567 inc(Discovered[pTarget]);3568 Inc(Discovered[pTarget]); 3568 3569 RW[pTarget].Map[Loc] := RW[pTarget].Map[Loc] and fInEnemyZoC 3569 3570 // always preserve this flag! … … 3581 3582 end; 3582 3583 3583 function PayPrice(pSender, pTarget, Price: integer; execute: boolean): boolean;3584 var 3585 pSubject, i, n, NewTreaty: integer;3586 begin 3587 result := true;3584 function PayPrice(pSender, pTarget, Price: Integer; execute: Boolean): Boolean; 3585 var 3586 pSubject, I, N, NewTreaty: Integer; 3587 begin 3588 Result := True; 3588 3589 case Price and opMask of 3589 3590 opCivilReport: // + turn + concerned player shl 16 … … 3591 3592 pSubject := Price shr 16 and $F; 3592 3593 if pTarget = pSubject then 3593 result := false3594 Result := False 3594 3595 else if pSender = pSubject then 3595 3596 begin 3596 3597 if execute then 3597 GiveCivilReport(pTarget, pSender) 3598 GiveCivilReport(pTarget, pSender); 3598 3599 end 3599 3600 else if RW[pSender].EnemyReport[pSubject].TurnOfCivilReport < 0 then 3600 result := false3601 Result := False 3601 3602 else if execute then 3602 3603 CopyCivilReport(pSender, pTarget, pSubject); … … 3606 3607 pSubject := Price shr 16 and $F; 3607 3608 if pTarget = pSubject then 3608 result := false3609 Result := False 3609 3610 else if pSender = pSubject then 3610 3611 begin 3611 3612 if execute then 3612 GiveMilReport(pTarget, pSender) 3613 GiveMilReport(pTarget, pSender); 3613 3614 end 3614 3615 else if RW[pSender].EnemyReport[pSubject].TurnOfMilReport < 0 then 3615 result := false3616 Result := False 3616 3617 else if execute then 3617 CopyMilReport(pSender, pTarget, pSubject) 3618 CopyMilReport(pSender, pTarget, pSubject); 3618 3619 end; 3619 3620 opMap: … … 3628 3629 begin // agreed treaty end 3629 3630 if execute then 3630 CancelTreaty(pSender, pTarget, false)3631 CancelTreaty(pSender, pTarget, False); 3631 3632 end 3632 3633 else … … 3639 3640 NewTreaty := trPeace; 3640 3641 if NewTreaty < 0 then 3641 result := false3642 Result := False 3642 3643 else if execute then 3643 3644 begin 3644 assert(NewTreaty > RW[pSender].Treaty[pTarget]);3645 Assert(NewTreaty > RW[pSender].Treaty[pTarget]); 3645 3646 RW[pSender].Treaty[pTarget] := NewTreaty; 3646 3647 RW[pTarget].Treaty[pSender] := NewTreaty; … … 3671 3672 opShipParts: // + number + part type shl 16 3672 3673 begin 3673 n:= Price and $FFFF; // number3674 i:= Price shr 16 and $F; // type3675 if ( i < nShipPart) and (GShip[pSender].Parts[i] >= n) then3674 N := Price and $FFFF; // number 3675 I := Price shr 16 and $F; // type 3676 if (I < nShipPart) and (GShip[pSender].Parts[I] >= N) then 3676 3677 begin 3677 3678 if execute then 3678 3679 begin 3679 dec(GShip[pSender].Parts[i], n);3680 RW[pSender].Ship[pSender].Parts[ i] := GShip[pSender].Parts[i];3681 RW[pTarget].Ship[pSender].Parts[ i] := GShip[pSender].Parts[i];3680 Dec(GShip[pSender].Parts[I], N); 3681 RW[pSender].Ship[pSender].Parts[I] := GShip[pSender].Parts[I]; 3682 RW[pTarget].Ship[pSender].Parts[I] := GShip[pSender].Parts[I]; 3682 3683 if RW[pTarget].NatBuilt[imSpacePort] > 0 then 3683 3684 begin // space ship control requires space port 3684 inc(GShip[pTarget].Parts[i], n);3685 RW[pSender].Ship[pTarget].Parts[ i] := GShip[pTarget].Parts[i];3686 RW[pTarget].Ship[pTarget].Parts[ i] := GShip[pTarget].Parts[i];3685 Inc(GShip[pTarget].Parts[I], N); 3686 RW[pSender].Ship[pTarget].Parts[I] := GShip[pTarget].Parts[I]; 3687 RW[pTarget].Ship[pTarget].Parts[I] := GShip[pTarget].Parts[I]; 3687 3688 end; 3688 3689 end; 3689 3690 end 3690 3691 else 3691 result := false;3692 Result := False; 3692 3693 end; 3693 3694 opMoney: // + value … … 3697 3698 if execute then 3698 3699 begin 3699 dec(RW[pSender].Money, Price - opMoney);3700 inc(RW[pTarget].Money, Price - opMoney);3700 Dec(RW[pSender].Money, Price - opMoney); 3701 Inc(RW[pTarget].Money, Price - opMoney); 3701 3702 end; 3702 3703 end 3703 3704 else 3704 result := false;3705 Result := False; 3705 3706 opTribute: // + value 3706 3707 if execute then … … 3717 3718 end 3718 3719 else 3719 result := false;3720 Result := False; 3720 3721 opAllTech: 3721 3722 if execute then 3722 for i:= 0 to nAdv - 1 do3723 if (RW[pSender].Tech[ i] >= tsApplicable) and3724 (RW[pTarget].Tech[ i] = tsNA) then3723 for I := 0 to nAdv - 1 do 3724 if (RW[pSender].Tech[I] >= tsApplicable) and 3725 (RW[pTarget].Tech[I] = tsNA) then 3725 3726 begin 3726 SeeTech(pTarget, i);3727 RW[pSender].EnemyReport[pTarget].Tech[ i] := tsSeen;3728 RW[pTarget].EnemyReport[pSender].Tech[ i] := tsApplicable;3727 SeeTech(pTarget, I); 3728 RW[pSender].EnemyReport[pTarget].Tech[I] := tsSeen; 3729 RW[pTarget].EnemyReport[pSender].Tech[I] := tsApplicable; 3729 3730 end; 3730 3731 opModel: // + model index … … 3732 3733 begin 3733 3734 if execute then 3734 CopyModel(pSender, pTarget, Price - opModel) 3735 CopyModel(pSender, pTarget, Price - opModel); 3735 3736 end 3736 3737 else 3737 result := false;3738 Result := False; 3738 3739 opAllModel: 3739 3740 if execute then 3740 for i:= 0 to RW[pSender].nModel - 1 do3741 begin 3742 TellAboutModel(pTarget, pSender, i);3743 CopyModel(pSender, pTarget, i);3741 for I := 0 to RW[pSender].nModel - 1 do 3742 begin 3743 TellAboutModel(pTarget, pSender, I); 3744 CopyModel(pSender, pTarget, I); 3744 3745 end; 3745 3746 { opCity: // + city ID 3746 3747 begin 3747 result:=false3748 Result:=False 3748 3749 end; } 3749 end 3750 end; 3751 3752 procedure CancelTreaty( p, pWith: integer; DecreaseCredibility: boolean);3750 end; 3751 end; 3752 3753 procedure CancelTreaty(P, pWith: Integer; DecreaseCredibility: Boolean); 3753 3754 // side effect: PeaceEnded := bitarray of players with which peace treaty was canceled 3754 3755 var 3755 p1, OldTreaty: integer;3756 begin 3757 OldTreaty := RW[ p].Treaty[pWith];3756 p1, OldTreaty: Integer; 3757 begin 3758 OldTreaty := RW[P].Treaty[pWith]; 3758 3759 PeaceEnded := 0; 3759 3760 if OldTreaty >= trPeace then 3760 RW[ p].LastCancelTreaty[pWith] := GTurn;3761 RW[P].LastCancelTreaty[pWith] := GTurn; 3761 3762 if DecreaseCredibility then 3762 3763 begin … … 3764 3765 trPeace: 3765 3766 begin 3766 RW[ p].Credibility := RW[p].Credibility shr 1;3767 if RW[ p].MaxCredibility > 0 then3768 dec(RW[p].MaxCredibility, 10);3769 if RW[ p].Credibility > RW[p].MaxCredibility then3770 RW[ p].Credibility := RW[p].MaxCredibility;3767 RW[P].Credibility := RW[P].Credibility shr 1; 3768 if RW[P].MaxCredibility > 0 then 3769 Dec(RW[P].MaxCredibility, 10); 3770 if RW[P].Credibility > RW[P].MaxCredibility then 3771 RW[P].Credibility := RW[P].MaxCredibility; 3771 3772 end; 3772 3773 trAlliance: 3773 RW[ p].Credibility := RW[p].Credibility * 3 div 4;3774 end; 3775 RW[pWith].EnemyReport[ p].Credibility := RW[p].Credibility;3774 RW[P].Credibility := RW[P].Credibility * 3 div 4; 3775 end; 3776 RW[pWith].EnemyReport[P].Credibility := RW[P].Credibility; 3776 3777 end; 3777 3778 … … 3779 3780 begin 3780 3781 for p1 := 0 to nPl - 1 do 3781 if (p1 = pWith) or DecreaseCredibility and (p1 <> p) and3782 (RW[pWith].Treaty[p1] = trAlliance) and (RW[ p].Treaty[p1] >= trPeace)3782 if (p1 = pWith) or DecreaseCredibility and (p1 <> P) and 3783 (RW[pWith].Treaty[p1] = trAlliance) and (RW[P].Treaty[p1] >= trPeace) 3783 3784 then 3784 3785 begin 3785 RW[ p].Treaty[p1] := trNone;3786 RW[p1].Treaty[ p] := trNone;3787 RW[ p].EvaStart[p1] := -PeaceEvaTurns - 1;3788 RW[p1].EvaStart[ p] := -PeaceEvaTurns - 1;3789 inc(PeaceEnded, 1 shl p1);3786 RW[P].Treaty[p1] := trNone; 3787 RW[p1].Treaty[P] := trNone; 3788 RW[P].EvaStart[p1] := -PeaceEvaTurns - 1; 3789 RW[p1].EvaStart[P] := -PeaceEvaTurns - 1; 3790 Inc(PeaceEnded, 1 shl p1); 3790 3791 end; 3791 3792 CheckBorders(-1); 3792 3793 if (Mode > moLoading_Fast) and (PeaceEnded > 0) then 3793 RecalcMapZoC( p);3794 RecalcMapZoC(P); 3794 3795 end 3795 3796 else 3796 3797 begin 3797 RW[ p].Treaty[pWith] := OldTreaty - 1;3798 RW[pWith].Treaty[ p] := OldTreaty - 1;3798 RW[P].Treaty[pWith] := OldTreaty - 1; 3799 RW[pWith].Treaty[P] := OldTreaty - 1; 3799 3800 if OldTreaty = TrFriendlyContact then 3800 3801 begin // necessary for loading 3801 GiveCivilReport( p, pWith);3802 GiveCivilReport(pWith, p);3802 GiveCivilReport(P, pWith); 3803 GiveCivilReport(pWith, P); 3803 3804 end 3804 3805 else if OldTreaty = trAlliance then 3805 3806 begin // necessary for loading 3806 GiveMilReport( p, pWith);3807 GiveMilReport(pWith, p);3807 GiveMilReport(P, pWith); 3808 GiveMilReport(pWith, P); 3808 3809 end; 3809 3810 if (Mode > moLoading_Fast) and (OldTreaty = trAlliance) then 3810 3811 begin 3811 RecalcMapZoC( p);3812 RecalcMapZoC(P); 3812 3813 RecalcMapZoC(pWith); 3813 3814 end; … … 3815 3816 if OldTreaty in [trPeace, trAlliance] then 3816 3817 begin 3817 RecalcPeaceMap( p);3818 RecalcPeaceMap(P); 3818 3819 RecalcPeaceMap(pWith); 3819 3820 end; 3820 3821 end; 3821 3822 3822 function DoSpyMission( p, pCity, cix, Mission: integer): Cardinal;3823 var 3824 p1: integer;3825 begin 3826 result := 0;3823 function DoSpyMission(P, pCity, cix, Mission: Integer): Cardinal; 3824 var 3825 p1: Integer; 3826 begin 3827 Result := 0; 3827 3828 case Mission of 3828 3829 smSabotageProd: … … 3831 3832 smStealMap: 3832 3833 begin 3833 CopyMap(pCity, p);3834 RecalcPeaceMap( p);3834 CopyMap(pCity, P); 3835 RecalcPeaceMap(P); 3835 3836 end; 3836 3837 smStealCivilReport: 3837 3838 begin 3838 if RW[ p].Treaty[pCity] = trNoContact then3839 IntroduceEnemy( p, pCity);3840 GiveCivilReport( p, pCity);3839 if RW[P].Treaty[pCity] = trNoContact then 3840 IntroduceEnemy(P, pCity); 3841 GiveCivilReport(P, pCity); 3841 3842 end; 3842 3843 smStealMilReport: 3843 3844 begin 3844 if RW[ p].Treaty[pCity] = trNoContact then3845 IntroduceEnemy( p, pCity);3846 GiveMilReport( p, pCity);3845 if RW[P].Treaty[pCity] = trNoContact then 3846 IntroduceEnemy(P, pCity); 3847 GiveMilReport(P, pCity); 3847 3848 end; 3848 3849 smStealForeignReports: 3849 3850 begin 3850 3851 for p1 := 0 to nPl - 1 do 3851 if (p1 <> p) and (p1 <> pCity) and (RW[pCity].EnemyReport[p1] <> nil)3852 if (p1 <> P) and (p1 <> pCity) and (RW[pCity].EnemyReport[p1] <> nil) 3852 3853 then 3853 3854 begin 3854 3855 if RW[pCity].EnemyReport[p1].TurnOfCivilReport >= 0 then 3855 if CopyCivilReport(pCity, p, p1) then3856 result := result or (1 shl (2 * p1));3856 if CopyCivilReport(pCity, P, p1) then 3857 Result := Result or (1 shl (2 * p1)); 3857 3858 if RW[pCity].EnemyReport[p1].TurnOfMilReport >= 0 then 3858 if CopyMilReport(pCity, p, p1) then3859 result := result or (2 shl (2 * p1));3859 if CopyMilReport(pCity, P, p1) then 3860 Result := Result or (2 shl (2 * p1)); 3860 3861 end; 3861 3862 end; … … 3867 3868 ____________________________________________________________________ 3868 3869 } 3869 procedure ClearTestFlags(ClearFlags: integer);3870 var 3871 p1: integer;3870 procedure ClearTestFlags(ClearFlags: Integer); 3871 var 3872 p1: Integer; 3872 3873 begin 3873 3874 GTestFlags := GTestFlags and (not ClearFlags or tfTested or tfAllTechs or … … 3878 3879 end; 3879 3880 3880 procedure SetTestFlags( p, SetFlags: integer);3881 var 3882 i, p1, p2, MoreFlags: integer;3881 procedure SetTestFlags(P, SetFlags: Integer); 3882 var 3883 I, p1, p2, MoreFlags: Integer; 3883 3884 begin 3884 3885 MoreFlags := SetFlags and not GTestFlags; … … 3895 3896 begin // make p1 and p2 know each other 3896 3897 if RW[p1].Treaty[p2] = trNoContact then 3897 IntroduceEnemy(p1, p2) 3898 IntroduceEnemy(p1, p2); 3898 3899 end; 3899 3900 … … 3904 3905 if 1 shl p1 and GAlive <> 0 then 3905 3906 begin 3906 for i:= 0 to nAdv - 1 do // give all techs to player p13907 if not( i in FutureTech) and (RW[p1].Tech[i] < tsApplicable) then3907 for I := 0 to nAdv - 1 do // give all techs to player p1 3908 if not(I in FutureTech) and (RW[p1].Tech[I] < tsApplicable) then 3908 3909 begin 3909 RW[p1].Tech[ i] := tsCheat;3910 CheckSpecialModels(p1, i);3910 RW[p1].Tech[I] := tsCheat; 3911 CheckSpecialModels(p1, I); 3911 3912 end; 3912 3913 for p2 := 0 to nPl - 1 do 3913 3914 if (p2 <> p1) and (1 shl p2 and (GAlive or GWatching) <> 0) then 3914 for i:= 1 to 3 do3915 if RW[p2].EnemyReport[p1].Tech[AgePreq[ i]] < tsApplicable then3916 RW[p2].EnemyReport[p1].Tech[AgePreq[ i]] := tsCheat;3915 for I := 1 to 3 do 3916 if RW[p2].EnemyReport[p1].Tech[AgePreq[I]] < tsApplicable then 3917 RW[p2].EnemyReport[p1].Tech[AgePreq[I]] := tsCheat; 3917 3918 end; 3918 3919 end; … … 3920 3921 if MoreFlags and tfUncover <> 0 then 3921 3922 begin 3922 DiscoverAll( p, lObserveSuper);3923 DiscoverAll(P, lObserveSuper); 3923 3924 for p1 := 0 to nPl - 1 do 3924 3925 if 1 shl p1 and GAlive <> 0 then 3925 3926 begin 3926 3927 ResourceMask[p1] := $FFFFFFFF; 3927 if p1 <> pthen3928 begin 3929 GiveCivilReport( p, p1);3930 GiveMilReport( p, p1);3928 if p1 <> P then 3929 begin 3930 GiveCivilReport(P, p1); 3931 GiveMilReport(P, p1); 3931 3932 end; 3932 3933 end; … … 3938 3939 ____________________________________________________________________ 3939 3940 } 3940 procedure IntServer(Command, Player, Subject: integer; var Data); 3941 var 3942 i, p1: integer; 3943 3941 procedure IntServer(Command, Player, Subject: Integer; var Data); 3942 var 3943 I, p1: Integer; 3944 3944 begin 3945 3945 if Mode = moPlaying then … … 3951 3951 begin 3952 3952 {$IFDEF TEXTLOG}CmdInfo := Format('IntTellAboutNation P%d+P%d', [Player, Subject]); {$ENDIF} 3953 assert((Player >= 0) and (Player < nPl) and (Subject >= 0) and3953 Assert((Player >= 0) and (Player < nPl) and (Subject >= 0) and 3954 3954 (Subject < nPl)); 3955 3955 IntroduceEnemy(Player, Subject); … … 3959 3959 begin 3960 3960 {$IFDEF TEXTLOG}CmdInfo := Format('IntHaveContact P%d+P%d', [Player, Subject]); {$ENDIF} 3961 assert(RW[Player].Treaty[Subject] > trNoContact);3961 Assert(RW[Player].Treaty[Subject] > trNoContact); 3962 3962 RW[Player].EnemyReport[Subject].TurnOfContact := GTurn; 3963 3963 RW[Subject].EnemyReport[Player].TurnOfContact := GTurn; … … 3981 3981 p1 := (Command - sIntTellAboutModel) shr 4; // told player 3982 3982 {$IFDEF TEXTLOG}CmdInfo := Format('IntTellAboutModel P%d about P%d Mod%d', [p1, Player, Subject]); {$ENDIF} 3983 assert((Player >= 0) and (Player < nPl));3984 assert((Subject >= 0) and (Subject < RW[Player].nModel));3983 Assert((Player >= 0) and (Player < nPl)); 3984 Assert((Subject >= 0) and (Subject < RW[Player].nModel)); 3985 3985 MakeModelInfo(Player, Subject, RW[Player].Model[Subject], 3986 3986 RW[p1].EnemyModel[RW[p1].nEnemyModel]); 3987 3987 RWemix[p1, Player, Subject] := RW[p1].nEnemyModel; 3988 inc(RW[p1].nEnemyModel);3989 assert(RW[p1].nEnemyModel < nemmax);3988 Inc(RW[p1].nEnemyModel); 3989 Assert(RW[p1].nEnemyModel < nemmax); 3990 3990 end; 3991 3991 3992 3992 sIntDiscoverZOC: 3993 3993 begin 3994 {$IFDEF TEXTLOG}CmdInfo := Format('IntDiscoverZOC P%d Loc%d', [Player, integer(Data)]); {$ENDIF}3995 Discover9( integer(Data), Player, lObserveUnhidden, true, false);3994 {$IFDEF TEXTLOG}CmdInfo := Format('IntDiscoverZOC P%d Loc%d', [Player, Integer(Data)]); {$ENDIF} 3995 Discover9(Integer(Data), Player, lObserveUnhidden, True, False); 3996 3996 end; 3997 3997 … … 4000 4000 begin 4001 4001 {$IFDEF TEXTLOG}CmdInfo := Format('IntExpandTerritory P%d Loc%d', [Player, RW[Player].City[Subject].Loc]); {$ENDIF} 4002 move(Data, BorderChanges, SizeOf(BorderChanges));4002 Move(Data, BorderChanges, SizeOf(BorderChanges)); 4003 4003 ExpandTerritory(RW[Player].City[Subject].Loc); 4004 4004 end; … … 4007 4007 with RW[Player].City[Subject] do 4008 4008 begin 4009 {$IFDEF TEXTLOG}CmdInfo := Format('IntBuyMaterial P%d Loc%d Cost%d', [Player, Loc, integer(Data)]); {$ENDIF}4010 dec(RW[Player].Money, integer(Data));4009 {$IFDEF TEXTLOG}CmdInfo := Format('IntBuyMaterial P%d Loc%d Cost%d', [Player, Loc, Integer(Data)]); {$ENDIF} 4010 Dec(RW[Player].Money, Integer(Data)); 4011 4011 if (GWonder[woMich].EffectiveOwner = Player) and (Project and cpImp <> 0) 4012 4012 then 4013 inc(Prod, integer(Data) div 2)4013 Inc(Prod, Integer(Data) div 2) 4014 4014 else 4015 inc(Prod, integer(Data) div 4);4015 Inc(Prod, Integer(Data) div 4); 4016 4016 if Project0 and not cpAuto <> Project and not cpAuto then 4017 4017 Project0 := Project; … … 4022 4022 begin 4023 4023 {$IFDEF TEXTLOG}CmdInfo := Format('IntPayPrices P%d+P%d', [Player, Subject]); {$ENDIF} 4024 for i:= 0 to TOffer(Data).nDeliver - 1 do4025 PayPrice(Player, Subject, TOffer(Data).Price[ i], true);4026 for i:= 0 to TOffer(Data).nCost - 1 do4024 for I := 0 to TOffer(Data).nDeliver - 1 do 4025 PayPrice(Player, Subject, TOffer(Data).Price[I], True); 4026 for I := 0 to TOffer(Data).nCost - 1 do 4027 4027 PayPrice(Subject, Player, TOffer(Data).Price[TOffer(Data).nDeliver 4028 + i], true);4029 for i:= 0 to TOffer(Data).nDeliver + TOffer(Data).nCost - 1 do4030 if TOffer(Data).Price[ i] = opTreaty + trAlliance then4028 + I], True); 4029 for I := 0 to TOffer(Data).nDeliver + TOffer(Data).nCost - 1 do 4030 if TOffer(Data).Price[I] = opTreaty + trAlliance then 4031 4031 begin // add view area of allied player 4032 4032 DiscoverViewAreas(Player); 4033 4033 DiscoverViewAreas(Subject); 4034 Break 4035 end 4034 Break; 4035 end; 4036 4036 end; 4037 4037 4038 4038 sIntSetDevModel: 4039 4039 if Mode < moPlaying then 4040 move(Data, RW[Player].DevModel.Kind, sIntSetDevModel and $F * 4);4040 Move(Data, RW[Player].DevModel.Kind, sIntSetDevModel and $F * 4); 4041 4041 4042 4042 sIntSetModelStatus: … … 4045 4045 {$IFDEF TEXTLOG}CmdInfo := Format('IntSetModelStatus P%d', [Player]); 4046 4046 {$ENDIF} 4047 RW[Player].Model[Subject].Status := integer(Data);4047 RW[Player].Model[Subject].Status := Integer(Data); 4048 4048 end; 4049 4049 … … 4053 4053 {$IFDEF TEXTLOG}CmdInfo := Format('IntSetUnitStatus P%d', [Player]); 4054 4054 {$ENDIF} 4055 RW[Player].Un[Subject].Status := integer(Data);4055 RW[Player].Un[Subject].Status := Integer(Data); 4056 4056 end; 4057 4057 … … 4061 4061 {$IFDEF TEXTLOG}CmdInfo := Format('IntSetCityStatus P%d', [Player]); 4062 4062 {$ENDIF} 4063 RW[Player].City[Subject].Status := integer(Data);4063 RW[Player].City[Subject].Status := Integer(Data); 4064 4064 end; 4065 4065 … … 4069 4069 {$IFDEF TEXTLOG}CmdInfo := Format('IntSetECityStatus P%d', [Player]); 4070 4070 {$ENDIF} 4071 RW[Player].EnemyCity[Subject].Status := integer(Data); 4072 end; 4073 4074 end; { case command } 4075 end; { IntServer } 4071 RW[Player].EnemyCity[Subject].Status := Integer(Data); 4072 end; 4073 end; 4074 end; 4076 4075 4077 4076 end.
Note:
See TracChangeset
for help on using the changeset viewer.