| 1 | unit Map;
|
|---|
| 2 |
|
|---|
| 3 | interface
|
|---|
| 4 |
|
|---|
| 5 | uses
|
|---|
| 6 | Classes, SysUtils;
|
|---|
| 7 |
|
|---|
| 8 | type
|
|---|
| 9 |
|
|---|
| 10 | { TMap }
|
|---|
| 11 |
|
|---|
| 12 | TMap = class
|
|---|
| 13 | private
|
|---|
| 14 | FSize: TPoint;
|
|---|
| 15 | function GetMapSize: Integer;
|
|---|
| 16 | procedure SetSize(AValue: TPoint);
|
|---|
| 17 | public
|
|---|
| 18 | MaxTurn: Integer;
|
|---|
| 19 | FormatId: Integer;
|
|---|
| 20 | Tiles: array of Cardinal;
|
|---|
| 21 | procedure LoadFromFile(FileName: string);
|
|---|
| 22 | procedure SaveToFile(FileName: string);
|
|---|
| 23 | constructor Create;
|
|---|
| 24 | property MapSize: Integer read GetMapSize;
|
|---|
| 25 | property Size: TPoint read FSize write SetSize;
|
|---|
| 26 | end;
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 | implementation
|
|---|
| 30 |
|
|---|
| 31 | uses
|
|---|
| 32 | Protocol;
|
|---|
| 33 |
|
|---|
| 34 | const
|
|---|
| 35 | FileId = 'cEvoMap'#0;
|
|---|
| 36 |
|
|---|
| 37 | procedure TMap.SaveToFile(FileName: string);
|
|---|
| 38 | var
|
|---|
| 39 | MapFile: TFileStream;
|
|---|
| 40 | begin
|
|---|
| 41 | MapFile := TFileStream.Create(FileName, fmCreate or fmShareExclusive);
|
|---|
| 42 | try
|
|---|
| 43 | MapFile.Position := 0;
|
|---|
| 44 | MapFile.Write(FileId[1], 8);
|
|---|
| 45 | MapFile.Write(FormatId, 4);
|
|---|
| 46 | MapFile.Write(MaxTurn, 4);
|
|---|
| 47 | MapFile.Write(Size.X, 4);
|
|---|
| 48 | MapFile.Write(Size.Y, 4);
|
|---|
| 49 | MapFile.Write(Tiles[0], MapSize * 4);
|
|---|
| 50 | finally
|
|---|
| 51 | FreeAndNil(MapFile);
|
|---|
| 52 | end;
|
|---|
| 53 | end;
|
|---|
| 54 |
|
|---|
| 55 | constructor TMap.Create;
|
|---|
| 56 | begin
|
|---|
| 57 | FormatId := 0;
|
|---|
| 58 | end;
|
|---|
| 59 |
|
|---|
| 60 | function TMap.GetMapSize: Integer;
|
|---|
| 61 | begin
|
|---|
| 62 | Result := Size.X * Size.Y;
|
|---|
| 63 | end;
|
|---|
| 64 |
|
|---|
| 65 | procedure TMap.SetSize(AValue: TPoint);
|
|---|
| 66 | begin
|
|---|
| 67 | if FSize = AValue then Exit;
|
|---|
| 68 | FSize := AValue;
|
|---|
| 69 | SetLength(Tiles, MapSize);
|
|---|
| 70 | end;
|
|---|
| 71 |
|
|---|
| 72 | procedure TMap.LoadFromFile(FileName: string);
|
|---|
| 73 | var
|
|---|
| 74 | Loc1: Integer;
|
|---|
| 75 | MapFile: TFileStream;
|
|---|
| 76 | ReadFileId: string;
|
|---|
| 77 | ReadFormatId: Integer;
|
|---|
| 78 | Width: Integer;
|
|---|
| 79 | Height: Integer;
|
|---|
| 80 | begin
|
|---|
| 81 | ReadFileId := '';
|
|---|
| 82 | ReadFormatId := 0;
|
|---|
| 83 | Width := 0;
|
|---|
| 84 | Height := 0;
|
|---|
| 85 | if not FileExists(FileName) then Exit;
|
|---|
| 86 | MapFile := TFileStream.Create(FileName, fmOpenRead or fmShareExclusive);
|
|---|
| 87 | try
|
|---|
| 88 | MapFile.Position := 0;
|
|---|
| 89 | SetLength(ReadFileId, 8);
|
|---|
| 90 | MapFile.Read(ReadFileId[1], 8);
|
|---|
| 91 | if ReadFileId <> FileId then
|
|---|
| 92 | raise Exception.Create('Incorrect map file id. Expected ''' + Trim(FileId) +
|
|---|
| 93 | ''' but ''' + Trim(ReadFileId) + ''' read.');
|
|---|
| 94 | MapFile.Read(ReadFormatId, 4);
|
|---|
| 95 | if ReadFormatId = 0 then begin
|
|---|
| 96 | MapFile.Read(MaxTurn, 4);
|
|---|
| 97 | MapFile.Read(Width, 4);
|
|---|
| 98 | MapFile.Read(Height, 4);
|
|---|
| 99 | Height := Height and not 1;
|
|---|
| 100 | if Width > lxmax then
|
|---|
| 101 | Width := lxmax;
|
|---|
| 102 | if Height > lymax then
|
|---|
| 103 | Height := lymax;
|
|---|
| 104 | Size := Point(Width, Height);
|
|---|
| 105 | MapFile.Read(Tiles[0], MapSize * 4);
|
|---|
| 106 | for Loc1 := 0 to MapSize - 1 do begin
|
|---|
| 107 | Tiles[Loc1] := Tiles[Loc1] and
|
|---|
| 108 | ($7F01FFFF or fPrefStartPos or fStartPos) or ($F shl 27);
|
|---|
| 109 | if Tiles[Loc1] and (fTerrain or fSpecial) = fSwamp or fSpecial2 then
|
|---|
| 110 | Tiles[Loc1] := Tiles[Loc1] and not (fTerrain or fSpecial) or
|
|---|
| 111 | (fSwamp or fSpecial1);
|
|---|
| 112 | if (Tiles[Loc1] and fDeadLands <> 0) and
|
|---|
| 113 | (Tiles[Loc1] and fTerrain <> fArctic) then
|
|---|
| 114 | Tiles[Loc1] := Tiles[Loc1] and not (fTerrain or fSpecial)
|
|---|
| 115 | or fDesert;
|
|---|
| 116 | end;
|
|---|
| 117 | end else raise Exception.Create('Unsupported map format id ' + IntToStr(ReadFormatId) + '.');
|
|---|
| 118 | finally
|
|---|
| 119 | FreeAndNil(MapFile);
|
|---|
| 120 | end;
|
|---|
| 121 | end;
|
|---|
| 122 |
|
|---|
| 123 | end.
|
|---|
| 124 |
|
|---|