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