Changeset 404 for trunk/ClientGUI.pas


Ignore:
Timestamp:
Jan 6, 2025, 10:21:08 PM (2 days ago)
Author:
chronos
Message:
  • Fixed: Crash on cyclic map new move creation.
  • Modified: TView class moved into separate unit.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ClientGUI.pas

    r377 r404  
    55uses
    66  Types, Classes, SysUtils, Graphics, GameClient, Player, Map, Game, Geometry,
    7   Math;
     7  Math, View;
    88
    99type
    10   { TView }
    11 
    12   TView = class
    13   private
    14     FDestRect: TRect;
    15     FZoom: Double;
    16     procedure SetDestRect(AValue: TRect);
    17     procedure SetZoom(AValue: Double);
    18   public
    19     Game: TObject; // TGame;
    20     SourceRect: TRect;
    21     FocusedCell: TPlayerCell;
    22     SelectedCell: TPlayerCell;
    23     procedure Clear;
    24     function IsCellVisible(Cell: TCell): Boolean;
    25     constructor Create;
    26     destructor Destroy; override;
    27     procedure SelectCell(Pos: TPoint; Player: TPlayer; ShiftState: TShiftState);
    28     procedure CenterMap;
    29     procedure CenterPlayerCity(Player: TPlayer);
    30     procedure ZoomAll;
    31     function CanvasToCellPos(Pos: TPoint): TPoint;
    32     function CellToCanvasPos(Pos: TPoint): TPoint;
    33     function CellToCanvasPosF(Pos: TPointF): TPointF;
    34     function CanvasToCellRect(Pos: TRect): TRect;
    35     function CellToCanvasRect(Pos: TRect): TRect;
    36     function CellToCanvasRectF(Pos: TRectF): TRectF;
    37     procedure Assign(Source: TView);
    38     property DestRect: TRect read FDestRect write SetDestRect;
    39     property Zoom: Double read FZoom write SetZoom;
    40   end;
    41 
    4210  { TClientGUI }
    4311
     
    7341
    7442resourcestring
    75   SZeroZoomNotAlowed = 'Zero zoom not allowed';
    7643  SWrongArrowAngle = 'Wrong arrow angle %s';
    7744
     
    521488end;
    522489
    523 { TView }
    524 
    525 procedure TView.SetZoom(AValue: Double);
    526 begin
    527   if FZoom = AValue then Exit;
    528   if AValue = 0 then
    529     raise Exception.Create(SZeroZoomNotAlowed);
    530   FZoom := AValue;
    531   SourceRect := TRect.CreateBounds(TPoint.Create(Trunc(SourceRect.P1.X + SourceRect.Size.X div 2 - DestRect.Size.X / Zoom / 2),
    532     Trunc(SourceRect.P1.Y +  SourceRect.Size.Y div 2 - DestRect.Size.Y / Zoom / 2)),
    533     TPoint.Create(Trunc(DestRect.Size.X / Zoom),
    534     Trunc(DestRect.Size.Y / Zoom)));
    535 end;
    536 
    537 procedure TView.Clear;
    538 begin
    539   FocusedCell := nil;
    540   SelectedCell := nil;
    541 end;
    542 
    543 procedure TView.SetDestRect(AValue: TRect);
    544 var
    545   Diff: TPoint;
    546 begin
    547   if FDestRect = AValue then Exit;
    548   Diff := TPoint.Create(Trunc(DestRect.Size.X / Zoom - AValue.Size.X / Zoom) div 2,
    549     Trunc(DestRect.Size.Y / Zoom - AValue.Size.Y / Zoom) div 2);
    550   FDestRect := AValue;
    551   SourceRect := TRect.CreateBounds(TPoint.Create(SourceRect.P1.X + Diff.X, SourceRect.P1.Y + Diff.Y),
    552     TPoint.Create(Trunc(DestRect.Size.X / Zoom),
    553     Trunc(DestRect.Size.Y / Zoom)));
    554 end;
    555 
    556 constructor TView.Create;
    557 begin
    558   Zoom := 1.5;
    559   Clear;
    560 end;
    561 
    562 destructor TView.Destroy;
    563 begin
    564   inherited;
    565 end;
    566 
    567 function TView.CanvasToCellPos(Pos: TPoint): TPoint;
    568 begin
    569   Result := TPoint.Create(Trunc((Pos.X - DestRect.P1.X) / Zoom + SourceRect.P1.X),
    570     Trunc((Pos.Y - DestRect.P1.Y) / Zoom + SourceRect.P1.Y));
    571 end;
    572 
    573 function TView.CellToCanvasPos(Pos: TPoint): TPoint;
    574 begin
    575   Result := TPoint.Create(Trunc((Pos.X - SourceRect.P1.X) * Zoom) + DestRect.P1.X,
    576     Trunc((Pos.Y - SourceRect.P1.Y) * Zoom) + DestRect.P1.Y);
    577 end;
    578 
    579 function TView.CellToCanvasPosF(Pos: TPointF): TPointF;
    580 begin
    581   Result := TPointF.Create((Pos.X - SourceRect.P1.X) * Zoom + DestRect.P1.X,
    582     (Pos.Y - SourceRect.P1.Y) * Zoom + DestRect.P1.Y);
    583 end;
    584 
    585 function TView.CanvasToCellRect(Pos: TRect): TRect;
    586 begin
    587   Result.P1 := CanvasToCellPos(Pos.P1);
    588   Result.P2 := CanvasToCellPos(Pos.P2);
    589 end;
    590 
    591 function TView.CellToCanvasRect(Pos: TRect): TRect;
    592 begin
    593   Result.P1 := CellToCanvasPos(Pos.P1);
    594   Result.P2 := CellToCanvasPos(Pos.P2);
    595 end;
    596 
    597 function TView.CellToCanvasRectF(Pos: TRectF): TRectF;
    598 begin
    599   Result.P1 := CellToCanvasPosF(Pos.P1);
    600   Result.P2 := CellToCanvasPosF(Pos.P2);
    601 end;
    602 
    603 procedure TView.Assign(Source: TView);
    604 begin
    605   SourceRect := Source.SourceRect;
    606   FDestRect := Source.DestRect;
    607   FZoom := Source.Zoom;
    608   SelectedCell := Source.SelectedCell;
    609   FocusedCell := Source.FocusedCell;
    610 end;
    611 
    612 procedure TView.SelectCell(Pos: TPoint; Player: TPlayer; ShiftState: TShiftState);
    613 var
    614   NewSelectedCell: TPlayerCell;
    615   UnitMove: TUnitMove;
    616   I: Integer;
    617   CellPos: TPoint;
    618   R: TRect;
    619 begin
    620   if TGame(Game).Map.Cyclic then begin
    621     R := CellToCanvasRect(TGame(Game).Map.PixelRect);
    622     CellPos := TPoint.Create(
    623       ModNeg(Pos.X - R.P1.X, R.Size.X) + R.P1.X,
    624       ModNeg(Pos.Y - R.P1.Y, R.Size.Y) + R.P1.Y
    625     );
    626     NewSelectedCell := Player.PlayerMap.PosToCell(
    627       CanvasToCellPos(CellPos));
    628   end else begin
    629     NewSelectedCell := Player.PlayerMap.PosToCell(
    630       CanvasToCellPos(Pos));
    631   end;
    632   if Assigned(NewSelectedCell) then begin
    633     if Assigned(SelectedCell) and (NewSelectedCell <> SelectedCell) and
    634     TGame(Game).CurrentPlayer.IsAllowedMoveTarget(SelectedCell, NewSelectedCell) then begin
    635       if ssShift in ShiftState then begin
    636         // Make maximum unit move without confirmation dialog
    637         for I := SelectedCell.MovesFrom.Count - 1 downto 0 do begin
    638           Player.Moves.Remove(SelectedCell.MovesFrom[I]);
    639         end;
    640         TGame(Game).CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.MapCell.OneUnit.Power, False);
    641         SelectedCell := nil;
    642       end else
    643       if ssCtrl in ShiftState then begin
    644         // If CTRL key pressed then storno all moved from selected cell and
    645         // move all power to new selected cell
    646         for I := SelectedCell.MovesFrom.Count - 1 downto 0 do
    647           Player.Moves.Remove(SelectedCell.MovesFrom[I]);
    648         UnitMove := TGame(Game).CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.MapCell.OneUnit.Power, False);
    649         if Assigned(UnitMove) then
    650           UnitMove.CountRepeat := TGame(Player.Game).Map.MaxPower;
    651         if NewSelectedCell.MapCell.Player = Player then SelectedCell := NewSelectedCell
    652           else SelectedCell := nil;
    653       end else begin
    654         TGame(Game).CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.MapCell.OneUnit.Power);
    655         SelectedCell := nil;
    656       end;
    657     end else
    658     if not Assigned(SelectedCell) and (NewSelectedCell <> SelectedCell) and (NewSelectedCell.MapCell.Player = Player) then begin
    659       SelectedCell := NewSelectedCell
    660     end else
    661     if (NewSelectedCell = SelectedCell) and (NewSelectedCell.MapCell.Player = Player) then begin
    662       SelectedCell := nil;
    663     end;
    664   end;
    665 end;
    666 
    667 procedure TView.CenterMap;
    668 var
    669   MapRect: TRect;
    670 begin
    671   MapRect := TGame(Game).Map.PixelRect;
    672   SourceRect := TRect.CreateBounds(TPoint.Create(MapRect.P1.X + MapRect.Size.X div 2 - SourceRect.Size.X div 2,
    673     MapRect.P1.Y + MapRect.Size.Y div 2 - SourceRect.Size.Y div 2),
    674     TPoint.Create(SourceRect.Size.X,
    675     SourceRect.Size.Y));
    676 end;
    677 
    678 procedure TView.CenterPlayerCity(Player: TPlayer);
    679 begin
    680   SourceRect := TRect.CreateBounds(TPoint.Create(Player.StartCell.PosPx.X - SourceRect.Size.X div 2,
    681     Player.StartCell.PosPx.Y - SourceRect.Size.Y div 2),
    682     TPoint.Create(SourceRect.Size.X,
    683     SourceRect.Size.Y));
    684 end;
    685 
    686 procedure TView.ZoomAll;
    687 var
    688   Factor: TPointF;
    689   MapRect: TRect;
    690   NewZoom: Single;
    691 begin
    692   MapRect := TGame(Game).Map.CalculatePixelRect;
    693   Factor := TPointF.Create(DestRect.Size.X / MapRect.Size.X,
    694     DestRect.Size.Y / MapRect.Size.Y);
    695   if Factor.X < Factor.Y then NewZoom := Factor.X
    696     else NewZoom := Factor.Y;
    697   if NewZoom = 0 then NewZoom := 1;
    698   Zoom := NewZoom * 0.9;
    699   CenterMap;
    700 end;
    701 
    702 function TView.IsCellVisible(Cell: TCell): Boolean;
    703 var
    704   RectPolygon: TRect;
    705 begin
    706   RectPolygon := CellToCanvasRect(Cell.Polygon.GetRect);
    707   Result := (
    708     (RectPolygon.P1.X < DestRect.Size.X) and
    709     (RectPolygon.P2.X > 0) and
    710     (RectPolygon.P1.Y < DestRect.Size.Y) and
    711     (RectPolygon.P2.Y > 0)
    712   );
    713 end;
    714 
    715490end.
    716491
Note: See TracChangeset for help on using the changeset viewer.