Changeset 154


Ignore:
Timestamp:
Nov 16, 2017, 12:16:36 AM (7 years ago)
Author:
chronos
Message:
  • Fixed: Avoid possible negative cell power if player unit was previously unsucessfully attacked and weaken by enemy.
  • Fixed: Same game structures were not correctly initialized during load from file.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UGame.pas

    r153 r154  
    204204    procedure ComputePlayerStats; virtual;
    205205    procedure Generate; virtual;
     206    procedure Clear;
    206207    constructor Create; virtual;
    207208    destructor Destroy; override;
     
    284285    procedure ClearMovesFromCell(Cell: TCell);
    285286    procedure MoveAll;
     287    procedure ReduceMovesPower;
    286288    procedure CheckCounterMove(Move: TUnitMove);
    287289    procedure SetMode(AValue: TPlayerMode);
    288290    function SetMove(CellFrom, CellTo: TCell; Power: Integer; Confirmation: Boolean = True): TUnitMove;
    289291    procedure UpdateRepeatMoves;
     292    procedure RemoveEmptyUnitMoves;
    290293  public
    291294    Id: Integer;
     
    441444    procedure CalculatePlayersDistance;
    442445    procedure PropagatePlayerDistance(List: TCells);
     446    procedure InitDefaultPlayers;
    443447  public
    444448    Players: TPlayers;
     
    474478    constructor Create;
    475479    destructor Destroy; override;
     480    procedure Clear;
    476481    procedure New;
    477482    procedure EndGame(Winner: TPlayer = nil);
     
    963968  Move: TUnitMove;
    964969  CellText: string;
     970  CellLink: TCellLink;
    965971begin
    966972  with Canvas, View do
     
    971977    Pen.Style := psSolid;
    972978    Pen.Width := 3;
    973     for C := 0 to Player.Game.Map.CellLinks.Count - 1 do
    974     with TCellLink(Player.Game.Map.CellLinks[C]) do begin
     979    for CellLink in Player.Game.Map.CellLinks do
     980    with CellLink do begin
    975981      if Length(Points) >= 2 then begin
    976982        MoveTo(View.CellToCanvasPos(Points[0]));
     
    981987
    982988    // Draw cells
    983     for C := 0 to Cells.Count - 1 do begin
    984       Cell := TPlayerCell(Cells[C]);
     989    for Cell in Cells do begin
    985990      if (Cell.MapCell.Terrain <> ttVoid) and Cell.MapCell.IsVisible(View) then begin
    986991        if Cell.MapCell.Player = Player then
     
    10141019    // Draw arrows
    10151020    Pen.Color := clCream;
    1016     for I := 0 to Player.Moves.Count - 1 do begin
    1017       Move := TUnitMove(Player.Moves[I]);
     1021    for Move in Player.Moves do begin
    10181022      PosFrom := Player.Game.Map.CellToPos(Move.CellFrom);
    10191023      PosTo := Player.Game.Map.CellToPos(Move.CellTo);
     
    12361240  with Config do begin
    12371241    NewCount := GetValue(DOMString(Path + '/Count'), -1);
     1242    NewPlayerId := 1;
    12381243    if NewCount >= 2 then begin
    12391244      Self.Clear;
     
    12411246      for I := 0 to Count - 1 do begin
    12421247        Items[I] := TPlayer.Create;
     1248        TPlayer(Items[I]).Id := GetNewPlayerId;
    12431249        TPlayer(Items[I]).Game := Game;
    12441250        TPlayer(Items[I]).LoadConfig(Config, Path + '/Player' + IntToStr(I));
     
    16041610end;
    16051611
     1612procedure TMap.Clear;
     1613begin
     1614  CellLinks.Clear;
     1615  Cells.Clear;
     1616end;
     1617
    16061618constructor TMap.Create;
    16071619begin
     
    17601772    raise Exception.Create(SNegativeCellPowerNotAllowed);
    17611773  FPower := AValue;
     1774  //Check;
    17621775end;
    17631776
     
    20232036var
    20242037  NewNode: TDOMNode;
     2038  Move: TUnitMove;
    20252039begin
    20262040  Id := ReadInteger(Node, 'Id', 0);
     
    23112325procedure TComputer.IncreaseMoves;
    23122326var
    2313   I: Integer;
     2327  Move: TUnitMove;
    23142328  AvailPower: Integer;
    23152329begin
    23162330  // If available power remains then use all for existed unit moves
    2317   for I := 0 to Player.Moves.Count - 1 do
    2318   with TUnitMove(Player.Moves[I]) do begin
     2331  for Move in Player.Moves do
     2332  with Move do begin
    23192333    if CellFrom.GetAvialPower > 0 then begin
    23202334      AvailPower := CellFrom.GetAvialPower;
     
    24702484destructor TPlayer.Destroy;
    24712485begin
     2486  Client := nil;
    24722487  FreeAndNil(Computer);
    24732488  FreeAndNil(TurnStats);
     
    26452660      if CountOnce > CellFrom.Power then
    26462661        UnitCount := CellFrom.Power;
     2662      CountOnce := 0;
    26472663      if CellTo.Player = Self then begin
    26482664        // Inner move
     
    26652681      end;
    26662682      CellFrom.Power := CellFrom.Power - UnitCount;
    2667       CountOnce := 0;
    2668     end;
    2669     end;
    2670   end;
    2671 
    2672   // Remove empty moves
    2673   for I := Moves.Count - 1 downto 0 do
    2674   if (TUnitMove(Moves[I]).CellFrom.Player = Self) and
    2675     (TUnitMove(Moves[I]).CountOnce = 0) and (TUnitMove(Moves[I]).CountRepeat = 0) then
    2676     Moves.Delete(I);
     2683    end;
     2684    end;
     2685  end;
     2686
     2687  RemoveEmptyUnitMoves;
     2688end;
     2689
     2690procedure TPlayer.ReduceMovesPower;
     2691var
     2692  UnitMove: TUnitMove;
     2693  Power: Integer;
     2694begin
     2695  // Power of cell can be reduced by unsucessful enemy attack
     2696  for UnitMove in Moves do begin
     2697    Power := UnitMove.CellFrom.GetAvialPower;
     2698    if Power < 0 then begin
     2699      if Abs(Power) <= UnitMove.CountOnce then
     2700        UnitMove.CountOnce := UnitMove.CountOnce - Abs(Power)
     2701    end;
     2702  end;
    26772703end;
    26782704
     
    27402766      // Add new move
    27412767      if (CountOnce > 0) or (CountRepeat > 0) then begin
    2742         NewMove := TUnitMove(Moves[Moves.Add(TUnitMove.Create)]);
     2768        NewMove := TUnitMove.Create;
    27432769        NewMove.List := Moves;
    27442770        NewMove.CellFrom := CellFrom;
     
    27462772        NewMove.CountOnce := CountOnce;
    27472773        NewMove.CountRepeat := CountRepeat;
     2774        Moves.Add(NewMove);
    27482775        Result := NewMove;
    27492776        CheckCounterMove(NewMove);
     
    27832810        else CountOnce := CellFrom.GetAvialPower;
    27842811  end;
     2812  RemoveEmptyUnitMoves;
     2813end;
     2814
     2815procedure TPlayer.RemoveEmptyUnitMoves;
     2816var
     2817  I: Integer;
     2818begin
     2819  // Remove empty moves
     2820  for I := Moves.Count - 1 downto 0 do
     2821  if (TUnitMove(Moves[I]).CellFrom.Player = Self) and
     2822    (TUnitMove(Moves[I]).CountOnce = 0) and (TUnitMove(Moves[I]).CountRepeat = 0) then
     2823    Moves.Delete(I);
    27852824end;
    27862825
     
    28442883procedure TGame.BuildTerrain;
    28452884var
    2846   C: Integer;
     2885  Cell: TCell;
    28472886begin
    28482887  if (Map.Shape = msImage) and FileExists(MapImageFileName) and
     
    28532892
    28542893  // Randomize map terrain
    2855   for C := 0 to Map.Cells.Count - 1 do
    2856   with TCell(Map.Cells[C]) do begin
     2894  for Cell in Map.Cells do
     2895  with Cell do begin
    28572896    if (VoidEnabled and (Random < VoidPercentage / 100)) or
    28582897    (Map.IsOutsideShape(PosPx)) then Terrain := ttVoid
     
    29542993procedure TGame.InitClients;
    29552994var
    2956   I: Integer;
     2995  Client: TClient;
     2996  Player: TPlayer;
    29572997begin
    29582998  Clients.Clear;
    29592999  Clients.New('Spectator');
    2960   for I := 0 to Players.Count - 1 do
    2961   with TPlayer(Players[I]) do
     3000
     3001  for Player in Players do
     3002  with Player do
    29623003  if Mode = pmHuman then begin
    2963     Clients.New(TPlayer(Players[I]).Name);
    2964     TPlayer(Players[I]).Client := TClient(Clients.Last);
    2965   end;
    2966 
    2967   for I := 0 to Clients.Count - 1 do
    2968   with TClient(Clients[I]) do begin
     3004    Clients.New(Player.Name);
     3005    Player.Client := TClient(Clients.Last);
     3006  end;
     3007
     3008  for Client in Clients do
     3009  with Client do begin
    29693010    View.Clear;
    29703011    View.Zoom := 1;
     
    30413082    PropagatePlayerDistance(NeighborList);
    30423083  FreeAndNil(NeighborList);
     3084end;
     3085
     3086procedure TGame.InitDefaultPlayers;
     3087begin
     3088  Players.Clear;
     3089  Players.New(SPlayer + ' 1', clBlue, pmHuman);
     3090  Players.New(SPlayer + ' 2', clRed, pmComputer);
    30433091end;
    30443092
     
    31033151  RootNode: TDOMNode;
    31043152  I: Integer;
     3153  Move: TUnitMove;
    31053154begin
    31063155  Self.FileName := FileName;
     3156  Clear;
    31073157  ReadXMLFile(Doc, FileName);
    31083158  with Doc do try
     
    31363186
    31373187      InitClients;
    3138 
    31393188      Map.Cells.FixRefId;
    31403189
     
    32773326  CheckWinObjective;
    32783327  CurrentPlayer.PlayerMap.CheckVisibility;
     3328  CurrentPlayer.ReduceMovesPower;
    32793329  // For computers take view from previous human
    32803330  //if CurrentPlayer.Mode = pmComputer then CurrentPlayer.View.Assign(PrevPlayer.View);
     
    33233373  Randomize;
    33243374
    3325   Players.New(SPlayer + ' 1', clBlue, pmHuman);
    3326   Players.New(SPlayer + ' 2', clRed, pmComputer);
    3327 
    33283375  VoidEnabled := True;
    33293376  VoidPercentage := 20;
     
    33423389end;
    33433390
     3391procedure TGame.Clear;
     3392begin
     3393  Clients.Clear;
     3394  Players.Clear;
     3395  Map.Clear;
     3396end;
     3397
    33443398procedure TGame.New;
    33453399var
     
    33493403  Player: TPlayer;
    33503404begin
     3405  Clear;
    33513406  FileName := SNewGameFile;
    33523407  TurnCounter := 1;
    33533408
     3409  Map.Generate;
    33543410  BuildTerrain;
    33553411
    33563412  // Build bridges
    3357   Map.CellLinks.Clear;
    33583413  if BridgeEnabled then begin
    33593414    BuildMapAreas;
     
    33753430  end;
    33763431
     3432  InitDefaultPlayers;
    33773433  for Player in Players do Player.StartCell := nil;
    33783434  I := 0;
    33793435  for Player in Players do
    33803436  with Player do begin
    3381     Clear;
    33823437    PlayerMap.Update;
    33833438    if (Map.Size.X > 0) and (Map.Size.Y > 0) then begin
     
    34143469  ArrowCenter: TPoint;
    34153470  Move: TUnitMove;
     3471  CellLink: TCellLink;
    34163472begin
    34173473  with Canvas, View do
     
    34233479    Pen.Style := psSolid;
    34243480    Pen.Width := 3;
    3425     for C := 0 to CellLinks.Count - 1 do
    3426     with TCellLink(CellLinks[C]) do begin
     3481    for CellLink in CellLinks do
     3482    with CellLink do begin
    34273483      if Length(Points) >= 2 then begin
    34283484        MoveTo(View.CellToCanvasPos(Points[0]));
     
    34333489
    34343490    // Draw cells
    3435     for C := 0 to Cells.Count - 1 do begin
    3436       Cell := TCell(Cells[C]);
     3491    for Cell in Cells do begin
    34373492      if (Cell.Terrain <> ttVoid) and Cell.IsVisible(View) then begin
    34383493        if Assigned(SelectedCell) and (SelectedCell = Cell) then
     
    34493504    // Draw arrows
    34503505    Pen.Color := clCream;
    3451     for I := 0 to Game.CurrentPlayer.Moves.Count - 1 do begin
    3452       Move := TUnitMove(Game.CurrentPlayer.Moves[I]);
     3506    for Move in Game.CurrentPlayer.Moves do begin
    34533507      PosFrom := CellToPos(Move.CellFrom);
    34543508      PosTo := CellToPos(Move.CellTo);
Note: See TracChangeset for help on using the changeset viewer.