source: branches/highdpi/LocalPlayer/IsoEngine.pas@ 210

Last change on this file since 210 was 210, checked in by chronos, 19 months ago
  • Modified: Improved HighDPI branch. Imported new changes from trunk branch.
File size: 51.6 KB
Line 
1{$INCLUDE Switches.inc}
2unit IsoEngine;
3
4interface
5
6uses
7 UDpiControls, Protocol, ClientTools, ScreenTools, Tribes, {$IFNDEF SCR}Term, {$ENDIF}
8 LCLIntf, LCLType, SysUtils, Classes, Graphics, UPixelPointer;
9
10type
11 TInitEnemyModelEvent = function(emix: integer): boolean;
12
13 { TIsoMap }
14
15 TIsoMap = class
16 constructor Create;
17 procedure SetOutput(Output: TDpiBitmap);
18 procedure SetPaintBounds(Left, Top, Right, Bottom: integer);
19 procedure Paint(x, y, Loc, nx, ny, CityLoc, CityOwner: integer;
20 UseBlink: boolean = false; CityAllowClick: boolean = false);
21 procedure PaintUnit(x, y: integer; const UnitInfo: TUnitInfo;
22 Status: integer);
23 procedure PaintCity(x, y: integer; const CityInfo: TCityInfo;
24 accessory: boolean = true);
25 procedure BitBltBitmap(Src: TDpiBitmap; x, y, Width, Height, xSrc, ySrc,
26 Rop: integer);
27
28 procedure AttackBegin(const ShowMove: TShowMove);
29 procedure AttackEffect(const ShowMove: TShowMove);
30 procedure AttackEnd;
31
32 private
33 procedure CityGrid(xm, ym: integer; CityAllowClick: Boolean);
34 function IsShoreTile(Loc: integer): boolean;
35 procedure MakeDark(Line: PPixelPointer; Length: Integer);
36 procedure ShadeOutside(x0, y0, x1, y1, xm, ym: integer);
37 protected
38 FOutput: TDpiBitmap;
39 FLeft, FTop, FRight, FBottom, RealTop, RealBottom, AttLoc, DefLoc,
40 DefHealth, FAdviceLoc: integer;
41 DataCanvas: TDpiCanvas;
42 MaskCanvas: TDpiCanvas;
43 function Connection4(Loc, Mask, Value: integer): integer;
44 function Connection8(Loc, Mask: integer): integer;
45 function OceanConnection(Loc: integer): integer;
46 procedure PaintShore(x, y, Loc: integer);
47 procedure PaintTileExtraTerrain(x, y, Loc: integer);
48 procedure PaintTileObjects(x, y, Loc, CityLoc, CityOwner: integer;
49 UseBlink: boolean);
50 procedure PaintGrid(x, y, nx, ny: integer);
51 procedure FillRect(x, y, Width, Height, Color: integer);
52 procedure Textout(x, y, Color: integer; const s: string);
53 procedure Sprite(HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
54 procedure TSprite(xDst, yDst, grix: integer; PureBlack: boolean = false);
55
56 public
57 property AdviceLoc: integer read FAdviceLoc write FAdviceLoc;
58 end;
59
60const
61 // options switched by buttons
62 moPolitical = 0;
63 moCityNames = 1;
64 moGreatWall = 4;
65 moGrid = 5;
66 moBareTerrain = 6;
67
68 // other options
69 moEditMode = 16;
70 moLocCodes = 17;
71
72var
73 NoMap: TIsoMap;
74 Options: integer;
75 pDebugMap: integer; // -1 for off
76
77function IsJungle(y: integer): boolean;
78procedure Init(InitEnemyModelHandler: TInitEnemyModelEvent);
79function ApplyTileSize(xxtNew, yytNew: integer): boolean;
80procedure Done;
81procedure Reset;
82
83implementation
84
85const
86 ShoreDither = fGrass;
87 TerrainIconLines = 21;
88 TerrainIconCols = 9;
89
90 // sprites indexes
91 spRow2 = 2 * TerrainIconCols + 6;
92 spBlink1 = 1 * TerrainIconCols + 8;
93 spBlink2 = 2 * TerrainIconCols + 8;
94 spPrefStartPos = 1 * TerrainIconCols;
95 spStartPos = 2 * TerrainIconCols;
96 spPlain = 2 * TerrainIconCols + 7;
97 spForest = 3 * TerrainIconCols;
98 spRoad = 9 * TerrainIconCols;
99 spRailRoad = 10 * TerrainIconCols;
100 spCanal = 11 * TerrainIconCols;
101 spIrrigation = 12 * TerrainIconCols;
102 spFarmLand = 12 * TerrainIconCols + 1;
103 spMine = 12 * TerrainIconCols + 2;
104 spFortFront = 12 * TerrainIconCols + 3;
105 spBase = 12 * TerrainIconCols + 4;
106 spSpacePort = 12 * TerrainIconCols + 5;
107 spPollution = 12 * TerrainIconCols + 6;
108 spFortBack = 12 * TerrainIconCols + 7;
109 spMinerals = 12 * TerrainIconCols + 8;
110 spRiver = 13 * TerrainIconCols;
111 spRiverMouths = 15 * TerrainIconCols;
112 spGrid = 15 * TerrainIconCols + 6;
113 spJungle = 18 * TerrainIconCols;
114 spCanalMouths = 20 * TerrainIconCols;
115
116var
117 BordersOK: integer;
118 OnInitEnemyModel: TInitEnemyModelEvent;
119 LandPatch, OceanPatch, Borders: TDpiBitmap;
120 TSpriteSize: array [0 .. TerrainIconLines * 9 - 1] of TRect;
121 DebugMap: ^TTileList;
122 CitiesPictures: array [2 .. 3, 0 .. 3] of TCityPicture;
123 FoW, ShowLoc, ShowCityNames, ShowObjects, ShowBorder, ShowMyBorder,
124 ShowGrWall, ShowDebug: boolean;
125
126function IsJungle(y: integer): boolean;
127begin
128 result := (y > (G.ly - 2) div 4) and (G.ly - 1 - y > (G.ly - 2) div 4)
129end;
130
131procedure Init(InitEnemyModelHandler: TInitEnemyModelEvent);
132begin
133 OnInitEnemyModel := InitEnemyModelHandler;
134 if NoMap <> nil then
135 NoMap.Free;
136 NoMap := TIsoMap.Create;
137end;
138
139function ApplyTileSize(xxtNew, yytNew: integer): boolean;
140var
141 i, x, y, xSrc, ySrc, HGrTerrainNew, HGrCitiesNew, age, size: integer;
142 LandMore, OceanMore, DitherMask, Mask24: TDpiBitmap;
143 MaskLine: array [0 .. 50 * 3 - 1] of TPixelPointer; // 32 = assumed maximum for yyt
144 Border: boolean;
145begin
146 result := false;
147 HGrTerrainNew := LoadGraphicSet(Format('Terrain%dx%d.png',
148 [xxtNew * 2, yytNew * 2]));
149 if HGrTerrainNew < 0 then
150 exit;
151 HGrCitiesNew := LoadGraphicSet(Format('Cities%dx%d.png',
152 [xxtNew * 2, yytNew * 2]));
153 if HGrCitiesNew < 0 then
154 exit;
155 xxt := xxtNew;
156 yyt := yytNew;
157 HGrTerrain := HGrTerrainNew;
158 HGrCities := HGrCitiesNew;
159 result := true;
160
161 // prepare age 2+3 cities
162 for age := 2 to 3 do
163 for size := 0 to 3 do
164 with CitiesPictures[age, size] do
165 FindPosition(HGrCities, size * (xxt * 2 + 1), (age - 2) * (yyt * 3 + 1),
166 xxt * 2 - 1, yyt * 3 - 1, $00FFFF, xShield, yShield);
167
168 { prepare dithered ground tiles }
169 if LandPatch <> nil then
170 LandPatch.Free;
171 LandPatch := TDpiBitmap.Create;
172 LandPatch.PixelFormat := pf24bit;
173 LandPatch.Canvas.Brush.Color := 0;
174 LandPatch.SetSize(xxt * 18, yyt * 9);
175 LandPatch.Canvas.FillRect(0, 0, LandPatch.Width, LandPatch.Height);
176 if OceanPatch <> nil then
177 OceanPatch.Free;
178 OceanPatch := TDpiBitmap.Create;
179 OceanPatch.PixelFormat := pf24bit;
180 OceanPatch.Canvas.Brush.Color := 0;
181 OceanPatch.SetSize(xxt * 8, yyt * 4);
182 OceanPatch.Canvas.FillRect(0, 0, OceanPatch.Width, OceanPatch.Height);
183 LandMore := TDpiBitmap.Create;
184 LandMore.PixelFormat := pf24bit;
185 LandMore.Canvas.Brush.Color := 0;
186 LandMore.SetSize(xxt * 18, yyt * 9);
187 LandMore.Canvas.FillRect(0, 0, LandMore.Width, LandMore.Height);
188 OceanMore := TDpiBitmap.Create;
189 OceanMore.PixelFormat := pf24bit;
190 OceanMore.Canvas.Brush.Color := 0;
191 OceanMore.SetSize(xxt * 8, yyt * 4);
192 OceanMore.Canvas.FillRect(0, 0, OceanMore.Width, OceanMore.Height);
193 DitherMask := TDpiBitmap.Create;
194 DitherMask.PixelFormat := pf24bit;
195 DitherMask.SetSize(xxt * 2, yyt * 2);
196 DitherMask.Canvas.FillRect(0, 0, DitherMask.Width, DitherMask.Height);
197 DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
198 GrExt[HGrTerrain].Mask.Canvas, 1 + 7 * (xxt * 2 + 1),
199 1 + yyt + 15 * (yyt * 3 + 1), SRCAND);
200
201 for x := -1 to 6 do
202 begin
203 if x = -1 then
204 begin
205 xSrc := ShoreDither * (xxt * 2 + 1) + 1;
206 ySrc := 1 + yyt
207 end
208 else if x = 6 then
209 begin
210 xSrc := 1 + (xxt * 2 + 1) * 2;
211 ySrc := 1 + yyt + (yyt * 3 + 1) * 2
212 end
213 else
214 begin
215 xSrc := (x + 2) * (xxt * 2 + 1) + 1;
216 ySrc := 1 + yyt
217 end;
218 for y := -1 to 6 do
219 DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
220 xxt * 2, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
221 for y := -2 to 6 do
222 DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt, xxt,
223 yyt, GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt,
224 SRCPAINT);
225 for y := -2 to 6 do
226 DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2) + xxt, (y + 2) * yyt,
227 xxt, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt,
228 SRCPAINT);
229 for y := -2 to 6 do
230 DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt, xxt,
231 yyt, DitherMask.Canvas, xxt, yyt, SRCAND);
232 for y := -2 to 6 do
233 DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2) + xxt, (y + 2) * yyt,
234 xxt, yyt, DitherMask.Canvas, 0, yyt, SRCAND);
235 end;
236
237 for y := -1 to 6 do
238 begin
239 if y = -1 then
240 begin
241 xSrc := ShoreDither * (xxt * 2 + 1) + 1;
242 ySrc := 1 + yyt
243 end
244 else if y = 6 then
245 begin
246 xSrc := 1 + 2 * (xxt * 2 + 1);
247 ySrc := 1 + yyt + 2 * (yyt * 3 + 1)
248 end
249 else
250 begin
251 xSrc := (y + 2) * (xxt * 2 + 1) + 1;
252 ySrc := 1 + yyt
253 end;
254 for x := -2 to 6 do
255 DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
256 xxt * 2, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
257 DpiBitCanvas(LandMore.Canvas, xxt * 2, (y + 2) * yyt, xxt, yyt,
258 GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt, SRCPAINT);
259 for x := 0 to 7 do
260 DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2) - xxt, (y + 2) * yyt,
261 xxt * 2, yyt, GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt,
262 SRCPAINT);
263 for x := -2 to 6 do
264 DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
265 xxt * 2, yyt, DitherMask.Canvas, 0, 0, SRCAND);
266 end;
267
268 for x := 0 to 3 do
269 for y := 0 to 3 do
270 begin
271 if (x = 1) and (y = 1) then
272 xSrc := 1
273 else
274 xSrc := (x mod 2) * (xxt * 2 + 1) + 1;
275 ySrc := 1 + yyt;
276 if (x >= 1) = (y >= 2) then
277 DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
278 GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
279 if (x >= 1) and ((y < 2) or (x >= 2)) then
280 begin
281 DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
282 GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt,
283 SRCPAINT);
284 DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
285 GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt, SRCPAINT);
286 end;
287 DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
288 DitherMask.Canvas, xxt, yyt, SRCAND);
289 DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
290 DitherMask.Canvas, 0, yyt, SRCAND);
291 end;
292
293 for y := 0 to 3 do
294 for x := 0 to 3 do
295 begin
296 if (x = 1) and (y = 1) then
297 xSrc := 1
298 else
299 xSrc := (y mod 2) * (xxt * 2 + 1) + 1;
300 ySrc := 1 + yyt;
301 if (x < 1) or (y >= 2) then
302 DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
303 GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc);
304 if (x = 1) and (y < 2) or (x >= 2) and (y >= 1) then
305 begin
306 DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt, yyt,
307 GrExt[HGrTerrain].Data.Canvas, xSrc + xxt, ySrc + yyt,
308 SRCPAINT);
309 DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2) + xxt, y * yyt, xxt, yyt,
310 GrExt[HGrTerrain].Data.Canvas, xSrc, ySrc + yyt, SRCPAINT);
311 end;
312 DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
313 DitherMask.Canvas, 0, 0, SRCAND);
314 end;
315
316 DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
317 DitherMask.Canvas, 0, 0, DSTINVERT); { invert dither mask }
318 DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt * 2,
319 GrExt[HGrTerrain].Mask.Canvas, 1, 1 + yyt, SRCPAINT);
320
321 for x := -1 to 6 do
322 for y := -2 to 6 do
323 DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), (y + 2) * yyt,
324 xxt * 2, yyt, DitherMask.Canvas, 0, 0, SRCAND);
325
326 for y := -1 to 6 do
327 for x := -2 to 7 do
328 DpiBitCanvas(LandMore.Canvas, (x + 2) * (xxt * 2) - xxt, (y + 2) * yyt,
329 xxt * 2, yyt, DitherMask.Canvas, 0, yyt, SRCAND);
330
331 DpiBitCanvas(LandPatch.Canvas, 0, 0, (xxt * 2) * 9, yyt * 9,
332 LandMore.Canvas, 0, 0, SRCPAINT);
333
334 for x := 0 to 3 do
335 for y := 0 to 3 do
336 DpiBitCanvas(OceanPatch.Canvas, x * (xxt * 2), y * yyt, xxt * 2, yyt,
337 DitherMask.Canvas, 0, 0, SRCAND);
338
339 for y := 0 to 3 do
340 for x := 0 to 4 do
341 DpiBitCanvas(OceanMore.Canvas, x * (xxt * 2) - xxt, y * yyt, xxt * 2,
342 yyt, DitherMask.Canvas, 0, yyt, SRCAND);
343
344 DpiBitCanvas(OceanPatch.Canvas, 0, 0, (xxt * 2) * 4, yyt * 4,
345 OceanMore.Canvas, 0, 0, SRCPAINT);
346
347 with DitherMask.Canvas do
348 begin
349 Brush.Color := $FFFFFF;
350 FillRect(Rect(0, 0, xxt * 2, yyt));
351 end;
352 DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt,
353 GrExt[HGrTerrain].Mask.Canvas, 1, 1 + yyt);
354
355 for x := 0 to 6 do
356 DpiBitCanvas(LandPatch.Canvas, (x + 2) * (xxt * 2), yyt, xxt * 2, yyt,
357 DitherMask.Canvas, 0, 0, SRCAND);
358 DpiBitCanvas(DitherMask.Canvas, 0, 0, xxt * 2, yyt, DitherMask.Canvas,
359 0, 0, DSTINVERT);
360
361 for y := 0 to 6 do
362 DpiBitCanvas(LandPatch.Canvas, xxt * 2, (y + 2) * yyt, xxt * 2, yyt,
363 DitherMask.Canvas, 0, 0, SRCAND);
364
365 LandMore.Free;
366 OceanMore.Free;
367 DitherMask.Free;
368
369 // reduce size of terrain icons
370 Mask24 := TDpiBitmap.Create;
371 Mask24.Assign(GrExt[HGrTerrain].Mask);
372 Mask24.PixelFormat := pf24bit;
373 Mask24.BeginUpdate;
374 for ySrc := 0 to TerrainIconLines - 1 do
375 begin
376 for i := 0 to yyt * 3 - 1 do
377 MaskLine[i] := PixelPointer(Mask24, 0, 1 + ySrc * (yyt * 3 + 1) + i);
378 for xSrc := 0 to 9 - 1 do
379 begin
380 i := ySrc * 9 + xSrc;
381 TSpriteSize[i].Left := 0;
382 repeat
383 Border := true;
384 for y := 0 to yyt * 3 - 1 do begin
385 MaskLine[y].SetX(1 + xSrc * (xxt * 2 + 1) + TSpriteSize[i].Left);
386 if MaskLine[y].Pixel^.B = 0 then Border := false;
387 end;
388 if Border then Inc(TSpriteSize[i].Left);
389 until not Border or (TSpriteSize[i].Left = xxt * 2 - 1);
390 TSpriteSize[i].Top := 0;
391 repeat
392 Border := true;
393 for x := 0 to xxt * 2 - 1 do begin
394 MaskLine[TSpriteSize[i].Top].SetX(1 + xSrc * (xxt * 2 + 1) + x);
395 if MaskLine[TSpriteSize[i].Top].Pixel^.B = 0 then Border := false;
396 end;
397 if Border then inc(TSpriteSize[i].Top);
398 until not Border or (TSpriteSize[i].Top = yyt * 3 - 1);
399 TSpriteSize[i].Right := xxt * 2;
400 repeat
401 Border := true;
402 for y := 0 to yyt * 3 - 1 do begin
403 MaskLine[y].SetX(xSrc * (xxt * 2 + 1) + TSpriteSize[i].Right);
404 if MaskLine[y].Pixel^.B = 0 then Border := false;
405 end;
406 if Border then Dec(TSpriteSize[i].Right);
407 until not Border or (TSpriteSize[i].Right = TSpriteSize[i].Left);
408 TSpriteSize[i].Bottom := yyt * 3;
409 repeat
410 Border := true;
411 for x := 0 to xxt * 2 - 1 do begin
412 MaskLine[TSpriteSize[i].Bottom - 1].SetX(1 + xSrc * (xxt * 2 + 1) + x);
413 if MaskLine[TSpriteSize[i].Bottom - 1].Pixel^.B = 0 then Border := false;
414 end;
415 if Border then Dec(TSpriteSize[i].Bottom);
416 until not Border or (TSpriteSize[i].Bottom = TSpriteSize[i].Top);
417 end
418 end;
419 Mask24.EndUpdate;
420 Mask24.Free;
421
422 if Borders <> nil then
423 Borders.Free;
424 Borders := TDpiBitmap.Create;
425 Borders.PixelFormat := pf24bit;
426 Borders.SetSize(xxt * 2, (yyt * 2) * nPl);
427 Borders.Canvas.FillRect(0, 0, Borders.Width, Borders.Height);
428 BordersOK := 0;
429end;
430
431procedure Done;
432begin
433 FreeAndNil(NoMap);
434 FreeAndNil(LandPatch);
435 FreeAndNil(OceanPatch);
436 FreeAndNil(Borders);
437end;
438
439procedure Reset;
440begin
441 BordersOK := 0;
442end;
443
444constructor TIsoMap.Create;
445begin
446 inherited;
447 FLeft := 0;
448 FTop := 0;
449 FRight := 0;
450 FBottom := 0;
451 AttLoc := -1;
452 DefLoc := -1;
453 FAdviceLoc := -1;
454end;
455
456procedure TIsoMap.SetOutput(Output: TDpiBitmap);
457begin
458 FOutput := Output;
459 FLeft := 0;
460 FTop := 0;
461 FRight := FOutput.Width;
462 FBottom := FOutput.Height;
463end;
464
465procedure TIsoMap.SetPaintBounds(Left, Top, Right, Bottom: integer);
466begin
467 FLeft := Left;
468 FTop := Top;
469 FRight := Right;
470 FBottom := Bottom;
471end;
472
473procedure TIsoMap.FillRect(x, y, Width, Height, Color: integer);
474begin
475 if x < FLeft then
476 begin
477 Width := Width - (FLeft - x);
478 x := FLeft;
479 end;
480 if y < FTop then
481 begin
482 Height := Height - (FTop - y);
483 y := FTop;
484 end;
485 if x + Width >= FRight then
486 Width := FRight - x;
487 if y + Height >= FBottom then
488 Height := FBottom - y;
489 if (Width <= 0) or (Height <= 0) then
490 exit;
491
492 FOutput.Canvas.Brush.Color := Color;
493 FOutput.Canvas.FillRect(Rect(x, y, x + Width, y + Height));
494 FOutput.Canvas.Brush.Style := bsClear;
495end;
496
497procedure TIsoMap.Textout(x, y, Color: integer; const s: string);
498begin
499 FOutput.Canvas.Font.Color := Color;
500 FOutput.Canvas.TextRect(Rect(FLeft, FTop, FRight, FBottom), x, y, s)
501end;
502
503procedure TIsoMap.BitBltBitmap(Src: TDpiBitmap; x, y, Width, Height, xSrc, ySrc,
504 Rop: integer);
505begin
506 if x < FLeft then
507 begin
508 Width := Width - (FLeft - x);
509 xSrc := xSrc + (FLeft - x);
510 x := FLeft;
511 end;
512 if y < FTop then
513 begin
514 Height := Height - (FTop - y);
515 ySrc := ySrc + (FTop - y);
516 y := FTop;
517 end;
518 if x + Width >= FRight then
519 Width := FRight - x;
520 if y + Height >= FBottom then
521 Height := FBottom - y;
522 if (Width <= 0) or (Height <= 0) then
523 exit;
524
525 DpiBitCanvas(FOutput.Canvas, x, y, Width, Height, Src.Canvas, xSrc, ySrc, Rop);
526end;
527
528procedure TIsoMap.Sprite(HGr, xDst, yDst, Width, Height, xGr, yGr: integer);
529begin
530 BitBltBitmap(GrExt[HGr].Mask, xDst, yDst, Width, Height, xGr, yGr, SRCAND);
531 BitBltBitmap(GrExt[HGr].Data, xDst, yDst, Width, Height, xGr, yGr, SRCPAINT);
532end;
533
534procedure TIsoMap.TSprite(xDst, yDst, grix: integer;
535 PureBlack: boolean = false);
536var
537 Width, Height, xSrc, ySrc: integer;
538begin
539 Width := TSpriteSize[grix].Right - TSpriteSize[grix].Left;
540 Height := TSpriteSize[grix].Bottom - TSpriteSize[grix].Top;
541 xSrc := 1 + grix mod 9 * (xxt * 2 + 1) + TSpriteSize[grix].Left;
542 ySrc := 1 + grix div 9 * (yyt * 3 + 1) + TSpriteSize[grix].Top;
543 xDst := xDst + TSpriteSize[grix].Left;
544 yDst := yDst - yyt + TSpriteSize[grix].Top;
545 if xDst < FLeft then
546 begin
547 Width := Width - (FLeft - xDst);
548 xSrc := xSrc + (FLeft - xDst);
549 xDst := FLeft
550 end;
551 if yDst < FTop then
552 begin
553 Height := Height - (FTop - yDst);
554 ySrc := ySrc + (FTop - yDst);
555 yDst := FTop
556 end;
557 if xDst + Width >= FRight then
558 Width := FRight - xDst;
559 if yDst + Height >= FBottom then
560 Height := FBottom - yDst;
561 if (Width <= 0) or (Height <= 0) then
562 exit;
563
564 DpiBitCanvas(FOutput.Canvas, xDst, yDst, Width, Height, MaskCanvas, xSrc, ySrc, SRCAND);
565 if not PureBlack then
566 DpiBitCanvas(FOutput.Canvas, xDst, yDst, Width, Height, DataCanvas, xSrc, ySrc, SRCPAINT);
567end;
568
569procedure TIsoMap.PaintUnit(x, y: integer; const UnitInfo: TUnitInfo;
570 Status: integer);
571var
572 xsh, ysh, xGr, yGr, j, mixShow: integer;
573begin
574 with UnitInfo do
575 if (Owner = me) or (emix <> $FFFF) then
576 begin
577 if Job = jCity then
578 mixShow := -1 // building site
579 else
580 mixShow := mix;
581 if (Tribe[Owner].ModelPicture[mixShow].HGr = 0) and
582 (@OnInitEnemyModel <> nil) then
583 if not OnInitEnemyModel(emix) then
584 exit;
585 xsh := Tribe[Owner].ModelPicture[mixShow].xShield;
586 ysh := Tribe[Owner].ModelPicture[mixShow].yShield;
587{$IFNDEF SCR} if Status and usStay <> 0 then
588 j := 19
589 else if Status and usRecover <> 0 then
590 j := 16
591 else if Status and (usGoto or usEnhance) = usGoto or usEnhance then
592 j := 18
593 else if Status and usEnhance <> 0 then
594 j := 17
595 else if Status and usGoto <> 0 then
596 j := 20
597 else {$ENDIF} if Job = jCity then
598 j := jNone
599 else
600 j := Job;
601 if Flags and unMulti <> 0 then
602 Sprite(Tribe[Owner].symHGr, x + xsh - 1 + 4, y + ysh - 2, 14, 12,
603 33 + Tribe[Owner].sympix mod 10 * 65,
604 1 + Tribe[Owner].sympix div 10 * 49);
605 Sprite(Tribe[Owner].symHGr, x + xsh - 1, y + ysh - 2, 14, 12,
606 18 + Tribe[Owner].sympix mod 10 * 65,
607 1 + Tribe[Owner].sympix div 10 * 49);
608 FillRect(x + xsh, y + ysh + 5, 1 + Health * 11 div 100, 3,
609 ColorOfHealth(Health));
610 if j > 0 then
611 begin
612 xGr := 121 + j mod 7 * 9;
613 yGr := 1 + j div 7 * 9;
614 BitBltBitmap(GrExt[HGrSystem].Mask, x + xsh + 3, y + ysh + 9, 8, 8, xGr,
615 yGr, SRCAND);
616 Sprite(HGrSystem, x + xsh + 2, y + ysh + 8, 8, 8, xGr, yGr);
617 end;
618 with Tribe[Owner].ModelPicture[mixShow] do
619 Sprite(HGr, x, y, 64, 48, pix mod 10 * 65 + 1, pix div 10 * 49 + 1);
620 if Flags and unFortified <> 0 then
621 begin
622 { DataCanvas:=GrExt[HGrTerrain].Data.Canvas;
623 MaskCanvas:=GrExt[HGrTerrain].Mask.Canvas;
624 TSprite(x,y+16,12*9+7); }
625 Sprite(HGrStdUnits, x, y, xxu * 2, yyu * 2, 1 + 6 * (xxu * 2 + 1), 1);
626 end;
627 end;
628end; { PaintUnit }
629
630procedure TIsoMap.PaintCity(x, y: integer; const CityInfo: TCityInfo;
631 accessory: boolean);
632var
633 age, cHGr, cpix, xGr, xShield, yShield, LabelTextColor, LabelLength: integer;
634 cpic: TCityPicture;
635 s: string;
636begin
637 age := GetAge(CityInfo.Owner);
638 if CityInfo.size < 5 then
639 xGr := 0
640 else if CityInfo.size < 9 then
641 xGr := 1
642 else if CityInfo.size < 13 then
643 xGr := 2
644 else
645 xGr := 3;
646 Tribe[CityInfo.Owner].InitAge(age);
647 if age < 2 then
648 begin
649 cHGr := Tribe[CityInfo.Owner].cHGr;
650 cpix := Tribe[CityInfo.Owner].cpix;
651 if (ciWalled and CityInfo.Flags = 0) or
652 (GrExt[cHGr].Data.Canvas.Pixels[(xGr + 4) * 65, cpix * 49 + 48] = $00FFFF)
653 then
654 Sprite(cHGr, x - xxc, y - 2 * yyc, xxc * 2, yyc * 3,
655 xGr * (xxc * 2 + 1) + 1, 1 + cpix * (yyc * 3 + 1));
656 if ciWalled and CityInfo.Flags <> 0 then
657 Sprite(cHGr, x - xxc, y - 2 * yyc, xxc * 2, yyc * 3,
658 (xGr + 4) * (xxc * 2 + 1) + 1, 1 + cpix * (yyc * 3 + 1));
659 end
660 else
661 begin
662 if ciWalled and CityInfo.Flags <> 0 then
663 Sprite(HGrCities, x - xxt, y - 2 * yyt, 2 * xxt, 3 * yyt,
664 (xGr + 4) * (2 * xxt + 1) + 1, 1 + (age - 2) * (3 * yyt + 1))
665 else
666 Sprite(HGrCities, x - xxt, y - 2 * yyt, 2 * xxt, 3 * yyt,
667 xGr * (2 * xxt + 1) + 1, 1 + (age - 2) * (3 * yyt + 1));
668 end;
669
670 if not accessory then
671 exit;
672
673 { if ciCapital and CityInfo.Flags<>0 then
674 Sprite(Tribe[CityInfo.Owner].symHGr,x+cpic.xf,y-13+cpic.yf,13,14,
675 1+Tribe[CityInfo.Owner].sympix mod 10 *65,
676 1+Tribe[CityInfo.Owner].sympix div 10 *49); {capital -- paint flag }
677
678 if MyMap[CityInfo.Loc] and fObserved <> 0 then
679 begin
680 if age < 2 then
681 begin
682 cpic := Tribe[CityInfo.Owner].CityPicture[xGr];
683 xShield := x - xxc + cpic.xShield;
684 yShield := y - 2 * yyc + cpic.yShield;
685 end
686 else
687 begin
688 cpic := CitiesPictures[age, xGr];
689 xShield := x - xxt + cpic.xShield;
690 yShield := y - 2 * yyt + cpic.yShield;
691 end;
692 s := IntToStr(CityInfo.size);
693 LabelLength := FOutput.Canvas.TextWidth(s);
694 FillRect(xShield, yShield, LabelLength + 4, 16, $000000);
695 if MyMap[CityInfo.Loc] and (fUnit or fObserved) = fObserved then
696 // empty city
697 LabelTextColor := Tribe[CityInfo.Owner].Color
698 else
699 begin
700 FillRect(xShield + 1, yShield + 1, LabelLength + 2, 14,
701 Tribe[CityInfo.Owner].Color);
702 LabelTextColor := $000000;
703 end;
704 Textout(xShield + 2, yShield - 1, LabelTextColor, s);
705 end
706end; { PaintCity }
707
708function PoleTile(Loc: integer): integer;
709begin { virtual pole tile }
710 result := fUNKNOWN;
711 if Loc < -2 * G.lx then
712 else if Loc < -G.lx then
713 begin
714 if (MyMap[dLoc(Loc, 0, 2)] and fTerrain <> fUNKNOWN) and
715 (MyMap[dLoc(Loc, -2, 2)] and fTerrain <> fUNKNOWN) and
716 (MyMap[dLoc(Loc, 2, 2)] and fTerrain <> fUNKNOWN) then
717 result := fArctic;
718 if (MyMap[dLoc(Loc, 0, 2)] and fObserved <> 0) and
719 (MyMap[dLoc(Loc, -2, 2)] and fObserved <> 0) and
720 (MyMap[dLoc(Loc, 2, 2)] and fObserved <> 0) then
721 result := result or fObserved
722 end
723 else if Loc < 0 then
724 begin
725 if (MyMap[dLoc(Loc, -1, 1)] and fTerrain <> fUNKNOWN) and
726 (MyMap[dLoc(Loc, 1, 1)] and fTerrain <> fUNKNOWN) then
727 result := fArctic;
728 if (MyMap[dLoc(Loc, -1, 1)] and fObserved <> 0) and
729 (MyMap[dLoc(Loc, 1, 1)] and fObserved <> 0) then
730 result := result or fObserved
731 end
732 else if Loc < G.lx * (G.ly + 1) then
733 begin
734 if (MyMap[dLoc(Loc, -1, -1)] and fTerrain <> fUNKNOWN) and
735 (MyMap[dLoc(Loc, 1, -1)] and fTerrain <> fUNKNOWN) then
736 result := fArctic;
737 if (MyMap[dLoc(Loc, -1, -1)] and fObserved <> 0) and
738 (MyMap[dLoc(Loc, 1, -1)] and fObserved <> 0) then
739 result := result or fObserved
740 end
741 else if Loc < G.lx * (G.ly + 2) then
742 begin
743 if (MyMap[dLoc(Loc, 0, -2)] and fTerrain <> fUNKNOWN) and
744 (MyMap[dLoc(Loc, -2, -2)] and fTerrain <> fUNKNOWN) and
745 (MyMap[dLoc(Loc, 2, -2)] and fTerrain <> fUNKNOWN) then
746 result := fArctic;
747 if (MyMap[dLoc(Loc, 0, -2)] and fObserved <> 0) and
748 (MyMap[dLoc(Loc, -2, -2)] and fObserved <> 0) and
749 (MyMap[dLoc(Loc, 2, -2)] and fObserved <> 0) then
750 result := result or fObserved
751 end
752end;
753
754const
755 Dirx: array [0 .. 7] of integer = (1, 2, 1, 0, -1, -2, -1, 0);
756 Diry: array [0 .. 7] of integer = (-1, 0, 1, 2, 1, 0, -1, -2);
757
758function TIsoMap.Connection4(Loc, Mask, Value: integer): integer;
759begin
760 result := 0;
761 if dLoc(Loc, 1, -1) >= 0 then
762 begin
763 if MyMap[dLoc(Loc, 1, -1)] and Mask = Cardinal(Value) then
764 inc(result, 1);
765 if MyMap[dLoc(Loc, -1, -1)] and Mask = Cardinal(Value) then
766 inc(result, 8);
767 end;
768 if dLoc(Loc, 1, 1) < G.lx * G.ly then
769 begin
770 if MyMap[dLoc(Loc, 1, 1)] and Mask = Cardinal(Value) then
771 inc(result, 2);
772 if MyMap[dLoc(Loc, -1, 1)] and Mask = Cardinal(Value) then
773 inc(result, 4);
774 end
775end;
776
777function TIsoMap.Connection8(Loc, Mask: integer): integer;
778var
779 Dir, ConnLoc: integer;
780begin
781 result := 0;
782 for Dir := 0 to 7 do
783 begin
784 ConnLoc := dLoc(Loc, Dirx[Dir], Diry[Dir]);
785 if (ConnLoc >= 0) and (ConnLoc < G.lx * G.ly) and
786 (MyMap[ConnLoc] and Mask <> 0) then
787 inc(result, 1 shl Dir);
788 end
789end;
790
791function TIsoMap.OceanConnection(Loc: integer): integer;
792var
793 Dir, ConnLoc: integer;
794begin
795 result := 0;
796 for Dir := 0 to 7 do
797 begin
798 ConnLoc := dLoc(Loc, Dirx[Dir], Diry[Dir]);
799 if (ConnLoc < 0) or (ConnLoc >= G.lx * G.ly) or
800 ((MyMap[ConnLoc] - 2) and fTerrain < 13) then
801 inc(result, 1 shl Dir);
802 end
803end;
804
805procedure TIsoMap.PaintShore(x, y, Loc: integer);
806var
807 Conn, Tile: integer;
808begin
809 if (y <= FTop - yyt * 2) or (y > FBottom) or (x <= FLeft - xxt * 2) or
810 (x > FRight) then
811 exit;
812 if (Loc < 0) or (Loc >= G.lx * G.ly) then
813 exit;
814 Tile := MyMap[Loc];
815 if Tile and fTerrain >= fGrass then
816 exit;
817 Conn := OceanConnection(Loc);
818 if Conn = 0 then
819 exit;
820
821 BitBltBitmap(GrExt[HGrTerrain].Data, x + xxt div 2, y, xxt, yyt,
822 1 + (Conn shr 6 + Conn and 1 shl 2) * (xxt * 2 + 1),
823 1 + yyt + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
824 BitBltBitmap(GrExt[HGrTerrain].Data, x + xxt, y + yyt div 2, xxt, yyt,
825 1 + (Conn and 7) * (xxt * 2 + 1) + xxt,
826 1 + yyt * 2 + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
827 BitBltBitmap(GrExt[HGrTerrain].Data, x + xxt div 2, y + yyt, xxt, yyt,
828 1 + (Conn shr 2 and 7) * (xxt * 2 + 1) + xxt,
829 1 + yyt + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
830 BitBltBitmap(GrExt[HGrTerrain].Data, x, y + yyt div 2, xxt, yyt,
831 1 + (Conn shr 4 and 7) * (xxt * 2 + 1),
832 1 + yyt * 2 + (16 + Tile and fTerrain) * (yyt * 3 + 1), SRCPAINT);
833 Conn := Connection4(Loc, fTerrain, fUNKNOWN); { dither to black }
834 if Conn and 1 <> 0 then
835 BitBltBitmap(GrExt[HGrTerrain].Mask, x + xxt, y, xxt, yyt, 1 + 7 * (xxt * 2 + 1) +
836 xxt, 1 + yyt + 15 * (yyt * 3 + 1), SRCAND);
837 if Conn and 2 <> 0 then
838 BitBltBitmap(GrExt[HGrTerrain].Mask, x + xxt, y + yyt, xxt, yyt,
839 1 + 7 * (xxt * 2 + 1) + xxt, 1 + yyt * 2 + 15 * (yyt * 3 + 1), SRCAND);
840 if Conn and 4 <> 0 then
841 BitBltBitmap(GrExt[HGrTerrain].Mask, x, y + yyt, xxt, yyt, 1 + 7 * (xxt * 2 + 1),
842 1 + yyt * 2 + 15 * (yyt * 3 + 1), SRCAND);
843 if Conn and 8 <> 0 then
844 BitBltBitmap(GrExt[HGrTerrain].Mask, x, y, xxt, yyt, 1 + 7 * (xxt * 2 + 1),
845 1 + yyt + 15 * (yyt * 3 + 1), SRCAND);
846end;
847
848procedure TIsoMap.PaintTileExtraTerrain(x, y, Loc: integer);
849var
850 Dir, Conn, RRConn, yGr, Tile, yLoc: integer;
851begin
852 if (Loc < 0) or (Loc >= G.lx * G.ly) or (y <= -yyt * 2) or
853 (y > FOutput.Height) or (x <= -xxt * 2) or (x > FOutput.Width) then
854 exit;
855 Tile := MyMap[Loc];
856 if Tile and fTerrain = fForest then
857 begin
858 yLoc := Loc div G.lx;
859 if IsJungle(yLoc) then
860 yGr := spJungle
861 else
862 yGr := spForest;
863 Conn := Connection4(Loc, fTerrain, Tile and fTerrain);
864 if (yLoc = (G.ly - 2) div 4) or (G.ly - 1 - yLoc = (G.ly + 2) div 4) then
865 Conn := Conn and not 6 // no connection to south
866 else if (yLoc = (G.ly + 2) div 4) or (G.ly - 1 - yLoc = (G.ly - 2) div 4)
867 then
868 Conn := Conn and not 9; // no connection to north
869 TSprite(x, y, yGr + Conn mod 8 + (Conn div 8) * TerrainIconCols);
870 end
871 else if Tile and fTerrain in [fHills, fMountains, fForest] then
872 begin
873 yGr := 3 + 2 * (Tile and fTerrain - fForest);
874 Conn := Connection4(Loc, fTerrain, Tile and fTerrain);
875 TSprite(x, y, Conn mod 8 + (yGr + Conn div 8) * TerrainIconCols);
876 end
877 else if Tile and fDeadLands <> 0 then
878 TSprite(x, y, spRow2);
879
880 if ShowObjects then
881 begin
882 if Tile and fTerImp = tiFarm then
883 TSprite(x, y, spFarmLand)
884 else if Tile and fTerImp = tiIrrigation then
885 TSprite(x, y, spIrrigation);
886 end;
887 if Tile and fRiver <> 0 then
888 begin
889 Conn := Connection4(Loc, fRiver, fRiver) or
890 Connection4(Loc, fTerrain, fShore) or Connection4(Loc, fTerrain,
891 fUNKNOWN);
892 TSprite(x, y, spRiver + Conn mod 8 + (Conn div 8) * TerrainIconCols);
893 end;
894
895 if Tile and fTerrain < fGrass then
896 begin
897 Conn := Connection4(Loc, fRiver, fRiver);
898 for Dir := 0 to 3 do
899 if Conn and (1 shl Dir) <> 0 then { river mouths }
900 TSprite(x, y, spRiverMouths + Dir);
901 if ShowObjects then
902 begin
903 Conn := Connection8(Loc, fCanal);
904 for Dir := 0 to 7 do
905 if Conn and (1 shl Dir) <> 0 then { canal mouths }
906 TSprite(x, y, spCanalMouths + 1 + Dir);
907 end
908 end;
909
910 if ShowObjects then
911 begin
912 if (Tile and fCanal <> 0) or (Tile and fCity <> 0) then
913 begin // paint canal connections
914 Conn := Connection8(Loc, fCanal or fCity);
915 if Tile and fCanal <> 0 then
916 Conn := Conn or ($FF - OceanConnection(Loc));
917 if Conn = 0 then
918 begin
919 if Tile and fCanal <> 0 then
920 TSprite(x, y, spCanal)
921 end
922 else
923 for Dir := 0 to 7 do
924 if (1 shl Dir) and Conn <> 0 then
925 TSprite(x, y, spCanal + 1 + Dir);
926 end;
927 if Tile and (fRR or fCity) <> 0 then
928 RRConn := Connection8(Loc, fRR or fCity)
929 else
930 RRConn := 0;
931 if Tile and (fRoad or fRR or fCity) <> 0 then
932 begin // paint road connections
933 Conn := Connection8(Loc, fRoad or fRR or fCity) and not RRConn;
934 if (Conn = 0) and (Tile and (fRR or fCity) = 0) then
935 TSprite(x, y, spRoad)
936 else if Conn > 0 then
937 for Dir := 0 to 7 do
938 if (1 shl Dir) and Conn <> 0 then
939 TSprite(x, y, spRoad + 1 + Dir);
940 end;
941 // paint railroad connections
942 if (Tile and fRR <> 0) and (RRConn = 0) then
943 TSprite(x, y, spRailRoad)
944 else if RRConn > 0 then
945 for Dir := 0 to 7 do
946 if (1 shl Dir) and RRConn <> 0 then
947 TSprite(x, y, spRailRoad + 1 + Dir);
948 end;
949end;
950
951// (x,y) is top left pixel of (2*xxt,3*yyt) rectangle
952procedure TIsoMap.PaintTileObjects(x, y, Loc, CityLoc, CityOwner: integer;
953 UseBlink: boolean);
954var
955 p1, p2, uix, cix, dy, Loc1, Tile, Multi, Destination: integer;
956 CityInfo: TCityInfo;
957 UnitInfo: TUnitInfo;
958 fog: boolean;
959 SpecialRow: Integer;
960 SpecialCol: Integer;
961
962 procedure NameCity;
963 var
964 cix, xs, w: integer;
965 BehindCityInfo: TCityInfo;
966 s: string;
967 IsCapital: boolean;
968 begin
969 BehindCityInfo.Loc := Loc - 2 * G.lx;
970 if ShowCityNames and (Options and (1 shl moEditMode) = 0) and
971 (BehindCityInfo.Loc >= 0) and (BehindCityInfo.Loc < G.lx * G.ly) and
972 (MyMap[BehindCityInfo.Loc] and fCity <> 0) then
973 begin
974 GetCityInfo(BehindCityInfo.Loc, cix, BehindCityInfo);
975 IsCapital := BehindCityInfo.Flags and ciCapital <> 0;
976 { if Showuix and (cix>=0) then s:=IntToStr(cix)
977 else } s := CityName(BehindCityInfo.ID);
978 w := FOutput.Canvas.TextWidth(s);
979 xs := x + xxt - (w + 1) div 2;
980 if IsCapital then
981 FOutput.Canvas.Font.Style := FOutput.Canvas.Font.Style + [fsUnderline];
982 Textout(xs + 1, y - 9, $000000, s);
983 Textout(xs, y - 10, $FFFFFF, s);
984 if IsCapital then
985 FOutput.Canvas.Font.Style := FOutput.Canvas.Font.Style - [fsUnderline];
986 end;
987 end;
988
989 procedure ShowSpacePort;
990 begin
991 if ShowObjects and (Options and (1 shl moEditMode) = 0) and
992 (Tile and fCity <> 0) and (CityInfo.Flags and ciSpacePort <> 0) then
993 TSprite(x + xxt, y - 6, spSpacePort);
994 end;
995
996 procedure PaintBorder;
997 var
998 dx, dy: integer;
999 PixelPtr: TPixelPointer;
1000 begin
1001 if ShowBorder and (Loc >= 0) and (Loc < G.lx * G.ly) and
1002 (Tile and fTerrain <> fUNKNOWN) then
1003 begin
1004 p1 := MyRO.Territory[Loc];
1005 if (p1 >= 0) and (ShowMyBorder or (p1 <> me)) then
1006 begin
1007 if BordersOK and (1 shl p1) = 0 then
1008 begin
1009 // Clearing before BitBltBitmap SRCCOPY shouldn't be neccesary but for some
1010 // reason without it code works different then under Delphi
1011 Borders.Canvas.FillRect(Bounds(0, p1 * (yyt * 2), xxt * 2, yyt * 2));
1012
1013 DpiBitCanvas(Borders.Canvas, 0, p1 * (yyt * 2), xxt * 2,
1014 yyt * 2, GrExt[HGrTerrain].Data.Canvas,
1015 1 + 8 * (xxt * 2 + 1), 1 + yyt + 16 * (yyt * 3 + 1));
1016 Borders.BeginUpdate;
1017 for dy := 0 to yyt * 2 - 1 do
1018 begin
1019 PixelPtr := PixelPointer(Borders, 0, p1 * (yyt * 2) + dy);
1020 for dx := 0 to xxt * 2 - 1 do begin
1021 if PixelPtr.Pixel^.B = 99 then begin
1022 PixelPtr.Pixel^.B := Tribe[p1].Color shr 16 and $FF;
1023 PixelPtr.Pixel^.G := Tribe[p1].Color shr 8 and $FF;
1024 PixelPtr.Pixel^.R := Tribe[p1].Color and $FF;
1025 end;
1026 PixelPtr.NextPixel;
1027 end;
1028 end;
1029 Borders.EndUpdate;
1030 BordersOK := BordersOK or 1 shl p1;
1031 end;
1032 for dy := 0 to 1 do
1033 for dx := 0 to 1 do
1034 begin
1035 Loc1 := dLoc(Loc, dx * 2 - 1, dy * 2 - 1);
1036 begin
1037 if (Loc1 < 0) or (Loc1 >= G.lx * G.ly) then
1038 p2 := -1
1039 else if MyMap[Loc1] and fTerrain = fUNKNOWN then
1040 p2 := p1
1041 else
1042 p2 := MyRO.Territory[Loc1];
1043 if p2 <> p1 then
1044 begin
1045 BitBltBitmap(GrExt[HGrTerrain].Mask, x + dx * xxt, y + dy * yyt, xxt,
1046 yyt, 1 + 8 * (xxt * 2 + 1) + dx * xxt,
1047 1 + yyt + 16 * (yyt * 3 + 1) + dy * yyt, SRCAND);
1048 BitBltBitmap(Borders, x + dx * xxt, y + dy * yyt, xxt, yyt, dx * xxt,
1049 p1 * (yyt * 2) + dy * yyt, SRCPAINT);
1050 end
1051 end;
1052 end
1053 end
1054 end;
1055 end;
1056
1057begin
1058 if (Loc < 0) or (Loc >= G.lx * G.ly) then
1059 Tile := PoleTile(Loc)
1060 else
1061 Tile := MyMap[Loc];
1062 if ShowObjects and (Options and (1 shl moEditMode) = 0) and
1063 (Tile and fCity <> 0) then
1064 GetCityInfo(Loc, cix, CityInfo);
1065 if (y <= FTop - yyt * 2) or (y > FBottom) or (x <= FLeft - xxt * 2) or
1066 (x > FRight) then
1067 begin
1068 NameCity;
1069 ShowSpacePort;
1070 exit;
1071 end;
1072 if Tile and fTerrain = fUNKNOWN then
1073 begin
1074 NameCity;
1075 ShowSpacePort;
1076 exit
1077 end; { square not discovered }
1078
1079 if not(FoW and (Tile and fObserved = 0)) then
1080 PaintBorder;
1081
1082 if (Loc >= 0) and (Loc < G.lx * G.ly) and (Loc = FAdviceLoc) then
1083 TSprite(x, y, spPlain);
1084
1085 if (Loc >= 0) and (Loc < G.lx * G.ly) and (Tile and fSpecial <> 0)
1086 then { special resources }
1087 begin
1088 dy := Loc div G.lx;
1089 SpecialCol := Tile and fTerrain;
1090 SpecialRow := Tile and fSpecial shr 5;
1091 if SpecialCol < fForest then
1092 TSprite(x, y, SpecialCol + SpecialRow * TerrainIconCols)
1093 else if (SpecialCol = fForest) and IsJungle(dy) then
1094 TSprite(x, y, spJungle - 1 + SpecialRow * TerrainIconCols)
1095 else
1096 TSprite(x, y, spForest - 1 + ((SpecialCol - fForest) * 2 + SpecialRow) * TerrainIconCols);
1097 end;
1098
1099 if ShowObjects then
1100 begin
1101 if Tile and fTerImp = tiMine then
1102 TSprite(x, y, spMine);
1103 if Tile and fTerImp = tiBase then
1104 TSprite(x, y, spBase);
1105 if Tile and fPoll <> 0 then
1106 TSprite(x, y, spPollution);
1107 if Tile and fTerImp = tiFort then
1108 begin
1109 TSprite(x, y, spFortBack);
1110 if Tile and fObserved = 0 then
1111 TSprite(x, y, spFortFront);
1112 end;
1113 end;
1114 if (Tile and fDeadLands) <> 0 then
1115 TSprite(x, y, spMinerals + (Tile shr 25 and 3) * TerrainIconCols);
1116
1117 if Options and (1 shl moEditMode) <> 0 then
1118 fog := (Loc < 0) or (Loc >= G.lx * G.ly)
1119 // else if CityLoc>=0 then
1120 // fog:= (Loc<0) or (Loc>=G.lx*G.ly) or (Distance(Loc,CityLoc)>5)
1121 else if ShowGrWall then
1122 fog := Tile and fGrWall = 0
1123 else
1124 fog := FoW and (Tile and fObserved = 0);
1125 if fog and ShowObjects then
1126 if Loc < -G.lx then
1127 Sprite(HGrTerrain, x, y + yyt, xxt * 2, yyt, 1 + 6 * (xxt * 2 + 1),
1128 1 + yyt * 2 + 15 * (yyt * 3 + 1))
1129 else if Loc >= G.lx * (G.ly + 1) then
1130 Sprite(HGrTerrain, x, y, xxt * 2, yyt, 1 + 6 * (xxt * 2 + 1),
1131 1 + yyt + 15 * (yyt * 3 + 1))
1132 else
1133 TSprite(x, y, spGrid, xxt <> 33);
1134
1135 if FoW and (Tile and fObserved = 0) then
1136 PaintBorder;
1137
1138{$IFNDEF SCR}
1139 // paint goto destination mark
1140 if DestinationMarkON and (CityOwner < 0) and (UnFocus >= 0) and
1141 (MyUn[UnFocus].Status and usGoto <> 0) then
1142 begin
1143 Destination := MyUn[UnFocus].Status shr 16;
1144 if (Destination = Loc) and (Destination <> MyUn[UnFocus].Loc) then
1145 if not UseBlink or BlinkOn then
1146 TSprite(x, y, spBlink1)
1147 else
1148 TSprite(x, y, spBlink2)
1149 end;
1150{$ENDIF}
1151 if Options and (1 shl moEditMode) <> 0 then
1152 begin
1153 if Tile and fPrefStartPos <> 0 then
1154 TSprite(x, y, spPrefStartPos)
1155 else if Tile and fStartPos <> 0 then
1156 TSprite(x, y, spStartPos);
1157 end
1158 else if ShowObjects then
1159 begin
1160 { if (CityLoc<0) and (UnFocus>=0) and (Loc=MyUn[UnFocus].Loc) then
1161 if BlinkOn then TSprite(x,y,8+9*0)
1162 else TSprite(x,y,8+9*1); }
1163
1164 NameCity;
1165 ShowSpacePort;
1166 if Tile and fCity <> 0 then
1167 PaintCity(x + xxt, y + yyt, CityInfo, CityOwner < 0);
1168
1169 if (Tile and fUnit <> 0) and (Loc <> AttLoc) and
1170 ((Loc <> DefLoc) or (DefHealth <> 0))
1171{$IFNDEF SCR} and ((CityOwner >= 0) or (UnFocus < 0) or not UseBlink or
1172 BlinkOn or (Loc <> MyUn[UnFocus].Loc)){$ENDIF}
1173 and ((Tile and fCity <> fCity) or (Loc = DefLoc)
1174{$IFNDEF SCR} or (not UseBlink or BlinkOn) and (UnFocus >= 0) and
1175 (Loc = MyUn[UnFocus].Loc){$ENDIF}) then
1176 begin { unit }
1177 GetUnitInfo(Loc, uix, UnitInfo);
1178 if (Loc = DefLoc) and (DefHealth >= 0) then
1179 UnitInfo.Health := DefHealth;
1180 if (UnitInfo.Owner <> CityOwner) and
1181 not((CityOwner = me) and (MyRO.Treaty[UnitInfo.Owner] = trAlliance))
1182 then
1183{$IFNDEF SCR} if (UnFocus >= 0) and (Loc = MyUn[UnFocus].Loc) then { active unit }
1184 begin
1185 Multi := UnitInfo.Flags and unMulti;
1186 MakeUnitInfo(me, MyUn[UnFocus], UnitInfo);
1187 UnitInfo.Flags := UnitInfo.Flags or Multi;
1188 PaintUnit(x + (xxt - xxu), y + (yyt - yyu_anchor), UnitInfo,
1189 MyUn[UnFocus].Status);
1190 end
1191 else if UnitInfo.Owner = me then
1192 begin
1193 if ClientMode = cMovieTurn then
1194 PaintUnit(x + (xxt - xxu), y + (yyt - yyu_anchor), UnitInfo, 0)
1195 // status is not set with precise timing during loading
1196 else
1197 PaintUnit(x + (xxt - xxu), y + (yyt - yyu_anchor), UnitInfo,
1198 MyUn[uix].Status);
1199 // if Showuix then Textout(x+16,y+5,$80FF00,IntToStr(uix));
1200 end
1201 else {$ENDIF} PaintUnit(x + (xxt - xxu), y + (yyt - yyu_anchor), UnitInfo, 0);
1202 end
1203 else if Tile and fHiddenUnit <> 0 then
1204 Sprite(HGrStdUnits, x + (xxt - xxu), y + (yyt - yyu_anchor), xxu * 2,
1205 yyu * 2, 1 + 5 * (xxu * 2 + 1), 1)
1206 else if Tile and fStealthUnit <> 0 then
1207 Sprite(HGrStdUnits, x + (xxt - xxu), y + (yyt - yyu_anchor), xxu * 2,
1208 yyu * 2, 1 + 5 * (xxu * 2 + 1), 1 + 1 * (yyu * 2 + 1))
1209 end;
1210
1211 if ShowObjects and (Tile and fTerImp = tiFort) and (Tile and fObserved <> 0)
1212 then
1213 TSprite(x, y, spFortFront);
1214
1215 if (Loc >= 0) and (Loc < G.lx * G.ly) then
1216 if ShowLoc then
1217 Textout(x + xxt - 16, y + yyt - 9, $FFFF00, IntToStr(Loc))
1218 else if ShowDebug and (DebugMap <> nil) and (Loc >= 0) and
1219 (Loc < G.lx * G.ly) and (DebugMap[Loc] <> 0) then
1220 Textout(x + xxt - 16, y + yyt - 9, $00E0FF,
1221 IntToStr(integer(DebugMap[Loc])))
1222end; { PaintTileObjects }
1223
1224procedure TIsoMap.PaintGrid(x, y, nx, ny: integer);
1225
1226 procedure ClippedLine(dx0, dy0: integer; mirror: boolean);
1227 var
1228 x0, x1, dxmin, dymin, dxmax, dymax, n: integer;
1229 begin
1230 with FOutput.Canvas do
1231 begin
1232 dxmin := (FLeft - x) div xxt;
1233 dymin := (RealTop - y) div yyt;
1234 dxmax := (FRight - x - 1) div xxt + 1;
1235 dymax := (RealBottom - y - 1) div yyt + 1;
1236 n := dymax - dy0;
1237 if mirror then
1238 begin
1239 if dx0 - dxmin < n then
1240 n := dx0 - dxmin;
1241 if dx0 > dxmax then
1242 begin
1243 n := n - (dx0 - dxmax);
1244 dy0 := dy0 + (dx0 - dxmax);
1245 dx0 := dxmax
1246 end;
1247 if dy0 < dymin then
1248 begin
1249 n := n - (dymin - dy0);
1250 dx0 := dx0 - (dymin - dy0);
1251 dy0 := dymin
1252 end;
1253 end
1254 else
1255 begin
1256 if dxmax - dx0 < n then
1257 n := dxmax - dx0;
1258 if dx0 < dxmin then
1259 begin
1260 n := n - (dxmin - dx0);
1261 dy0 := dy0 + (dxmin - dx0);
1262 dx0 := dxmin
1263 end;
1264 if dy0 < dymin then
1265 begin
1266 n := n - (dymin - dy0);
1267 dx0 := dx0 + (dymin - dy0);
1268 dy0 := dymin
1269 end;
1270 end;
1271 if n <= 0 then
1272 exit;
1273 if mirror then
1274 begin
1275 x0 := x + dx0 * xxt - 1;
1276 x1 := x + (dx0 - n) * xxt - 1;
1277 end
1278 else
1279 begin
1280 x0 := x + dx0 * xxt;
1281 x1 := x + (dx0 + n) * xxt;
1282 end;
1283 moveto(x0, y + dy0 * yyt);
1284 lineto(x1, y + (dy0 + n) * yyt);
1285 end
1286 end;
1287
1288var
1289 i: integer;
1290begin
1291 FOutput.Canvas.pen.Color := $000000; // $FF shl (8*random(3));
1292 for i := 0 to nx div 2 do
1293 ClippedLine(i * 2, 0, false);
1294 for i := 1 to (nx + 1) div 2 do
1295 ClippedLine(i * 2, 0, true);
1296 for i := 0 to ny div 2 do
1297 begin
1298 ClippedLine(0, 2 * i + 2, false);
1299 ClippedLine(nx + 1, 2 * i + 1 + nx and 1, true);
1300 end;
1301end;
1302
1303function TIsoMap.IsShoreTile(Loc: integer): boolean;
1304const
1305 Dirx: array [0 .. 7] of integer = (1, 2, 1, 0, -1, -2, -1, 0);
1306 Diry: array [0 .. 7] of integer = (-1, 0, 1, 2, 1, 0, -1, -2);
1307var
1308 Dir, ConnLoc: integer;
1309begin
1310 result := false;
1311 for Dir := 0 to 7 do
1312 begin
1313 ConnLoc := dLoc(Loc, Dirx[Dir], Diry[Dir]);
1314 if (ConnLoc < 0) or (ConnLoc >= G.lx * G.ly) or
1315 ((MyMap[ConnLoc] - 2) and fTerrain < 13) then
1316 result := true
1317 end
1318end;
1319
1320procedure TIsoMap.MakeDark(Line: PPixelPointer; Length: Integer);
1321var
1322 I: Integer;
1323begin
1324 for I := 0 to Length - 1 do begin
1325 Line^.Pixel^.B := (Line^.Pixel^.B shr 1) and $7f;
1326 Line^.Pixel^.G := (Line^.Pixel^.G shr 1) and $7f;
1327 Line^.Pixel^.R := (Line^.Pixel^.R shr 1) and $7f;
1328 Line^.NextPixel;
1329 end;
1330end;
1331
1332procedure TIsoMap.ShadeOutside(x0, y0, x1, y1, xm, ym: integer);
1333const
1334 rShade = 3.75;
1335var
1336 y, wBright: integer;
1337 y_n, w_n: single;
1338 Line: TPixelPointer;
1339begin
1340 FOutput.BeginUpdate;
1341 for y := y0 to y1 - 1 do begin
1342 Line := PixelPointer(FOutput, 0, y);
1343 y_n := (y - ym) / yyt;
1344 if abs(y_n) < rShade then begin
1345 // Darken left and right parts of elipsis
1346 w_n := sqrt(sqr(rShade) - sqr(y_n));
1347 wBright := trunc(w_n * xxt + 0.5);
1348 Line.SetX(x0);
1349 MakeDark(@Line, xm - x0 - wBright);
1350 Line.SetX(xm + wBright);
1351 MakeDark(@Line, x1 - xm - wBright);
1352 end else begin
1353 // Darken entire line
1354 Line.SetX(x0);
1355 MakeDark(@Line, x1 - x0);
1356 end;
1357 end;
1358 FOutput.EndUpdate;
1359end;
1360
1361procedure TIsoMap.CityGrid(xm, ym: integer; CityAllowClick: Boolean);
1362var
1363 i: integer;
1364begin
1365 with FOutput.Canvas do
1366 begin
1367 if CityAllowClick then
1368 pen.Color := $FFFFFF
1369 else
1370 pen.Color := $000000;
1371 pen.Width := 1;
1372 for i := 0 to 3 do
1373 begin
1374 moveto(xm - xxt * (4 - i), ym + yyt * (1 + i));
1375 lineto(xm + xxt * (1 + i), ym - yyt * (4 - i));
1376 moveto(xm - xxt * (4 - i), ym - yyt * (1 + i));
1377 lineto(xm + xxt * (1 + i), ym + yyt * (4 - i));
1378 end;
1379 moveto(xm - xxt * 4, ym + yyt * 1);
1380 lineto(xm - xxt * 1, ym + yyt * 4);
1381 moveto(xm + xxt * 1, ym + yyt * 4);
1382 lineto(xm + xxt * 4, ym + yyt * 1);
1383 moveto(xm - xxt * 4, ym - yyt * 1);
1384 lineto(xm - xxt * 1, ym - yyt * 4);
1385 moveto(xm + xxt * 1, ym - yyt * 4);
1386 lineto(xm + xxt * 4, ym - yyt * 1);
1387 pen.Width := 1;
1388 end
1389end;
1390
1391procedure TIsoMap.Paint(x, y, Loc, nx, ny, CityLoc, CityOwner: integer;
1392 UseBlink: boolean; CityAllowClick: boolean);
1393var
1394 dx, dy, xm, ym, ALoc, BLoc, ATer, BTer, Aix, bix: integer;
1395begin
1396 FoW := true;
1397 ShowLoc := Options and (1 shl moLocCodes) <> 0;
1398 ShowDebug := pDebugMap >= 0;
1399 ShowObjects := (CityOwner >= 0) or (Options and (1 shl moBareTerrain) = 0);
1400 ShowCityNames := ShowObjects and (CityOwner < 0) and
1401 (Options and (1 shl moCityNames) <> 0);
1402 ShowBorder := true;
1403 ShowMyBorder := CityOwner < 0;
1404 ShowGrWall := (CityOwner < 0) and (Options and (1 shl moGreatWall) <> 0);
1405 if ShowDebug then
1406 Server(sGetDebugMap, me, pDebugMap, DebugMap)
1407 else
1408 DebugMap := nil;
1409 with FOutput.Canvas do
1410 begin
1411 RealTop := y - ((Loc + 12345 * G.lx) div G.lx - 12345) * yyt;
1412 RealBottom := y + (G.ly - ((Loc + 12345 * G.lx) div G.lx - 12345) +
1413 3) * yyt;
1414 Brush.Color := EmptySpaceColor;
1415 if RealTop > FTop then
1416 FillRect(Rect(FLeft, FTop, FRight, RealTop))
1417 else
1418 RealTop := FTop;
1419 if RealBottom < FBottom then
1420 FillRect(Rect(FLeft, RealBottom, FRight, FBottom))
1421 else
1422 RealBottom := FBottom;
1423 Brush.Color := $000000;
1424 FillRect(Rect(FLeft, RealTop, FRight, RealBottom));
1425 Brush.Style := bsClear;
1426 end;
1427
1428 for dy := 0 to ny + 1 do
1429 if (Loc + dy * G.lx >= 0) and (Loc + (dy - 3) * G.lx < G.lx * G.ly) then
1430 for dx := 0 to nx do
1431 begin
1432 ALoc := dLoc(Loc, dx - (dy + dx) and 1, dy - 2);
1433 BLoc := dLoc(Loc, dx - (dy + dx + 1) and 1, dy - 1);
1434 if (ALoc < 0) or (ALoc >= G.lx * G.ly) then
1435 ATer := PoleTile(ALoc) and fTerrain
1436 else
1437 ATer := MyMap[ALoc] and fTerrain;
1438 if (BLoc < 0) or (BLoc >= G.lx * G.ly) then
1439 BTer := PoleTile(BLoc) and fTerrain
1440 else
1441 BTer := MyMap[BLoc] and fTerrain;
1442
1443 if (ATer <> fUNKNOWN) or (BTer <> fUNKNOWN) then
1444 if ((ATer < fGrass) or (ATer = fUNKNOWN)) and
1445 ((BTer < fGrass) or (BTer = fUNKNOWN)) then
1446 begin
1447 if ATer = fUNKNOWN then
1448 Aix := 0
1449 else if IsShoreTile(ALoc) then
1450 if ATer = fOcean then
1451 Aix := -1
1452 else
1453 Aix := 1
1454 else
1455 Aix := ATer + 2;
1456 if BTer = fUNKNOWN then
1457 bix := 0
1458 else if IsShoreTile(BLoc) then
1459 if BTer = fOcean then
1460 bix := -1
1461 else
1462 bix := 1
1463 else
1464 bix := BTer + 2;
1465 if (Aix > 1) or (bix > 1) then
1466 begin
1467 if Aix = -1 then
1468 if bix = fOcean + 2 then
1469 begin
1470 Aix := 0;
1471 bix := 0
1472 end
1473 else
1474 begin
1475 Aix := 0;
1476 bix := 1
1477 end
1478 else if bix = -1 then
1479 if Aix = fOcean + 2 then
1480 begin
1481 Aix := 1;
1482 bix := 1
1483 end
1484 else
1485 begin
1486 Aix := 1;
1487 bix := 0
1488 end;
1489 BitBltBitmap(OceanPatch, x + dx * xxt, y + dy * yyt, xxt, yyt,
1490 Aix * (xxt * 2) + (dx + dy + 1) and 1 * xxt, bix * yyt, SRCCOPY)
1491 end
1492 end
1493 else
1494 begin
1495 if ATer = fUNKNOWN then
1496 Aix := 0
1497 else if (ALoc >= 0) and (ALoc < G.lx * G.ly) and
1498 (MyMap[ALoc] and fDeadLands <> 0) then
1499 Aix := -2
1500 else if ATer = fOcean then
1501 Aix := -1
1502 else if ATer = fShore then
1503 Aix := 1
1504 else if ATer >= fForest then
1505 Aix := 8
1506 else
1507 Aix := ATer;
1508 if BTer = fUNKNOWN then
1509 bix := 0
1510 else if (BLoc >= 0) and (BLoc < G.lx * G.ly) and
1511 (MyMap[BLoc] and fDeadLands <> 0) then
1512 bix := -2
1513 else if BTer = fOcean then
1514 bix := -1
1515 else if BTer = fShore then
1516 bix := 1
1517 else if BTer >= fForest then
1518 bix := 8
1519 else
1520 bix := BTer;
1521 if (Aix = -2) and (bix = -2) then
1522 begin
1523 Aix := fDesert;
1524 bix := fDesert
1525 end
1526 else if Aix = -2 then
1527 if bix < 2 then
1528 Aix := 8
1529 else
1530 Aix := bix
1531 else if bix = -2 then
1532 if Aix < 2 then
1533 bix := 8
1534 else
1535 bix := Aix;
1536 if Aix = -1 then
1537 BitBltBitmap(GrExt[HGrTerrain].Data, x + dx * xxt, y + dy * yyt, xxt,
1538 yyt, 1 + 6 * (xxt * 2 + 1) + (dx + dy + 1) and 1 * xxt, 1 + yyt,
1539 SRCCOPY) // arctic <-> ocean
1540 else if bix = -1 then
1541 BitBltBitmap(GrExt[HGrTerrain].Data, x + dx * xxt, y + dy * yyt, xxt,
1542 yyt, 1 + 6 * (xxt * 2 + 1) + xxt - (dx + dy + 1) and 1 * xxt,
1543 1 + yyt * 2, SRCCOPY) // arctic <-> ocean
1544 else
1545 BitBltBitmap(LandPatch, x + dx * xxt, y + dy * yyt, xxt, yyt,
1546 Aix * (xxt * 2) + (dx + dy + 1) and 1 * xxt, bix * yyt, SRCCOPY)
1547 end
1548 end;
1549
1550 DataCanvas := GrExt[HGrTerrain].Data.Canvas;
1551 MaskCanvas := GrExt[HGrTerrain].Mask.Canvas;
1552 for dy := -2 to ny + 1 do
1553 for dx := -1 to nx do
1554 if (dx + dy) and 1 = 0 then
1555 PaintShore(x + xxt * dx, y + yyt + yyt * dy, dLoc(Loc, dx, dy));
1556 for dy := -2 to ny + 1 do
1557 for dx := -1 to nx do
1558 if (dx + dy) and 1 = 0 then
1559 PaintTileExtraTerrain(x + xxt * dx, y + yyt + yyt * dy,
1560 dLoc(Loc, dx, dy));
1561 if CityOwner >= 0 then
1562 begin
1563 for dy := -2 to ny + 1 do
1564 for dx := -2 to nx + 1 do
1565 if (dx + dy) and 1 = 0 then
1566 begin
1567 ALoc := dLoc(Loc, dx, dy);
1568 if Distance(ALoc, CityLoc) > 5 then
1569 PaintTileObjects(x + xxt * dx, y + yyt + yyt * dy, ALoc, CityLoc,
1570 CityOwner, UseBlink);
1571 end;
1572 dx := ((CityLoc mod G.lx * 2 + CityLoc div G.lx and 1) -
1573 ((Loc + 666 * G.lx) mod G.lx * 2 + (Loc + 666 * G.lx) div G.lx and 1) + 3
1574 * G.lx) mod (2 * G.lx) - G.lx;
1575 dy := CityLoc div G.lx - (Loc + 666 * G.lx) div G.lx + 666;
1576 xm := x + (dx + 1) * xxt;
1577 ym := y + (dy + 1) * yyt + yyt;
1578 ShadeOutside(FLeft, FTop, FRight, FBottom, xm, ym);
1579 CityGrid(xm, ym, CityAllowClick);
1580 for dy := -2 to ny + 1 do
1581 for dx := -2 to nx + 1 do
1582 if (dx + dy) and 1 = 0 then
1583 begin
1584 ALoc := dLoc(Loc, dx, dy);
1585 if Distance(ALoc, CityLoc) <= 5 then
1586 PaintTileObjects(x + xxt * dx, y + yyt + yyt * dy, ALoc, CityLoc,
1587 CityOwner, UseBlink);
1588 end;
1589 end
1590 else
1591 begin
1592 if ShowLoc or (Options and (1 shl moEditMode) <> 0) or
1593 (Options and (1 shl moGrid) <> 0) then
1594 PaintGrid(x, y, nx, ny);
1595 for dy := -2 to ny + 1 do
1596 for dx := -2 to nx + 1 do
1597 if (dx + dy) and 1 = 0 then
1598 PaintTileObjects(x + xxt * dx, y + yyt + yyt * dy, dLoc(Loc, dx, dy),
1599 CityLoc, CityOwner, UseBlink);
1600 end;
1601
1602 // frame(FOutput.Canvas,x+1,y+1,x+nx*33+33-2,y+ny*16+32-2,$FFFF,$FFFF);
1603end; { Paint }
1604
1605procedure TIsoMap.AttackBegin(const ShowMove: TShowMove);
1606begin
1607 AttLoc := ShowMove.FromLoc;
1608 DefLoc := dLoc(AttLoc, ShowMove.dx, ShowMove.dy);
1609 DefHealth := -1;
1610end;
1611
1612procedure TIsoMap.AttackEffect(const ShowMove: TShowMove);
1613begin
1614 DefHealth := ShowMove.EndHealthDef;
1615end;
1616
1617procedure TIsoMap.AttackEnd;
1618begin
1619 AttLoc := -1;
1620 DefLoc := -1;
1621end;
1622
1623initialization
1624
1625NoMap := nil;
1626LandPatch := nil;
1627OceanPatch := nil;
1628Borders := nil;
1629
1630end.
Note: See TracBrowser for help on using the repository browser.