unit c_map;

interface

uses
  sysutils, classes;

const
  signature = 'DGM';

  WPStart = $FFF0;
  WPEnd   = $FFF1;

type
  TCell = (cFree, cLandie, cNB);

  TWayPoint = packed record
    X, Y : word;
    ID : Word;
    NextID : Word;
    Radius : Byte;
  end;

  TTree = packed record
    X, Y : Word;
    Size : Byte;
    angle : Byte;
  end;

  TTreeanim = packed record
    l1, l2 : byte;
  end;

  TDGmap = object
    cells : array [0..127, 0..127] of TCell;
    wp : array of TWayPoint;
    tree : array of TTree;
    treeanim : array of TTreeanim;
    wpCount : Word;
    lastwp : Word;
    treecount : Word;
    procedure save(Filename : string);
    procedure load(Filename : string);
    procedure AddWayPoint(nX, nY : word);
    function FindWP(nX, nY : word) : word;
    function FindWPwithID(nID : word) : word;
    procedure DeleteWP(nID : word);
    procedure ClearWP;
    procedure AddTree(nX, nY : word);
    procedure process(delta : Single);
  end;

implementation

uses Math;

procedure TDGmap.save(Filename : string);
var
  f : TFileStream;
begin
  f:= TFileStream.Create(Filename, fmCreate);
  f.Write(signature, 3);
  f.Write(cells, sizeOf(cells));
  f.Write(wpCount, 2);
  f.Write(lastwp, 2);
  if wpCount > 0 then f.Write(wp[0], sizeof(TWayPoint)*wpCount);
  f.Write(treeCount, 2);
  if treeCount > 0 then f.Write(tree[0], sizeof(TTree)*treeCount);
  f.Free;
end;

procedure TDGmap.load(Filename : string);
var
  f : TFileStream;
  sign : array [0..2] of char;
  i : integer;
begin
  f:= TFileStream.Create(Filename, fmOpenRead);
  f.Read(sign, 3);
  if sign <> signature then exit;
  f.Read(cells, sizeOf(cells));
  f.Read(wpCount, 2);
  f.Read(lastwp, 2);
  if wpCount > 0 then
  begin
    SetLength(wp, wpCount);
    f.Read(wp[0], sizeof(TWayPoint)*wpCount);
  end;
  f.Read(treeCount, 2);
  if treeCount > 0 then
  begin
    SetLength(tree, treeCount);
    SetLength(treeanim, treeCount);

    for i:= 0 to treecount-1 do
    begin
      treeanim[i].l1:= random(4);
      treeanim[i].l2:= random(4);
    end;

    f.Read(tree[0], sizeof(TTree)*treeCount);
  end;

  f.Free;
end;

procedure TDGmap.AddWayPoint(nX, nY : word);
begin
  inc(wpCount);
  inc(Lastwp);
  SetLength(wp, wpCount);
  with wp[wpCount-1] do
  begin
    X:= nX;
    Y:= nY;
    ID:= Lastwp;
    Radius:= 32;
    NextID:= 0;
  end;
end;

function TDGmap.FindWP(nX, nY : word) : word;
var
  i : integer;
begin
  result:= 0;

  for i:=0 to wpCount - 1 do
  if (abs(nx - wp[i].X) < 16) and (abs(ny - wp[i].y ) < 16) then
  begin
    Result:= wp[i].ID;
    exit;
  end;
end;

function TDGmap.FindWPwithID(nID : word) : word;
var
  i : integer;
begin
  result:= 0;

  for i:=0 to wpCount - 1 do
  if wp[i].ID = nID then
  begin
    Result:= i;
    exit;
  end;
end;

procedure TDGmap.DeleteWP(nID : word);
var
  i, j : integer;
begin
  j:= 0;
  for i:=0 to wpCount - 1 do
  if wp[i].ID = nID then j:= i;

  if j = 0 then exit;

  for i:= j  to wpCount - 2 do
  wp[i]:= wp[i+1];

  dec(wpCount);
  SetLength(wp, wpCount);
end;

procedure TDGmap.ClearWP;
begin
  SetLength(wp, 0);
  wpCount:= 0;
  lastwp:= 0;
end;

procedure TDGmap.AddTree(nX, nY : word);
begin
  inc(treeCount);
  SetLength(tree, treecount);
  with tree[treecount-1] do
  begin
    X:= nX;
    Y:= nY;
    Size:= 196 + random(64);
    angle:= random(256);
  end;
end;

procedure TDGmap.process(delta : Single);
begin

end;

end.
