unit UBuilding;

{$mode delphi}

interface

uses
  Classes, SysUtils, UItemList;

type
  TBuildingSpecialType = (stNone, stCity);

  { TBuildingKind }

  TBuildingKind = class(TItem)
    Cost: Integer;
    SpecialType: TBuildingSpecialType;
    BonusAttack: Integer;
    BonusDefense: Integer;
    BonusViewRange: Integer;
    BonusGrow: Integer;
    class function GetFields: TItemFields; override;
    procedure GetValue(Index: Integer; out Value); override;
    procedure SetValue(Index: Integer; var Value); override;
    class function GetClassSysName: string; override;
    class function GetClassName: string; override;
  end;

  { TBuildingKinds }

  TBuildingKinds = class(TItemList)
    class function GetItemClass: TItemClass; override;
    function FindBySpecialType(SpecialType: TBuildingSpecialType): TItem;
  end;

  { TBuilding }

  TBuilding = class(TItem)
  private
    FMapCell: TObject;
    procedure SetMapCell(AValue: TObject);
  public
    Kind: TBuildingKind;
    procedure Assign(Source: TItem); override;
    property MapCell: TObject read FMapCell write SetMapCell; // TMapCell;
  end;

  { TBuildings }

  TBuildings = class(TItemList)
    Game: TObject; // TGame;
    class function GetItemClass: TItemClass; override;
  end;

resourcestring
  SBuildingKind = 'Building';
  SCost = 'Cost';
  SSpecialType = 'Special type';
  SNone = 'None';
  SCity = 'City';
  SBonusAttack = 'Unit attack bonus';
  SBonusDefense = 'Unit defense bonus';
  SBonusViewRange = 'Unit view range bonus';
  SBonusGrow = 'Unit grow bonus';


implementation

uses
  UMap;

{ TBuildings }

class function TBuildings.GetItemClass: TItemClass;
begin
  Result := TBuilding;
end;

{ TBuilding }

procedure TBuilding.SetMapCell(AValue: TObject);
var
  OldValue: TCell;
begin
  if FMapCell = AValue then Exit;
  OldValue := TCell(FMapCell);
  FMapCell := nil;
  if Assigned(OldValue) then TCell(OldValue).Building := nil;
  FMapCell := AValue;
  if Assigned(FMapCell) then TCell(FMapCell).Building := Self;
end;

procedure TBuilding.Assign(Source: TItem);
begin
  inherited;
  Kind := TBuilding(Source).Kind;
end;

{ TBuildingKind }

class function TBuildingKind.GetFields: TItemFields;
var
  Field: TItemField;
begin
  Result := inherited;
  Result.AddField(2, 'Cost', SCost, dtInteger);
  Field := Result.AddField(3, 'SpecialType', SSpecialType, dtEnumeration);
  Field.EnumStates.Add(SNone);
  Field.EnumStates.Add(SCity);
  Result.AddField(4, 'BonusAttack', SBonusAttack, dtInteger);
  Result.AddField(5, 'BonusDefense', SBonusDefense, dtInteger);
  Result.AddField(6, 'BonusViewRange', SBonusViewRange, dtInteger);
  Result.AddField(7, 'BonusGrow', SBonusGrow, dtInteger);
end;

procedure TBuildingKind.GetValue(Index: Integer; out Value);
begin
  if Index = 1 then string(Value) := Name
  else if Index = 2 then Integer(Value) := Cost
  else if Index = 3 then TBuildingSpecialType(Value) := SpecialType
  else if Index = 4 then Integer(Value) := BonusAttack
  else if Index = 5 then Integer(Value) := BonusDefense
  else if Index = 6 then Integer(Value) := BonusViewRange
  else if Index = 7 then Integer(Value) := BonusGrow
  else inherited;
end;

procedure TBuildingKind.SetValue(Index: Integer; var Value);
begin
  if Index = 1 then Name := string(Value)
  else if Index = 2 then Cost := Integer(Value)
  else if Index = 3 then SpecialType := TBuildingSpecialType(Value)
  else if Index = 4 then BonusAttack := Integer(Value)
  else if Index = 5 then BonusDefense := Integer(Value)
  else if Index = 6 then BonusViewRange := Integer(Value)
  else if Index = 7 then BonusGrow := Integer(Value)
  else inherited;
end;

class function TBuildingKind.GetClassSysName: string;
begin
  Result := 'BuildingKind';
end;

class function TBuildingKind.GetClassName: string;
begin
  Result := SBuildingKind;
end;

{ TBuildingKinds }

class function TBuildingKinds.GetItemClass: TItemClass;
begin
  Result := TBuildingKind;
end;

function TBuildingKinds.FindBySpecialType(SpecialType: TBuildingSpecialType
  ): TItem;
var
  I: Integer;
begin
  I := 0;
  while (I < Count) and (TBuildingKind(Items[I]).SpecialType <> SpecialType) do Inc(I);
  if I < Count then Result := Items[I]
    else Result := nil;
end;

end.

