unit uObjects;

interface

uses uGlobal;

type
  TMapObject = class
  private
    OnCollusionCalled: array of boolean;
    PartOfBuilding: boolean;
  public     
    ID: integer;
    Radius: integer;
    Model: integer;
    Position, Rotation: array[0..2] of Double;
    Reflect: boolean;
    OnCollusion, OnUnCollusion: procedure(ObjectID, Player: integer);

    procedure Collusion(ObjectID, Player: integer);
    procedure UnCollusion(ObjectID, Player: integer);

    procedure Place(X, Y, Z: double);

    constructor Create;
  end;
  TBuilding = class
  public    
    ID: integer;
    Model, Portal: TMapObject;
    Icon, IconTexture: integer;

    OnCollusion, OnUnCollusion: procedure(BuildingID, Player: integer);

    constructor Create;
    procedure Place(X, Y, Z: double);

    procedure Collusion(Player: integer);
    procedure UnCollusion(Player: integer);

    procedure IconLoad(MaterialName: string); overload;
    procedure IconLoad(MaterialID: integer); overload;
    procedure IconPlace(X, Y: Double);
    procedure IconSize(Width, Height: Double);
  end;

var
  Objects: array of TMapObject;
  Buildings: array of TBuilding;
  function AddObject: integer;
  function AddBuilding: integer;

implementation

function AddObject: integer;
begin
  SetLength(Objects, length(Objects)+1);
  Objects[length(Objects)-1]:=TMapObject.Create;
  Objects[length(Objects)-1].ID:=length(Objects)-1;
  Result:=length(Objects)-1;
end;

function AddBuilding: integer;
begin
  SetLength(Buildings, length(Buildings)+1);
  Buildings[length(Buildings)-1]:=TBuilding.Create;
  Buildings[length(Buildings)-1].ID:=length(Buildings)-1;
  Result:=length(Buildings)-1;
end;

constructor TMapObject.Create;
begin
  inherited Create;
  Reflect:=true;
  Model:=-1;
  PartOfBuilding:=false;
  SetLength(OnCollusionCalled, 0);
end;

procedure TMapObject.Place(X, Y, Z: double);
begin
  Position[0]:=x;
  Position[1]:=y;
  Position[2]:=z;

  if Model=-1 then exit;

  call('poaposition', [Model, 0, 0, 0]);
  call('poaRotation', [Model, Rotation[0], Rotation[1], Rotation[2]]);
  call('poaposition', [Model, Position[0], Position[1], Position[2]]);
end;

procedure TMapObject.Collusion(ObjectID, Player: integer);
var
  I: Integer;
begin
 if length(OnCollusionCalled)<=Player then SetLength(OnCollusionCalled, Player+1);
  if not OnCollusionCalled[Player] then
  begin
    if @OnCollusion<>nil then OnCollusion(ObjectID, Player);
    if PartOfBuilding then
      for I := 0 to length(Buildings) - 1 do
        if Buildings[i].Portal.ID=ObjectID then
          Buildings[i].Collusion(Player);
    OnCollusionCalled[Player]:=true;
  end;
end;

procedure TMapObject.UnCollusion(ObjectID, Player: integer);  
var
  I: Integer;
begin
  if length(OnCollusionCalled)<=Player then SetLength(OnCollusionCalled, Player+1);
  if OnCollusionCalled[Player] then
  begin
    if @OnUnCollusion<>nil then OnUnCollusion(ObjectID, Player);
    if PartOfBuilding then
      for I := 0 to length(Buildings) - 1 do
        if Buildings[i].Portal.ID=ObjectID then
          Buildings[i].UnCollusion(Player);
    OnCollusionCalled[Player]:=false;
  end;
end;

///////////////////


constructor TBuilding.Create;
begin
  Model:=Objects[AddObject];

  Portal:=Objects[AddObject];
  Portal.PartOfBuilding:=true;
  Portal.Reflect:=false;

  Icon:=call('glObjectAdd', [otHUDSprite, 'icon_'+inttostr(length(Objects)-1),-1]);
  call('glObjectVisible', [Icon, false]);
  IconPlace(WndSize[0]/2, 64);
  IconSize(128,128);
end;

procedure TBuilding.Place(X, Y, Z: double);
begin
  Portal.Place(X, Y, Z);
  Model.Place(X, Y, Z);
end;

procedure TBuilding.IconPlace(X, Y: Double);
begin
  call('glPosition', [Icon, X, Y, 0]) ;
end;

procedure TBuilding.IconSize(Width, Height: Double);
begin
  call('glObjectParams', [Icon, Width, Height]);
end;

procedure TBuilding.IconLoad(MaterialName: string);
begin
  call('glObjectMaterial', [Icon, MaterialName]);
end;

procedure TBuilding.IconLoad(MaterialID: integer);
begin
  IconTexture:=MaterialID;
  call('glObjectMaterial', [Icon, IconTexture]);
end;

procedure TBuilding.Collusion(Player: integer);
begin     
  if Player<>0 then exit;

  call('glObjectVisible', [Icon, true]);
  if @onCollusion<>nil then onCollusion(ID, Player);
end;

procedure TBuilding.UnCollusion(Player: integer);
begin
  if Player<>0 then exit;

  call('glObjectVisible', [Icon, false]);
  if @onUnCollusion<>nil then onUnCollusion(ID, Player);
end;

end.

