Changeset 6 for trunk/LocalPlayer/CityScreen.pas
- Timestamp:
- Jan 7, 2017, 11:32:14 AM (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LocalPlayer/CityScreen.pas
r3 r6 1 1 {$INCLUDE switches} 2 3 2 unit CityScreen; 4 3 … … 6 5 7 6 uses 8 Protocol,ClientTools,Term,ScreenTools,IsoEngine,BaseWin, 9 10 Windows,Messages,SysUtils,Classes,Graphics,Controls,Forms,ExtCtrls,ButtonA, 7 Protocol, ClientTools, Term, ScreenTools, IsoEngine, BaseWin, 8 9 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, ExtCtrls, 10 ButtonA, 11 11 ButtonB, ButtonBase, ButtonC, Area; 12 12 13 13 const 14 WM_PLAYSOUND=WM_USER;14 WM_PLAYSOUND = WM_USER; 15 15 16 16 type 17 TCityCloseAction =(None, RestoreFocus, StepFocus);17 TCityCloseAction = (None, RestoreFocus, StepFocus); 18 18 19 19 TCityDlg = class(TBufferedDrawDlg) … … 36 36 Pop1Area: TArea; 37 37 SupportArea: TArea; 38 procedure FormCreate(Sender: TObject);39 procedure FormDestroy(Sender: TObject);40 procedure FormMouseDown(Sender: TObject;Button:TMouseButton;41 Shift: TShiftState;x,y:integer);42 procedure BuyClick(Sender: TObject);43 procedure CloseBtnClick(Sender: TObject);38 procedure FormCreate(Sender: TObject); 39 procedure FormDestroy(Sender: TObject); 40 procedure FormMouseDown(Sender: TObject; Button: TMouseButton; 41 Shift: TShiftState; x, y: integer); 42 procedure BuyClick(Sender: TObject); 43 procedure CloseBtnClick(Sender: TObject); 44 44 procedure FormShow(Sender: TObject); 45 45 procedure FormClose(Sender: TObject; var Action: TCloseAction); … … 48 48 procedure NextCityBtnClick(Sender: TObject); 49 49 procedure PrevCityBtnClick(Sender: TObject); 50 procedure FormKeyDown(Sender: TObject; var Key: Word; 51 Shift: TShiftState); 52 //procedure AdviceBtnClick(Sender: TObject); 50 procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 51 // procedure AdviceBtnClick(Sender: TObject); 53 52 procedure PageUpBtnClick(Sender: TObject); 54 53 procedure PageDownBtnClick(Sender: TObject); … … 58 57 CloseAction: TCityCloseAction; 59 58 procedure OffscreenPaint; override; 60 procedure ShowNewContent(NewMode, Loc: integer; ShowEvent: cardinal);59 procedure ShowNewContent(NewMode, Loc: integer; ShowEvent: cardinal); 61 60 procedure Reset; 62 61 procedure CheckAge; … … 64 63 private 65 64 c: TCity; 66 Report:TCityReportNew; 67 cOwner,cGov, 68 emix{enemy model index of produced unit}, 69 cix,cLoc,Mode,ZoomArea,Page,PageCount,BlinkTime,OpenSoundEvent, 70 SizeClass,AgePrepared: integer; 71 Optimize_cixTileChange,Optimize_TilesBeforeChange: integer; 65 Report: TCityReportNew; 66 cOwner, cGov, emix { enemy model index of produced unit } , cix, cLoc, Mode, 67 ZoomArea, Page, PageCount, BlinkTime, OpenSoundEvent, SizeClass, 68 AgePrepared: integer; 69 Optimize_cixTileChange, Optimize_TilesBeforeChange: integer; 72 70 Happened: cardinal; 73 imix: array[0..15] of integer;71 imix: array [0 .. 15] of integer; 74 72 CityAreaInfo: TCityAreaInfo; 75 73 AreaMap: TIsoMap; 76 CityMapTemplate, SmallCityMapTemplate, Back, SmallCityMap, ZoomCityMap, Template: TBitmap; 77 IsPort,ProdHint,AllowChange: boolean; 74 CityMapTemplate, SmallCityMapTemplate, Back, SmallCityMap, ZoomCityMap, 75 Template: TBitmap; 76 IsPort, ProdHint, AllowChange: boolean; 78 77 procedure InitSmallCityMap; 79 78 procedure InitZoomCityMap; … … 81 80 procedure ChangeCity(d: integer); 82 81 procedure ChangeResourceWeights(iResourceWeights: integer); 83 procedure OnPlaySound(var Msg: TMessage); message WM_PLAYSOUND;82 procedure OnPlaySound(var Msg: TMessage); message WM_PLAYSOUND; 84 83 end; 85 84 86 85 var 87 CityDlg: TCityDlg;86 CityDlg: TCityDlg; 88 87 89 88 implementation 90 89 91 90 uses 92 Select, Messg,MessgEx,Help,Inp,Tribes,Directories,91 Select, Messg, MessgEx, Help, Inp, Tribes, Directories, 93 92 94 93 Math; … … 97 96 98 97 const 99 {modes} 100 mSupp=1; mImp=2; 101 102 wBar=106; 103 xDiv=400; xService=296; 104 xmArea=197; ymArea=170; 105 xView=326; yView=275; 106 dxBar=wBar+12; dyBar=39; 107 xHapp=404; yHapp=9; 108 xFood=404; yFood=yHapp+3*dyBar+6; 109 xProd=404; yProd=yFood+3*dyBar+6; 110 xTrade=404; yTrade=yProd+2*dyBar+22; 111 xPoll=xmArea-186; yPoll=ymArea+64; 112 xmOpt=40; ymOpt=ymArea+96+34; 113 xSmallMap=271; ySmallMap=339; wSmallMap=98; hSmallMap=74; 114 xSupport=xSmallMap; ySupport=ySmallmap+hSmallmap+2; wSupport=64; hSupport=18; 115 xZoomMap=34; yZoomMap=338; wZoomMap=228; hZoomMap=124; wZoomEnvironment=68; 116 117 ImpPosition: array[28..nImp-1] of integer= 118 (-1, //imTrGoods 119 21, //imBarracks 120 6, //imGranary 121 1, //imTemple 122 7, //imMarket 123 14, //imLibrary 124 8, //imCourt 125 18, //imWalls 126 10, //imAqueduct 127 11, //imBank 128 5, //imCathedral 129 13, //imUniversity 130 29, //imHarbor 131 2, //imTheater 132 24, //imFactory 133 25, //imMfgPlant 134 28, //imRecycling 135 27, //imPower 136 27, //imHydro 137 27, //imNuclear 138 26, //imPlatform 139 8, //imTownHall 140 10, //imSewer 141 3, //imSupermarket 142 17, //imHighways 143 15, //imResLab 144 19, //imMissileBat 145 23, //imCoastalFort 146 22, //imAirport 147 20, //imDockyard 148 8, //imPalace 149 -1, //imGrWall 150 4, //imColosseum 151 16, //imObservatory 152 21, //imMilAcademy 153 -1, //imBunker 154 -1, //imAlgae 155 9, //imStockEx 156 -1, //imSpacePort 157 -1, //imShipComp 158 -1, //imShipPow 159 -1); //imShipHab 160 98 { modes } 99 mSupp = 1; 100 mImp = 2; 101 102 wBar = 106; 103 xDiv = 400; 104 xService = 296; 105 xmArea = 197; 106 ymArea = 170; 107 xView = 326; 108 yView = 275; 109 dxBar = wBar + 12; 110 dyBar = 39; 111 xHapp = 404; 112 yHapp = 9; 113 xFood = 404; 114 yFood = yHapp + 3 * dyBar + 6; 115 xProd = 404; 116 yProd = yFood + 3 * dyBar + 6; 117 xTrade = 404; 118 yTrade = yProd + 2 * dyBar + 22; 119 xPoll = xmArea - 186; 120 yPoll = ymArea + 64; 121 xmOpt = 40; 122 ymOpt = ymArea + 96 + 34; 123 xSmallMap = 271; 124 ySmallMap = 339; 125 wSmallMap = 98; 126 hSmallMap = 74; 127 xSupport = xSmallMap; 128 ySupport = ySmallMap + hSmallMap + 2; 129 wSupport = 64; 130 hSupport = 18; 131 xZoomMap = 34; 132 yZoomMap = 338; 133 wZoomMap = 228; 134 hZoomMap = 124; 135 wZoomEnvironment = 68; 136 137 ImpPosition: array [28 .. nImp - 1] of integer = (-1, // imTrGoods 138 21, // imBarracks 139 6, // imGranary 140 1, // imTemple 141 7, // imMarket 142 14, // imLibrary 143 8, // imCourt 144 18, // imWalls 145 10, // imAqueduct 146 11, // imBank 147 5, // imCathedral 148 13, // imUniversity 149 29, // imHarbor 150 2, // imTheater 151 24, // imFactory 152 25, // imMfgPlant 153 28, // imRecycling 154 27, // imPower 155 27, // imHydro 156 27, // imNuclear 157 26, // imPlatform 158 8, // imTownHall 159 10, // imSewer 160 3, // imSupermarket 161 17, // imHighways 162 15, // imResLab 163 19, // imMissileBat 164 23, // imCoastalFort 165 22, // imAirport 166 20, // imDockyard 167 8, // imPalace 168 -1, // imGrWall 169 4, // imColosseum 170 16, // imObservatory 171 21, // imMilAcademy 172 -1, // imBunker 173 -1, // imAlgae 174 9, // imStockEx 175 -1, // imSpacePort 176 -1, // imShipComp 177 -1, // imShipPow 178 -1); // imShipHab 161 179 162 180 var 163 ImpSorted: array[0..nImp-1] of integer; 164 165 166 procedure TCityDlg.FormCreate(Sender:TObject); 167 begin 168 inherited; 169 AreaMap:=TIsoMap.Create; 170 AreaMap.SetOutput(offscreen); 171 AreaMap.SetPaintBounds(xmArea-192,ymArea-96-32,xmArea+192,ymArea+96); 172 Mode:=mImp; 173 ZoomArea:=1; 174 ProdHint:=false; 175 RestoreUnFocus:=-1; 176 OpenSoundEvent:=-1; 177 AgePrepared:=-2; 178 Optimize_cixTileChange:=-1; 179 InitButtons(); 180 //InitWindowRegion; 181 CloseBtn.Caption:=Phrases.Lookup('BTN_OK'); 182 BuyBtn.Hint:=Phrases.Lookup('BTN_BUY'); 183 if not Phrases2FallenBackToEnglish then 184 SupportArea.Hint:=Phrases2.Lookup('TIP_SUPUNITS') 185 else SupportArea.Hint:=Phrases.Lookup('SUPUNITS'); 186 if not Phrases2FallenBackToEnglish then 187 begin 188 Pop0Area.Hint:=Phrases2.Lookup('TIP_WORKING'); 189 Pop1Area.Hint:=Phrases2.Lookup('TIP_CIVIL'); 190 PrimacyArea.Hint:=Phrases2.Lookup('TIP_PRIMACY'); 191 ProjectArea.Hint:=Phrases2.Lookup('TIP_PROJECT'); 192 end; 193 194 Back:=TBitmap.Create; 195 Back.PixelFormat:=pf24bit; 196 Back.Width:=ClientWidth; Back.Height:=ClientHeight; 197 Template:=TBitmap.Create; 198 LoadGraphicFile(Template, HomeDir+'Graphics\City', gfNoGamma); 199 Template.PixelFormat:=pf8bit; 200 CityMapTemplate:=TBitmap.Create; 201 LoadGraphicFile(CityMapTemplate, HomeDir+'Graphics\BigCityMap', gfNoGamma); 202 CityMapTemplate.PixelFormat:=pf8bit; 203 SmallCityMapTemplate:=TBitmap.Create; 204 LoadGraphicFile(SmallCityMapTemplate, HomeDir+'Graphics\SmallCityMap', gfNoGamma); 205 SmallCityMapTemplate.PixelFormat:=pf24bit; 206 SmallCityMap:=TBitmap.Create; 207 SmallCityMap.PixelFormat:=pf24bit; 208 SmallCityMap.Width:=98; SmallCityMap.Height:=74; 209 ZoomCityMap:=TBitmap.Create; 210 ZoomCityMap.PixelFormat:=pf24bit; 211 ZoomCityMap.Width:=228; ZoomCityMap.Height:=124; 212 end; 213 214 procedure TCityDlg.FormDestroy(Sender:TObject); 215 begin 216 AreaMap.Free; 217 SmallCityMap.Free; 218 ZoomCityMap.Free; 219 CityMapTemplate.Free; 220 Template.Free; 221 Back.Free; 181 ImpSorted: array [0 .. nImp - 1] of integer; 182 183 procedure TCityDlg.FormCreate(Sender: TObject); 184 begin 185 inherited; 186 AreaMap := TIsoMap.Create; 187 AreaMap.SetOutput(offscreen); 188 AreaMap.SetPaintBounds(xmArea - 192, ymArea - 96 - 32, xmArea + 192, 189 ymArea + 96); 190 Mode := mImp; 191 ZoomArea := 1; 192 ProdHint := false; 193 RestoreUnFocus := -1; 194 OpenSoundEvent := -1; 195 AgePrepared := -2; 196 Optimize_cixTileChange := -1; 197 InitButtons(); 198 // InitWindowRegion; 199 CloseBtn.Caption := Phrases.Lookup('BTN_OK'); 200 BuyBtn.Hint := Phrases.Lookup('BTN_BUY'); 201 if not Phrases2FallenBackToEnglish then 202 SupportArea.Hint := Phrases2.Lookup('TIP_SUPUNITS') 203 else 204 SupportArea.Hint := Phrases.Lookup('SUPUNITS'); 205 if not Phrases2FallenBackToEnglish then 206 begin 207 Pop0Area.Hint := Phrases2.Lookup('TIP_WORKING'); 208 Pop1Area.Hint := Phrases2.Lookup('TIP_CIVIL'); 209 PrimacyArea.Hint := Phrases2.Lookup('TIP_PRIMACY'); 210 ProjectArea.Hint := Phrases2.Lookup('TIP_PROJECT'); 211 end; 212 213 Back := TBitmap.Create; 214 Back.PixelFormat := pf24bit; 215 Back.Width := ClientWidth; 216 Back.Height := ClientHeight; 217 Template := TBitmap.Create; 218 LoadGraphicFile(Template, HomeDir + 'Graphics\City', gfNoGamma); 219 Template.PixelFormat := pf8bit; 220 CityMapTemplate := TBitmap.Create; 221 LoadGraphicFile(CityMapTemplate, HomeDir + 'Graphics\BigCityMap', gfNoGamma); 222 CityMapTemplate.PixelFormat := pf8bit; 223 SmallCityMapTemplate := TBitmap.Create; 224 LoadGraphicFile(SmallCityMapTemplate, HomeDir + 'Graphics\SmallCityMap', 225 gfNoGamma); 226 SmallCityMapTemplate.PixelFormat := pf24bit; 227 SmallCityMap := TBitmap.Create; 228 SmallCityMap.PixelFormat := pf24bit; 229 SmallCityMap.Width := 98; 230 SmallCityMap.Height := 74; 231 ZoomCityMap := TBitmap.Create; 232 ZoomCityMap.PixelFormat := pf24bit; 233 ZoomCityMap.Width := 228; 234 ZoomCityMap.Height := 124; 235 end; 236 237 procedure TCityDlg.FormDestroy(Sender: TObject); 238 begin 239 AreaMap.Free; 240 SmallCityMap.Free; 241 ZoomCityMap.Free; 242 CityMapTemplate.Free; 243 Template.Free; 244 Back.Free; 222 245 end; 223 246 224 247 procedure TCityDlg.Reset; 225 248 begin 226 Mode:=mImp;227 ZoomArea:=1;249 Mode := mImp; 250 ZoomArea := 1; 228 251 end; 229 252 230 253 procedure TCityDlg.CheckAge; 231 254 begin 232 if MainTextureAge<>AgePrepared then233 begin 234 AgePrepared:=MainTextureAge;235 bitblt(Back.Canvas.Handle,0,0,ClientWidth,ClientHeight,236 MainTexture.Image.Canvas.Handle,0,0,SRCCOPY);237 ImageOp_B(Back,Template,0,0,0,0,ClientWidth,ClientHeight);255 if MainTextureAge <> AgePrepared then 256 begin 257 AgePrepared := MainTextureAge; 258 bitblt(Back.Canvas.Handle, 0, 0, ClientWidth, ClientHeight, 259 MainTexture.Image.Canvas.Handle, 0, 0, SRCCOPY); 260 ImageOp_B(Back, Template, 0, 0, 0, 0, ClientWidth, ClientHeight); 238 261 end 239 262 end; 240 263 241 procedure TCityDlg.CloseBtnClick(Sender: TObject);242 begin 243 Close264 procedure TCityDlg.CloseBtnClick(Sender: TObject); 265 begin 266 Close 244 267 end; 245 268 246 269 procedure TCityDlg.InitSmallCityMap; 247 270 var 248 i,iix,cli1,Color0,Color1,Color2: integer; 249 begin 250 if cix>=0 then c:=MyCity[cix]; 251 case MyMap[cLoc] and fTerrain of 252 fPrairie: cli1:=cliPrairie; 253 fHills: cli1:=cliHills; 254 fTundra: cli1:=cliTundra; 255 else cli1:=cliPlains; 256 end; 257 Color0:=Colors.Canvas.Pixels[clkAge0+Age,cliRoad]; 258 Color1:=Colors.Canvas.Pixels[clkCity,cli1]; 259 Color2:=Colors.Canvas.Pixels[clkAge0+Age,cliHouse]; 260 BitBlt(SmallCityMap.Canvas.Handle,0,0,83,hSmallMap,SmallCityMapTemplate.Canvas.Handle,83*SizeClass,0,SRCCOPY); 261 if IsPort then 262 begin 263 BitBlt(SmallCityMap.Canvas.Handle,83,0,15,hSmallMap,SmallCityMapTemplate.Canvas.Handle,332+15,0,SRCCOPY); 264 ImageOp_CCC(SmallCityMap,0,0,83,hSmallMap,Color0,Color1,Color2); 265 Color2:=Colors.Canvas.Pixels[clkCity,cliWater]; 266 ImageOp_CCC(SmallCityMap,83,0,15,hSmallMap,Color0,Color1,Color2); 271 i, iix, cli1, Color0, Color1, Color2: integer; 272 begin 273 if cix >= 0 then 274 c := MyCity[cix]; 275 case MyMap[cLoc] and fTerrain of 276 fPrairie: 277 cli1 := cliPrairie; 278 fHills: 279 cli1 := cliHills; 280 fTundra: 281 cli1 := cliTundra; 282 else 283 cli1 := cliPlains; 284 end; 285 Color0 := Colors.Canvas.Pixels[clkAge0 + Age, cliRoad]; 286 Color1 := Colors.Canvas.Pixels[clkCity, cli1]; 287 Color2 := Colors.Canvas.Pixels[clkAge0 + Age, cliHouse]; 288 bitblt(SmallCityMap.Canvas.Handle, 0, 0, 83, hSmallMap, 289 SmallCityMapTemplate.Canvas.Handle, 83 * SizeClass, 0, SRCCOPY); 290 if IsPort then 291 begin 292 bitblt(SmallCityMap.Canvas.Handle, 83, 0, 15, hSmallMap, 293 SmallCityMapTemplate.Canvas.Handle, 332 + 15, 0, SRCCOPY); 294 ImageOp_CCC(SmallCityMap, 0, 0, 83, hSmallMap, Color0, Color1, Color2); 295 Color2 := Colors.Canvas.Pixels[clkCity, cliWater]; 296 ImageOp_CCC(SmallCityMap, 83, 0, 15, hSmallMap, Color0, Color1, Color2); 267 297 end 268 else 269 begin 270 BitBlt(SmallCityMap.Canvas.Handle,83,0,15,hSmallMap,SmallCityMapTemplate.Canvas.Handle,332,0,SRCCOPY); 271 ImageOp_CCC(SmallCityMap,0,0,wSmallMap,hSmallMap,Color0,Color1,Color2); 272 end; 273 274 with SmallCityMap.canvas do 275 begin 276 brush.Color:=Colors.Canvas.Pixels[clkAge0+Age,cliImp]; 277 for i:=0 to 29 do 278 begin 279 for iix:=28 to nImp-1 do 280 if (ImpPosition[iix]=i) and (c.Built[iix]>0) then 298 else 299 begin 300 bitblt(SmallCityMap.Canvas.Handle, 83, 0, 15, hSmallMap, 301 SmallCityMapTemplate.Canvas.Handle, 332, 0, SRCCOPY); 302 ImageOp_CCC(SmallCityMap, 0, 0, wSmallMap, hSmallMap, Color0, 303 Color1, Color2); 304 end; 305 306 with SmallCityMap.Canvas do 307 begin 308 brush.Color := Colors.Canvas.Pixels[clkAge0 + Age, cliImp]; 309 for i := 0 to 29 do 310 begin 311 for iix := 28 to nImp - 1 do 312 if (ImpPosition[iix] = i) and (c.Built[iix] > 0) then 281 313 begin 282 FillRect(Rect(5+16*(i mod 3)+48*(i div 18), 3+12*(i mod 18 div 3), 283 13+16*(i mod 3)+48*(i div 18), 11+12*(i mod 18 div 3))); 284 break; 314 FillRect(Rect(5 + 16 * (i mod 3) + 48 * (i div 18), 315 3 + 12 * (i mod 18 div 3), 13 + 16 * (i mod 3) + 48 * (i div 18), 316 11 + 12 * (i mod 18 div 3))); 317 break; 285 318 end 286 319 end; 287 i:=30;288 for iix:=0 to nImp do289 if (c.Built[iix]>0) and ((iix<28) or (ImpPosition[iix]<0)) then320 i := 30; 321 for iix := 0 to nImp do 322 if (c.Built[iix] > 0) and ((iix < 28) or (ImpPosition[iix] < 0)) then 290 323 begin 291 FillRect(Rect(5+16*(i mod 3)+48*(i div 18), 3+12*(i mod 18 div 3), 292 13+16*(i mod 3)+48*(i div 18), 11+12*(i mod 18 div 3))); 293 inc(i); 294 if i=36 then break; // area is full 324 FillRect(Rect(5 + 16 * (i mod 3) + 48 * (i div 18), 325 3 + 12 * (i mod 18 div 3), 13 + 16 * (i mod 3) + 48 * (i div 18), 326 11 + 12 * (i mod 18 div 3))); 327 inc(i); 328 if i = 36 then 329 break; // area is full 295 330 end; 296 if c.Project and cpImp<>0 then297 begin 298 iix:=c.Project and cpIndex;299 if iix<>imTrGoods then331 if c.Project and cpImp <> 0 then 332 begin 333 iix := c.Project and cpIndex; 334 if iix <> imTrGoods then 300 335 begin 301 if (iix>=28) and (ImpPosition[iix]>=0) then302 i:=ImpPosition[iix];303 if i<36 then336 if (iix >= 28) and (ImpPosition[iix] >= 0) then 337 i := ImpPosition[iix]; 338 if i < 36 then 304 339 begin 305 brush.Color:=Colors.Canvas.Pixels[clkAge0+Age,cliImpProject]; 306 FillRect(Rect(5+16*(i mod 3)+48*(i div 18), 3+12*(i mod 18 div 3), 307 13+16*(i mod 3)+48*(i div 18), 11+12*(i mod 18 div 3))); 340 brush.Color := Colors.Canvas.Pixels[clkAge0 + Age, cliImpProject]; 341 FillRect(Rect(5 + 16 * (i mod 3) + 48 * (i div 18), 342 3 + 12 * (i mod 18 div 3), 13 + 16 * (i mod 3) + 48 * (i div 18), 343 11 + 12 * (i mod 18 div 3))); 308 344 end 309 345 end 310 346 end; 311 brush.style:=bsClear;347 brush.style := bsClear; 312 348 end 313 349 end; … … 315 351 procedure TCityDlg.InitZoomCityMap; 316 352 begin 317 bitblt(ZoomCityMap.canvas.handle,0,0,wZoomMap,hZoomMap,Back.Canvas.handle, 318 xZoomMap,yZoomMap,SRCCOPY); 319 if Mode=mImp then 320 begin 321 if ZoomArea<3 then 322 ImageOp_B(ZoomCityMap,CityMapTemplate,0,0,376*SizeClass, 323 112*ZoomArea,wZoomMap,hZoomMap) 324 else 325 begin 326 ImageOp_B(ZoomCityMap,CityMapTemplate,0,0,376*SizeClass+216, 327 112*(ZoomArea-3),wZoomMap-wZoomEnvironment,hZoomMap); 328 ImageOp_B(ZoomCityMap,CityMapTemplate,wZoomMap-wZoomEnvironment,0, 329 1504+wZoomEnvironment*byte(IsPort),112*(ZoomArea-3),wZoomEnvironment,hZoomMap); 330 end; 331 end 353 bitblt(ZoomCityMap.Canvas.Handle, 0, 0, wZoomMap, hZoomMap, 354 Back.Canvas.Handle, xZoomMap, yZoomMap, SRCCOPY); 355 if Mode = mImp then 356 begin 357 if ZoomArea < 3 then 358 ImageOp_B(ZoomCityMap, CityMapTemplate, 0, 0, 376 * SizeClass, 359 112 * ZoomArea, wZoomMap, hZoomMap) 360 else 361 begin 362 ImageOp_B(ZoomCityMap, CityMapTemplate, 0, 0, 376 * SizeClass + 216, 363 112 * (ZoomArea - 3), wZoomMap - wZoomEnvironment, hZoomMap); 364 ImageOp_B(ZoomCityMap, CityMapTemplate, wZoomMap - wZoomEnvironment, 0, 365 1504 + wZoomEnvironment * byte(IsPort), 112 * (ZoomArea - 3), 366 wZoomEnvironment, hZoomMap); 367 end; 368 end 332 369 end; 333 370 334 371 procedure TCityDlg.OffscreenPaint; 335 372 336 procedure FillBar(x,y,pos,Growth,max,Kind: integer; IndicateComplete: boolean); 373 procedure FillBar(x, y, pos, Growth, max, Kind: integer; 374 IndicateComplete: boolean); 337 375 var 338 Tex: TTexture;339 begin 340 Tex:=MainTexture;341 if Kind=3 then342 begin 343 Tex.clBevelLight:=GrExt[HGrSystem].Data.Canvas.Pixels[104,36];344 Tex.clBevelShade:=Tex.clBevelLight;345 end; 346 PaintRelativeProgressBar(offscreen.Canvas,Kind,x-3,y,wBar-4,pos,Growth,max,347 IndicateComplete,Tex);348 end; 349 350 procedure PaintResources(x, y,Loc:integer; Add4Happy: boolean);376 Tex: TTexture; 377 begin 378 Tex := MainTexture; 379 if Kind = 3 then 380 begin 381 Tex.clBevelLight := GrExt[HGrSystem].Data.Canvas.Pixels[104, 36]; 382 Tex.clBevelShade := Tex.clBevelLight; 383 end; 384 PaintRelativeProgressBar(offscreen.Canvas, Kind, x - 3, y, wBar - 4, pos, 385 Growth, max, IndicateComplete, Tex); 386 end; 387 388 procedure PaintResources(x, y, Loc: integer; Add4Happy: boolean); 351 389 var 352 d,i,Total,xGr,yGr:integer; 353 TileInfo:TTileInfo; 354 rare: boolean; 355 begin 356 if Server(sGetCityTileInfo,me,Loc,TileInfo)<>eOk then 357 begin assert(cix<0); exit end; 358 Total:=TileInfo.Food+TileInfo.Prod+TileInfo.Trade; 359 rare:=MyMap[Loc] and $06000000>0; 360 if rare then 361 inc(Total); 362 if Add4Happy then 363 inc(Total,4); 364 if Total>1 then d:=(xxt-11) div (Total-1); 365 if d<1 then d:=1; 366 if d>4 then d:=4; 367 for i:=0 to Total-1 do 368 begin 369 yGr:=115; 370 if Add4Happy and (i>=Total-4) then 371 begin xGr:=132; yGr:=126 end 372 else if rare and (i=Total-1) then xGr:=66+110 373 else if i>=TileInfo.Food+TileInfo.Prod then xGr:=66+44 374 else if i>=TileInfo.Prod then xGr:=66 375 else xGr:=66+22; 376 Sprite(offscreen,HGrSystem,x+xxt-5+d*(2*i+1-Total),y+yyt-5,10,10,xGr,yGr); 390 d, i, Total, xGr, yGr: integer; 391 TileInfo: TTileInfo; 392 rare: boolean; 393 begin 394 if Server(sGetCityTileInfo, me, Loc, TileInfo) <> eOk then 395 begin 396 assert(cix < 0); 397 exit 398 end; 399 Total := TileInfo.Food + TileInfo.Prod + TileInfo.Trade; 400 rare := MyMap[Loc] and $06000000 > 0; 401 if rare then 402 inc(Total); 403 if Add4Happy then 404 inc(Total, 4); 405 if Total > 1 then 406 d := (xxt - 11) div (Total - 1); 407 if d < 1 then 408 d := 1; 409 if d > 4 then 410 d := 4; 411 for i := 0 to Total - 1 do 412 begin 413 yGr := 115; 414 if Add4Happy and (i >= Total - 4) then 415 begin 416 xGr := 132; 417 yGr := 126 418 end 419 else if rare and (i = Total - 1) then 420 xGr := 66 + 110 421 else if i >= TileInfo.Food + TileInfo.Prod then 422 xGr := 66 + 44 423 else if i >= TileInfo.Prod then 424 xGr := 66 425 else 426 xGr := 66 + 22; 427 Sprite(offscreen, HGrSystem, x + xxt - 5 + d * (2 * i + 1 - Total), 428 y + yyt - 5, 10, 10, xGr, yGr); 377 429 end 378 430 end; 379 431 380 procedure MakeRed(x, y,w,h: integer);432 procedure MakeRed(x, y, w, h: integer); 381 433 type 382 TLine=array[0..99999,0..2] of Byte;383 PLine=^TLine;434 TLine = array [0 .. 99999, 0 .. 2] of byte; 435 PLine = ^TLine; 384 436 385 437 procedure RedLine(line: PLine; length: integer); 386 438 var 387 i,gray: integer;388 begin 389 for i:=0 to length-1 do439 i, gray: integer; 440 begin 441 for i := 0 to length - 1 do 390 442 begin 391 gray:=(integer(line[i,0])+integer(line[i,1])+integer(line[i,2])) *85 shr 8; 392 line[i,0]:=0; 393 line[i,1]:=0; 394 line[i,2]:=gray; //255-(255-gray) div 2; 443 gray := (integer(line[i, 0]) + integer(line[i, 1]) + integer(line[i, 2]) 444 ) * 85 shr 8; 445 line[i, 0] := 0; 446 line[i, 1] := 0; 447 line[i, 2] := gray; // 255-(255-gray) div 2; 395 448 end 396 449 end; 397 450 398 451 var 399 i: integer;400 begin 401 for i:=0 to h-1 do402 RedLine(@(PLine(Offscreen.ScanLine[y+i])[x]),w)452 i: integer; 453 begin 454 for i := 0 to h - 1 do 455 RedLine(@(PLine(offscreen.ScanLine[y + i])[x]), w) 403 456 end; 404 457 405 458 var 406 line, MessageCount: integer;459 line, MessageCount: integer; 407 460 408 461 procedure CheckMessage(Flag: integer); 409 462 var 410 i, test: integer; 411 s: string; 412 begin 413 if Happened and Flag<>0 then 414 begin 415 i:=0; 416 test:=1; 417 while test<Flag do begin inc(i); inc(test,test) end; 418 419 if AllowChange and (Sounds<>nil) and (OpenSoundEvent=-1) then 463 i, test: integer; 464 s: string; 465 begin 466 if Happened and Flag <> 0 then 467 begin 468 i := 0; 469 test := 1; 470 while test < Flag do 420 471 begin 421 s:=CityEventSoundItem[i]; 422 if s<>'' then s:=Sounds.Lookup(s); 423 if (Flag=chProduction) or (s<>'') and (s[1]<>'*') and (s[1]<>'[') then 424 OpenSoundEvent:=i 472 inc(i); 473 inc(test, test) 425 474 end; 426 475 427 s:=CityEventName(i); 428 { if Flag=chNoGrowthWarning then 429 if c.Built[imAqueduct]=0 then 476 if AllowChange and (Sounds <> nil) and (OpenSoundEvent = -1) then 477 begin 478 s := CityEventSoundItem[i]; 479 if s <> '' then 480 s := Sounds.Lookup(s); 481 if (Flag = chProduction) or (s <> '') and (s[1] <> '*') and (s[1] <> '[') 482 then 483 OpenSoundEvent := i 484 end; 485 486 s := CityEventName(i); 487 { if Flag=chNoGrowthWarning then 488 if c.Built[imAqueduct]=0 then 430 489 s:=Format(s,[Phrases.Lookup('IMPROVEMENTS',imAqueduct)]) 431 else s:=Format(s,[Phrases.Lookup('IMPROVEMENTS',imSewer)]);} 432 RisedTextOut(offscreen.Canvas,xmOpt+40,ymOpt-1-8*MessageCount+16*line,s); 433 inc(line) 490 else s:=Format(s,[Phrases.Lookup('IMPROVEMENTS',imSewer)]); } 491 RisedTextOut(offscreen.Canvas, xmOpt + 40, ymOpt - 1 - 8 * MessageCount + 492 16 * line, s); 493 inc(line) 434 494 end 435 495 end; 436 496 437 497 var 438 x,y,xGr,i,i1,j,iix,d,dx,dy,PrCost,Cnt,Loc1,FreeSupp,Paintiix,HappyGain, 439 OptiType,rx,ry,TrueFood,TrueProd,TruePoll: integer; 440 av: Integer; 441 PrName,s:string; 442 UnitInfo: TUnitInfo; 443 UnitReport: TUnitReport; 444 RedTex: TTexture; 445 IsCityAlive,CanGrow: boolean; 446 begin 447 inherited; 448 if cix>=0 then c:=MyCity[cix]; 449 Report.HypoTiles:=-1; 450 Report.HypoTaxRate:=-1; 451 Report.HypoLuxuryRate:=-1; 452 if cix>=0 then Server(sGetCityReportNew,me,cix,Report) // own city 453 else Server(sGetEnemyCityReportNew,me,cLoc,Report); // enemy city 454 TrueFood:=c.Food; 455 TrueProd:=c.Prod; 456 TruePoll:=c.Pollution; 457 if supervising or (cix<0) then 498 x, y, xGr, i, i1, j, iix, d, dx, dy, PrCost, Cnt, Loc1, FreeSupp, Paintiix, 499 HappyGain, OptiType, rx, ry, TrueFood, TrueProd, TruePoll: integer; 500 av: integer; 501 PrName, s: string; 502 UnitInfo: TUnitInfo; 503 UnitReport: TUnitReport; 504 RedTex: TTexture; 505 IsCityAlive, CanGrow: boolean; 506 begin 507 inherited; 508 if cix >= 0 then 509 c := MyCity[cix]; 510 Report.HypoTiles := -1; 511 Report.HypoTaxRate := -1; 512 Report.HypoLuxuryRate := -1; 513 if cix >= 0 then 514 Server(sGetCityReportNew, me, cix, Report) // own city 515 else 516 Server(sGetEnemyCityReportNew, me, cLoc, Report); // enemy city 517 TrueFood := c.Food; 518 TrueProd := c.Prod; 519 TruePoll := c.Pollution; 520 if supervising or (cix < 0) then 458 521 begin // normalize city from after-turn state 459 dec(TrueFood,Report.FoodSurplus); 460 if TrueFood<0 then 461 TrueFood:=0; // shouldn't happen 462 dec(TrueProd,Report.Production); 463 if TrueProd<0 then 464 TrueProd:=0; // shouldn't happen 465 dec(TruePoll,Report.AddPollution); 466 if TruePoll<0 then 467 TruePoll:=0; // shouldn't happen 468 end; 469 IsCityAlive:= (cGov<>gAnarchy) and (c.Flags and chCaptured=0); 470 if not IsCityAlive then Report.Working:=c.Size; 471 472 RedTex:=MainTexture; 473 RedTex.clBevelLight:=$0000FF; 474 RedTex.clBevelShade:=$000000; 475 RedTex.clTextLight:=$000000; 476 RedTex.clTextShade:=$0000FF; 477 478 bitblt(offscreen.canvas.handle,0,0,640,480,Back.Canvas.handle,0,0,SRCCOPY); 479 480 offscreen.Canvas.Font.Assign(UniFont[ftCaption]); 481 RisedTextout(offscreen.Canvas,42,7,Caption); 482 with offscreen.canvas do 522 dec(TrueFood, Report.FoodSurplus); 523 if TrueFood < 0 then 524 TrueFood := 0; // shouldn't happen 525 dec(TrueProd, Report.Production); 526 if TrueProd < 0 then 527 TrueProd := 0; // shouldn't happen 528 dec(TruePoll, Report.AddPollution); 529 if TruePoll < 0 then 530 TruePoll := 0; // shouldn't happen 531 end; 532 IsCityAlive := (cGov <> gAnarchy) and (c.Flags and chCaptured = 0); 533 if not IsCityAlive then 534 Report.Working := c.Size; 535 536 RedTex := MainTexture; 537 RedTex.clBevelLight := $0000FF; 538 RedTex.clBevelShade := $000000; 539 RedTex.clTextLight := $000000; 540 RedTex.clTextShade := $0000FF; 541 542 bitblt(offscreen.Canvas.Handle, 0, 0, 640, 480, Back.Canvas.Handle, 0, 543 0, SRCCOPY); 544 545 offscreen.Canvas.Font.Assign(UniFont[ftCaption]); 546 RisedTextOut(offscreen.Canvas, 42, 7, Caption); 547 with offscreen.Canvas do 483 548 begin // city size 484 brush.color:=$000000; 485 fillrect(rect(8+1,7+1,36+1,32+1)); 486 brush.color:=$FFFFFF; 487 fillrect(rect(8,7,36,32)); 488 brush.style:=bsClear; 489 font.color:=$000000; 490 s:=inttostr(c.Size); 491 TextOut(8+14-textwidth(s) div 2, 7, s); 492 end; 493 offscreen.Canvas.Font.Assign(UniFont[ftSmall]); 494 495 if not IsCityAlive then 496 begin 497 MakeRed(18,280,298,40); 498 if cGov=gAnarchy then s:=Phrases.Lookup('GOVERNMENT',gAnarchy) 499 else {if c.Flags and chCaptured<>0 then} 500 s:=Phrases.Lookup('CITYEVENTS',14); 501 RisedTextout(offscreen.canvas,167-BiColorTextWidth(offscreen.canvas,s) div 2,ymOpt-9, s); 549 brush.Color := $000000; 550 FillRect(Rect(8 + 1, 7 + 1, 36 + 1, 32 + 1)); 551 brush.Color := $FFFFFF; 552 FillRect(Rect(8, 7, 36, 32)); 553 brush.style := bsClear; 554 Font.Color := $000000; 555 s := inttostr(c.Size); 556 TextOut(8 + 14 - textwidth(s) div 2, 7, s); 557 end; 558 offscreen.Canvas.Font.Assign(UniFont[ftSmall]); 559 560 if not IsCityAlive then 561 begin 562 MakeRed(18, 280, 298, 40); 563 if cGov = gAnarchy then 564 s := Phrases.Lookup('GOVERNMENT', gAnarchy) 565 else { if c.Flags and chCaptured<>0 then } 566 s := Phrases.Lookup('CITYEVENTS', 14); 567 RisedTextOut(offscreen.Canvas, 167 - BiColorTextWidth(offscreen.Canvas, s) 568 div 2, ymOpt - 9, s); 502 569 end 503 else if AllowChange then 504 begin 505 OptiType:=c.Status shr 4 and $0F; 506 Sprite(offscreen,HGrSystem2,xmOpt-32,ymOpt-32,64,64,1+OptiType mod 3*64,217+OptiType div 3*64); 507 508 {display messages now} 509 MessageCount:=0; 510 for i:=0 to 31 do 511 if Happened and ($FFFFFFFF-chCaptured) and (1 shl i)<>0 then 512 inc(MessageCount); 513 if MessageCount>3 then 514 MessageCount:=3; 515 if MessageCount>0 then 516 begin 517 MakeBlue(Offscreen,74,280,242,40); 518 line:=0; 519 for i:=0 to nCityEventPriority-1 do 520 if line<MessageCount then 521 CheckMessage(CityEventPriority[i]); 570 else if AllowChange then 571 begin 572 OptiType := c.Status shr 4 and $0F; 573 Sprite(offscreen, HGrSystem2, xmOpt - 32, ymOpt - 32, 64, 64, 574 1 + OptiType mod 3 * 64, 217 + OptiType div 3 * 64); 575 576 { display messages now } 577 MessageCount := 0; 578 for i := 0 to 31 do 579 if Happened and ($FFFFFFFF - chCaptured) and (1 shl i) <> 0 then 580 inc(MessageCount); 581 if MessageCount > 3 then 582 MessageCount := 3; 583 if MessageCount > 0 then 584 begin 585 MakeBlue(offscreen, 74, 280, 242, 40); 586 line := 0; 587 for i := 0 to nCityEventPriority - 1 do 588 if line < MessageCount then 589 CheckMessage(CityEventPriority[i]); 522 590 end 523 else 524 begin 525 s:=Phrases.Lookup('CITYMANAGETYPE',OptiType); 526 j:=pos('\',s); 527 if j=0 then 528 LoweredTextout(offscreen.canvas, -1, MainTexture, xmOpt+40, ymOpt-9, s) 529 else 591 else 592 begin 593 s := Phrases.Lookup('CITYMANAGETYPE', OptiType); 594 j := pos('\', s); 595 if j = 0 then 596 LoweredTextout(offscreen.Canvas, -1, MainTexture, xmOpt + 40, 597 ymOpt - 9, s) 598 else 530 599 begin 531 LoweredTextout(offscreen.canvas, -1, MainTexture, xmOpt+40, ymOpt-17,532 copy(s,1,j-1));533 LoweredTextout(offscreen.canvas, -1, MainTexture, xmOpt+40, ymOpt-1,534 copy(s,j+1,255));600 LoweredTextout(offscreen.Canvas, -1, MainTexture, xmOpt + 40, 601 ymOpt - 17, copy(s, 1, j - 1)); 602 LoweredTextout(offscreen.Canvas, -1, MainTexture, xmOpt + 40, ymOpt - 1, 603 copy(s, j + 1, 255)); 535 604 end 536 605 end 537 606 end; 538 607 539 rx:=(192+xxt*2-1) div (xxt*2); 540 ry:=(96+yyt*2-1) div (yyt*2); 541 AreaMap.Paint(xmArea-xxt*2*rx,ymArea-yyt*2*ry-3*yyt,dLoc(cLoc,-2*rx+1,-2*ry-1),4*rx-1,4*ry+1,cLoc,cOwner, 542 false,AllowChange and IsCityAlive and (c.Status and csResourceWeightsMask=0)); 543 bitblt(offscreen.canvas.handle,xmArea+102,42,90,33,Back.Canvas.handle,xmArea+102,42,SRCCOPY); 544 545 if IsCityAlive then 546 for dy:=-3 to 3 do for dx:=-3 to 3 do 547 if ((dx+dy) and 1=0) and (dx*dx*dy*dy<81) then 608 rx := (192 + xxt * 2 - 1) div (xxt * 2); 609 ry := (96 + yyt * 2 - 1) div (yyt * 2); 610 AreaMap.Paint(xmArea - xxt * 2 * rx, ymArea - yyt * 2 * ry - 3 * yyt, 611 dLoc(cLoc, -2 * rx + 1, -2 * ry - 1), 4 * rx - 1, 4 * ry + 1, cLoc, cOwner, 612 false, AllowChange and IsCityAlive and 613 (c.Status and csResourceWeightsMask = 0)); 614 bitblt(offscreen.Canvas.Handle, xmArea + 102, 42, 90, 33, Back.Canvas.Handle, 615 xmArea + 102, 42, SRCCOPY); 616 617 if IsCityAlive then 618 for dy := -3 to 3 do 619 for dx := -3 to 3 do 620 if ((dx + dy) and 1 = 0) and (dx * dx * dy * dy < 81) then 621 begin 622 Loc1 := dLoc(cLoc, dx, dy); 623 av := CityAreaInfo.Available[(dy + 3) shl 2 + (dx + 3) shr 1]; 624 if ((av = faNotAvailable) or (av = faTreaty) or (av = faInvalid)) and 625 ((Loc1 < 0) or (Loc1 >= G.lx * G.ly) or (MyMap[Loc1] and fCity = 0)) 626 then 627 Sprite(offscreen, HGrTerrain, xmArea - xxt + xxt * dx, 628 ymArea - yyt + yyt * dy, xxt * 2, yyt * 2, 1 + 5 * (xxt * 2 + 1), 629 1 + yyt + 15 * (yyt * 3 + 1)); 630 if (1 shl ((dy + 3) shl 2 + (dx + 3) shr 1) and c.Tiles <> 0) then 631 PaintResources(xmArea - xxt + xxt * dx, ymArea - yyt + yyt * dy, 632 Loc1, (dx = 0) and (dy = 0)); 633 end; 634 635 if Report.Working > 1 then 636 d := (xService - (xmArea - 192) - 8 - 32) div (Report.Working - 1); 637 if d > 28 then 638 d := 28; 639 for i := Report.Working - 1 downto 0 do 640 begin 641 if IsCityAlive then 642 xGr := 29 643 else 644 xGr := 141; 645 bitblt(offscreen.Canvas.Handle, xmArea - 192 + 5 + i * d, ymArea - 96 - 29, 646 27, 30, GrExt[HGrSystem].Mask.Canvas.Handle, xGr, 171, SRCAND); { shadow } 647 Sprite(offscreen, HGrSystem, xmArea - 192 + 4 + i * d, ymArea - 96 - 30, 27, 648 30, xGr, 171); 649 end; 650 if c.Size - Report.Working > 1 then 651 d := (xmArea + 192 - xService - 32) div (c.Size - Report.Working - 1); 652 if d > 28 then 653 d := 28; 654 for i := 0 to c.Size - Report.Working - 1 do 655 begin 656 xGr := 1 + 112; 657 bitblt(offscreen.Canvas.Handle, xmArea + 192 - 27 + 1 - i * d, 29 + 1, 27, 658 30, GrExt[HGrSystem].Mask.Canvas.Handle, xGr, 171, SRCAND); { shadow } 659 Sprite(offscreen, HGrSystem, xmArea + 192 - 27 - i * d, 29, 27, 30, 660 xGr, 171); 661 Sprite(offscreen, HGrSystem, xmArea + 192 - 27 + 4 - i * d, 29 + 32, 10, 662 10, 121, 126); 663 Sprite(offscreen, HGrSystem, xmArea + 192 - 27 + 13 - i * d, 29 + 32, 10, 664 10, 121, 126); 665 // Sprite(offscreen,HGrSystem,xmArea+192-31+18-i*d,ymArea-96-80+32,10,10,88,115); 666 end; 667 668 if c.Project and cpImp = 0 then 669 PrName := Tribe[cOwner].ModelName[c.Project and cpIndex] 670 else 671 PrName := Phrases.Lookup('IMPROVEMENTS', c.Project and cpIndex); 672 PrCost := Report.ProjectCost; 673 674 // happiness section 675 if IsCityAlive then 676 begin 677 if cGov = gFundamentalism then 678 CountBar(offscreen, xHapp, yHapp + dyBar, wBar, 17, 679 Phrases.Lookup('FAITH'), Report.CollectedControl, MainTexture) 680 else 681 begin 682 CountBar(offscreen, xHapp, yHapp + dyBar, wBar, 17, 683 Phrases.Lookup('HAPPINESS'), Report.Morale, MainTexture); 684 CountBar(offscreen, xHapp, yHapp + 2 * dyBar, wBar, 16, 685 Phrases.Lookup('CONTROL'), Report.CollectedControl, MainTexture); 686 end; 687 CountBar(offscreen, xHapp, yHapp, wBar, 8, Phrases.Lookup('LUX'), 688 Report.Luxury, MainTexture); 689 CountBar(offscreen, xHapp + dxBar, yHapp, wBar, 19, 690 Phrases.Lookup('UNREST'), 2 * Report.Deployed, MainTexture); 691 CountBar(offscreen, xHapp + dxBar, yHapp + dyBar, wBar, 17, 692 Phrases.Lookup('HAPPINESSDEMAND'), c.Size, MainTexture); 693 if Report.HappinessBalance >= 0 then 694 CountBar(offscreen, xHapp + dxBar, yHapp + 2 * dyBar, wBar, 17, 695 Phrases.Lookup('HAPPINESSPLUS'), Report.HappinessBalance, MainTexture) 696 else 697 begin 698 MakeRed(xHapp + dxBar - 6, yHapp + 2 * dyBar, wBar + 10, 38); 699 CountBar(offscreen, xHapp + dxBar, yHapp + 2 * dyBar, wBar, 18, 700 Phrases.Lookup('LACK'), -Report.HappinessBalance, RedTex); 701 end; 702 end; 703 704 // food section 705 if IsCityAlive then 706 begin 707 CountBar(offscreen, xFood, yFood + dyBar div 2, wBar, 0, 708 Phrases.Lookup('FOOD'), Report.CollectedFood, MainTexture); 709 CountBar(offscreen, xFood + dxBar, yFood + dyBar, wBar, 0, 710 Phrases.Lookup('DEMAND'), 2 * c.Size, MainTexture); 711 CountBar(offscreen, xFood + dxBar, yFood, wBar, 0, 712 Phrases.Lookup('SUPPORT'), Report.FoodSupport, MainTexture); 713 if Report.FoodSurplus >= 0 then 714 if (cGov = gFuture) or (c.Size >= NeedAqueductSize) and 715 (Report.FoodSurplus < 2) then 716 CountBar(offscreen, xFood + dxBar, yFood + 2 * dyBar, wBar, 6, 717 Phrases.Lookup('PROFIT'), Report.FoodSurplus, MainTexture) 718 else 719 CountBar(offscreen, xFood + dxBar, yFood + 2 * dyBar, wBar, 0, 720 Phrases.Lookup('SURPLUS'), Report.FoodSurplus, MainTexture) 721 else 722 begin 723 MakeRed(xFood + dxBar - 6, yFood + 2 * dyBar, wBar + 10, 38); 724 CountBar(offscreen, xFood + dxBar, yFood + 2 * dyBar, wBar, 1, 725 Phrases.Lookup('LACK'), -Report.FoodSurplus, RedTex); 726 end; 727 end; 728 CanGrow := (c.Size < MaxCitySize) and (cGov <> gFuture) and 729 (Report.FoodSurplus > 0) and ((c.Size < NeedAqueductSize) or 730 (c.Built[imAqueduct] = 1) and (c.Size < NeedSewerSize) or 731 (c.Built[imSewer] = 1)); 732 FillBar(xFood + 3, yFood + 102, TrueFood, 733 CutCityFoodSurplus(Report.FoodSurplus, IsCityAlive, cGov, c.Size), 734 Report.Storage, 1, CanGrow); 735 LoweredTextout(offscreen.Canvas, -1, MainTexture, xFood + 3 - 5, 736 yFood + 102 - 20, Format('%d/%d', [TrueFood, Report.Storage])); 737 LoweredTextout(offscreen.Canvas, -1, MainTexture, xFood - 2, yFood + 66, 738 Phrases.Lookup('STORAGE')); 739 740 // production section 741 if IsCityAlive then 742 begin 743 CountBar(offscreen, xProd, yProd, wBar, 2, Phrases.Lookup('MATERIAL'), 744 Report.CollectedMaterial, MainTexture); 745 CountBar(offscreen, xProd + dxBar, yProd, wBar, 2, 746 Phrases.Lookup('SUPPORT'), Report.MaterialSupport, MainTexture); 747 if Report.Production >= 0 then 748 if c.Project and (cpImp + cpIndex) = cpImp + imTrGoods then 749 CountBar(offscreen, xProd + dxBar, yProd + dyBar + 16, wBar, 6, 750 Phrases.Lookup('PROFIT'), Report.Production, MainTexture) 751 else 752 CountBar(offscreen, xProd + dxBar, yProd + dyBar + 16, wBar, 2, 753 Phrases.Lookup('PROD'), Report.Production, MainTexture) 754 else 755 begin 756 MakeRed(xProd + dxBar - 6, yProd + dyBar, wBar + 10, 38); 757 CountBar(offscreen, xProd + dxBar, yProd + dyBar + 16, wBar, 3, 758 Phrases.Lookup('LACK'), -Report.Production, RedTex); 759 end; 760 end; 761 if c.Project and (cpImp + cpIndex) <> cpImp + imTrGoods then 762 with offscreen.Canvas do 763 begin 764 i := Report.Production; 765 if (i < 0) or not IsCityAlive then 766 i := 0; 767 FillBar(xProd + 3, yProd + 16 + 63, TrueProd, i, PrCost, 4, true); 768 LoweredTextout(offscreen.Canvas, -1, MainTexture, xProd + 3 - 5, 769 yProd + 16 + 43, Format('%d/%d', [TrueProd, PrCost])); 770 if BiColorTextWidth(offscreen.Canvas, PrName) > wBar + dxBar then 548 771 begin 549 Loc1:=dLoc(cLoc,dx,dy); 550 av := CityAreaInfo.Available[(dy+3) shl 2+(dx+3) shr 1]; 551 if ((av = faNotAvailable) or (av = faTreaty) or (av =faInvalid)) 552 and ((Loc1<0) or (Loc1>=G.lx*G.ly) or (MyMap[Loc1] and fCity=0)) then 553 Sprite(offscreen,HGrTerrain,xmArea-xxt+xxt*dx,ymArea-yyt+yyt*dy,xxt*2, 554 yyt*2,1+5*(xxt*2+1),1+yyt+15*(yyt*3+1)); 555 if (1 shl((dy+3) shl 2+(dx+3) shr 1) and c.Tiles<>0) then 556 PaintResources(xmArea-xxt+xxt*dx,ymArea-yyt+yyt*dy,Loc1,(dx=0) and (dy=0)); 772 repeat 773 Delete(PrName, length(PrName), 1) 774 until BiColorTextWidth(offscreen.Canvas, PrName) <= wBar + dxBar; 775 PrName := PrName + '.' 557 776 end; 558 559 if Report.Working>1 then d:=(xService-(xmArea-192)-8-32) div(Report.Working-1); 560 if d>28 then d:=28; 561 for i:=Report.Working-1 downto 0 do 562 begin 563 if IsCityAlive then xGr:=29 564 else xGr:=141; 565 BitBlt(offscreen.Canvas.Handle,xmArea-192+5+i*d,ymArea-96-29, 566 27,30,GrExt[HGrSystem].Mask.Canvas.Handle,xGr,171,SRCAND); {shadow} 567 Sprite(offscreen,HGrSystem,xmArea-192+4+i*d,ymArea-96-30,27,30,xGr,171); 568 end; 569 if c.Size-Report.Working>1 then d:=(xmArea+192-xService-32) div(c.Size-Report.Working-1); 570 if d>28 then d:=28; 571 for i:=0 to c.Size-Report.Working-1 do 572 begin 573 xGr:=1+112; 574 BitBlt(offscreen.Canvas.Handle,xmArea+192-27+1-i*d,29+1, 575 27,30,GrExt[HGrSystem].Mask.Canvas.Handle,xGr,171,SRCAND); {shadow} 576 Sprite(offscreen,HGrSystem,xmArea+192-27-i*d,29,27,30,xGr,171); 577 Sprite(offscreen,HGrSystem,xmArea+192-27+4-i*d,29+32,10,10,121,126); 578 Sprite(offscreen,HGrSystem,xmArea+192-27+13-i*d,29+32,10,10,121,126); 579 // Sprite(offscreen,HGrSystem,xmArea+192-31+18-i*d,ymArea-96-80+32,10,10,88,115); 580 end; 581 582 if c.Project and cpImp=0 then 583 PrName:=Tribe[cOwner].ModelName[c.Project and cpIndex] 584 else PrName:=Phrases.Lookup('IMPROVEMENTS',c.Project and cpIndex); 585 PrCost:=Report.ProjectCost; 586 587 // happiness section 588 if IsCityAlive then 589 begin 590 if cGov=gFundamentalism then 591 CountBar(offscreen,xHapp,yHapp+dyBar,wBar,17,Phrases.Lookup('FAITH'), 592 Report.CollectedControl,MainTexture) 777 end; 778 RisedTextOut(offscreen.Canvas, xProd - 2, yProd + 36, PrName); 779 780 // pollution section 781 if IsCityAlive and (Report.AddPollution > 0) then 782 begin 783 FillBar(xPoll + 3, yPoll + 20, TruePoll, Report.AddPollution, 784 MaxPollution, 3, true); 785 RisedTextOut(offscreen.Canvas, xPoll + 3 - 5, yPoll + 20 - 20, 786 Phrases.Lookup('POLL')); 787 end; 788 789 // trade section 790 if IsCityAlive and (Report.CollectedTrade > 0) then 791 begin 792 CountBar(offscreen, xTrade, yTrade + dyBar div 2, wBar, 4, 793 Phrases.Lookup('TRADE'), Report.CollectedTrade, MainTexture); 794 CountBar(offscreen, xTrade + dxBar, yTrade + 2 * dyBar, wBar, 5, 795 Phrases.Lookup('CORR'), Report.Corruption, MainTexture); 796 CountBar(offscreen, xTrade + dxBar, yTrade, wBar, 6, Phrases.Lookup('TAX'), 797 Report.Tax, MainTexture); 798 CountBar(offscreen, xTrade + dxBar, yTrade + dyBar, wBar, 12, 799 Phrases.Lookup('SCIENCE'), Report.Science, MainTexture); 800 end; 801 802 // small map 803 bitblt(offscreen.Canvas.Handle, xSmallMap, ySmallMap, wSmallMap, hSmallMap, 804 SmallCityMap.Canvas.Handle, 0, 0, SRCCOPY); 805 if Mode = mImp then 806 Frame(offscreen.Canvas, xSmallMap + 48 * (ZoomArea div 3), 807 ySmallMap + 24 * (ZoomArea mod 3), xSmallMap + 48 * (ZoomArea div 3) + 49, 808 ySmallMap + 24 * (ZoomArea mod 3) + 25, MainTexture.clMark, 809 MainTexture.clMark); 810 Frame(offscreen.Canvas, xSmallMap - 1, ySmallMap - 1, xSmallMap + wSmallMap, 811 ySmallMap + hSmallMap, $B0B0B0, $FFFFFF); 812 RFrame(offscreen.Canvas, xSmallMap - 2, ySmallMap - 2, xSmallMap + wSmallMap + 813 1, ySmallMap + hSmallMap + 1, $FFFFFF, $B0B0B0); 814 815 Frame(offscreen.Canvas, xSupport - 1, ySupport - 1, xSupport + wSupport, 816 ySupport + hSupport, $B0B0B0, $FFFFFF); 817 RFrame(offscreen.Canvas, xSupport - 2, ySupport - 2, xSupport + wSupport + 1, 818 ySupport + hSupport + 1, $FFFFFF, $B0B0B0); 819 x := xSupport + wSupport div 2; 820 y := ySupport + hSupport div 2; 821 if Mode = mSupp then 822 begin 823 offscreen.Canvas.brush.Color := MainTexture.clMark; 824 offscreen.Canvas.FillRect(Rect(x - 27, y - 6, x + 27, y + 6)); 825 offscreen.Canvas.brush.style := bsClear; 826 end; 827 Sprite(offscreen, HGrSystem, x - 16, y - 5, 10, 10, 88, 115); 828 Sprite(offscreen, HGrSystem, x - 5, y - 5, 10, 10, 66, 115); 829 Sprite(offscreen, HGrSystem, x + 6, y - 5, 10, 10, 154, 126); 830 831 bitblt(offscreen.Canvas.Handle, xZoomMap, yZoomMap, wZoomMap, hZoomMap, 832 ZoomCityMap.Canvas.Handle, 0, 0, SRCCOPY); 833 834 for i := 0 to 5 do 835 imix[i] := -1; 836 if Mode = mImp then 837 begin 838 if ZoomArea = 5 then 839 begin 840 Cnt := 0; 841 for iix := 0 to nImp - 1 do 842 if ((iix < 28) or (ImpPosition[iix] < 0)) and (c.Built[iix] > 0) then 843 begin 844 i := Cnt - Page * 6; 845 if (i >= 0) and (i < 6) then 846 imix[i] := iix; 847 inc(Cnt); 848 end; 849 PageCount := (Cnt + 5) div 6; 850 end 851 else 852 begin 853 for iix := 28 to nImp - 1 do 854 begin 855 i := ImpPosition[iix] - 6 * ZoomArea; 856 if (i >= 0) and (i < 6) and (c.Built[iix] > 0) then 857 imix[i] := iix; 858 end; 859 PageCount := 0; 860 end; 861 for i := 0 to 5 do 862 if imix[i] >= 0 then 863 begin 864 iix := imix[i]; 865 x := xZoomMap + 14 + 72 * (i mod 3); 866 y := yZoomMap + 14 + 56 * (i div 3); 867 ImpImage(offscreen.Canvas, x, y, iix, cGov, AllowChange and 868 (ClientMode < scContact)); 869 if IsCityAlive then 870 begin 871 if iix = imColosseum then 872 begin 873 Sprite(offscreen, HGrSystem, x + 46, y, 14, 14, 82, 100); 874 end 875 else 876 begin 877 HappyGain := 0; 878 case iix of 879 0 .. 27, imTemple: 880 HappyGain := 2; 881 imTheater: 882 HappyGain := 4; 883 imCathedral: 884 if MyRO.Wonder[woBach].EffectiveOwner = cOwner then 885 HappyGain := 6 886 else 887 HappyGain := 4; 888 end; 889 if HappyGain > 1 then 890 begin 891 d := 30 div (HappyGain - 1); 892 if d > 10 then 893 d := 10 894 end; 895 for j := 0 to HappyGain - 1 do 896 Sprite(offscreen, HGrSystem, x + 50, y + d * j, 10, 10, 132, 126); 897 end; 898 for j := 0 to Imp[iix].Maint - 1 do 899 Sprite(offscreen, HGrSystem, x - 4, y + 29 - 3 * j, 10, 10, 900 132, 115); 901 end 902 end; 903 if imix[0] >= 0 then 904 Imp0Area.Hint := Phrases.Lookup('IMPROVEMENTS', imix[0]) 905 else 906 Imp0Area.Hint := ''; 907 if imix[1] >= 0 then 908 Imp1Area.Hint := Phrases.Lookup('IMPROVEMENTS', imix[1]) 909 else 910 Imp1Area.Hint := ''; 911 if imix[2] >= 0 then 912 Imp2Area.Hint := Phrases.Lookup('IMPROVEMENTS', imix[2]) 913 else 914 Imp2Area.Hint := ''; 915 if imix[3] >= 0 then 916 Imp3Area.Hint := Phrases.Lookup('IMPROVEMENTS', imix[3]) 917 else 918 Imp3Area.Hint := ''; 919 if imix[4] >= 0 then 920 Imp4Area.Hint := Phrases.Lookup('IMPROVEMENTS', imix[4]) 921 else 922 Imp4Area.Hint := ''; 923 if imix[5] >= 0 then 924 Imp5Area.Hint := Phrases.Lookup('IMPROVEMENTS', imix[5]) 925 else 926 Imp5Area.Hint := ''; 927 end 928 else { if mode=mSupp then } 929 begin 930 LoweredTextout(offscreen.Canvas, -1, MainTexture, xZoomMap + 6, 931 yZoomMap + 2, Phrases.Lookup('SUPUNITS')); 932 FreeSupp := c.Size * SupportFree[cGov] shr 1; 933 Cnt := 0; 934 for i := 0 to MyRO.nUn - 1 do 935 if (MyUn[i].Loc >= 0) and (MyUn[i].Home = cix) then 936 with MyModel[MyUn[i].mix] do 937 begin 938 Server(sGetUnitReport, me, i, UnitReport); 939 if (Cnt >= 6 * Page) and (Cnt < 6 * (Page + 1)) then 940 begin // unit visible in display 941 imix[Cnt - 6 * Page] := i; 942 x := ((Cnt - 6 * Page) mod 3) * 64 + xZoomMap; 943 y := ((Cnt - 6 * Page) div 3) * 52 + yZoomMap + 20; 944 MakeUnitInfo(me, MyUn[i], UnitInfo); 945 NoMap.SetOutput(offscreen); 946 NoMap.PaintUnit(x, y, UnitInfo, MyUn[i].Status); 947 948 for j := 0 to UnitReport.FoodSupport - 1 do 949 Sprite(offscreen, HGrSystem, x + 38 + 11 * j, y + 40, 10, 950 10, 66, 115); 951 for j := 0 to UnitReport.ProdSupport - 1 do 952 begin 953 if (FreeSupp > 0) and 954 (UnitReport.ReportFlags and urfAlwaysSupport = 0) then 955 begin 956 Sprite(offscreen, HGrSystem, x + 16 - 11 * j, y + 40, 10, 957 10, 143, 115); 958 dec(FreeSupp); 959 end 960 else 961 Sprite(offscreen, HGrSystem, x + 16 - 11 * j, y + 40, 10, 962 10, 88, 115); 963 end; 964 if UnitReport.ReportFlags and urfDeployed <> 0 then 965 for j := 0 to 1 do 966 Sprite(offscreen, HGrSystem, x + 27 + 11 * j, y + 40, 10, 967 10, 154, 126) 968 end // unit visible in display 969 else 970 dec(FreeSupp, UnitReport.ProdSupport); 971 inc(Cnt); 972 end; 973 PageCount := (Cnt + 5) div 6; 974 Imp0Area.Hint := ''; 975 Imp1Area.Hint := ''; 976 Imp2Area.Hint := ''; 977 Imp3Area.Hint := ''; 978 Imp4Area.Hint := ''; 979 Imp5Area.Hint := ''; 980 end; 981 PageUpBtn.Visible := PageCount > 1; 982 PageDownBtn.Visible := PageCount > 1; 983 984 with offscreen.Canvas do 985 begin 986 { display project now } 987 DLine(offscreen.Canvas, xView + 9 + xSizeBig, xProd + 2 * wBar + 10, 988 yProd + dyBar + 16, $FFFFFF, $B0B0B0); 989 if ProdHint then 990 begin 991 Frame(offscreen.Canvas, xView + 9 - 1, yView + 5 - 1, 992 xView + 9 + xSizeBig, yView + 5 + ySizeBig, $B0B0B0, $FFFFFF); 993 RFrame(offscreen.Canvas, xView + 9 - 2, yView + 5 - 2, 994 xView + 9 + xSizeBig + 1, yView + 5 + ySizeBig + 1, $FFFFFF, $B0B0B0); 995 with offscreen.Canvas do 996 begin 997 brush.Color := $000000; 998 FillRect(Rect(xView + 9, yView + 5, xView + 1 + 72 - 8, 999 yView + 5 + 40)); 1000 brush.style := bsClear; 1001 end 1002 end 1003 else if AllowChange and (c.Status and 7 <> 0) then 1004 begin // city type autobuild 1005 FrameImage(offscreen.Canvas, bigimp, xView + 9, yView + 5, xSizeBig, 1006 ySizeBig, (c.Status and 7 - 1 + 3) * xSizeBig, 0, (cix >= 0) and 1007 (ClientMode < scContact)); 1008 end 1009 else if c.Project and cpImp = 0 then 1010 begin // project is unit 1011 FrameImage(offscreen.Canvas, bigimp, xView + 9, yView + 5, xSizeBig, 1012 ySizeBig, 0, 0, AllowChange and (ClientMode < scContact)); 1013 with Tribe[cOwner].ModelPicture[c.Project and cpIndex] do 1014 Sprite(offscreen, HGr, xView + 5, yView + 1, 64, 44, 1015 pix mod 10 * 65 + 1, pix div 10 * 49 + 1); 1016 end 1017 else 1018 begin // project is building 1019 if ProdHint then 1020 Paintiix := c.Project0 and cpIndex 1021 else 1022 Paintiix := c.Project and cpIndex; 1023 ImpImage(offscreen.Canvas, xView + 9, yView + 5, Paintiix, cGov, 1024 AllowChange and (ClientMode < scContact)); 1025 end; 1026 end; 1027 1028 if AllowChange and (ClientMode < scContact) then 1029 begin 1030 i := Server(sBuyCityProject - sExecute, me, cix, nil^); 1031 BuyBtn.Visible := (i = eOk) or (i = eViolation); 1032 end 593 1033 else 594 begin 595 CountBar(offscreen,xHapp,yHapp+dyBar,wBar,17,Phrases.Lookup('HAPPINESS'), 596 Report.Morale,MainTexture); 597 CountBar(offscreen,xHapp,yHapp+2*dyBar,wBar,16,Phrases.Lookup('CONTROL'), 598 Report.CollectedControl,MainTexture); 599 end; 600 CountBar(offscreen,xHapp,yHapp,wBar,8,Phrases.Lookup('LUX'), 601 Report.Luxury,MainTexture); 602 CountBar(offscreen,xHapp+dxBar,yHapp,wBar,19,Phrases.Lookup('UNREST'), 603 2*Report.Deployed,MainTexture); 604 CountBar(offscreen,xHapp+dxBar,yHapp+dyBar,wBar,17,Phrases.Lookup('HAPPINESSDEMAND'), 605 c.Size,MainTexture); 606 if Report.HappinessBalance>=0 then 607 CountBar(offscreen,xHapp+dxBar,yHapp+2*dyBar,wBar,17,Phrases.Lookup('HAPPINESSPLUS'), 608 Report.HappinessBalance,MainTexture) 1034 BuyBtn.Visible := false; 1035 1036 MarkUsedOffscreen(ClientWidth, ClientHeight); 1037 end; { OffscreenPaint } 1038 1039 procedure TCityDlg.FormShow(Sender: TObject); 1040 var 1041 dx, dy, Loc1: integer; 1042 GetCityData: TGetCityData; 1043 begin 1044 BlinkTime := 5; 1045 if cix >= 0 then 1046 begin { own city } 1047 c := MyCity[cix]; 1048 cOwner := me; 1049 cGov := MyRO.Government; 1050 ProdHint := (cGov <> gAnarchy) and 1051 (Happened and (chProduction or chFounded or chCaptured or 1052 chAllImpsMade) <> 0); 1053 Server(sGetCityAreaInfo, me, cix, CityAreaInfo); 1054 NextCityBtn.Visible := WindowMode = wmPersistent; 1055 PrevCityBtn.Visible := WindowMode = wmPersistent; 1056 end 1057 else { enemy city } 1058 begin 1059 Mode := mImp; 1060 Server(sGetCity, me, cLoc, GetCityData); 1061 c := GetCityData.c; 1062 cOwner := GetCityData.Owner; 1063 cGov := MyRO.EnemyReport[cOwner].Government; 1064 Happened := c.Flags and $7FFFFFFF; 1065 ProdHint := false; 1066 Server(sGetEnemyCityAreaInfo, me, cLoc, CityAreaInfo); 1067 1068 if c.Project and cpImp = 0 then 1069 begin 1070 emix := MyRO.nEnemyModel - 1; 1071 while (emix > 0) and ((MyRO.EnemyModel[emix].Owner <> cOwner) or 1072 (integer(MyRO.EnemyModel[emix].mix) <> c.Project and cpIndex)) do 1073 dec(emix); 1074 if Tribe[cOwner].ModelPicture[c.Project and cpIndex].HGr = 0 then 1075 InitEnemyModel(emix); 1076 end; 1077 1078 NextCityBtn.Visible := false; 1079 PrevCityBtn.Visible := false; 1080 end; 1081 Page := 0; 1082 1083 if c.Size < 5 then 1084 SizeClass := 0 1085 else if c.Size < 9 then 1086 SizeClass := 1 1087 else if c.Size < 13 then 1088 SizeClass := 2 609 1089 else 610 begin 611 MakeRed(xHapp+dxBar-6,yHapp+2*dyBar,wBar+10,38); 612 CountBar(offscreen,xHapp+dxBar,yHapp+2*dyBar,wBar,18,Phrases.Lookup('LACK'), 613 -Report.HappinessBalance,RedTex); 614 end; 615 end; 616 617 // food section 618 if IsCityAlive then 619 begin 620 CountBar(offscreen,xFood,yFood+dyBar div 2,wBar,0,Phrases.Lookup('FOOD'),Report.CollectedFood,MainTexture); 621 CountBar(offscreen,xFood+dxBar,yFood+dyBar,wBar,0,Phrases.Lookup('DEMAND'),2*c.Size,MainTexture); 622 CountBar(offscreen,xFood+dxBar,yFood,wBar,0,Phrases.Lookup('SUPPORT'),Report.FoodSupport,MainTexture); 623 if Report.FoodSurplus>=0 then 624 if (cGov=gFuture) 625 or (c.Size>=NeedAqueductSize) and (Report.FoodSurplus<2) then 626 CountBar(offscreen,xFood+dxBar,yFood+2*dyBar,wBar,6,Phrases.Lookup('PROFIT'), 627 Report.FoodSurplus,MainTexture) 628 else CountBar(offscreen,xFood+dxBar,yFood+2*dyBar,wBar,0,Phrases.Lookup('SURPLUS'), 629 Report.FoodSurplus,MainTexture) 1090 SizeClass := 3; 1091 1092 // check if port 1093 IsPort := false; 1094 for dx := -2 to 2 do 1095 for dy := -2 to 2 do 1096 if abs(dx) + abs(dy) = 2 then 1097 begin 1098 Loc1 := dLoc(cLoc, dx, dy); 1099 if (Loc1 >= 0) and (Loc1 < G.lx * G.ly) and 1100 (MyMap[Loc1] and fTerrain < fGrass) then 1101 IsPort := true; 1102 end; 1103 1104 if WindowMode = wmModal then 1105 begin { center on screen } 1106 Left := (Screen.Width - Width) div 2; 1107 Top := (Screen.Height - Height) div 2; 1108 end; 1109 1110 Caption := CityName(c.ID); 1111 1112 InitSmallCityMap; 1113 InitZoomCityMap; 1114 OpenSoundEvent := -1; 1115 OffscreenPaint; 1116 Timer1.Enabled := true; 1117 end; 1118 1119 procedure TCityDlg.ShowNewContent(NewMode, Loc: integer; ShowEvent: cardinal); 1120 begin 1121 if MyMap[Loc] and fOwned <> 0 then 1122 begin // own city 1123 cix := MyRO.nCity - 1; 1124 while (cix >= 0) and (MyCity[cix].Loc <> Loc) do 1125 dec(cix); 1126 assert(cix >= 0); 1127 if (Optimize_cixTileChange >= 0) and 1128 (Optimize_TilesBeforeChange and not MyCity[Optimize_cixTileChange].Tiles 1129 <> 0) then 1130 begin 1131 CityOptimizer_ReleaseCityTiles(Optimize_cixTileChange, 1132 Optimize_TilesBeforeChange and 1133 not MyCity[Optimize_cixTileChange].Tiles); 1134 if WindowMode <> wmModal then 1135 MainScreen.UpdateViews; 1136 end; 1137 Optimize_cixTileChange := cix; 1138 Optimize_TilesBeforeChange := MyCity[cix].Tiles; 1139 end 630 1140 else 631 begin 632 MakeRed(xFood+dxBar-6,yFood+2*dyBar,wBar+10,38); 633 CountBar(offscreen,xFood+dxBar,yFood+2*dyBar,wBar,1,Phrases.Lookup('LACK'), 634 -Report.FoodSurplus,RedTex); 635 end; 636 end; 637 CanGrow:= (c.Size<MaxCitySize) and (cGov<>gFuture) 638 and (Report.FoodSurplus>0) 639 and ((c.Size<NeedAqueductSize) 640 or (c.Built[imAqueduct]=1) and (c.Size<NeedSewerSize) 641 or (c.Built[imSewer]=1)); 642 FillBar(xFood+3,yFood+102,TrueFood, 643 CutCityFoodSurplus(Report.FoodSurplus,IsCityAlive,cGov,c.size), 644 Report.Storage,1,CanGrow); 645 LoweredTextOut(offscreen.Canvas,-1,MainTexture,xFood+3-5,yFood+102-20,Format('%d/%d',[TrueFood,Report.Storage])); 646 LoweredTextOut(offscreen.Canvas,-1,MainTexture,xFood-2,yFood+66,Phrases.Lookup('STORAGE')); 647 648 // production section 649 if IsCityAlive then 650 begin 651 CountBar(offscreen,xProd,yProd,wBar,2,Phrases.Lookup('MATERIAL'), 652 Report.CollectedMaterial,MainTexture); 653 CountBar(offscreen,xProd+dxBar,yProd,wBar,2,Phrases.Lookup('SUPPORT'), 654 Report.MaterialSupport,MainTexture); 655 if Report.Production>=0 then 656 if c.Project and (cpImp+cpIndex)=cpImp+imTrGoods then 657 CountBar(offscreen,xProd+dxBar,yProd+dyBar+16,wBar,6,Phrases.Lookup('PROFIT'), 658 Report.Production,MainTexture) 659 else CountBar(offscreen,xProd+dxBar,yProd+dyBar+16,wBar,2,Phrases.Lookup('PROD'), 660 Report.Production,MainTexture) 661 else 662 begin 663 MakeRed(xProd+dxBar-6,yProd+dyBar,wBar+10,38); 664 CountBar(offscreen,xProd+dxBar,yProd+dyBar+16,wBar,3,Phrases.Lookup('LACK'), 665 -Report.Production,RedTex); 666 end; 667 end; 668 if c.Project and (cpImp+cpIndex)<>cpImp+imTrGoods then with offscreen.Canvas do 669 begin 670 i:=Report.Production; 671 if (i<0) or not IsCityAlive then i:=0; 672 FillBar(xProd+3,yProd+16+63,TrueProd,i,PrCost,4,true); 673 LoweredTextOut(offscreen.Canvas,-1,MainTexture,xProd+3-5,yProd+16+43, 674 Format('%d/%d',[TrueProd,PrCost])); 675 if BiColorTextWidth(offscreen.Canvas,PrName)>wBar+dxBar then 676 begin 677 repeat Delete(PrName,Length(PrName),1) 678 until BiColorTextWidth(offscreen.Canvas,PrName)<=wBar+dxBar; 679 PrName:=PrName+'.' 680 end; 681 end; 682 RisedTextOut(offscreen.Canvas,xProd-2,yProd+36,PrName); 683 684 // pollution section 685 if IsCityAlive and (Report.AddPollution>0) then 686 begin 687 FillBar(xPoll+3,yPoll+20,TruePoll,Report.AddPollution, 688 MaxPollution,3,true); 689 RisedTextOut(offscreen.Canvas,xPoll+3-5,yPoll+20-20,Phrases.Lookup('POLL')); 690 end; 691 692 // trade section 693 if IsCityAlive and (Report.CollectedTrade>0) then 694 begin 695 CountBar(offscreen,xTrade,yTrade+dyBar div 2,wBar,4,Phrases.Lookup('TRADE'),Report.CollectedTrade,MainTexture); 696 CountBar(offscreen,xTrade+dxBar,yTrade+2*dyBar,wBar,5,Phrases.Lookup('CORR'),Report.Corruption,MainTexture); 697 CountBar(offscreen,xTrade+dxBar,yTrade,wBar,6,Phrases.Lookup('TAX'),Report.Tax,MainTexture); 698 CountBar(offscreen,xTrade+dxBar,yTrade+dyBar,wBar,12,Phrases.Lookup('SCIENCE'),Report.Science,MainTexture); 699 end; 700 701 // small map 702 BitBlt(Offscreen.Canvas.Handle,xSmallMap,ySmallmap,wSmallMap,hSmallMap,SmallCitymap.Canvas.Handle,0,0,SRCCOPY); 703 if Mode=mImp then 704 Frame(Offscreen.Canvas,xSmallMap+48*(ZoomArea div 3),ySmallmap+24*(ZoomArea mod 3), 705 xSmallMap+48*(ZoomArea div 3)+49,ySmallmap+24*(ZoomArea mod 3)+25, 706 MainTexture.clMark,MainTexture.clMark); 707 Frame(Offscreen.Canvas,xSmallMap-1,ySmallmap-1,xSmallMap+wSmallMap,ySmallmap+hSmallMap,$B0B0B0,$FFFFFF); 708 RFrame(Offscreen.Canvas,xSmallMap-2,ySmallmap-2,xSmallMap+wSmallMap+1,ySmallmap+hSmallMap+1,$FFFFFF,$B0B0B0); 709 710 Frame(Offscreen.Canvas,xSupport-1,ySupport-1,xSupport+wSupport,ySupport+hSupport,$B0B0B0,$FFFFFF); 711 RFrame(Offscreen.Canvas,xSupport-2,ySupport-2,xSupport+wSupport+1,ySupport+hSupport+1,$FFFFFF,$B0B0B0); 712 x:=xSupport+wSupport div 2; 713 y:=ySupport+hSupport div 2; 714 if Mode=mSupp then 715 begin 716 Offscreen.Canvas.brush.Color:=MainTexture.clMark; 717 Offscreen.Canvas.FillRect(Rect(x-27,y-6,x+27,y+6)); 718 Offscreen.Canvas.brush.style:=bsClear; 719 end; 720 Sprite(offscreen,HGrSystem,x-16,y-5,10,10,88,115); 721 Sprite(offscreen,HGrSystem,x-5,y-5,10,10,66,115); 722 Sprite(offscreen,HGrSystem,x+6,y-5,10,10,154,126); 723 724 BitBlt(Offscreen.Canvas.Handle,xZoomMap,yZoommap,wZoomMap,hZoomMap,ZoomCitymap.Canvas.Handle,0,0,SRCCOPY); 725 726 for i:=0 to 5 do imix[i]:=-1; 727 if Mode=mImp then 728 begin 729 if ZoomArea=5 then 730 begin 731 Cnt:=0; 732 for iix:=0 to nImp-1 do 733 if ((iix<28) or (ImpPosition[iix]<0)) and (c.Built[iix]>0) then 1141 cix := -1; 1142 AllowChange := not supervising and (cix >= 0); 1143 cLoc := Loc; 1144 Happened := ShowEvent; 1145 inherited ShowNewContent(NewMode); 1146 end; 1147 1148 procedure TCityDlg.FormMouseDown(Sender: TObject; Button: TMouseButton; 1149 Shift: TShiftState; x, y: integer); 1150 var 1151 i, qx, qy, dx, dy, fix, NewTiles, Loc1, iix, SellResult: integer; 1152 Rebuild: boolean; 1153 begin 1154 if (ssLeft in Shift) and (x >= xSmallMap) and (x < xSmallMap + wSmallMap) and 1155 (y >= ySmallMap) and (y < ySmallMap + hSmallMap) then 1156 begin 1157 Mode := mImp; 1158 ZoomArea := (y - ySmallMap) * 3 div hSmallMap + 3 * 1159 ((x - xSmallMap) * 2 div wSmallMap); 1160 Page := 0; 1161 InitZoomCityMap; 1162 SmartUpdateContent; 1163 exit; 1164 end; 1165 if (ssLeft in Shift) and (x >= xSupport) and (x < xSupport + wSupport) and 1166 (y >= ySupport) and (y < ySupport + hSupport) then 1167 begin 1168 Mode := mSupp; 1169 Page := 0; 1170 InitZoomCityMap; 1171 SmartUpdateContent; 1172 exit; 1173 end; 1174 if not AllowChange then 1175 exit; // not an own city 1176 1177 if (ssLeft in Shift) then 1178 if (ClientMode < scContact) and (x >= xView) and (y >= yView) and 1179 (x < xView + 73) and (y < yView + 50) then 1180 if cGov = gAnarchy then 1181 with MessgExDlg do 734 1182 begin 735 i:=Cnt-Page*6; 736 if (i>=0) and (i<6) then 737 imix[i]:=iix; 738 inc(Cnt); 739 end; 740 PageCount:=(Cnt+5) div 6; 741 end 742 else 743 begin 744 for iix:=28 to nImp-1 do 745 begin 746 i:=ImpPosition[iix]-6*ZoomArea; 747 if (i>=0) and (i<6) and (c.Built[iix]>0) then 748 imix[i]:=iix; 749 end; 750 PageCount:=0; 751 end; 752 for i:=0 to 5 do if imix[i]>=0 then 753 begin 754 iix:=imix[i]; 755 x:=xZoomMap+14+72*(i mod 3); 756 y:=yZoomMap+14+56*(i div 3); 757 ImpImage(offscreen.Canvas,x,y,iix,cGov,AllowChange and (ClientMode<scContact)); 758 if IsCityAlive then 759 begin 760 if iix=imColosseum then 761 begin 762 Sprite(offscreen,HGrSystem,x+46,y,14,14,82,100); 1183 { MessgText:=Phrases.Lookup('OUTOFCONTROL'); 1184 if c.Project and cpImp=0 then 1185 MessgText:=Format(MessgText,[Tribe[cOwner].ModelName[c.Project and cpIndex]]) 1186 else MessgText:=Format(MessgText,[Phrases.Lookup('IMPROVEMENTS',c.Project and cpIndex)]); } 1187 MessgText := Phrases.Lookup('NOCHANGEINANARCHY'); 1188 Kind := mkOk; 1189 ShowModal; 763 1190 end 764 1191 else 1192 begin 1193 if ProdHint then 765 1194 begin 766 HappyGain:=0; 767 case iix of 768 0..27,imTemple: HappyGain:=2; 769 imTheater: HappyGain:=4; 770 imCathedral: 771 if MyRO.Wonder[woBach].EffectiveOwner=cOwner then HappyGain:=6 772 else HappyGain:=4; 773 end; 774 if HappyGain>1 then 775 begin d:=30 div(HappyGain-1);if d>10 then d:=10 end; 776 for j:=0 to HappyGain-1 do 777 Sprite(offscreen,HGrSystem,x+50,y+d*j,10,10,132,126); 1195 ProdHint := false; 1196 SmartUpdateContent 778 1197 end; 779 for j:=0 to Imp[iix].Maint-1 do 780 Sprite(offscreen,HGrSystem,x-4,y+29-3*j,10,10,132,115); 1198 ChooseProject; 781 1199 end 782 end; 783 if imix[0]>=0 then 784 Imp0Area.Hint:=Phrases.Lookup('IMPROVEMENTS',imix[0]) 785 else Imp0Area.Hint:=''; 786 if imix[1]>=0 then 787 Imp1Area.Hint:=Phrases.Lookup('IMPROVEMENTS',imix[1]) 788 else Imp1Area.Hint:=''; 789 if imix[2]>=0 then 790 Imp2Area.Hint:=Phrases.Lookup('IMPROVEMENTS',imix[2]) 791 else Imp2Area.Hint:=''; 792 if imix[3]>=0 then 793 Imp3Area.Hint:=Phrases.Lookup('IMPROVEMENTS',imix[3]) 794 else Imp3Area.Hint:=''; 795 if imix[4]>=0 then 796 Imp4Area.Hint:=Phrases.Lookup('IMPROVEMENTS',imix[4]) 797 else Imp4Area.Hint:=''; 798 if imix[5]>=0 then 799 Imp5Area.Hint:=Phrases.Lookup('IMPROVEMENTS',imix[5]) 800 else Imp5Area.Hint:=''; 801 end 802 else {if mode=mSupp then} 803 begin 804 LoweredTextOut(offscreen.Canvas,-1,MainTexture,xZoomMap+6,yZoomMap+2,Phrases.Lookup('SUPUNITS')); 805 FreeSupp:=c.Size*SupportFree[cGov] shr 1; 806 Cnt:=0; 807 for i:=0 to MyRO.nUn-1 do if (MyUn[i].Loc>=0) and (MyUn[i].Home=cix) then 808 with MyModel[MyUn[i].mix] do 1200 else if (Mode = mImp) and (x >= xZoomMap) and (x < xZoomMap + wZoomMap) and 1201 (y >= yZoomMap) and (y < yZoomMap + hZoomMap) then 1202 begin 1203 i := 5; 1204 while (i >= 0) and not((x >= xZoomMap + 14 + 72 * (i mod 3)) and 1205 (x < xZoomMap + 14 + 56 + 72 * (i mod 3)) and 1206 (y >= yZoomMap + 14 + 56 * (i div 3)) and 1207 (y < yZoomMap + 14 + 40 + 56 * (i div 3))) do 1208 dec(i); 1209 if i >= 0 then 809 1210 begin 810 Server(sGetUnitReport, me, i, UnitReport); 811 if (Cnt>=6*Page) and (Cnt<6*(Page+1)) then 812 begin // unit visible in display 813 imix[Cnt-6*Page]:=i; 814 x:=((Cnt-6*Page) mod 3)*64+xZoomMap; 815 y:=((Cnt-6*Page) div 3)*52+yZoomMap+20; 816 MakeUnitInfo(me,MyUn[i],UnitInfo); 817 NoMap.SetOutput(offscreen); 818 NoMap.PaintUnit(x,y,UnitInfo,MyUn[i].Status); 819 820 for j:=0 to UnitReport.FoodSupport-1 do 821 Sprite(offscreen,HGrSystem,x+38+11*j,y+40,10,10,66,115); 822 for j:=0 to UnitReport.ProdSupport-1 do 823 begin 824 if (FreeSupp>0) and (UnitReport.ReportFlags and urfAlwaysSupport=0) then 1211 iix := imix[i]; 1212 if iix >= 0 then 1213 if ssShift in Shift then 1214 HelpDlg.ShowNewContent(Mode or wmPersistent, hkImp, iix) 1215 else if (ClientMode < scContact) then 1216 with MessgExDlg do 825 1217 begin 826 Sprite(offscreen,HGrSystem,x+16-11*j,y+40,10,10,143,115); 827 dec(FreeSupp); 828 end 829 else Sprite(offscreen,HGrSystem,x+16-11*j,y+40,10,10,88,115); 830 end; 831 if UnitReport.ReportFlags and urfDeployed<>0 then 832 for j:=0 to 1 do 833 Sprite(offscreen,HGrSystem,x+27+11*j,y+40,10,10,154,126) 834 end // unit visible in display 835 else dec(FreeSupp, UnitReport.ProdSupport); 836 inc(Cnt); 837 end; 838 PageCount:=(Cnt+5) div 6; 839 Imp0Area.Hint:=''; 840 Imp1Area.Hint:=''; 841 Imp2Area.Hint:=''; 842 Imp3Area.Hint:=''; 843 Imp4Area.Hint:=''; 844 Imp5Area.Hint:=''; 845 end; 846 PageUpBtn.Visible:= PageCount>1; 847 PageDownBtn.Visible:= PageCount>1; 848 849 with offscreen.Canvas do 850 begin 851 {display project now} 852 DLine(offscreen.Canvas,xView+9+xSizeBig,xProd+2*wBar+10,yProd+dyBar+16, 853 $FFFFFF,$B0B0B0); 854 if prodhint then 855 begin 856 Frame(offscreen.canvas,xView+9-1,yView+5-1,xView+9+xSizeBig,yView+5+ySizeBig,$B0B0B0,$FFFFFF); 857 RFrame(offscreen.canvas,xView+9-2,yView+5-2,xView+9+xSizeBig+1,yView+5+ySizeBig+1,$FFFFFF,$B0B0B0); 858 with offscreen.canvas do 859 begin 860 Brush.Color:=$000000; 861 FillRect(Rect(xView+9,yView+5,xView+1+72-8,yView+5+40)); 862 Brush.Style:=bsClear; 863 end 864 end 865 else if AllowChange and (c.Status and 7<>0) then 866 begin // city type autobuild 867 FrameImage(offscreen.canvas,bigimp,xView+9,yView+5,xSizeBig,ySizeBig, 868 (c.Status and 7-1+3)*xSizeBig,0, 869 (cix>=0) and (ClientMode<scContact)); 870 end 871 else if c.Project and cpImp=0 then 872 begin // project is unit 873 FrameImage(offscreen.canvas,bigimp,xView+9,yView+5,xSizeBig,ySizeBig,0,0, 874 AllowChange and (ClientMode<scContact)); 875 with Tribe[cOwner].ModelPicture[c.Project and cpIndex] do 876 Sprite(offscreen,HGr,xView+5,yView+1,64,44, 877 pix mod 10 *65+1,pix div 10*49+1); 878 end 879 else 880 begin // project is building 881 if ProdHint then Paintiix:=c.Project0 and cpIndex 882 else Paintiix:=c.Project and cpIndex; 883 ImpImage(Offscreen.Canvas,xView+9,yView+5,Paintiix,cGov, 884 AllowChange and (ClientMode<scContact)); 885 end; 886 end; 887 888 if AllowChange and (ClientMode<scContact) then 889 begin 890 i:=Server(sBuyCityProject-sExecute,me,cix,nil^); 891 BuyBtn.Visible:= (i=eOk) or (i=eViolation); 892 end 893 else BuyBtn.Visible:=false; 894 895 MarkUsedOffscreen(ClientWidth,ClientHeight); 896 end;{OffscreenPaint} 897 898 procedure TCityDlg.FormShow(Sender: TObject); 899 var 900 dx,dy,Loc1: integer; 901 GetCityData: TGetCityData; 902 begin 903 BlinkTime:=5; 904 if cix>=0 then 905 begin {own city} 906 c:=MyCity[cix]; 907 cOwner:=me; 908 cGov:=MyRO.Government; 909 ProdHint:= (cGov<>gAnarchy) 910 and (Happened and (chProduction or chFounded or chCaptured or chAllImpsMade)<>0); 911 Server(sGetCityAreaInfo,me,cix,CityAreaInfo); 912 NextCityBtn.Visible:= WindowMode=wmPersistent; 913 PrevCityBtn.Visible:= WindowMode=wmPersistent; 914 end 915 else {enemy city} 916 begin 917 Mode:=mImp; 918 Server(sGetCity,me,cLoc,GetCityData); 919 c:=GetCityData.c; 920 cOwner:=GetCityData.Owner; 921 cGov:=MyRO.EnemyReport[cOwner].Government; 922 Happened:=c.Flags and $7FFFFFFF; 923 ProdHint:=false; 924 Server(sGetEnemyCityAreaInfo,me,cLoc,CityAreaInfo); 925 926 if c.Project and cpImp=0 then 927 begin 928 emix:=MyRO.nEnemyModel-1; 929 while (emix>0) and ((MyRO.EnemyModel[emix].Owner<>cOwner) 930 or (integer(MyRO.EnemyModel[emix].mix)<>c.Project and cpIndex)) do dec(emix); 931 if Tribe[cOwner].ModelPicture[c.Project and cpIndex].HGr=0 then 932 InitEnemyModel(emix); 933 end; 934 935 NextCityBtn.Visible:=false; 936 PrevCityBtn.Visible:=false; 937 end; 938 Page:=0; 939 940 if c.Size<5 then SizeClass:=0 941 else if c.Size<9 then SizeClass:=1 942 else if c.Size<13 then SizeClass:=2 943 else SizeClass:=3; 944 945 // check if port 946 IsPort:=false; 947 for dx:=-2 to 2 do for dy:=-2 to 2 do if abs(dx)+abs(dy)=2 then 948 begin 949 Loc1:=dLoc(cLoc,dx,dy); 950 if (Loc1>=0) and (Loc1<G.lx*G.ly) and (MyMap[Loc1] and fTerrain<fGrass) then 951 IsPort:=true; 952 end; 953 954 if WindowMode=wmModal then 955 begin {center on screen} 956 Left:=(Screen.Width-Width) div 2; 957 Top:=(Screen.Height-Height) div 2; 958 end; 959 960 Caption:=CityName(c.ID); 961 962 InitSmallCityMap; 963 InitZoomCityMap; 964 OpenSoundEvent:=-1; 965 OffscreenPaint; 966 Timer1.Enabled:=true; 967 end; 968 969 procedure TCityDlg.ShowNewContent(NewMode,Loc: integer; ShowEvent: cardinal); 970 begin 971 if MyMap[Loc] and fOwned<>0 then 972 begin // own city 973 cix:=MyRO.nCity-1; 974 while (cix>=0) and (MyCity[cix].Loc<>Loc) do dec(cix); 975 assert(cix>=0); 976 if (Optimize_cixTileChange>=0) 977 and (Optimize_TilesBeforeChange 978 and not MyCity[Optimize_cixTileChange].Tiles<>0) then 979 begin 980 CityOptimizer_ReleaseCityTiles(Optimize_cixTileChange, 981 Optimize_TilesBeforeChange and not MyCity[Optimize_cixTileChange].Tiles); 982 if WindowMode<>wmModal then 983 MainScreen.UpdateViews; 984 end; 985 Optimize_cixTileChange:=cix; 986 Optimize_TilesBeforeChange:=MyCity[cix].Tiles; 987 end 988 else cix:=-1; 989 AllowChange:=not supervising and (cix>=0); 990 cLoc:=Loc; 991 Happened:=ShowEvent; 992 inherited ShowNewContent(NewMode); 993 end; 994 995 procedure TCityDlg.FormMouseDown(Sender:TObject; 996 Button:TMouseButton;Shift:TShiftState;x,y:integer); 997 var 998 i,qx,qy,dx,dy,fix,NewTiles,Loc1,iix,SellResult: integer; 999 Rebuild: boolean; 1000 begin 1001 if (ssLeft in Shift) and (x>=xSmallMap) and (x<xSmallMap+wSmallMap) 1002 and (y>=ySmallMap) and (y<ySmallMap+hSmallMap) then 1003 begin 1004 Mode:=mImp; 1005 ZoomArea:=(y-ySmallMap)*3 div hSmallMap+3*((x-xSmallMap)*2 div wSmallMap); 1006 Page:=0; 1007 InitZoomCityMap; 1008 SmartUpdateContent; 1009 exit; 1010 end; 1011 if (ssLeft in Shift) and (x>=xSupport) and (x<xSupport+wSupport) 1012 and (y>=ySupport) and (y<ySupport+hSupport) then 1013 begin 1014 Mode:=mSupp; 1015 Page:=0; 1016 InitZoomCityMap; 1017 SmartUpdateContent; 1018 exit; 1019 end; 1020 if not AllowChange then exit; // not an own city 1021 1022 if (ssLeft in Shift) then 1023 if (ClientMode<scContact) 1024 and (x>=xView) and (y>=yView) and (x<xView+73) and (y<yView+50) then 1025 if cGov=gAnarchy then with MessgExDlg do 1026 begin 1027 { MessgText:=Phrases.Lookup('OUTOFCONTROL'); 1028 if c.Project and cpImp=0 then 1029 MessgText:=Format(MessgText,[Tribe[cOwner].ModelName[c.Project and cpIndex]]) 1030 else MessgText:=Format(MessgText,[Phrases.Lookup('IMPROVEMENTS',c.Project and cpIndex)]);} 1031 MessgText:=Phrases.Lookup('NOCHANGEINANARCHY'); 1032 Kind:=mkOk; 1033 ShowModal; 1034 end 1035 else 1036 begin 1037 if ProdHint then 1038 begin 1039 ProdHint:=false; 1040 SmartUpdateContent 1041 end; 1042 ChooseProject; 1043 end 1044 else if (Mode=mImp) and (x>=xZoomMap) and (x<xZoomMap+wZoomMap) 1045 and (y>=yZoomMap) and (y<yZoomMap+hZoomMap) then 1046 begin 1047 i:=5; 1048 while (i>=0) and 1049 not ((x>=xZoomMap+14+72*(i mod 3)) 1050 and (x<xZoomMap+14+56+72*(i mod 3)) 1051 and (y>=yZoomMap+14+56*(i div 3)) 1052 and (y<yZoomMap+14+40+56*(i div 3))) do 1053 dec(i); 1054 if i>=0 then 1055 begin 1056 iix:=imix[i]; 1057 if iix>=0 then 1058 if ssShift in Shift then 1059 HelpDlg.ShowNewContent(Mode or wmPersistent, hkImp, iix) 1060 else if (ClientMode<scContact) then with MessgExDlg do 1061 begin 1062 IconKind:=mikImp; 1063 IconIndex:=iix; 1064 if (iix=imPalace) or (Imp[iix].Kind=ikWonder) then 1065 begin 1066 MessgText:=Phrases.Lookup('IMPROVEMENTS',iix); 1067 if iix=woOracle then 1068 MessgText:=MessgText+'\'+Format(Phrases.Lookup('ORACLEINCOME'), 1069 [MyRO.OracleIncome]); 1070 Kind:=mkOk; 1071 ShowModal; 1072 end 1073 else 1074 begin 1075 SellResult:=Server(sSellCityImprovement-sExecute,me,cix,iix); 1076 if SellResult<rExecuted then 1218 IconKind := mikImp; 1219 IconIndex := iix; 1220 if (iix = imPalace) or (Imp[iix].Kind = ikWonder) then 1077 1221 begin 1078 if SellResult=eOnlyOnce then1079 MessgText:=Phrases.Lookup('NOSELLAGAIN')1080 else MessgText:=Phrases.Lookup('OUTOFCONTROL');1081 MessgText:=Format(MessgText,[Phrases.Lookup('IMPROVEMENTS',iix)]);1082 Kind:=mkOk;1083 ShowModal;1222 MessgText := Phrases.Lookup('IMPROVEMENTS', iix); 1223 if iix = woOracle then 1224 MessgText := MessgText + '\' + 1225 Format(Phrases.Lookup('ORACLEINCOME'), [MyRO.OracleIncome]); 1226 Kind := mkOk; 1227 ShowModal; 1084 1228 end 1085 else1229 else 1086 1230 begin 1087 if Server(sRebuildCityImprovement-sExecute,me,cix,iix)<rExecuted then 1088 begin // no rebuild possible, ask for sell only 1089 Rebuild:=false; 1090 MessgText:=Phrases.Lookup('IMPROVEMENTS',iix); 1091 if not Phrases2FallenBackToEnglish then 1092 MessgText:=Format(Phrases2.Lookup('SELL2'),[MessgText, 1093 Imp[iix].Cost*BuildCostMod[G.Difficulty[me]] div 12]) 1094 else MessgText:=Format(Phrases.Lookup('SELL'),[MessgText]); 1095 if iix=imSpacePort then with MyRO.Ship[me] do 1096 if Parts[0]+Parts[1]+Parts[2]>0 then 1097 MessgText:=MessgText+' '+Phrases.Lookup('SPDESTRUCTQUERY'); 1098 Kind:=mkYesNo; 1099 ShowModal; 1100 if ModalResult<>mrOK then iix:=-1 1231 SellResult := Server(sSellCityImprovement - sExecute, me, 1232 cix, iix); 1233 if SellResult < rExecuted then 1234 begin 1235 if SellResult = eOnlyOnce then 1236 MessgText := Phrases.Lookup('NOSELLAGAIN') 1237 else 1238 MessgText := Phrases.Lookup('OUTOFCONTROL'); 1239 MessgText := Format(MessgText, 1240 [Phrases.Lookup('IMPROVEMENTS', iix)]); 1241 Kind := mkOk; 1242 ShowModal; 1101 1243 end 1102 else1244 else 1103 1245 begin 1104 Rebuild:=true; 1105 MessgText:=Phrases.Lookup('IMPROVEMENTS',iix); 1106 if not Phrases2FallenBackToEnglish then 1107 MessgText:=Format(Phrases2.Lookup('DISPOSE2'),[MessgText, 1108 Imp[iix].Cost*BuildCostMod[G.Difficulty[me]] div 12 *2 div 3]) 1109 else MessgText:=Format(Phrases.Lookup('DISPOSE'),[MessgText]); 1110 if iix=imSpacePort then with MyRO.Ship[me] do 1111 if Parts[0]+Parts[1]+Parts[2]>0 then 1112 MessgText:=MessgText+' '+Phrases.Lookup('SPDESTRUCTQUERY'); 1113 Kind:=mkYesNo; 1114 ShowModal; 1115 if ModalResult<>mrOK then iix:=-1 1116 end; 1117 if iix>=0 then 1118 begin 1119 if Rebuild then 1246 if Server(sRebuildCityImprovement - sExecute, me, cix, iix) < rExecuted 1247 then 1248 begin // no rebuild possible, ask for sell only 1249 Rebuild := false; 1250 MessgText := Phrases.Lookup('IMPROVEMENTS', iix); 1251 if not Phrases2FallenBackToEnglish then 1252 MessgText := Format(Phrases2.Lookup('SELL2'), 1253 [MessgText, Imp[iix].Cost * BuildCostMod 1254 [G.Difficulty[me]] div 12]) 1255 else 1256 MessgText := Format(Phrases.Lookup('SELL'), [MessgText]); 1257 if iix = imSpacePort then 1258 with MyRO.Ship[me] do 1259 if Parts[0] + Parts[1] + Parts[2] > 0 then 1260 MessgText := MessgText + ' ' + 1261 Phrases.Lookup('SPDESTRUCTQUERY'); 1262 Kind := mkYesNo; 1263 ShowModal; 1264 if ModalResult <> mrOK then 1265 iix := -1 1266 end 1267 else 1120 1268 begin 1121 Play('CITY_REBUILDIMP'); 1122 Server(sRebuildCityImprovement,me,cix,iix); 1269 Rebuild := true; 1270 MessgText := Phrases.Lookup('IMPROVEMENTS', iix); 1271 if not Phrases2FallenBackToEnglish then 1272 MessgText := Format(Phrases2.Lookup('DISPOSE2'), 1273 [MessgText, Imp[iix].Cost * BuildCostMod 1274 [G.Difficulty[me]] div 12 * 2 div 3]) 1275 else 1276 MessgText := Format(Phrases.Lookup('DISPOSE'), 1277 [MessgText]); 1278 if iix = imSpacePort then 1279 with MyRO.Ship[me] do 1280 if Parts[0] + Parts[1] + Parts[2] > 0 then 1281 MessgText := MessgText + ' ' + 1282 Phrases.Lookup('SPDESTRUCTQUERY'); 1283 Kind := mkYesNo; 1284 ShowModal; 1285 if ModalResult <> mrOK then 1286 iix := -1 1287 end; 1288 if iix >= 0 then 1289 begin 1290 if Rebuild then 1291 begin 1292 Play('CITY_REBUILDIMP'); 1293 Server(sRebuildCityImprovement, me, cix, iix); 1294 end 1295 else 1296 begin 1297 Play('CITY_SELLIMP'); 1298 Server(sSellCityImprovement, me, cix, iix); 1299 end; 1300 CityOptimizer_CityChange(cix); 1301 InitSmallCityMap; 1302 SmartUpdateContent; 1303 if WindowMode <> wmModal then 1304 MainScreen.UpdateViews; 1123 1305 end 1124 else1125 begin1126 Play('CITY_SELLIMP');1127 Server(sSellCityImprovement,me,cix,iix);1128 end;1129 CityOptimizer_CityChange(cix);1130 InitSmallCityMap;1131 SmartUpdateContent;1132 if WindowMode<>wmModal then1133 MainScreen.UpdateViews;1134 1306 end 1135 1307 end 1136 1308 end 1137 end1138 1309 end 1139 1310 end 1140 else if (Mode=mSupp) and (x>=xZoomMap) and (x<xZoomMap+wZoomMap)1141 and (y>=yZoomMap) and (y<yZoomMap+hZoomMap) then1142 begin 1143 i:=5;1144 while (i>=0) and1145 not ((x>=xZoomMap+64*(i mod 3))1146 and (x<xZoomMap+64+64*(i mod 3))1147 and (y>=yZoomMap+20+48*(i div 3))1148 and (y<yZoomMap+20+52+48*(i div 3))) do1149 dec(i);1150 if (i>=0) and (imix[i]>=0)then1151 if ssShift in Shift then1152 else if (cix>=0) and (ClientMode<scContact) and (WindowMode<>wmModal) then1311 else if (Mode = mSupp) and (x >= xZoomMap) and (x < xZoomMap + wZoomMap) and 1312 (y >= yZoomMap) and (y < yZoomMap + hZoomMap) then 1313 begin 1314 i := 5; 1315 while (i >= 0) and not((x >= xZoomMap + 64 * (i mod 3)) and 1316 (x < xZoomMap + 64 + 64 * (i mod 3)) and 1317 (y >= yZoomMap + 20 + 48 * (i div 3)) and 1318 (y < yZoomMap + 20 + 52 + 48 * (i div 3))) do 1319 dec(i); 1320 if (i >= 0) and (imix[i] >= 0) then 1321 if ssShift in Shift then 1322 else if (cix >= 0) and (ClientMode < scContact) and 1323 (WindowMode <> wmModal) then 1153 1324 begin 1154 CloseAction:=None;1155 Close;1156 MainScreen.CityClosed(imix[i],false,true);1325 CloseAction := None; 1326 Close; 1327 MainScreen.CityClosed(imix[i], false, true); 1157 1328 end 1158 1329 end 1159 else if (x>=xmArea-192) and (x<xmArea+192) and (y>=ymArea-96) and (y<ymArea+96) then 1160 begin 1161 qx:=((4000*xxt*yyt)+(x-xmArea)*(yyt*2)+(y-ymArea+yyt)*(xxt*2)) div (xxt*yyt*4)-1000; 1162 qy:=((4000*xxt*yyt)+(y-ymArea+yyt)*(xxt*2)-(x-xmArea)*(yyt*2)) div (xxt*yyt*4)-1000; 1163 dx:=qx-qy; 1164 dy:=qx+qy; 1165 if (dx>=-3) and (dx<=3) and (dy>=-3) and (dy<=3) and (dx*dx*dy*dy<81) 1166 and ((dx<>0) or (dy<>0)) then 1167 if ssShift in Shift then 1330 else if (x >= xmArea - 192) and (x < xmArea + 192) and (y >= ymArea - 96) 1331 and (y < ymArea + 96) then 1332 begin 1333 qx := ((4000 * xxt * yyt) + (x - xmArea) * (yyt * 2) + (y - ymArea + yyt) 1334 * (xxt * 2)) div (xxt * yyt * 4) - 1000; 1335 qy := ((4000 * xxt * yyt) + (y - ymArea + yyt) * (xxt * 2) - (x - xmArea) 1336 * (yyt * 2)) div (xxt * yyt * 4) - 1000; 1337 dx := qx - qy; 1338 dy := qx + qy; 1339 if (dx >= -3) and (dx <= 3) and (dy >= -3) and (dy <= 3) and 1340 (dx * dx * dy * dy < 81) and ((dx <> 0) or (dy <> 0)) then 1341 if ssShift in Shift then 1168 1342 begin // terrain help 1169 Loc1:=dLoc(cLoc,dx,dy);1170 if (Loc1>=0) and (Loc1<G.lx*G.ly) then1171 HelpOnTerrain(Loc1, Mode or wmPersistent)1343 Loc1 := dLoc(cLoc, dx, dy); 1344 if (Loc1 >= 0) and (Loc1 < G.lx * G.ly) then 1345 HelpOnTerrain(Loc1, Mode or wmPersistent) 1172 1346 end 1173 else if (ClientMode<scContact) and (cGov<>gAnarchy)1174 and (c.Flags and chCaptured=0) then1347 else if (ClientMode < scContact) and (cGov <> gAnarchy) and 1348 (c.Flags and chCaptured = 0) then 1175 1349 begin // toggle exploitation 1176 assert(not supervising);1177 if c.Status and csResourceWeightsMask<>0 then1350 assert(not supervising); 1351 if c.Status and csResourceWeightsMask <> 0 then 1178 1352 begin 1179 with MessgExDlg do1353 with MessgExDlg do 1180 1354 begin 1181 MessgText:=Phrases.Lookup('CITYMANAGEOFF');1182 OpenSound:='MSG_DEFAULT';1183 Kind:=mkOkCancel;1184 IconKind:=mikFullControl;1185 ShowModal;1355 MessgText := Phrases.Lookup('CITYMANAGEOFF'); 1356 OpenSound := 'MSG_DEFAULT'; 1357 Kind := mkOkCancel; 1358 IconKind := mikFullControl; 1359 ShowModal; 1186 1360 end; 1187 if MessgExDlg.ModalResult=mrOK then1361 if MessgExDlg.ModalResult = mrOK then 1188 1362 begin 1189 MyCity[cix].Status:=MyCity[cix].Status1190 andnot csResourceWeightsMask; // off1191 c.Status:=MyCity[cix].Status;1192 SmartUpdateContent1363 MyCity[cix].Status := MyCity[cix].Status and 1364 not csResourceWeightsMask; // off 1365 c.Status := MyCity[cix].Status; 1366 SmartUpdateContent 1193 1367 end; 1194 exit;1368 exit; 1195 1369 end; 1196 fix:=(dy+3) shl 2+(dx+3) shr 1;1197 NewTiles:=MyCity[cix].Tiles xor (1 shl fix);1198 if Server(sSetCityTiles,me,cix,NewTiles)>=rExecuted then1370 fix := (dy + 3) shl 2 + (dx + 3) shr 1; 1371 NewTiles := MyCity[cix].Tiles xor (1 shl fix); 1372 if Server(sSetCityTiles, me, cix, NewTiles) >= rExecuted then 1199 1373 begin 1200 SmartUpdateContent;1201 if WindowMode<>wmModal then1202 MainScreen.UpdateViews;1374 SmartUpdateContent; 1375 if WindowMode <> wmModal then 1376 MainScreen.UpdateViews; 1203 1377 end 1204 1378 end 1205 1379 end 1206 else if (ClientMode<scContact) and (cGov<>gAnarchy) and (c.Flags and chCaptured=0) 1207 and (x>=xmOpt-32) and (x<xmOpt+32) and (y>=ymOpt-32) and (y<ymOpt+32) then 1208 begin 1209 i:=sqr(x-xmOpt)+sqr(y-ymOpt); // click radius 1210 if i<=32*32 then 1380 else if (ClientMode < scContact) and (cGov <> gAnarchy) and 1381 (c.Flags and chCaptured = 0) and (x >= xmOpt - 32) and (x < xmOpt + 32) 1382 and (y >= ymOpt - 32) and (y < ymOpt + 32) then 1383 begin 1384 i := sqr(x - xmOpt) + sqr(y - ymOpt); // click radius 1385 if i <= 32 * 32 then 1211 1386 begin 1212 if i<16*16 then // inner area clicked 1213 if c.Status and csResourceWeightsMask<>0 then 1214 i:=(c.Status shr 4 and $0F) mod 5 +1 // rotate except off 1215 else i:=3 // rwGrowth 1216 else case trunc(arctan2(x-xmOpt,ymOpt-y)*180/pi) of 1217 -25-52*2..-26-52: i:=1; 1218 -25-52..-26: i:=2; 1219 -25..25: i:=3; 1220 26..25+52: i:=4; 1221 26+52..25+52*2: i:=5; 1222 180-26..180,-180..-180+26: i:=0; 1223 else i:=-1; 1224 end; 1225 if i>=0 then 1387 if i < 16 * 16 then // inner area clicked 1388 if c.Status and csResourceWeightsMask <> 0 then 1389 i := (c.Status shr 4 and $0F) mod 5 + 1 // rotate except off 1390 else 1391 i := 3 // rwGrowth 1392 else 1393 case trunc(arctan2(x - xmOpt, ymOpt - y) * 180 / pi) of 1394 - 25 - 52 * 2 .. -26 - 52: 1395 i := 1; 1396 -25 - 52 .. -26: 1397 i := 2; 1398 -25 .. 25: 1399 i := 3; 1400 26 .. 25 + 52: 1401 i := 4; 1402 26 + 52 .. 25 + 52 * 2: 1403 i := 5; 1404 180 - 26 .. 180, -180 .. -180 + 26: 1405 i := 0; 1406 else 1407 i := -1; 1408 end; 1409 if i >= 0 then 1226 1410 begin 1227 ChangeResourceWeights(i);1228 SmartUpdateContent;1229 if WindowMode<>wmModal then1230 MainScreen.UpdateViews;1411 ChangeResourceWeights(i); 1412 SmartUpdateContent; 1413 if WindowMode <> wmModal then 1414 MainScreen.UpdateViews; 1231 1415 end 1232 1416 end 1233 1417 end; 1234 end; {FormMouseDown}1418 end; { FormMouseDown } 1235 1419 1236 1420 procedure TCityDlg.ChooseProject; 1237 1421 const 1238 ptSelect=0; ptTrGoods=1; ptUn=2; ptCaravan=3; ptImp=4; ptWonder=6; 1239 ptShip=7; ptInvalid=8; 1422 ptSelect = 0; 1423 ptTrGoods = 1; 1424 ptUn = 2; 1425 ptCaravan = 3; 1426 ptImp = 4; 1427 ptWonder = 6; 1428 ptShip = 7; 1429 ptInvalid = 8; 1240 1430 1241 1431 function ProjectType(Project: integer): integer; 1242 1432 begin 1243 if Project and cpCompleted<>0 then result:=ptSelect 1244 else if Project and (cpImp+cpIndex)=cpImp+imTrGoods then result:=ptTrGoods 1245 else if Project and cpImp=0 then 1246 if MyModel[Project and cpIndex].Kind=mkCaravan then result:=ptCaravan 1247 else result:=ptUn 1248 else if Project and cpIndex>=nImp then result:=ptInvalid 1249 else if Imp[Project and cpIndex].Kind=ikWonder then result:=ptWonder 1250 else if Imp[Project and cpIndex].Kind=ikShipPart then result:=ptShip 1251 else result:=ptImp 1433 if Project and cpCompleted <> 0 then 1434 result := ptSelect 1435 else if Project and (cpImp + cpIndex) = cpImp + imTrGoods then 1436 result := ptTrGoods 1437 else if Project and cpImp = 0 then 1438 if MyModel[Project and cpIndex].Kind = mkCaravan then 1439 result := ptCaravan 1440 else 1441 result := ptUn 1442 else if Project and cpIndex >= nImp then 1443 result := ptInvalid 1444 else if Imp[Project and cpIndex].Kind = ikWonder then 1445 result := ptWonder 1446 else if Imp[Project and cpIndex].Kind = ikShipPart then 1447 result := ptShip 1448 else 1449 result := ptImp 1252 1450 end; 1253 1451 1254 1452 var 1255 NewProject, OldMoney,pt0,pt1,cix1: integer;1256 QueryOk: boolean;1257 begin 1258 assert(not supervising);1259 ModalSelectDlg.ShowNewContent_CityProject(wmModal,cix);1260 if ModalSelectDlg.result<>-1 then1261 begin 1262 if ModalSelectDlg.result and cpType<>0 then1263 begin 1264 MyCity[cix].Status:=MyCity[cix].Status and not 71265 or (1+ModalSelectDlg.result and cpIndex);1266 AutoBuild(cix, MyData.ImpOrder[ModalSelectDlg.result and cpIndex]);1453 NewProject, OldMoney, pt0, pt1, cix1: integer; 1454 QueryOk: boolean; 1455 begin 1456 assert(not supervising); 1457 ModalSelectDlg.ShowNewContent_CityProject(wmModal, cix); 1458 if ModalSelectDlg.result <> -1 then 1459 begin 1460 if ModalSelectDlg.result and cpType <> 0 then 1461 begin 1462 MyCity[cix].Status := MyCity[cix].Status and not 7 or 1463 (1 + ModalSelectDlg.result and cpIndex); 1464 AutoBuild(cix, MyData.ImpOrder[ModalSelectDlg.result and cpIndex]); 1267 1465 end 1268 else1269 begin 1270 NewProject:=ModalSelectDlg.result;1271 QueryOk:=true;1272 if (NewProject and cpImp<>0) and (NewProject and cpIndex>=28)1273 and (MyRO.NatBuilt[NewProject and cpIndex]>0) then1274 with MessgExDlg do1466 else 1467 begin 1468 NewProject := ModalSelectDlg.result; 1469 QueryOk := true; 1470 if (NewProject and cpImp <> 0) and (NewProject and cpIndex >= 28) and 1471 (MyRO.NatBuilt[NewProject and cpIndex] > 0) then 1472 with MessgExDlg do 1275 1473 begin 1276 cix1:=MyRO.nCity-1; 1277 while (cix1>=0) and (MyCity[cix1].Built[NewProject and cpIndex]=0) do 1278 dec(cix1); 1279 MessgText:=Format(Phrases.Lookup('DOUBLESTATEIMP'), 1280 [Phrases.Lookup('IMPROVEMENTS', NewProject and cpIndex), 1281 CityName(MyCity[cix1].ID)]); 1282 OpenSound:='MSG_DEFAULT'; 1283 Kind:=mkOkCancel; 1284 IconKind:=mikImp; 1285 IconIndex:=NewProject and cpIndex; 1286 ShowModal; 1287 QueryOk:= ModalResult=mrOK; 1474 cix1 := MyRO.nCity - 1; 1475 while (cix1 >= 0) and 1476 (MyCity[cix1].Built[NewProject and cpIndex] = 0) do 1477 dec(cix1); 1478 MessgText := Format(Phrases.Lookup('DOUBLESTATEIMP'), 1479 [Phrases.Lookup('IMPROVEMENTS', NewProject and cpIndex), 1480 CityName(MyCity[cix1].ID)]); 1481 OpenSound := 'MSG_DEFAULT'; 1482 Kind := mkOkCancel; 1483 IconKind := mikImp; 1484 IconIndex := NewProject and cpIndex; 1485 ShowModal; 1486 QueryOk := ModalResult = mrOK; 1288 1487 end; 1289 if not QueryOk then1290 exit;1291 1292 if (MyCity[cix].Prod>0) then1488 if not QueryOk then 1489 exit; 1490 1491 if (MyCity[cix].Prod > 0) then 1293 1492 begin 1294 pt0:=ProjectType(MyCity[cix].Project0);1295 pt1:=ProjectType(NewProject);1296 if (pt0<>ptSelect) and (pt1<>ptTrGoods) then1493 pt0 := ProjectType(MyCity[cix].Project0); 1494 pt1 := ProjectType(NewProject); 1495 if (pt0 <> ptSelect) and (pt1 <> ptTrGoods) then 1297 1496 begin 1298 if NewProject and (cpImp or cpIndex)<>MyCity[cix].Project0 and (cpImp or cpIndex) then 1497 if NewProject and (cpImp or cpIndex) <> MyCity[cix].Project0 and 1498 (cpImp or cpIndex) then 1299 1499 begin // loss of material -- do query 1300 if (pt1=ptTrGoods) or (pt1=ptShip) or (pt1<>pt0) and (pt0<>ptCaravan) then 1301 QueryOk:=SimpleQuery(mkOkCancel,Format(Phrases.Lookup('LOSEMAT'), 1302 [MyCity[cix].Prod0,MyCity[cix].Prod0]),'MSG_DEFAULT')=mrOK 1303 else if MyCity[cix].Project and (cpImp or cpIndex)=MyCity[cix].Project0 and (cpImp or cpIndex) then 1304 QueryOk:=SimpleQuery(mkOkCancel,Phrases.Lookup('LOSEMAT3'),'MSG_DEFAULT')=mrOK 1500 if (pt1 = ptTrGoods) or (pt1 = ptShip) or (pt1 <> pt0) and 1501 (pt0 <> ptCaravan) then 1502 QueryOk := SimpleQuery(mkOkCancel, 1503 Format(Phrases.Lookup('LOSEMAT'), [MyCity[cix].Prod0, 1504 MyCity[cix].Prod0]), 'MSG_DEFAULT') = mrOK 1505 else if MyCity[cix].Project and (cpImp or cpIndex) = MyCity[cix] 1506 .Project0 and (cpImp or cpIndex) then 1507 QueryOk := SimpleQuery(mkOkCancel, Phrases.Lookup('LOSEMAT3'), 1508 'MSG_DEFAULT') = mrOK 1305 1509 end; 1306 1510 end 1307 1511 end; 1308 if not QueryOk then 1309 exit; 1310 1311 OldMoney:=MyRO.Money; 1312 MyCity[cix].Status:=MyCity[cix].Status and not 7; 1313 if (NewProject and cpImp=0) 1314 and ((MyCity[cix].Size<4) and (MyModel[NewProject and cpIndex].Kind=mkSettler) 1315 or (MyCity[cix].Size<3) and ((MyModel[NewProject and cpIndex].Kind=mkSlaves) 1316 or (NewProject and cpConscripts<>0))) then 1317 if SimpleQuery(mkYesNo,Phrases.Lookup('EMIGRATE'),'MSG_DEFAULT')<>mrOK then 1318 NewProject:=NewProject or cpDisbandCity; 1319 Server(sSetCityProject,me,cix,NewProject); 1320 c.Project:=MyCity[cix].Project; 1321 if MyRO.Money>OldMoney then 1322 Play('CITY_SELLIMP'); 1323 end; 1324 CityOptimizer_CityChange(cix); 1325 1326 if WindowMode<>wmModal then 1327 MainScreen.UpdateViews; 1328 InitSmallCityMap; 1329 SmartUpdateContent; 1330 end; 1331 end; 1332 1333 procedure TCityDlg.BuyClick(Sender:TObject); 1512 if not QueryOk then 1513 exit; 1514 1515 OldMoney := MyRO.Money; 1516 MyCity[cix].Status := MyCity[cix].Status and not 7; 1517 if (NewProject and cpImp = 0) and 1518 ((MyCity[cix].Size < 4) and 1519 (MyModel[NewProject and cpIndex].Kind = mkSettler) or 1520 (MyCity[cix].Size < 3) and 1521 ((MyModel[NewProject and cpIndex].Kind = mkSlaves) or 1522 (NewProject and cpConscripts <> 0))) then 1523 if SimpleQuery(mkYesNo, Phrases.Lookup('EMIGRATE'), 'MSG_DEFAULT') <> mrOK 1524 then 1525 NewProject := NewProject or cpDisbandCity; 1526 Server(sSetCityProject, me, cix, NewProject); 1527 c.Project := MyCity[cix].Project; 1528 if MyRO.Money > OldMoney then 1529 Play('CITY_SELLIMP'); 1530 end; 1531 CityOptimizer_CityChange(cix); 1532 1533 if WindowMode <> wmModal then 1534 MainScreen.UpdateViews; 1535 InitSmallCityMap; 1536 SmartUpdateContent; 1537 end; 1538 end; 1539 1540 procedure TCityDlg.BuyClick(Sender: TObject); 1334 1541 var 1335 NextProd,Cost:integer; 1336 begin 1337 if (cix<0) or (ClientMode>=scContact) then exit; 1338 with MyCity[cix],MessgExDlg do 1339 begin 1340 Cost:=Report.ProjectCost; 1341 NextProd:=Report.Production; 1342 if NextProd<0 then NextProd:=0; 1343 Cost:=Cost-Prod-NextProd; 1344 if (MyRO.Wonder[woMich].EffectiveOwner=me) and (Project and cpImp<>0) then 1345 Cost:=Cost*2 1346 else Cost:=Cost*4; 1347 if (Cost<=0) and (Report.HappinessBalance>=0) {no disorder} then 1348 begin MessgText:=Phrases.Lookup('READY'); Kind:=mkOK; end 1349 else if Cost>MyRO.Money then 1350 begin 1351 OpenSound:='MSG_DEFAULT'; 1352 MessgText:=Format(Phrases.Lookup('NOMONEY'),[Cost,MyRO.Money]); 1353 Kind:=mkOK; 1542 NextProd, Cost: integer; 1543 begin 1544 if (cix < 0) or (ClientMode >= scContact) then 1545 exit; 1546 with MyCity[cix], MessgExDlg do 1547 begin 1548 Cost := Report.ProjectCost; 1549 NextProd := Report.Production; 1550 if NextProd < 0 then 1551 NextProd := 0; 1552 Cost := Cost - Prod - NextProd; 1553 if (MyRO.Wonder[woMich].EffectiveOwner = me) and (Project and cpImp <> 0) 1554 then 1555 Cost := Cost * 2 1556 else 1557 Cost := Cost * 4; 1558 if (Cost <= 0) and (Report.HappinessBalance >= 0) { no disorder } then 1559 begin 1560 MessgText := Phrases.Lookup('READY'); 1561 Kind := mkOk; 1354 1562 end 1355 else begin MessgText:=Format(Phrases.Lookup('BUY'),[Cost]); Kind:=mkYesNo; end; 1356 ShowModal; 1357 if (Kind=mkYesNo) and (ModalResult=mrOK) then 1358 begin 1359 if Server(sBuyCityProject,me,cix,nil^)>=rExecuted then 1563 else if Cost > MyRO.Money then 1564 begin 1565 OpenSound := 'MSG_DEFAULT'; 1566 MessgText := Format(Phrases.Lookup('NOMONEY'), [Cost, MyRO.Money]); 1567 Kind := mkOk; 1568 end 1569 else 1570 begin 1571 MessgText := Format(Phrases.Lookup('BUY'), [Cost]); 1572 Kind := mkYesNo; 1573 end; 1574 ShowModal; 1575 if (Kind = mkYesNo) and (ModalResult = mrOK) then 1576 begin 1577 if Server(sBuyCityProject, me, cix, nil^) >= rExecuted then 1360 1578 begin 1361 Play('CITY_BUYPROJECT');1362 SmartUpdateContent;1363 if WindowMode<>wmModal then1364 MainScreen.UpdateViews;1579 Play('CITY_BUYPROJECT'); 1580 SmartUpdateContent; 1581 if WindowMode <> wmModal then 1582 MainScreen.UpdateViews; 1365 1583 end 1366 1584 end … … 1370 1588 procedure TCityDlg.FormClose(Sender: TObject; var Action: TCloseAction); 1371 1589 begin 1372 Timer1.Enabled:=false; 1373 ProdHint:=false; 1374 MarkCityLoc:=-1; 1375 if Optimize_cixTileChange>=0 then 1376 begin 1377 if Optimize_TilesBeforeChange 1378 and not MyCity[Optimize_cixTileChange].Tiles<>0 then 1379 begin 1380 CityOptimizer_ReleaseCityTiles(Optimize_cixTileChange, 1381 Optimize_TilesBeforeChange and not MyCity[Optimize_cixTileChange].Tiles); 1382 if WindowMode<>wmModal then 1383 MainScreen.UpdateViews; 1384 end; 1385 Optimize_cixTileChange:=-1; 1386 end; 1387 if CloseAction>None then 1388 MainScreen.CityClosed(RestoreUnFocus,CloseAction=StepFocus); 1389 RestoreUnFocus:=-1; 1390 inherited; 1590 Timer1.Enabled := false; 1591 ProdHint := false; 1592 MarkCityLoc := -1; 1593 if Optimize_cixTileChange >= 0 then 1594 begin 1595 if Optimize_TilesBeforeChange and not MyCity[Optimize_cixTileChange] 1596 .Tiles <> 0 then 1597 begin 1598 CityOptimizer_ReleaseCityTiles(Optimize_cixTileChange, 1599 Optimize_TilesBeforeChange and 1600 not MyCity[Optimize_cixTileChange].Tiles); 1601 if WindowMode <> wmModal then 1602 MainScreen.UpdateViews; 1603 end; 1604 Optimize_cixTileChange := -1; 1605 end; 1606 if CloseAction > None then 1607 MainScreen.CityClosed(RestoreUnFocus, CloseAction = StepFocus); 1608 RestoreUnFocus := -1; 1609 inherited; 1391 1610 end; 1392 1611 1393 1612 procedure TCityDlg.Timer1Timer(Sender: TObject); 1394 1613 begin 1395 if ProdHint then 1396 begin 1397 BlinkTime:=(BlinkTime+1) mod 12; 1398 if BlinkTime=0 then with Canvas do 1399 begin 1400 BitBlt(canvas.Handle,xView+5,yView+1,64,2, 1401 back.Canvas.Handle,xView+5,yView+1,SRCCOPY); 1402 BitBlt(canvas.Handle,xView+5,yView+3,2,42, 1403 back.Canvas.Handle,xView+5,yView+3,SRCCOPY); 1404 BitBlt(canvas.Handle,xView+5+62,yView+3,2,42, 1405 back.Canvas.Handle,xView+5+62,yView+3,SRCCOPY); 1406 Frame(canvas,xView+9-1,yView+5-1,xView+9+xSizeBig,yView+5+ySizeBig,$B0B0B0,$FFFFFF); 1407 RFrame(canvas,xView+9-2,yView+5-2,xView+9+xSizeBig+1,yView+5+ySizeBig+1,$FFFFFF,$B0B0B0); 1408 Brush.Color:=$000000; 1409 FillRect(Rect(xView+9,yView+5,xView+1+72-8,yView+5+40)); 1410 Brush.Style:=bsClear; 1411 end 1412 else if BlinkTime=6 then 1413 begin 1414 if AllowChange and (c.Status and 7<>0) then 1614 if ProdHint then 1615 begin 1616 BlinkTime := (BlinkTime + 1) mod 12; 1617 if BlinkTime = 0 then 1618 with Canvas do 1619 begin 1620 bitblt(Canvas.Handle, xView + 5, yView + 1, 64, 2, Back.Canvas.Handle, 1621 xView + 5, yView + 1, SRCCOPY); 1622 bitblt(Canvas.Handle, xView + 5, yView + 3, 2, 42, Back.Canvas.Handle, 1623 xView + 5, yView + 3, SRCCOPY); 1624 bitblt(Canvas.Handle, xView + 5 + 62, yView + 3, 2, 42, 1625 Back.Canvas.Handle, xView + 5 + 62, yView + 3, SRCCOPY); 1626 Frame(Canvas, xView + 9 - 1, yView + 5 - 1, xView + 9 + xSizeBig, 1627 yView + 5 + ySizeBig, $B0B0B0, $FFFFFF); 1628 RFrame(Canvas, xView + 9 - 2, yView + 5 - 2, xView + 9 + xSizeBig + 1, 1629 yView + 5 + ySizeBig + 1, $FFFFFF, $B0B0B0); 1630 brush.Color := $000000; 1631 FillRect(Rect(xView + 9, yView + 5, xView + 1 + 72 - 8, 1632 yView + 5 + 40)); 1633 brush.style := bsClear; 1634 end 1635 else if BlinkTime = 6 then 1636 begin 1637 if AllowChange and (c.Status and 7 <> 0) then 1415 1638 begin // city type autobuild 1416 FrameImage(canvas,bigimp,xView+9,yView+5,xSizeBig,ySizeBig,1417 (c.Status and 7-1+3)*xSizeBig,0,true);1639 FrameImage(Canvas, bigimp, xView + 9, yView + 5, xSizeBig, ySizeBig, 1640 (c.Status and 7 - 1 + 3) * xSizeBig, 0, true); 1418 1641 end 1419 else if c.Project and cpImp=0 then1642 else if c.Project and cpImp = 0 then 1420 1643 begin // project is unit 1421 BitBlt(canvas.Handle,xView+9,yView+5,xSizeBig,ySizeBig,1422 bigimp.Canvas.Handle,0,0,SRCCOPY);1423 with Tribe[cOwner].ModelPicture[c.Project and cpIndex] do1424 Sprite(canvas,HGr,xView+5,yView+1,64,44,1425 pix mod 10 *65+1,pix div 10*49+1);1644 bitblt(Canvas.Handle, xView + 9, yView + 5, xSizeBig, ySizeBig, 1645 bigimp.Canvas.Handle, 0, 0, SRCCOPY); 1646 with Tribe[cOwner].ModelPicture[c.Project and cpIndex] do 1647 Sprite(Canvas, HGr, xView + 5, yView + 1, 64, 44, pix mod 10 * 65 + 1, 1648 pix div 10 * 49 + 1); 1426 1649 end 1427 else ImpImage(Canvas,xView+9,yView+5, 1428 c.Project0 and cpIndex,cGov,true); 1650 else 1651 ImpImage(Canvas, xView + 9, yView + 5, c.Project0 and cpIndex, 1652 cGov, true); 1429 1653 end 1430 1654 end … … 1433 1657 procedure TCityDlg.FormPaint(Sender: TObject); 1434 1658 begin 1435 inherited; 1436 if OpenSoundEvent>=0 then PostMessage(Handle, WM_PLAYSOUND, 0, 0); 1437 end; 1438 1439 procedure TCityDlg.OnPlaySound(var Msg:TMessage); 1440 begin 1441 if 1 shl OpenSoundEvent=chProduction then 1442 begin 1443 if c.Project0 and cpImp<>0 then 1444 begin 1445 if c.Project0 and cpIndex>=28 then // wonders have already extra message with sound 1446 if Imp[c.Project0 and cpIndex].Kind=ikShipPart then Play('SHIP_BUILT') 1447 else Play('CITY_IMPCOMPLETE') 1659 inherited; 1660 if OpenSoundEvent >= 0 then 1661 PostMessage(Handle, WM_PLAYSOUND, 0, 0); 1662 end; 1663 1664 procedure TCityDlg.OnPlaySound(var Msg: TMessage); 1665 begin 1666 if 1 shl OpenSoundEvent = chProduction then 1667 begin 1668 if c.Project0 and cpImp <> 0 then 1669 begin 1670 if c.Project0 and cpIndex >= 28 then 1671 // wonders have already extra message with sound 1672 if Imp[c.Project0 and cpIndex].Kind = ikShipPart then 1673 Play('SHIP_BUILT') 1674 else 1675 Play('CITY_IMPCOMPLETE') 1448 1676 end 1449 else Play('CITY_UNITCOMPLETE'); 1677 else 1678 Play('CITY_UNITCOMPLETE'); 1450 1679 end 1451 else Play(CityEventSoundItem[OpenSoundEvent]); 1452 OpenSoundEvent:=-2; 1680 else 1681 Play(CityEventSoundItem[OpenSoundEvent]); 1682 OpenSoundEvent := -2; 1453 1683 end; 1454 1684 1455 1685 function Prio(iix: integer): integer; 1456 1686 begin 1457 case Imp[iix].Kind of 1458 ikWonder: result:=iix+10000; 1459 ikNatLocal, ikNatGlobal: 1687 case Imp[iix].Kind of 1688 ikWonder: 1689 result := iix + 10000; 1690 ikNatLocal, ikNatGlobal: 1691 case iix of 1692 imPalace: 1693 result := 0; 1694 else 1695 result := iix + 20000; 1696 end; 1697 else 1460 1698 case iix of 1461 im Palace: result:=0;1462 else result:=iix+20000;1463 end;1464 else case iix of1465 imTownHall, imCourt: result:=iix+30000;1466 imAqueduct, imSewer: result:=iix+40000;1467 imTemple, imTheater, imCathedral: result:=iix+50000;1468 else result:=iix+90000;1699 imTownHall, imCourt: 1700 result := iix + 30000; 1701 imAqueduct, imSewer: 1702 result := iix + 40000; 1703 imTemple, imTheater, imCathedral: 1704 result := iix + 50000; 1705 else 1706 result := iix + 90000; 1469 1707 end; 1470 1708 end; … … 1473 1711 procedure TCityDlg.NextCityBtnClick(Sender: TObject); 1474 1712 begin 1475 ChangeCity(+1);1713 ChangeCity(+1); 1476 1714 end; 1477 1715 1478 1716 procedure TCityDlg.PrevCityBtnClick(Sender: TObject); 1479 1717 begin 1480 ChangeCity(-1);1718 ChangeCity(-1); 1481 1719 end; 1482 1720 1483 1721 procedure TCityDlg.ChangeCity(d: integer); 1484 1722 var 1485 cixNew: integer;1486 begin 1487 cixNew:=cix;1488 repeat1489 cixNew:=(cixNew+MyRO.nCity+d) mod MyRO.nCity;1490 until (MyCity[cixNew].Loc>=0) or (cixNew=cix);1491 if cixNew<>cix then1492 MainScreen.ZoomToCity(MyCity[cixNew].Loc);1723 cixNew: integer; 1724 begin 1725 cixNew := cix; 1726 repeat 1727 cixNew := (cixNew + MyRO.nCity + d) mod MyRO.nCity; 1728 until (MyCity[cixNew].Loc >= 0) or (cixNew = cix); 1729 if cixNew <> cix then 1730 MainScreen.ZoomToCity(MyCity[cixNew].Loc); 1493 1731 end; 1494 1732 … … 1496 1734 Shift: TShiftState); 1497 1735 begin 1498 if ((Key=VK_UP) or (Key=VK_NUMPAD8)) 1499 and (cix>=0) and (WindowMode=wmPersistent) then 1500 ChangeCity(-1) 1501 else if ((Key=VK_DOWN) or (Key=VK_NUMPAD2)) 1502 and (cix>=0) and (WindowMode=wmPersistent) then 1503 ChangeCity(+1) 1504 else inherited 1505 end; 1506 1507 {procedure TCityDlg.AdviceBtnClick(Sender: TObject); 1508 begin 1509 AdvisorDlg.GiveCityAdvice(cix); 1510 end;} 1736 if ((Key = VK_UP) or (Key = VK_NUMPAD8)) and (cix >= 0) and 1737 (WindowMode = wmPersistent) then 1738 ChangeCity(-1) 1739 else if ((Key = VK_DOWN) or (Key = VK_NUMPAD2)) and (cix >= 0) and 1740 (WindowMode = wmPersistent) then 1741 ChangeCity(+1) 1742 else 1743 inherited 1744 end; 1745 1746 { procedure TCityDlg.AdviceBtnClick(Sender: TObject); 1747 begin 1748 AdvisorDlg.GiveCityAdvice(cix); 1749 end; } 1511 1750 1512 1751 var 1513 i,j,k: integer;1752 i, j, k: integer; 1514 1753 1515 1754 procedure TCityDlg.PageUpBtnClick(Sender: TObject); 1516 1755 begin 1517 if Page>0 then1518 begin 1519 dec(Page);1520 SmartUpdateContent1756 if Page > 0 then 1757 begin 1758 dec(Page); 1759 SmartUpdateContent 1521 1760 end 1522 1761 end; … … 1524 1763 procedure TCityDlg.PageDownBtnClick(Sender: TObject); 1525 1764 begin 1526 if Page<PageCount-1 then1527 begin 1528 inc(Page);1529 SmartUpdateContent1765 if Page < PageCount - 1 then 1766 begin 1767 inc(Page); 1768 SmartUpdateContent 1530 1769 end 1531 1770 end; … … 1533 1772 procedure TCityDlg.ChangeResourceWeights(iResourceWeights: integer); 1534 1773 var 1535 Advice: TCityTileAdviceData; 1536 begin 1537 assert(not supervising); 1538 assert(cix>=0); 1539 MyCity[cix].Status:=MyCity[cix].Status 1540 and not csResourceWeightsMask or (iResourceWeights shl 4); 1541 c.Status:=MyCity[cix].Status; 1542 if iResourceWeights>0 then 1543 begin 1544 Advice.ResourceWeights:=OfferedResourceWeights[iResourceWeights]; 1545 Server(sGetCityTileAdvice,me,cix,Advice); 1546 if Advice.Tiles<>MyCity[cix].Tiles then 1547 Server(sSetCityTiles,me,cix,Advice.Tiles); 1548 end 1549 end; 1550 1774 Advice: TCityTileAdviceData; 1775 begin 1776 assert(not supervising); 1777 assert(cix >= 0); 1778 MyCity[cix].Status := MyCity[cix].Status and not csResourceWeightsMask or 1779 (iResourceWeights shl 4); 1780 c.Status := MyCity[cix].Status; 1781 if iResourceWeights > 0 then 1782 begin 1783 Advice.ResourceWeights := OfferedResourceWeights[iResourceWeights]; 1784 Server(sGetCityTileAdvice, me, cix, Advice); 1785 if Advice.Tiles <> MyCity[cix].Tiles then 1786 Server(sSetCityTiles, me, cix, Advice.Tiles); 1787 end 1788 end; 1551 1789 1552 1790 initialization 1553 for i:=0 to nImp-1 do ImpSorted[i]:=i; 1554 for i:=0 to nImp-2 do for j:=i+1 to nImp-1 do 1555 if Prio(ImpSorted[i])>Prio(ImpSorted[j]) then 1556 begin k:=ImpSorted[i]; ImpSorted[i]:=ImpSorted[j]; ImpSorted[j]:=k end; 1791 1792 for i := 0 to nImp - 1 do 1793 ImpSorted[i] := i; 1794 for i := 0 to nImp - 2 do 1795 for j := i + 1 to nImp - 1 do 1796 if Prio(ImpSorted[i]) > Prio(ImpSorted[j]) then 1797 begin 1798 k := ImpSorted[i]; 1799 ImpSorted[i] := ImpSorted[j]; 1800 ImpSorted[j] := k 1801 end; 1802 1557 1803 end. 1558
Note:
See TracChangeset
for help on using the changeset viewer.