Changeset 148


Ignore:
Timestamp:
Nov 12, 2017, 11:06:20 PM (7 years ago)
Author:
chronos
Message:
  • Modified: Unit moves moved from TGame to TPlayer. Moves belong to player rather then to game so one player can't see and change moves of other players.
  • Added: New Unit moves window available from Tools menu.
Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Forms/UFormMain.lfm

    r145 r148  
    194194        Action = Core.AShowCharts
    195195      end
     196      object MenuItem25: TMenuItem
     197        Action = Core.AShowUnitMoves
     198      end
    196199    end
    197200    object MenuItem16: TMenuItem
  • trunk/Forms/UFormMain.pas

    r145 r148  
    4343    MenuItem23: TMenuItem;
    4444    MenuItem24: TMenuItem;
     45    MenuItem25: TMenuItem;
    4546    MenuItemLoadRecent: TMenuItem;
    4647    MenuItem3: TMenuItem;
  • trunk/Languages/xtactics.cs.po

    r147 r148  
    8686
    8787#: tcore.ashowcharts.caption
    88 msgid "Show charts"
     88#, fuzzy
     89#| msgid "Show charts"
     90msgctxt "tcore.ashowcharts.caption"
     91msgid "Charts"
    8992msgstr "Ukázat grafy"
     93
     94#: tcore.ashowunitmoves.caption
     95msgctxt "tcore.ashowunitmoves.caption"
     96msgid "Unit moves"
     97msgstr ""
    9098
    9199#: tformabout.buttonclose.caption
     
    117125
    118126#: tformcharts.caption
     127msgctxt "tformcharts.caption"
    119128msgid "Charts"
    120129msgstr "Grafy"
     
    468477msgid "General"
    469478msgstr "Obecné"
     479
     480#: tformunitmoves.caption
     481msgctxt "tformunitmoves.caption"
     482msgid "Unit moves"
     483msgstr ""
     484
     485#: tformunitmoves.listview1.columns[0].caption
     486msgid "From cell"
     487msgstr ""
     488
     489#: tformunitmoves.listview1.columns[1].caption
     490msgid "To cell"
     491msgstr ""
     492
     493#: tformunitmoves.listview1.columns[2].caption
     494msgid "Once count"
     495msgstr ""
     496
     497#: tformunitmoves.listview1.columns[3].caption
     498msgid "Repeat count"
     499msgstr ""
    470500
    471501#: ucore.sendgame
  • trunk/Languages/xtactics.po

    r147 r148  
    7676
    7777#: tcore.ashowcharts.caption
    78 msgid "Show charts"
     78msgctxt "tcore.ashowcharts.caption"
     79msgid "Charts"
     80msgstr ""
     81
     82#: tcore.ashowunitmoves.caption
     83msgctxt "tcore.ashowunitmoves.caption"
     84msgid "Unit moves"
    7985msgstr ""
    8086
     
    107113
    108114#: tformcharts.caption
     115msgctxt "tformcharts.caption"
    109116msgid "Charts"
    110117msgstr ""
     
    451458#: tformsettings.tabsheetgeneral.caption
    452459msgid "General"
     460msgstr ""
     461
     462#: tformunitmoves.caption
     463msgctxt "tformunitmoves.caption"
     464msgid "Unit moves"
     465msgstr ""
     466
     467#: tformunitmoves.listview1.columns[0].caption
     468msgid "From cell"
     469msgstr ""
     470
     471#: tformunitmoves.listview1.columns[1].caption
     472msgid "To cell"
     473msgstr ""
     474
     475#: tformunitmoves.listview1.columns[2].caption
     476msgid "Once count"
     477msgstr ""
     478
     479#: tformunitmoves.listview1.columns[3].caption
     480msgid "Repeat count"
    453481msgstr ""
    454482
  • trunk/UCore.lfm

    r138 r148  
    7575    end
    7676    object AShowCharts: TAction
    77       Caption = 'Show charts'
     77      Caption = 'Charts'
    7878      OnExecute = AShowChartsExecute
     79    end
     80    object AShowUnitMoves: TAction
     81      Caption = 'Unit moves'
     82      OnExecute = AShowUnitMovesExecute
    7983    end
    8084  end
  • trunk/UCore.pas

    r145 r148  
    1616  TCore = class(TDataModule)
    1717    AAbout: TAction;
     18    AShowUnitMoves: TAction;
    1819    AShowCharts: TAction;
    1920    AHelp: TAction;
     
    4849    procedure ASettingsExecute(Sender: TObject);
    4950    procedure AShowChartsExecute(Sender: TObject);
     51    procedure AShowUnitMovesExecute(Sender: TObject);
    5052    procedure CoolTranslator1Translate(Sender: TObject);
    5153    procedure DataModuleCreate(Sender: TObject);
     
    6062    procedure StartNewGame;
    6163    procedure DoPlayerChange(Sender: TObject);
     64    procedure DoMoveUpdated(UnitMove: TUnitMove);
    6265    procedure DoOnMove(CellFrom, CellTo: TCell; var CountOnce,
    6366      CountRepeat: Integer; Update: Boolean; var Confirm: Boolean);
     
    9598uses
    9699  UFormMove, UFormMain, UFormNew, UFormSettings, UFormAbout, UFormPlayer,
    97   UFormHelp, UFormCharts;
     100  UFormHelp, UFormCharts, UFormUnitMoves;
    98101
    99102const
     
    278281
    279282procedure TCore.ProcessComputerTurns;
    280 var
    281   Computer: TComputer;
    282283begin
    283284  while Game.Running and (Game.CurrentPlayer.Mode <> pmHuman) do begin
    284285    if Game.CurrentPlayer.Mode = pmComputer then begin
    285       Computer := TComputer.Create;
    286       try
    287         Computer.Game := Game;
    288         Computer.Process;
    289       finally
    290         Computer.Free;
    291       end;
     286      Game.CurrentPlayer.Computer.Process;
    292287      FormMain.Redraw;
    293288      Delay(Trunc((100 - AnimationSpeed) / 100 * 2000));
     
    374369end;
    375370
     371procedure TCore.AShowUnitMovesExecute(Sender: TObject);
     372begin
     373  FormUnitMoves.Show;
     374end;
     375
    376376procedure TCore.CoolTranslator1Translate(Sender: TObject);
    377377begin
     
    385385  Game := TGame.Create;
    386386  Game.OnMove := DoOnMove;
     387  Game.OnMoveUpdated := DoMoveUpdated;
    387388  Game.OnWin := DoOnWin;
    388389  Game.OnNewTurn := GameNewTurnExecute;
     
    421422  FormMain.Redraw;
    422423  if FormCharts.Visible then FormCharts.Redraw;
     424  if FormUnitMoves.Visible then FormUnitMoves.ReloadList;
    423425end;
    424426
     
    430432  FormMain.Redraw;
    431433  if FormCharts.Visible then FormCharts.Redraw;
     434  if FormUnitMoves.Visible then FormUnitMoves.ReloadList;
    432435  ProcessComputerTurns;
    433436  UpdateActions;
     
    439442    CurrentClient := Game.CurrentPlayer.Client;
    440443  if FormCharts.Visible then FormCharts.Redraw;
     444  if FormUnitMoves.Visible then FormUnitMoves.ReloadList;
     445end;
     446
     447procedure TCore.DoMoveUpdated(UnitMove: TUnitMove);
     448begin
     449  if FormUnitMoves.Visible then FormUnitMoves.ReloadList;
    441450end;
    442451
  • trunk/UGame.pas

    r147 r148  
    7171    function GetAvialPower: Integer;
    7272    function GetAttackPower: Integer;
     73    function ToString: ansistring; override;
    7374    constructor Create;
    7475    destructor Destroy; override;
     
    267268  TPlayerMode = (pmHuman, pmComputer);
    268269  TComputerAgressivity = (caLow, caMedium, caHigh);
     270  TComputer = class;
     271  TUnitMove = class;
    269272
    270273  { TPlayer }
     
    274277    FClient: TClient;
    275278    FGame: TGame;
     279    FMode: TPlayerMode;
    276280    procedure SetClient(AValue: TClient);
    277281    procedure SetGame(AValue: TGame);
     282    procedure Attack(var AttackPower, DefendPower: Integer);
     283    procedure ClearMovesFromCell(Cell: TCell);
     284    procedure MoveAll;
     285    procedure CheckCounterMove(Move: TUnitMove);
     286    procedure SetMode(AValue: TPlayerMode);
     287    function SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove;
     288    procedure UpdateRepeatMoves;
    278289  public
    279290    Id: Integer;
    280291    Name: string;
    281292    Color: TColor;
    282     Mode: TPlayerMode;
    283293    TotalUnits: Integer;
    284294    TotalCells: Integer;
     
    291301    Agressivity: TComputerAgressivity;
    292302    TurnStats: TGameTurnStats;
     303    Moves: TUnitMoves;
     304    Computer: TComputer;
    293305    procedure Clear;
    294306    procedure LoadFromNode(Node: TDOMNode);
     
    300312    property Game: TGame read FGame write SetGame;
    301313    property Client: TClient read FClient write SetClient;
    302   end;
    303 
    304 
    305   { TComputer }
     314    property Mode: TPlayerMode read FMode write SetMode;
     315  end;
     316
     317    { TComputer }
    306318
    307319  TComputer = class
     
    309321    //Targets: TFPGObjectList<TPlayer>;
    310322    CellProcessDirection: Boolean;
     323    Player: TPlayer;
    311324    procedure AttackNeutral;
    312325    procedure AttackPlayers;
     
    358371  TUnitMoves = class(TFPGObjectList<TUnitMove>)
    359372    Game: TGame;
     373    function SearchByFromTo(CellFrom, CellTo: TCell): TUnitMove;
    360374    procedure LoadFromNode(Node: TDOMNode);
    361375    procedure SaveToNode(Node: TDOMNode);
     
    390404  TMoveEvent = procedure(CellFrom, CellTo: TCell; var CountOnce, CountRepeat: Integer;
    391405    Update: Boolean; var Confirm: Boolean) of object;
     406  TMoveUpdatedEvent = procedure(UnitMove: TUnitMove) of object;
     407
    392408  TWinEvent = procedure(Player: TPlayer) of object;
    393409  TGrowAmount = (gaByOne, gaBySquareRoot);
     
    401417    FMapType: TMapType;
    402418    FOnMove: TMoveEvent;
     419    FOnMoveUpdated: TMoveUpdatedEvent;
    403420    FOnNewTurn: TNotifyEvent;
    404421    FOnPlayerChange: TNotifyEvent;
     
    407424    LoadedImageFileName: string;
    408425    ProbabilityMatrix: array of array of Single;
    409     procedure Attack(var AttackPower, DefendPower: Integer);
    410     procedure MoveAll(Player: TPlayer);
    411     procedure ClearMovesFromCell(Cell: TCell);
    412426    procedure RecordTurnStats;
    413427    procedure SetMapType(AValue: TMapType);
    414     function SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove;
    415428    procedure SetRunning(AValue: Boolean);
    416     procedure UpdateRepeatMoves(Player: TPlayer);
    417     procedure CheckCounterMove(Move: TUnitMove);
    418429    function SearchDifferentCellArea(List: TCells; SourceArea, DestArea: TMapArea): TCell;
    419430    procedure BuildTerrain;
     
    437448    CityPercentage: Integer;
    438449    CurrentPlayer: TPlayer;
    439     Moves: TUnitMoves;
    440450    TurnCounter: Integer;
    441451    WinObjective: TWinObjective;
     
    464474  published
    465475    property OnMove: TMoveEvent read FOnMove write FOnMove;
     476    property OnMoveUpdated: TMoveUpdatedEvent read FOnMoveUpdated write FOnMoveUpdated;
    466477    property OnWin: TWinEvent read FOnWin write FOnWin;
    467478    property OnNewTurn: TNotifyEvent read FOnNewTurn write FOnNewTurn;
     
    9901001    // Draw arrows
    9911002    Pen.Color := clCream;
    992     for I := 0 to Game.Moves.Count - 1 do begin
    993       Move := TUnitMove(Game.Moves[I]);
     1003    for I := 0 to Player.Moves.Count - 1 do begin
     1004      Move := TUnitMove(Player.Moves[I]);
    9941005      PosFrom := Player.Game.Map.CellToPos(Move.CellFrom);
    9951006      PosTo := Player.Game.Map.CellToPos(Move.CellTo);
     
    11911202
    11921203{ TUnitMoves }
     1204
     1205function TUnitMoves.SearchByFromTo(CellFrom, CellTo: TCell): TUnitMove;
     1206var
     1207  UnitMove: TUnitMove;
     1208begin
     1209  Result := nil;
     1210  for UnitMove in Self do
     1211  if (UnitMove.CellFrom = CellFrom) and (UnitMove.CellTo = CellTo) then begin
     1212    Result := UnitMove;
     1213    Break;
     1214  end;
     1215end;
    11931216
    11941217procedure TUnitMoves.LoadFromNode(Node: TDOMNode);
     
    18231846function TCell.GetAvialPower: Integer;
    18241847var
    1825   I: Integer;
     1848  UnitMove: TUnitMove;
    18261849begin
    18271850  Result := Power;
    1828   for I := 0 to MovesFrom.Count - 1 do
    1829     Result := Result - TUnitMove(MovesFrom[I]).CountOnce;
    1830   if Result < 0 then Result := 0;
     1851  for UnitMove in MovesFrom do
     1852    Result := Result - UnitMove.CountOnce;
     1853  if Result < 0 then raise Exception.Create('Unit move power mismatch. Cell power is ' +
     1854    IntToStr(Power) + ' but ' + IntToStr(- (Result - Power)) + ' moved away.');
    18311855end;
    18321856
     
    18381862  for I := 0 to MovesTo.Count - 1 do
    18391863    Result := Result + TUnitMove(MovesTo[I]).CountOnce;
     1864end;
     1865
     1866function TCell.ToString: ansistring;
     1867begin
     1868  Result := IntToStr(Id);
    18401869end;
    18411870
     
    19121941  if FGame = AValue then Exit;
    19131942  FGame := AValue;
     1943  Moves.Game := AValue;
     1944  Computer.Game := AValue;
    19141945end;
    19151946
     
    19171948begin
    19181949  TurnStats.Clear;
     1950  Moves.Clear;
    19191951end;
    19201952
     
    19461978  end;
    19471979  with Node do begin
     1980    NewNode := FindNode('UnitMoves');
     1981    if Assigned(NewNode) then
     1982      Moves.LoadFromNode(NewNode);
     1983  end;
     1984  with Node do begin
    19481985    NewNode := FindNode('TurnStats');
    19491986    if Assigned(NewNode) then
     
    19712008  end;
    19722009  with Node do begin
     2010    NewNode := OwnerDocument.CreateElement('UnitMoves');
     2011    AppendChild(NewNode);
     2012    Moves.SaveToNode(NewNode);
     2013  end;
     2014  with Node do begin
    19732015    NewNode := OwnerDocument.CreateElement('TurnStats');
    19742016    AppendChild(NewNode);
     
    19972039  AttackPower: Integer;
    19982040  TotalAttackPower: Integer;
    1999   I: Integer;
    2000   C: Integer;
    20012041  CanAttack: Integer;
    20022042  TargetCells: TCells;
     2043  Cell: TCell;
     2044  NeighborCell: TCell;
    20032045const
    20042046  AttackDiff = 1;
     
    20092051
    20102052  // Get list of all attack target cells
    2011   for C := 0 to AllCells.Count - 1 do
    2012   with TCell(AllCells[C]) do begin
     2053  for Cell in AllCells do
     2054  with Cell do begin
    20132055    if (Terrain <> ttVoid) and (Player = nil) then begin
    20142056      CanAttack := 0;
    2015       for I := 0 to Neighbors.Count - 1 do
    2016       if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
     2057      for NeighborCell in Neighbors do
     2058      if NeighborCell.Player = Game.CurrentPlayer then begin
    20172059        Inc(CanAttack);
    20182060      end;
    2019       if CanAttack > 0 then TargetCells.Add(AllCells[C]);
     2061      if CanAttack > 0 then TargetCells.Add(Cell);
    20202062    end;
    20212063  end;
     
    20252067  TargetCells.Sort(CellCompare);
    20262068
    2027   for C := 0 to TargetCells.Count - 1 do
    2028   with TCell(TargetCells[C]) do begin
     2069  for Cell in TargetCells do
     2070  with Cell do begin
    20292071      // Attack to not owned cell yet
    20302072      // Count own possible power
    20312073      TotalPower := 0;
    2032       for I := 0 to Neighbors.Count - 1 do
    2033       if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
    2034         TotalPower := TotalPower + TCell(Neighbors[I]).GetAvialPower;
    2035       end;
     2074      for NeighborCell in Neighbors do
     2075      if NeighborCell.Player = Game.CurrentPlayer then
     2076        TotalPower := TotalPower + NeighborCell.GetAvialPower;
     2077
    20362078      // Attack if target is weaker
    20372079      if TotalPower >= (Power + AttackDiff) then begin
    20382080        TotalAttackPower := 0;
    2039         for I := 0 to Neighbors.Count - 1 do
    2040         if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
     2081        for NeighborCell in Neighbors do
     2082        if NeighborCell.Player = Game.CurrentPlayer then begin
    20412083          // Use only necessary power
    20422084          AttackPower := Power - TotalAttackPower + AttackDiff;
    2043           if TCell(Neighbors[I]).GetAvialPower < AttackPower then
    2044             AttackPower := TCell(Neighbors[I]).GetAvialPower;
    2045           Game.SetMove(Tcell(Neighbors[I]), TCell(TargetCells[C]), AttackPower, False);
     2085          if NeighborCell.GetAvialPower < AttackPower then
     2086            AttackPower := NeighborCell.GetAvialPower;
     2087          Self.Player.SetMove(NeighborCell, Cell, AttackPower, False);
    20462088          TotalAttackPower := TotalAttackPower + AttackPower;
    20472089        end;
     
    20492091  end;
    20502092
    2051   TargetCells.Free;
     2093  FreeAndNil(TargetCells);
    20522094end;
    20532095
     
    20582100  AttackPower: Integer;
    20592101  TotalAttackPower: Integer;
    2060   I: Integer;
    2061   C: Integer;
    20622102  CanAttack: Integer;
    20632103  TargetCells: TCells;
     2104  TargetCell: TCell;
     2105  NeighborCell: TCell;
    20642106begin
    20652107  if Game.CurrentPlayer.Defensive then Exit;
     
    20702112
    20712113  // Get list of all attack target cells
    2072   for C := 0 to AllCells.Count - 1 do
    2073   with TCell(AllCells[C]) do begin
    2074     if (Terrain <> ttVoid) and (Player <> Game.CurrentPlayer) and (Player <> nil) then begin
     2114  for TargetCell in AllCells do begin
     2115    if (TargetCell.Terrain <> ttVoid) and (TargetCell.Player <> Player) and
     2116      (TargetCell.Player <> nil) then begin
    20752117      CanAttack := 0;
    2076       for I := 0 to Neighbors.Count - 1 do
    2077       if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
     2118      for NeighborCell in TargetCell.Neighbors do
     2119      if NeighborCell.Player = Player then begin
    20782120        Inc(CanAttack);
    20792121      end;
    2080       if CanAttack > 0 then TargetCells.Add(AllCells[C]);
     2122      if CanAttack > 0 then TargetCells.Add(TargetCell);
    20812123    end;
    20822124  end;
     
    20862128  TargetCells.Sort(CellCompareDescending);
    20872129
    2088   for C := 0 to TargetCells.Count - 1 do
    2089   with TCell(TargetCells[C]) do begin
     2130  for TargetCell in TargetCells do begin
    20902131      // Attack to not owned cell yet
    20912132      // Count own possible power
    20922133      TotalPower := 0;
    2093       for I := 0 to Neighbors.Count - 1 do
    2094       if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
    2095         TotalPower := TotalPower + TCell(Neighbors[I]).GetAvialPower;
     2134      for NeighborCell in TargetCell.Neighbors do
     2135      if NeighborCell.Player = Player then begin
     2136        TotalPower := TotalPower + NeighborCell.GetAvialPower;
    20962137      end;
    20972138      // Attack if target is weaker
    2098       if Game.AttackProbability(TotalPower, Power) >= ComputerAggroProbability[Game.CurrentPlayer.Agressivity] then begin
     2139      if Game.AttackProbability(TotalPower, TargetCell.Power) >=
     2140        ComputerAggroProbability[Player.Agressivity] then begin
    20992141        // Try to limit total attacking power to necessary minimum
    2100         while Game.AttackProbability(TotalPower - 1, Power) >= ComputerAggroProbability[Game.CurrentPlayer.Agressivity] do
     2142        while Game.AttackProbability(TotalPower - 1, TargetCell.Power) >=
     2143          ComputerAggroProbability[Player.Agressivity] do
    21012144          Dec(TotalPower);
    21022145
    21032146        // Collect required attack units from our cells
    21042147        TotalAttackPower := 0;
    2105         for I := 0 to Neighbors.Count - 1 do
    2106         if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) then begin
     2148        for NeighborCell in TargetCell.Neighbors do
     2149        if NeighborCell.Player = Player then begin
    21072150          // Use only necessary power
    21082151          AttackPower := TotalPower - TotalAttackPower;
    2109           if TCell(Neighbors[I]).GetAvialPower < AttackPower then
    2110             AttackPower := TCell(Neighbors[I]).GetAvialPower;
    2111           Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), AttackPower, False);
     2152          if NeighborCell.GetAvialPower < AttackPower then
     2153            AttackPower := NeighborCell.GetAvialPower;
     2154          Self.Player.SetMove(NeighborCell, TargetCell, AttackPower, False);
    21122155          TotalAttackPower := TotalAttackPower + AttackPower;
    21132156          if TotalAttackPower >= TotalPower then Break;
     
    21162159  end;
    21172160
    2118   TargetCells.Free;
     2161  FreeAndNil(TargetCells);
    21192162end;
    21202163
     
    21852228              if (TCell(TargetCells[C]).GetAvialPower + TCell(TargetCells[C]).GetAttackPower + MovedPower) > Game.Map.MaxPower then
    21862229                MovedPower := Game.Map.MaxPower - TCell(TargetCells[C]).GetAvialPower - TCell(TargetCells[C]).GetAttackPower;
    2187               Game.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), MovedPower, False);
     2230              Player.SetMove(TCell(Neighbors[I]), TCell(TargetCells[C]), MovedPower, False);
    21882231            end;
    21892232          end;
     
    21952238
    21962239    // Use source cells NewTargetCells as new TargetCells
    2197     TargetCells.Free;
     2240    FreeAndNil(TargetCells);
    21982241    TargetCells := NewTargetCells;
    21992242    NewTargetCells := TCells.Create;
     
    22012244  end;
    22022245
    2203   TargetCells.Free;
    2204   NewTargetCells.Free;
     2246  FreeAndNil(TargetCells);
     2247  FreeAndNil(NewTargetCells);
    22052248end;
    22062249
     
    22112254begin
    22122255  // If available power remains then use all for existed unit moves
    2213   for I := 0 to Game.Moves.Count - 1 do
    2214   with TUnitMove(Game.Moves[I]) do begin
     2256  for I := 0 to Player.Moves.Count - 1 do
     2257  with TUnitMove(Player.Moves[I]) do begin
    22152258    if CellFrom.GetAvialPower > 0 then begin
    22162259      AvailPower := CellFrom.GetAvialPower;
     
    22662309        TUnitMove(MovesTo[I]).Free;
    22672310      for I := 0 to Neighbors.Count - 1 do
    2268       if (TCell(Neighbors[I]).Player = Game.CurrentPlayer) and (AttackersCount(TCell(Neighbors[I])) = 0) then begin
    2269 
    2270         Game.SetMove(TCell(BorderCells[C]), TCell(Neighbors[I]), GetAvialPower, False);
     2311      if (TCell(Neighbors[I]).Player = Player) and (AttackersCount(TCell(Neighbors[I])) = 0) then begin
     2312        Player.SetMove(TCell(BorderCells[C]), TCell(Neighbors[I]), GetAvialPower, False);
    22712313        Break;
    22722314      end;
     
    22742316  end;
    22752317
    2276   BorderCells.Free;
     2318  FreeAndNil(BorderCells);
    22772319end;
    22782320
     
    23022344        for I := SelectedCell.MovesFrom.Count - 1 downto 0 do
    23032345          TUnitMove(SelectedCell.MovesFrom[I]).Free;
    2304         Game.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False);
     2346        Game.CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False);
    23052347        SelectedCell := nil;
    23062348      end else
     
    23102352        for I := SelectedCell.MovesFrom.Count - 1 downto 0 do
    23112353          TUnitMove(SelectedCell.MovesFrom[I]).Free;
    2312         UnitMove := Game.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False);
     2354        UnitMove := Game.CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power, False);
    23132355        if Assigned(UnitMove) then
    23142356          UnitMove.CountRepeat := Player.Game.Map.MaxPower;
     
    23162358          else SelectedCell := nil;
    23172359      end else begin
    2318         Game.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power);
     2360        Game.CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.Power);
    23192361        SelectedCell := nil;
    23202362      end;
     
    23542396constructor TPlayer.Create;
    23552397begin
     2398  Moves := TUnitMoves.Create;
    23562399  StartUnits := DefaultPlayerStartUnits;
    23572400  StartCell := nil;
     
    23592402  PlayerMap.Player := Self;
    23602403  TurnStats := TGameTurnStats.Create;
     2404  Computer := TComputer.Create;
     2405  Computer.Player := Self;
    23612406end;
    23622407
    23632408destructor TPlayer.Destroy;
    23642409begin
     2410  FreeAndNil(Computer);
    23652411  FreeAndNil(TurnStats);
    23662412  FreeAndNil(PlayerMap);
     2413  FreeAndNil(Moves);
    23672414  inherited Destroy;
    23682415end;
     
    23902437end;
    23912438
    2392 procedure TGame.Attack(var AttackPower, DefendPower: Integer);
     2439procedure TPlayer.Attack(var AttackPower, DefendPower: Integer);
    23932440var
    23942441  AttackerDiceCount: Integer;
     
    24332480      else Dec(AttackPower);
    24342481  end;
    2435   AttackRolls.Free;
    2436   DefendRolls.Free;
     2482  FreeAndNil(AttackRolls);
     2483  FreeAndNil(DefendRolls);
    24372484end;
    24382485
     
    24952542end;
    24962543
    2497 procedure TGame.MoveAll(Player: TPlayer);
     2544procedure TPlayer.MoveAll;
    24982545var
    24992546  I: Integer;
     
    25012548  DefenderPower: Integer;
    25022549  UnitCount: Integer;
    2503 begin
    2504   I := 0;
    2505   while I < Moves.Count do
    2506   with TUnitMove(Moves[I]) do begin
     2550  UnitMove: TUnitMove;
     2551begin
     2552  for UnitMove in Moves do
     2553  with UnitMove do begin
    25072554  if CountOnce > 0 then begin
    2508     if CellFrom.Player = Player then begin
     2555    if CellFrom.Player = Self then begin
    25092556      UnitCount := CountOnce;
    25102557      if CountOnce > CellFrom.Power then
    25112558        UnitCount := CellFrom.Power;
    2512       if CellTo.Player = Player then begin
     2559      if CellTo.Player = Self then begin
    25132560        // Inner move
    25142561        CellTo.Power := CellTo.Power + UnitCount;
     
    25202567          // Attacker wins with possible loses
    25212568          ClearMovesFromCell(CellTo);
    2522           CellTo.Player := Player;
     2569          CellTo.Player := Self;
    25232570          CellTo.Power := AttackerPower;
    25242571        end else
     
    25332580    end;
    25342581    end;
    2535     Inc(I);
    25362582  end;
    25372583  // Remove empty moves
    25382584  for I := Moves.Count - 1 downto 0 do
    2539   if (TUnitMove(Moves[I]).CellFrom.Player = Player) and
     2585  if (TUnitMove(Moves[I]).CellFrom.Player = Self) and
    25402586    (TUnitMove(Moves[I]).CountOnce = 0) and (TUnitMove(Moves[I]).CountRepeat = 0) then
    25412587    Moves.Delete(I);
    25422588end;
    25432589
    2544 procedure TGame.ClearMovesFromCell(Cell: TCell);
    2545 var
    2546   I: Integer;
    2547 begin
    2548   for I := Moves.Count - 1 downto 0 do
    2549   if TUnitMove(Moves[I]).CellFrom = Cell then
    2550     Moves.Delete(I);
     2590procedure TPlayer.ClearMovesFromCell(Cell: TCell);
     2591var
     2592  I: Integer;
     2593begin
     2594  if Assigned(Cell.Player) then
     2595  for I := Cell.Player.Moves.Count - 1 downto 0 do
     2596  if TUnitMove(Cell.Player.Moves[I]).CellFrom = Cell then
     2597    Cell.Player.Moves.Delete(I);
    25512598end;
    25522599
     
    25662613  end;
    25672614  Map.Assign(OldMap);
    2568   OldMap.Free;
     2615  FreeAndNil(OldMap);
    25692616  FMapType := AValue;
    25702617end;
    25712618
    2572 function TGame.SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove;
     2619function TPlayer.SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove;
    25732620var
    25742621  NewMove: TUnitMove;
    2575   OldMove: TUnitMove;
    25762622  I: Integer;
    25772623  CountOnce: Integer;
     
    25812627  I := 0;
    25822628  Confirm := True;
    2583   while (I < Moves.Count) and ((TUnitMove(Moves[I]).CellFrom <> CellFrom) or
    2584     (TUnitMove(Moves[I]).CellTo <> CellTo)) do Inc(I);
    2585   if I < Moves.Count then OldMove := TUnitMove(Moves[I])
    2586     else OldMove := nil;
    2587   Result := OldMove;
    2588   if Assigned(OldMove) then begin
    2589     CountOnce := OldMove.CountOnce;
    2590     CountRepeat := OldMove.CountRepeat;
    2591     if Assigned(CurrentPlayer) and Confirmation and
    2592       Assigned(FOnMove) then FOnMove(CellFrom, CellTo, CountOnce, CountRepeat, True, Confirm);
     2629  Result := Moves.SearchByFromTo(CellFrom, CellTo);
     2630
     2631  if Assigned(Result) then begin
     2632    CountOnce := Result.CountOnce;
     2633    CountRepeat := Result.CountRepeat;
     2634    if (Mode = pmHuman) and Confirmation and
     2635      Assigned(Game.FOnMove) then Game.FOnMove(CellFrom, CellTo, CountOnce, CountRepeat, True, Confirm);
    25932636  end else begin
    25942637    CountOnce := Power;
    25952638    CountRepeat := 0;
    2596     if Assigned(CurrentPlayer) and Confirmation and
    2597       Assigned(FOnMove) then FOnMove(CellFrom, CellTo, CountOnce, CountRepeat, False, Confirm);
     2639    if (Mode = pmHuman) and Confirmation and
     2640      Assigned(Game.FOnMove) then Game.FOnMove(CellFrom, CellTo, CountOnce, CountRepeat, False, Confirm);
    25982641  end;
    25992642  if Confirm then begin
    2600     if Assigned(OldMove) then begin
     2643    if Assigned(Result) then begin
    26012644      // Already have such move
    26022645      if (CountOnce = 0) and (CountRepeat = 0) then Moves.Delete(I)
    26032646        else begin
    2604           OldMove.CountOnce := CountOnce;
    2605           OldMove.CountRepeat := CountRepeat;
    2606           CheckCounterMove(OldMove);
     2647          Result.CountOnce := CountOnce;
     2648          Result.CountRepeat := CountRepeat;
     2649          CheckCounterMove(Result);
    26072650        end;
    26082651    end else begin
     
    26192662      end;
    26202663    end;
     2664    if Assigned(Game.FOnMoveUpdated) then Game.FOnMoveUpdated(Result);
    26212665  end;
    26222666end;
     
    26392683end;
    26402684
    2641 procedure TGame.UpdateRepeatMoves(Player: TPlayer);
    2642 var
    2643   I: Integer;
    2644 begin
    2645   for I := 0 to Moves.Count - 1 do
    2646   with TUnitMove(Moves[I]) do begin
    2647     if CellFrom.Player = Player then
     2685procedure TPlayer.UpdateRepeatMoves;
     2686var
     2687  Move: TUnitMove;
     2688begin
     2689  for Move in Moves do
     2690  with Move do begin
     2691    if CellFrom.Player = Self then
    26482692      if CountRepeat <= CellFrom.GetAvialPower then
    26492693        CountOnce := CountRepeat
     
    26522696end;
    26532697
    2654 procedure TGame.CheckCounterMove(Move: TUnitMove);
    2655 var
    2656   I: Integer;
     2698procedure TPlayer.CheckCounterMove(Move: TUnitMove);
     2699var
    26572700  CounterMove: TUnitMove;
    26582701begin
    2659   I := 0;
    2660   while (I < Moves.Count) and ((TUnitMove(Moves[I]).CellTo <> Move.CellFrom) or
    2661     (TUnitMove(Moves[I]).CellFrom <> Move.CellTo)) do Inc(I);
    2662   if I < Moves.Count then CounterMove := TUnitMove(Moves[I])
    2663     else CounterMove := nil;
     2702  CounterMove := Moves.SearchByFromTo(Move.CellTo, Move.CellFrom);
    26642703  if Assigned(CounterMove) then begin
    26652704    // For now, just remove counter move
    26662705    Moves.Remove(CounterMove);
    26672706  end;
     2707end;
     2708
     2709procedure TPlayer.SetMode(AValue: TPlayerMode);
     2710begin
     2711  if FMode = AValue then Exit;
     2712  FMode := AValue;
    26682713end;
    26692714
     
    27042749  end;
    27052750
    2706   NewListVoid.Free;
    2707   NewList.Free;
     2751  FreeAndNil(NewListVoid);
     2752  FreeAndNil(NewList);
    27082753end;
    27092754
     
    27932838
    27942839  end;
    2795   List.Free;
    2796   BorderList.Free;
     2840  FreeAndNil(List);
     2841  FreeAndNil(BorderList);
    27972842end;
    27982843
     
    29983043      InitClients;
    29993044
    3000       NewNode := FindNode('UnitMoves');
    3001       if Assigned(NewNode) then
    3002         Moves.LoadFromNode(NewNode);
    3003 
    30043045      Map.Cells.FixRefId;
    30053046
     
    30113052    end;
    30123053  finally
    3013     Doc.Free;
     3054    FreeAndNil(Doc);
    30143055  end;
    30153056end;
     
    30493090      AppendChild(NewNode);
    30503091      Players.SaveToNode(NewNode);
    3051 
    3052       NewNode := OwnerDocument.CreateElement('UnitMoves');
    3053       AppendChild(NewNode);
    3054       Moves.SaveToNode(NewNode);
    30553092  end;
    30563093    ForceDirectoriesUTF8(ExtractFileDir(FileName));
    30573094    WriteXMLFile(Doc, FileName);
    30583095  finally
    3059     Doc.Free;
     3096    FreeAndNil(Doc);
    30603097  end;
    30613098end;
     
    31273164begin
    31283165  //TODO CurrentPlayer.View.SelectedCell := nil;
    3129   MoveAll(CurrentPlayer);
     3166  CurrentPlayer.MoveAll;
    31303167  Map.Grow(CurrentPlayer);
    3131   UpdateRepeatMoves(CurrentPlayer);
     3168  CurrentPlayer.UpdateRepeatMoves;
    31323169  ComputePlayerStats;
    31333170  PrevPlayer := CurrentPlayer;
     
    31833220constructor TGame.Create;
    31843221begin
    3185   Moves := TUnitMoves.Create;
    3186   Moves.Game := Self;
    31873222  Map := TMap.Create;
    31883223  Players := TPlayers.Create;
     
    32083243begin
    32093244  FreeAndNil(Clients);
    3210   FreeAndNil(Moves);
    32113245  FreeAndNil(Players);
    32123246  FreeAndNil(Map);
     
    32233257  FileName := SNewGameFile;
    32243258  TurnCounter := 1;
    3225   Moves.Clear;
    32263259
    32273260  BuildTerrain;
     
    33223355    // Draw arrows
    33233356    Pen.Color := clCream;
    3324     for I := 0 to Game.Moves.Count - 1 do begin
    3325       Move := TUnitMove(Game.Moves[I]);
     3357    for I := 0 to Game.CurrentPlayer.Moves.Count - 1 do begin
     3358      Move := TUnitMove(Game.CurrentPlayer.Moves[I]);
    33263359      PosFrom := CellToPos(Move.CellFrom);
    33273360      PosTo := CellToPos(Move.CellTo);
  • trunk/xtactics.lpi

    r147 r148  
    173173      </Item6>
    174174    </RequiredPackages>
    175     <Units Count="12">
     175    <Units Count="13">
    176176      <Unit0>
    177177        <Filename Value="xtactics.lpr"/>
     
    249249        <ResourceBaseClass Value="Form"/>
    250250      </Unit11>
     251      <Unit12>
     252        <Filename Value="Forms/UFormUnitMoves.pas"/>
     253        <IsPartOfProject Value="True"/>
     254        <ComponentName Value="FormUnitMoves"/>
     255        <ResourceBaseClass Value="Form"/>
     256      </Unit12>
    251257    </Units>
    252258  </ProjectOptions>
  • trunk/xtactics.lpr

    r145 r148  
    1111  TemplateGenerics, UFormPlayer
    1212  { you can add units after this },
    13   SysUtils, UFormMain, UFormMove, UFormNew, UFormCharts;
     13  SysUtils, UFormMain, UFormMove, UFormNew, UFormCharts, UFormUnitMoves;
    1414
    1515{$R *.res}
     
    3636  Application.CreateForm(TFormPlayer, FormPlayer);
    3737  Application.CreateForm(TFormCharts, FormCharts);
     38  Application.CreateForm(TFormUnitMoves, FormUnitMoves);
    3839  Application.Run;
    3940end.
Note: See TracChangeset for help on using the changeset viewer.