source: tags/1.4.0/View.pas

Last change on this file was 409, checked in by chronos, 2 weeks ago

Merged revision(s) 403-408 from trunk:

  • Added: Cover image.
  • Fixed: Crash on cyclic map new move creation.
  • Modified: TView class moved into separate unit.
  • Added: French translation.
  • Fixed: Do not stop running game on Quit action.
  • Fixed: Cell cities were not correctly stored the saved game.
  • Fixed: ItemList references were loaded by item index instead of item id.
  • Fixed: Wrong default map image path initialization.
File size: 7.2 KB
Line 
1unit View;
2
3interface
4
5uses
6 Classes, SysUtils, Game, Player, Map, Geometry;
7
8type
9 { TView }
10
11 TView = class
12 private
13 FDestRect: TRect;
14 FZoom: Double;
15 procedure SetDestRect(AValue: TRect);
16 procedure SetZoom(AValue: Double);
17 public
18 Game: TGame;
19 SourceRect: TRect;
20 FocusedCell: TPlayerCell;
21 SelectedCell: TPlayerCell;
22 procedure Clear;
23 function IsCellVisible(Cell: TCell): Boolean;
24 constructor Create;
25 destructor Destroy; override;
26 procedure SelectCell(Pos: TPoint; Player: TPlayer; ShiftState: TShiftState);
27 procedure CenterMap;
28 procedure CenterPlayerCity(Player: TPlayer);
29 procedure ZoomAll;
30 function CanvasToCellPos(Pos: TPoint): TPoint;
31 function CellToCanvasPos(Pos: TPoint): TPoint;
32 function CellToCanvasPosF(Pos: TPointF): TPointF;
33 function CanvasToCellRect(Pos: TRect): TRect;
34 function CellToCanvasRect(Pos: TRect): TRect;
35 function CellToCanvasRectF(Pos: TRectF): TRectF;
36 procedure Assign(Source: TView);
37 property DestRect: TRect read FDestRect write SetDestRect;
38 property Zoom: Double read FZoom write SetZoom;
39 end;
40
41
42implementation
43
44resourcestring
45 SZeroZoomNotAlowed = 'Zero zoom not allowed';
46
47{ TView }
48
49procedure TView.SetZoom(AValue: Double);
50begin
51 if FZoom = AValue then Exit;
52 if AValue = 0 then
53 raise Exception.Create(SZeroZoomNotAlowed);
54 FZoom := AValue;
55 SourceRect := TRect.CreateBounds(TPoint.Create(Trunc(SourceRect.P1.X + SourceRect.Size.X div 2 - DestRect.Size.X / Zoom / 2),
56 Trunc(SourceRect.P1.Y + SourceRect.Size.Y div 2 - DestRect.Size.Y / Zoom / 2)),
57 TPoint.Create(Trunc(DestRect.Size.X / Zoom),
58 Trunc(DestRect.Size.Y / Zoom)));
59end;
60
61procedure TView.Clear;
62begin
63 FocusedCell := nil;
64 SelectedCell := nil;
65end;
66
67procedure TView.SetDestRect(AValue: TRect);
68var
69 Diff: TPoint;
70begin
71 if FDestRect = AValue then Exit;
72 Diff := TPoint.Create(Trunc(DestRect.Size.X / Zoom - AValue.Size.X / Zoom) div 2,
73 Trunc(DestRect.Size.Y / Zoom - AValue.Size.Y / Zoom) div 2);
74 FDestRect := AValue;
75 SourceRect := TRect.CreateBounds(TPoint.Create(SourceRect.P1.X + Diff.X, SourceRect.P1.Y + Diff.Y),
76 TPoint.Create(Trunc(DestRect.Size.X / Zoom),
77 Trunc(DestRect.Size.Y / Zoom)));
78end;
79
80constructor TView.Create;
81begin
82 Zoom := 1.5;
83 Clear;
84end;
85
86destructor TView.Destroy;
87begin
88 inherited;
89end;
90
91function TView.CanvasToCellPos(Pos: TPoint): TPoint;
92begin
93 Result := TPoint.Create(Trunc((Pos.X - DestRect.P1.X) / Zoom + SourceRect.P1.X),
94 Trunc((Pos.Y - DestRect.P1.Y) / Zoom + SourceRect.P1.Y));
95end;
96
97function TView.CellToCanvasPos(Pos: TPoint): TPoint;
98begin
99 Result := TPoint.Create(Trunc((Pos.X - SourceRect.P1.X) * Zoom) + DestRect.P1.X,
100 Trunc((Pos.Y - SourceRect.P1.Y) * Zoom) + DestRect.P1.Y);
101end;
102
103function TView.CellToCanvasPosF(Pos: TPointF): TPointF;
104begin
105 Result := TPointF.Create((Pos.X - SourceRect.P1.X) * Zoom + DestRect.P1.X,
106 (Pos.Y - SourceRect.P1.Y) * Zoom + DestRect.P1.Y);
107end;
108
109function TView.CanvasToCellRect(Pos: TRect): TRect;
110begin
111 Result.P1 := CanvasToCellPos(Pos.P1);
112 Result.P2 := CanvasToCellPos(Pos.P2);
113end;
114
115function TView.CellToCanvasRect(Pos: TRect): TRect;
116begin
117 Result.P1 := CellToCanvasPos(Pos.P1);
118 Result.P2 := CellToCanvasPos(Pos.P2);
119end;
120
121function TView.CellToCanvasRectF(Pos: TRectF): TRectF;
122begin
123 Result.P1 := CellToCanvasPosF(Pos.P1);
124 Result.P2 := CellToCanvasPosF(Pos.P2);
125end;
126
127procedure TView.Assign(Source: TView);
128begin
129 SourceRect := Source.SourceRect;
130 FDestRect := Source.DestRect;
131 FZoom := Source.Zoom;
132 SelectedCell := Source.SelectedCell;
133 FocusedCell := Source.FocusedCell;
134end;
135
136procedure TView.SelectCell(Pos: TPoint; Player: TPlayer; ShiftState: TShiftState);
137var
138 NewSelectedCell: TPlayerCell;
139 UnitMove: TUnitMove;
140 I: Integer;
141 CellPos: TPoint;
142 R: TRect;
143begin
144 if TGame(Game).Map.Cyclic then begin
145 R := CellToCanvasRect(TGame(Game).Map.PixelRect);
146 CellPos := TPoint.Create(
147 ModNeg(Pos.X - R.P1.X, R.Size.X) + R.P1.X,
148 ModNeg(Pos.Y - R.P1.Y, R.Size.Y) + R.P1.Y
149 );
150 NewSelectedCell := Player.PlayerMap.PosToCell(
151 CanvasToCellPos(CellPos));
152 end else begin
153 NewSelectedCell := Player.PlayerMap.PosToCell(
154 CanvasToCellPos(Pos));
155 end;
156 if Assigned(NewSelectedCell) then begin
157 if Assigned(SelectedCell) and (NewSelectedCell <> SelectedCell) and
158 TGame(Game).CurrentPlayer.IsAllowedMoveTarget(SelectedCell, NewSelectedCell) then begin
159 if ssShift in ShiftState then begin
160 // Make maximum unit move without confirmation dialog
161 for I := SelectedCell.MovesFrom.Count - 1 downto 0 do begin
162 Player.Moves.Remove(SelectedCell.MovesFrom[I]);
163 end;
164 TGame(Game).CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.MapCell.OneUnit.Power, False);
165 SelectedCell := nil;
166 end else
167 if ssCtrl in ShiftState then begin
168 // If CTRL key pressed then storno all moved from selected cell and
169 // move all power to new selected cell
170 for I := SelectedCell.MovesFrom.Count - 1 downto 0 do
171 Player.Moves.Remove(SelectedCell.MovesFrom[I]);
172 UnitMove := TGame(Game).CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.MapCell.OneUnit.Power, False);
173 if Assigned(UnitMove) then
174 UnitMove.CountRepeat := TGame(Player.Game).Map.MaxPower;
175 if NewSelectedCell.MapCell.Player = Player then SelectedCell := NewSelectedCell
176 else SelectedCell := nil;
177 end else begin
178 TGame(Game).CurrentPlayer.SetMove(SelectedCell, NewSelectedCell, SelectedCell.MapCell.OneUnit.Power);
179 SelectedCell := nil;
180 end;
181 end else
182 if not Assigned(SelectedCell) and (NewSelectedCell <> SelectedCell) and (NewSelectedCell.MapCell.Player = Player) then begin
183 SelectedCell := NewSelectedCell
184 end else
185 if (NewSelectedCell = SelectedCell) and (NewSelectedCell.MapCell.Player = Player) then begin
186 SelectedCell := nil;
187 end;
188 end;
189end;
190
191procedure TView.CenterMap;
192var
193 MapRect: TRect;
194begin
195 MapRect := TGame(Game).Map.PixelRect;
196 SourceRect := TRect.CreateBounds(TPoint.Create(MapRect.P1.X + MapRect.Size.X div 2 - SourceRect.Size.X div 2,
197 MapRect.P1.Y + MapRect.Size.Y div 2 - SourceRect.Size.Y div 2),
198 TPoint.Create(SourceRect.Size.X,
199 SourceRect.Size.Y));
200end;
201
202procedure TView.CenterPlayerCity(Player: TPlayer);
203begin
204 SourceRect := TRect.CreateBounds(TPoint.Create(Player.StartCell.PosPx.X - SourceRect.Size.X div 2,
205 Player.StartCell.PosPx.Y - SourceRect.Size.Y div 2),
206 TPoint.Create(SourceRect.Size.X,
207 SourceRect.Size.Y));
208end;
209
210procedure TView.ZoomAll;
211var
212 Factor: TPointF;
213 MapRect: TRect;
214 NewZoom: Single;
215begin
216 MapRect := TGame(Game).Map.CalculatePixelRect;
217 Factor := TPointF.Create(DestRect.Size.X / MapRect.Size.X,
218 DestRect.Size.Y / MapRect.Size.Y);
219 if Factor.X < Factor.Y then NewZoom := Factor.X
220 else NewZoom := Factor.Y;
221 if NewZoom = 0 then NewZoom := 1;
222 Zoom := NewZoom * 0.9;
223 CenterMap;
224end;
225
226function TView.IsCellVisible(Cell: TCell): Boolean;
227var
228 RectPolygon: TRect;
229begin
230 RectPolygon := CellToCanvasRect(Cell.Polygon.GetRect);
231 Result := (
232 (RectPolygon.P1.X < DestRect.Size.X) and
233 (RectPolygon.P2.X > 0) and
234 (RectPolygon.P1.Y < DestRect.Size.Y) and
235 (RectPolygon.P2.Y > 0)
236 );
237end;
238
239end.
240
Note: See TracBrowser for help on using the repository browser.