Changeset 127 for trunk/UEngine.pas
- Timestamp:
- Apr 25, 2023, 10:52:20 PM (13 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UEngine.pas
r126 r127 20 20 TMetroTrain = class; 21 21 22 TStationStyle = (ssShapes, ssLinear, ssAlpha); 23 22 24 { TMapStation } 23 25 … … 28 30 public 29 31 Engine: TEngine; 30 Shape: TStationShape;32 DestinationIndex: TDestinationIndex; 31 33 Position: TPoint; 32 34 Passengers: TMetroPassengers; 33 35 Lines: TMetroLines; 34 ShapeDistance: array[TStationShape]of Integer;36 DestinationDistance: array of Integer; 35 37 OverloadDuration: TDateTime; 36 38 IsTerminal: Boolean; 37 39 function GetMaxPassengers: Integer; 38 function IsBestStationForShape( Shape: TStationShape; Check, Current: TLineStation): Boolean;40 function IsBestStationForShape(DestinationIndex: TDestinationIndex; Check, Current: TLineStation): Boolean; 39 41 procedure LoadFromXmlNode(Node: TDOMNode); 40 42 procedure SaveToXmlNode(Node: TDOMNode); … … 183 185 end; 184 186 187 TVisualStyle = (vsLondon, vsPrague); 188 185 189 { TEngine } 186 190 … … 189 193 FDarkMode: Boolean; 190 194 FFullScreen: Boolean; 195 FMovableTracks: Boolean; 191 196 FOnDarkModeChange: TNotifyEvent; 192 197 FOnExit: TNotifyEvent; 193 198 FOnFullScreenChange: TFullScrenChangeEvent; 194 199 FState: TGameState; 200 FStationStyle: TStationStyle; 195 201 FTranslator: TTranslator; 202 FVisualStyle: TVisualStyle; 196 203 LastMousePos: TPoint; 197 204 LastFocusedStation: TMapStation; … … 210 217 MenuCareer: TMenu; 211 218 MenuGame: TMenu; 219 MenuCustomGame: TMenu; 212 220 LastState: TGameState; 213 221 TimePerSecond: TDateTime; … … 220 228 GrabbedTrainDirection: Integer; 221 229 LastGrabbedTrain: TMetroTrain; 230 function GetMetroLineThickness: Integer; 222 231 function GetServedDaysCount: Integer; 232 function DestinationIndexToText(DestinationIndex: TDestinationIndex): string; 233 function DestinationIndexToShape(DestinationIndex: TDestinationIndex): TDestinationShape; 223 234 procedure ResizeView(Force: Boolean); 224 function GetExistStation Shapes: TStationShapeSet;235 function GetExistStationDestinationIndex(DestinationIndex: TDestinationIndex): Boolean; 225 236 function GetStationOnPos(Pos: TPoint): TMapStation; 226 237 function GetTrackOnPos(Pos: TPoint; out Intersect: TPoint): TTrackLink; … … 229 240 procedure DrawFrame(Canvas: TCanvas; Rect: TRect); 230 241 procedure DrawLine(Canvas: TCanvas; Pos: TPoint); 231 procedure DrawShape(Canvas: TCanvas; Position: TPoint; Shape: T StationShape;242 procedure DrawShape(Canvas: TCanvas; Position: TPoint; Shape: TDestinationShape; 232 243 Size: Integer; Angle: Double); 233 244 procedure DrawClock(Canvas: TCanvas; CanvasSize: TPoint); … … 244 255 procedure DrawGrabbed(Canvas: TCanvas; CanvasSize: TPoint); 245 256 procedure ComputeShapeDistance; 246 procedure Compute ShapeDistanceStation(Station: TMapStation;247 Updated Shape: TStationShape; Distance: Integer);257 procedure ComputeDestinationIndexDistanceStation(Station: TMapStation; 258 UpdatedDestinationIndex: TDestinationIndex; Distance: Integer); 248 259 procedure SetDarkMode(AValue: Boolean); 249 260 procedure SetFullScreen(AValue: Boolean); … … 258 269 procedure MenuItemCareer(Sender: TObject); 259 270 procedure MenuItemOptions(Sender: TObject); 271 procedure MenuItemCustomGame(Sender: TObject); 272 procedure MenuItemCustomPlay(Sender: TObject); 260 273 procedure MenuItemGameContinue(Sender: TObject); 261 274 procedure MenuItemGameExit(Sender: TObject); … … 272 285 procedure LanguageChanged(Sender: TObject); 273 286 procedure FullScreenChanged(Sender: TObject); 287 procedure MovableTrackChanged(Sender: TObject); 288 procedure StationStyleChanged(Sender: TObject); 289 procedure VisualStyleChanged(Sender: TObject); 274 290 procedure UpdateInterface; 275 291 function GetImprovementText(Improvement: TMetroImprovement): string; … … 288 304 Trains: TMetroTrains; 289 305 Carriages: TMetroCarriages; 290 ShapeCount: Integer;306 DestinationCount: Integer; 291 307 Map: TMap; 292 308 View: TView; … … 344 360 property ServedDaysCount: Integer read GetServedDaysCount; 345 361 published 362 property MovableTracks: Boolean read FMovableTracks write FMovableTracks; 363 property VisualStyle: TVisualStyle read FVisualStyle write FVisualStyle; 364 property StationStyle: TStationStyle read FStationStyle write FStationStyle; 346 365 property DarkMode: Boolean read FDarkMode write SetDarkMode; 347 366 property FullScreen: Boolean read FFullScreen write SetFullScreen; … … 402 421 STrain = 'Train'; 403 422 SPlay = 'Play'; 423 SCustomGame = 'Custom game'; 404 424 SOptions = 'Options'; 405 425 SExit = 'Exit'; … … 407 427 SDarkMode = 'Dark mode'; 408 428 SLanguage = 'Language'; 429 SMovableTrack = 'Movable track'; 409 430 SCzech = 'Czech'; 410 431 SEnglish = 'English'; … … 425 446 SUnlockedCity = 'City %s is now unlocked.'; 426 447 SWrongFileFormat = 'Wrong file format'; 448 SVisualStyle = 'Visual style'; 449 SStationStyle = 'Station style'; 427 450 428 451 // Cities … … 435 458 SSeoul = 'Seoul'; 436 459 SBeijing = 'Beijing'; 460 461 // Station styles 462 SShapes = 'Shapes'; 463 SLinear = 'Linear'; 464 SAlpha = 'Alpha'; 465 466 var 467 StationStyleText: array[TStationStyle] of string = (SShapes, SLinear, SAlpha); 468 VisualStyleText: array[TVisualStyle] of string = (SLondon, SPrague); 437 469 438 470 { TClock } … … 659 691 until (MinD > StationMinDistance) or 660 692 (Pass > 1000) or (Engine.Stations.Count = 0); 661 Result. Shape := TStationShape(Random(Integer(Engine.ShapeCount)));693 Result.DestinationIndex := Random(Engine.DestinationCount); 662 694 Add(Result); 663 695 Engine.ComputeShapeDistance; … … 1139 1171 // Get orthogonal angle 1140 1172 HAngle := (Angle + Pi / 2) mod Pi; 1141 NewShift.X := Trunc( MetroLineThickness * Cos(HAngle) * (J - (TrackLinks.Count - 1) / 2));1142 NewShift.Y := Trunc( MetroLineThickness * Sin(HAngle) * (J - (TrackLinks.Count - 1) / 2));1173 NewShift.X := Trunc(Engine.GetMetroLineThickness * Cos(HAngle) * (J - (TrackLinks.Count - 1) / 2)); 1174 NewShift.Y := Trunc(Engine.GetMetroLineThickness * Sin(HAngle) * (J - (TrackLinks.Count - 1) / 2)); 1143 1175 Shift := NewShift; 1144 1176 end; … … 1167 1199 end; 1168 1200 1169 function TMapStation.IsBestStationForShape( Shape: TStationShape;1201 function TMapStation.IsBestStationForShape(DestinationIndex: TDestinationIndex; 1170 1202 Check, Current: TLineStation): Boolean; 1171 1203 var … … 1213 1245 end else DirectionUp := False; 1214 1246 end; 1215 if DirectionDown and (NextStationDown.MapStation. ShapeDistance[Shape] <> -1) and1216 (NextStationDown.MapStation. ShapeDistance[Shape] < Distance) then begin1217 Distance := NextStationDown.MapStation. ShapeDistance[Shape];1218 end; 1219 if DirectionUp and (NextStationUp.MapStation. ShapeDistance[Shape] <> -1) and1220 (NextStationUp.MapStation. ShapeDistance[Shape] < Distance) then begin1221 Distance := NextStationUp.MapStation. ShapeDistance[Shape];1222 end; 1223 end; 1224 Result := (Check.MapStation. ShapeDistance[Shape] <> -1) and1225 (Check.MapStation. ShapeDistance[Shape] <= Distance);1247 if DirectionDown and (NextStationDown.MapStation.DestinationDistance[DestinationIndex] <> -1) and 1248 (NextStationDown.MapStation.DestinationDistance[DestinationIndex] < Distance) then begin 1249 Distance := NextStationDown.MapStation.DestinationDistance[DestinationIndex]; 1250 end; 1251 if DirectionUp and (NextStationUp.MapStation.DestinationDistance[DestinationIndex] <> -1) and 1252 (NextStationUp.MapStation.DestinationDistance[DestinationIndex] < Distance) then begin 1253 Distance := NextStationUp.MapStation.DestinationDistance[DestinationIndex]; 1254 end; 1255 end; 1256 Result := (Check.MapStation.DestinationDistance[DestinationIndex] <> -1) and 1257 (Check.MapStation.DestinationDistance[DestinationIndex] <= Distance); 1226 1258 end; 1227 1259 … … 1230 1262 Position.X := ReadInteger(Node, 'PositionX', Position.X); 1231 1263 Position.Y := ReadInteger(Node, 'PositionY', Position.Y); 1232 Shape := TStationShape(ReadInteger(Node, 'Shape', Integer(Shape)));1264 DestinationIndex := ReadInteger(Node, 'DestinationIndex', Integer(DestinationIndex)); 1233 1265 IsTerminal := ReadBoolean(Node, 'IsTerminal', IsTerminal); 1234 1266 end; … … 1238 1270 WriteInteger(Node, 'PositionX', Position.X); 1239 1271 WriteInteger(Node, 'PositionY', Position.Y); 1240 WriteInteger(Node, ' Shape', Integer(Shape));1272 WriteInteger(Node, 'DestinationIndex', DestinationIndex); 1241 1273 WriteBoolean(Node, 'IsTerminal', IsTerminal); 1242 1274 end; … … 1248 1280 Lines := TMetroLines.Create; 1249 1281 Lines.OwnsObjects := False; 1282 SetLength(DestinationDistance, Integer(High(TDestinationShape)) + 1); 1250 1283 end; 1251 1284 … … 1287 1320 end; 1288 1321 1322 function TEngine.GetMetroLineThickness: Integer; 1323 begin 1324 case VisualStyle of 1325 vsLondon: Result := MetroLineThickness; 1326 vsPrague: Result := Round(3 * MetroLineThickness); 1327 end; 1328 end; 1329 1289 1330 function TEngine.GetServedDaysCount: Integer; 1290 1331 begin … … 1292 1333 end; 1293 1334 1294 function TEngine.GetExistStationShapes: TStationShapeSet; 1335 function TEngine.GetExistStationDestinationIndex( 1336 DestinationIndex: TDestinationIndex): Boolean; 1295 1337 var 1296 1338 Station: TMapStation; 1297 1339 begin 1298 Result := [];1340 Result := False; 1299 1341 for Station in Stations do 1300 Result := Result + [Station.Shape]; 1342 if Station.DestinationIndex = DestinationIndex then 1343 Result := True; 1301 1344 end; 1302 1345 … … 1409 1452 end; 1410 1453 1411 procedure TEngine.DrawShape(Canvas: TCanvas; Position: TPoint; Shape: T StationShape;1454 procedure TEngine.DrawShape(Canvas: TCanvas; Position: TPoint; Shape: TDestinationShape; 1412 1455 Size: Integer; Angle: Double); 1413 1456 var … … 1539 1582 procedure TEngine.ComputeShapeDistance; 1540 1583 var 1541 S: T StationShape;1584 S: TDestinationIndex; 1542 1585 Station: TMapStation; 1543 1586 begin … … 1545 1588 for Station in Stations do 1546 1589 with Station do begin 1547 for S := Low( ShapeDistance) to High(ShapeDistance) do1548 ShapeDistance[S] := -1;1590 for S := Low(DestinationDistance) to High(DestinationDistance) do 1591 DestinationDistance[S] := -1; 1549 1592 end; 1550 1593 … … 1553 1596 for Station in Stations do 1554 1597 with Station do begin 1555 Compute ShapeDistanceStation(Station, Shape, 0);1556 end; 1557 end; 1558 1559 procedure TEngine.Compute ShapeDistanceStation(Station: TMapStation;1560 Updated Shape: TStationShape; Distance: Integer);1598 ComputeDestinationIndexDistanceStation(Station, DestinationIndex, 0); 1599 end; 1600 end; 1601 1602 procedure TEngine.ComputeDestinationIndexDistanceStation(Station: TMapStation; 1603 UpdatedDestinationIndex: TDestinationIndex; Distance: Integer); 1561 1604 var 1562 1605 I: Integer; … … 1567 1610 begin 1568 1611 with Station do begin 1569 if (Distance < ShapeDistance[UpdatedShape]) or (ShapeDistance[UpdatedShape] = -1) then begin1570 ShapeDistance[UpdatedShape] := Distance;1612 if (Distance < DestinationDistance[UpdatedDestinationIndex]) or (DestinationDistance[UpdatedDestinationIndex] = -1) then begin 1613 DestinationDistance[UpdatedDestinationIndex] := Distance; 1571 1614 // Do for all lines connected to station 1572 1615 for I := 0 to Lines.Count - 1 do … … 1577 1620 // Update for all adjecent stations 1578 1621 if StationIndex > 0 then 1579 Compute ShapeDistanceStation(LineStations[StationIndex - 1].MapStation,1580 Updated Shape, Station.ShapeDistance[UpdatedShape] + 1);1622 ComputeDestinationIndexDistanceStation(LineStations[StationIndex - 1].MapStation, 1623 UpdatedDestinationIndex, Station.DestinationDistance[UpdatedDestinationIndex] + 1); 1581 1624 if (StationIndex >= 0) and (StationIndex < LineStations.Count - 1) then 1582 Compute ShapeDistanceStation(LineStations[StationIndex + 1].MapStation,1583 Updated Shape, Station.ShapeDistance[UpdatedShape] + 1);1625 ComputeDestinationIndexDistanceStation(LineStations[StationIndex + 1].MapStation, 1626 UpdatedDestinationIndex, Station.DestinationDistance[UpdatedDestinationIndex] + 1); 1584 1627 end else begin 1585 1628 // If circular then trains might go in single direction so passengers … … 1591 1634 if Trains[T].Direction = -1 then DirectionDown := True; 1592 1635 end; 1636 1593 1637 // Update for all adjecent stations 1594 1638 if DirectionUp then begin 1595 1639 if StationIndex = 0 then 1596 Compute ShapeDistanceStation(LineStations[LineStations.Count - 2].MapStation,1597 Updated Shape, Station.ShapeDistance[UpdatedShape] + 1);1640 ComputeDestinationIndexDistanceStation(LineStations[LineStations.Count - 2].MapStation, 1641 UpdatedDestinationIndex, Station.DestinationDistance[UpdatedDestinationIndex] + 1); 1598 1642 if StationIndex > 0 then 1599 Compute ShapeDistanceStation(LineStations[StationIndex - 1].MapStation,1600 Updated Shape, Station.ShapeDistance[UpdatedShape] + 1);1643 ComputeDestinationIndexDistanceStation(LineStations[StationIndex - 1].MapStation, 1644 UpdatedDestinationIndex, Station.DestinationDistance[UpdatedDestinationIndex] + 1); 1601 1645 end; 1602 1646 if DirectionDown then begin 1603 1647 if (StationIndex >= 0) and (StationIndex = LineStations.Count - 1) then 1604 Compute ShapeDistanceStation(LineStations[1].MapStation,1605 Updated Shape, Station.ShapeDistance[UpdatedShape] + 1);1648 ComputeDestinationIndexDistanceStation(LineStations[1].MapStation, 1649 UpdatedDestinationIndex, Station.DestinationDistance[UpdatedDestinationIndex] + 1); 1606 1650 if (StationIndex >= 0) and (StationIndex < LineStations.Count - 1) then 1607 Compute ShapeDistanceStation(LineStations[StationIndex + 1].MapStation,1608 Updated Shape, Station.ShapeDistance[UpdatedShape] + 1);1651 ComputeDestinationIndexDistanceStation(LineStations[StationIndex + 1].MapStation, 1652 UpdatedDestinationIndex, Station.DestinationDistance[UpdatedDestinationIndex] + 1); 1609 1653 end; 1610 1654 end; … … 1689 1733 if Assigned(CurrentStation) then begin 1690 1734 for P := Passengers.Count - 1 downto 0 do begin 1691 if Passengers[P]. Shape = CurrentStation.MapStation.Shapethen begin1735 if Passengers[P].DestinationIndex = CurrentStation.MapStation.DestinationIndex then begin 1692 1736 Passenger := Passengers[P]; 1693 1737 Passengers.Delete(P); … … 1699 1743 with Carriages[J] do begin 1700 1744 for P := Passengers.Count - 1 downto 0 do begin 1701 if Passengers[P]. Shape = CurrentStation.MapStation.Shapethen begin1745 if Passengers[P].DestinationIndex = CurrentStation.MapStation.DestinationIndex then begin 1702 1746 Passenger := Passengers[P]; 1703 1747 Passengers.Delete(P); … … 1712 1756 if Assigned(CurrentStation) then begin 1713 1757 for P := Passengers.Count - 1 downto 0 do begin 1714 if not CurrentStation.MapStation.IsBestStationForShape(Passengers[P]. Shape,1758 if not CurrentStation.MapStation.IsBestStationForShape(Passengers[P].DestinationIndex, 1715 1759 TargetStation, CurrentStation) then begin 1716 1760 Passenger := Passengers[P]; … … 1722 1766 with Carriages[J] do begin 1723 1767 for P := Passengers.Count - 1 downto 0 do begin 1724 if not CurrentStation.MapStation.IsBestStationForShape(Passengers[P]. Shape,1768 if not CurrentStation.MapStation.IsBestStationForShape(Passengers[P].DestinationIndex, 1725 1769 TargetStation, CurrentStation) then begin 1726 1770 Passenger := Passengers[P]; … … 1739 1783 if (Passengers.Count < TrainPassengerCount) then begin 1740 1784 Passenger := CurrentStation.MapStation.Passengers[P]; 1741 if CurrentStation.MapStation.IsBestStationForShape(Passenger. Shape,1785 if CurrentStation.MapStation.IsBestStationForShape(Passenger.DestinationIndex, 1742 1786 TargetStation, CurrentStation) then begin 1743 1787 CurrentStation.MapStation.Passengers.Delete(P); … … 1750 1794 if (Passengers.Count < TrainPassengerCount) then begin 1751 1795 Passenger := CurrentStation.MapStation.Passengers[P]; 1752 if CurrentStation.MapStation.IsBestStationForShape(Passenger. Shape,1796 if CurrentStation.MapStation.IsBestStationForShape(Passenger.DestinationIndex, 1753 1797 TargetStation, CurrentStation) then begin 1754 1798 CurrentStation.MapStation.Passengers.Delete(P); … … 1935 1979 1936 1980 procedure TEngine.MenuItemOptions(Sender: TObject); 1981 var 1982 VisualStyleIndex: TVisualStyle; 1983 StationStyleIndex: TStationStyle; 1937 1984 begin 1938 1985 MenuOptions.Parent := MenuMain; … … 1967 2014 Checked := FullScreen; 1968 2015 end; 2016 with AddComboBox(SVisualStyle, [], VisualStyleChanged) do begin 2017 TextSize := 40; 2018 TextColor := Colors.MenuItemText; 2019 TextDisabledColor := Colors.MenuItemDisabledText; 2020 BackgroundColor := Colors.MenuItemBackground; 2021 BackgroundSelectedColor := Colors.MenuItemBackgroundSelected; 2022 for VisualStyleIndex := Low(TVisualStyle) to High(TVisualStyle) do 2023 States.AddObject(VisualStyleText[VisualStyleIndex], TObject(VisualStyleIndex)); 2024 Index := States.IndexOfObject(TObject(VisualStyle)); 2025 if Index = -1 then Index := 0; 2026 end; 2027 with AddComboBox(SStationStyle, [], StationStyleChanged) do begin 2028 TextSize := 40; 2029 TextColor := Colors.MenuItemText; 2030 TextDisabledColor := Colors.MenuItemDisabledText; 2031 BackgroundColor := Colors.MenuItemBackground; 2032 BackgroundSelectedColor := Colors.MenuItemBackgroundSelected; 2033 for StationStyleIndex := Low(TStationStyle) to High(TStationStyle) do 2034 States.AddObject(StationStyleText[StationStyleIndex], TObject(StationStyleIndex)); 2035 Index := States.IndexOfObject(TObject(StationStyle)); 2036 if Index = -1 then Index := 0; 2037 end; 2038 with AddCheckBox(SMovableTrack, MovableTrackChanged) do begin 2039 TextSize := 40; 2040 TextColor := Colors.MenuItemText; 2041 TextDisabledColor := Colors.MenuItemDisabledText; 2042 BackgroundColor := Colors.MenuItemBackground; 2043 BackgroundSelectedColor := Colors.MenuItemBackgroundSelected; 2044 Checked := MovableTracks; 2045 end; 1969 2046 with AddButton(SBack, MenuItemBack) do begin 1970 2047 TextSize := 40; … … 1981 2058 end; 1982 2059 2060 procedure TEngine.MenuItemCustomGame(Sender: TObject); 2061 var 2062 VisualStyleIndex: TVisualStyle; 2063 StationStyleIndex: TStationStyle; 2064 begin 2065 MenuCustomGame.Parent := MenuMain; 2066 with MenuCustomGame, Items do begin 2067 Clear; 2068 with AddButton(SPlay, MenuItemCustomPlay) do begin 2069 TextSize := 40; 2070 TextColor := Colors.MenuItemText; 2071 TextDisabledColor := Colors.MenuItemDisabledText; 2072 BackgroundColor := Colors.MenuItemBackground; 2073 BackgroundSelectedColor := Colors.MenuItemBackgroundSelected; 2074 end; 2075 with AddButton(SBack, MenuItemBack) do begin 2076 TextSize := 40; 2077 TextColor := Colors.MenuItemText; 2078 TextDisabledColor := Colors.MenuItemDisabledText; 2079 BackgroundColor := Colors.MenuItemBackground; 2080 BackgroundSelectedColor := Colors.MenuItemBackgroundSelected; 2081 end; 2082 OnExit := MenuItemBack; 2083 end; 2084 2085 Menu := MenuCustomGame; 2086 Redraw; 2087 end; 2088 2089 procedure TEngine.MenuItemCustomPlay(Sender: TObject); 2090 begin 2091 City := nil; 2092 NewGame; 2093 end; 2094 1983 2095 procedure TEngine.MenuItemBack(Sender: TObject); 1984 2096 begin … … 2112 2224 end; 2113 2225 2226 procedure TEngine.MovableTrackChanged(Sender: TObject); 2227 begin 2228 MovableTracks := TMenuItemCheckBox(Sender).Checked; 2229 end; 2230 2231 procedure TEngine.StationStyleChanged(Sender: TObject); 2232 begin 2233 StationStyle := TStationStyle(TMenuItemComboBox(Sender).States.Objects[TMenuItemComboBox(Sender).Index]); 2234 end; 2235 2236 procedure TEngine.VisualStyleChanged(Sender: TObject); 2237 begin 2238 VisualStyle := TVisualStyle(TMenuItemComboBox(Sender).States.Objects[TMenuItemComboBox(Sender).Index]); 2239 end; 2240 2114 2241 procedure TEngine.UpdateInterface; 2115 2242 begin … … 2198 2325 miTerminal: Inc(AvailableTerminals); 2199 2326 end; 2327 end; 2328 2329 function TEngine.DestinationIndexToText(DestinationIndex: TDestinationIndex): string; 2330 begin 2331 case StationStyle of 2332 ssShapes: Result := ''; 2333 ssAlpha: Result := Chr(Ord('A') + Integer(DestinationIndex)); 2334 ssLinear: Result := IntToStr(1 + Integer(DestinationIndex)); 2335 end; 2336 end; 2337 2338 function TEngine.DestinationIndexToShape(DestinationIndex: TDestinationIndex): TDestinationShape; 2339 begin 2340 if StationStyle = ssShapes then Result := TDestinationShape(DestinationIndex) 2341 else Result := ssCircle; 2200 2342 end; 2201 2343 … … 2226 2368 BackgroundSelectedColor := Colors.MenuItemBackgroundSelected; 2227 2369 end; 2370 { 2371 with AddButton(SCustomGame, MenuItemCustomGame) do begin 2372 TextSize := 40; 2373 TextColor := Colors.MenuItemText; 2374 TextDisabledColor := Colors.MenuItemDisabledText; 2375 BackgroundColor := Colors.MenuItemBackground; 2376 BackgroundSelectedColor := Colors.MenuItemBackgroundSelected; 2377 end; 2378 } 2228 2379 with AddButton(SCareer, MenuItemCareer) do begin 2229 2380 TextSize := 40; … … 2351 2502 Carriage: TMetroCarriage; 2352 2503 Vector: TVector; 2504 Text: string; 2353 2505 begin 2354 2506 for Train in Trains do … … 2357 2509 Canvas.Brush.Color := Line.Color; 2358 2510 Canvas.Brush.Style := bsSolid; 2359 Canvas.Pen.Style := psClear; 2511 Canvas.Pen.Width := 1; 2512 case VisualStyle of 2513 vsLondon: Canvas.Pen.Style := psClear; 2514 vsPrague: begin 2515 Canvas.Pen.Style := psSolid; 2516 Canvas.Pen.Color := Colors.Text; 2517 end; 2518 end; 2360 2519 Vector := TrackPosition.GetVector; 2361 2520 Pos := Vector.Position; … … 2368 2527 Points[3] := RotatePoint(Pos, Point(Pos.X - TrainSize div 2, Pos.Y + TrainSize div 3), Angle); 2369 2528 Canvas.Polygon(Points); 2529 2530 Canvas.Pen.Style := psClear; 2370 2531 Canvas.Brush.Color := clWhite; 2371 2532 P := 0; … … 2375 2536 Pos.Y - Trunc(TrainSize div 6 * 1) + (P div 3) * TrainSize div 3); 2376 2537 ShapePos := RotatePoint(Pos, ShapePos, Angle); 2377 DrawShape(Canvas, ShapePos, Shape, TrainSize div 3, Angle + Pi / 2); 2538 if StationStyle = ssShapes then begin 2539 DrawShape(Canvas, ShapePos, DestinationIndexToShape(DestinationIndex), TrainSize div 3, Angle + Pi / 2); 2540 end else begin 2541 Text := DestinationIndexToText(DestinationIndex); 2542 if Text <> '' then begin 2543 Canvas.Brush.Style := bsClear; 2544 Canvas.Font.Color := clWhite; 2545 Canvas.Font.Size := Round(TrainSize * 0.15); 2546 Canvas.Font.Orientation := Round((-Angle / Pi * 180) * 10); 2547 Canvas.TextOut(ShapePos.X - Round(TrainSize * 0.15), 2548 ShapePos.Y - Round(TrainSize * 0.15), Text); 2549 Canvas.Font.Orientation := 0; 2550 end; 2551 end; 2378 2552 Inc(P); 2379 2553 end; … … 2384 2558 Canvas.Brush.Color := Line.Color; 2385 2559 Canvas.Brush.Style := bsSolid; 2386 Canvas.Pen.Style := psClear; 2560 case VisualStyle of 2561 vsLondon: Canvas.Pen.Style := psClear; 2562 vsPrague: begin 2563 Canvas.Pen.Style := psSolid; 2564 Canvas.Pen.Color := Colors.Text; 2565 end; 2566 end; 2387 2567 Vector := GetTrackPosition.GetVector; 2388 2568 Pos := Vector.Position; … … 2395 2575 Points[3] := RotatePoint(Pos, Point(Pos.X - TrainSize div 2, Pos.Y + TrainSize div 3), Angle); 2396 2576 Canvas.Polygon(Points); 2577 2578 Canvas.Pen.Style := psClear; 2397 2579 Canvas.Brush.Color := clWhite; 2398 2580 P := 0; … … 2402 2584 Pos.Y - Trunc(TrainSize div 6 * 1) + (P div 3) * TrainSize div 3); 2403 2585 ShapePos := RotatePoint(Pos, ShapePos, Angle); 2404 DrawShape(Canvas, ShapePos, Shape, TrainSize div 3, Angle + Pi / 2); 2586 if StationStyle = ssShapes then begin 2587 DrawShape(Canvas, ShapePos, DestinationIndexToShape(DestinationIndex), TrainSize div 3, Angle + Pi / 2); 2588 end else begin 2589 Text := DestinationIndexToText(DestinationIndex); 2590 if Text <> '' then begin 2591 Canvas.Brush.Style := bsClear; 2592 Canvas.Font.Color := clWhite; 2593 Canvas.Font.Size := Round(TrainSize * 0.15); 2594 Canvas.Font.Orientation := Round((-Angle / Pi * 180) * 10); 2595 Canvas.TextOut(ShapePos.X - Round(TrainSize * 0.15), 2596 ShapePos.Y - Round(TrainSize * 0.15), Text); 2597 Canvas.Font.Orientation := 0; 2598 end; 2599 end; 2405 2600 Inc(P); 2406 2601 end; … … 2672 2867 Canvas.Pen.Color := Color; 2673 2868 Canvas.Pen.Style := psSolid; 2674 Canvas.Pen.Width := MetroLineThickness;2869 Canvas.Pen.Width := GetMetroLineThickness; 2675 2870 if Track.Points.Count > 0 then Canvas.MoveTo(Track.Points[0].Position); 2676 2871 for S := 1 to Track.Points.Count - 1 do begin … … 2692 2887 (* Canvas.Pen.Color := Color; 2693 2888 Canvas.Pen.Style := psSolid; 2694 Canvas.Pen.Width := MetroLineThickness div 2;2889 Canvas.Pen.Width := GetMetroLineThickness div 2; 2695 2890 if Track.Points.Count > 0 then Canvas.MoveTo(Track.Points[0].PositionDesigned); 2696 2891 for S := 1 to Track.Points.Count - 1 do begin … … 2748 2943 Direction: Integer; 2749 2944 UsedStationSize: Integer; 2945 Text: string; 2750 2946 begin 2751 2947 Canvas.Pen.Width := 5; … … 2757 2953 2758 2954 if Assigned(SelectedLine) and (Lines.IndexOf(SelectedLine) <> -1) then begin 2955 case VisualStyle of 2956 vsLondon: begin 2957 Canvas.Brush.Style := bsClear; 2958 Canvas.Pen.Style := psSolid; 2959 Canvas.Pen.Color := SelectedLine.Color; 2960 end; 2961 vsPrague: begin 2962 Canvas.Brush.Style := bsSolid; 2963 Canvas.Brush.Color := SelectedLine.Color; 2964 Canvas.Pen.Style := psClear; 2965 Canvas.Pen.Color := Colors.Background; 2966 end; 2967 end; 2968 DrawShape(Canvas, Position, DestinationIndexToShape(Integer(DestinationIndex)), 2969 UsedStationSize + Canvas.Pen.Width + 4, 0); 2970 end; 2971 2972 case VisualStyle of 2973 vsLondon: begin 2974 Canvas.Brush.Style := bsSolid; 2975 Canvas.Brush.Color := Colors.ShapeBackground; 2976 Canvas.Pen.Color := Colors.Text; 2977 end; 2978 vsPrague: begin 2979 if Lines.Count = 0 then begin 2980 Canvas.Brush.Style := bsSolid; 2981 Canvas.Brush.Color := Colors.Background2; 2982 end else Canvas.Brush.Style := bsClear; 2983 Canvas.Pen.Style := psClear; 2984 end; 2985 end; 2986 DrawShape(Canvas, Position, DestinationIndexToShape(Integer(DestinationIndex)), 2987 UsedStationSize, 0); 2988 Text := DestinationIndexToText(Integer(DestinationIndex)); 2989 if Text <> '' then begin 2759 2990 Canvas.Brush.Style := bsClear; 2760 Canvas.Pen.Color := SelectedLine.Color; 2761 DrawShape(Canvas, Position, Shape, UsedStationSize + Canvas.Pen.Width + 4, 0); 2762 end; 2763 2764 Canvas.Brush.Color := Colors.ShapeBackground; 2765 Canvas.Brush.Style := bsSolid; 2766 Canvas.Pen.Color := Colors.Text; 2767 DrawShape(Canvas, Position, Shape, UsedStationSize, 0); 2991 Canvas.Font.Size := Round(UsedStationSize * 0.4); 2992 Canvas.Font.Color := Colors.Text; 2993 Canvas.Font.Style := [fsBold]; 2994 Canvas.TextOut(Position.X - Canvas.TextWidth(Text) div 2, 2995 Position.Y - Canvas.TextHeight(Text) div 2, Text); 2996 end; 2997 2998 // Draw station border 2999 if (VisualStyle = vsPrague) and (Lines.Count > 0) then begin 3000 Canvas.Brush.Style := bsClear; 3001 Canvas.Pen.Style := psSolid; 3002 Canvas.Pen.Color := Colors.Background; 3003 DrawShape(Canvas, Position, DestinationIndexToShape(Integer(DestinationIndex)), 3004 UsedStationSize + Canvas.Pen.Width + 4, 0); 3005 end; 2768 3006 2769 3007 // Draw passengers … … 2774 3012 for Passenger in Passengers do 2775 3013 with Passenger do begin 2776 DrawShape(Canvas, Point(Position.X + StationSize + PassengerPos.X, 2777 Position.Y - StationSize div 2 + PassengerPos.Y), 2778 Shape, PassengerSize, 0); 3014 if StationStyle = ssShapes then begin 3015 DrawShape(Canvas, Point(Position.X + StationSize + PassengerPos.X, 3016 Position.Y - StationSize div 2 + PassengerPos.Y), 3017 DestinationIndexToShape(DestinationIndex), PassengerSize, 0); 3018 end else begin 3019 Text := DestinationIndexToText(Integer(DestinationIndex)); 3020 if Text <> '' then begin 3021 Canvas.Brush.Style := bsClear; 3022 Canvas.Font.Size := Round(StationSize * 0.3); 3023 Canvas.Font.Color := Colors.Text; 3024 Canvas.Font.Style := [fsBold]; 3025 Canvas.TextOut(Position.X + StationSize + PassengerPos.X - Canvas.TextWidth(Text) div 2, 3026 Position.Y - StationSize div 2 + PassengerPos.Y - Canvas.TextHeight(Text) div 2, Text); 3027 end; 3028 end; 2779 3029 PassengerPos := Point(PassengerPos.X + Direction * (PassengerSize + 2), PassengerPos.Y); 2780 3030 if PassengerPos.X >= (PassengerSize + 2) * VisiblePassengersPerLine then begin … … 2794 3044 Text := ''; 2795 3045 for P := 0 to 5 do 2796 Text := Text + IntToStr( ShapeDistance[TStationShape(P)]) + ',';3046 Text := Text + IntToStr(DestinationDistance[TDestinationIndex(P)]) + ','; 2797 3047 Canvas.TextOut(Position.X + StationSize div 2, Position.Y + StationSize div 2, Text); 2798 3048 end; … … 3036 3286 if (Time - LastNewShapeTime) > NewShapePeriod then begin 3037 3287 LastNewShapeTime := Time; 3038 if ShapeCount <= Integer(High(TStationShape)) then Inc(ShapeCount);3288 if DestinationCount < Integer(High(TDestinationShape)) then Inc(DestinationCount); 3039 3289 Redraw; 3040 3290 end; … … 3055 3305 if Random < NewPassengerProbability then begin 3056 3306 Passenger := Self.Passengers.AddNew; 3057 Passenger. Shape := TStationShape(Random(Integer(ShapeCount)));3307 Passenger.DestinationIndex := Random(DestinationCount); 3058 3308 Passengers.Add(Passenger); 3059 3309 3060 // Passenger is not allowed to have same shape3061 while (Passenger. Shape = Shape) or3062 not (Passenger.Shape in GetExistStationShapes) do3063 Passenger. Shape := TStationShape((Integer(Passenger.Shape) + 1) mod Integer(ShapeCount));3310 // Passenger is not allowed to have same DestinationIndex 3311 while (Passenger.DestinationIndex = DestinationIndex) or 3312 not GetExistStationDestinationIndex(Passenger.DestinationIndex) do 3313 Passenger.DestinationIndex := (Passenger.DestinationIndex + 1) mod DestinationCount; 3064 3314 Redraw; 3065 3315 end; … … 3134 3384 if Assigned(Line) and not Assigned(LastFocusedStation) and Assigned(FocusedStation) then begin 3135 3385 if Assigned(TrackStationDown) and (TLineStation(TrackStationDown.OwnerPoint).MapStation = FocusedStation) then begin 3136 // Disconnect down 3137 CurrentTrackPoint := TrackStationDown; 3138 TrackStationDown := TrackStationDown.GetDown; 3139 Line.DisconnectStation(TLineStation(CurrentTrackPoint.OwnerPoint)); 3386 if MovableTracks then begin 3387 // Disconnect down 3388 CurrentTrackPoint := TrackStationDown; 3389 TrackStationDown := TrackStationDown.GetDown; 3390 Line.DisconnectStation(TLineStation(CurrentTrackPoint.OwnerPoint)); 3391 end; 3140 3392 end else 3141 3393 if Assigned(TrackStationUp) and (TLineStation(TrackStationUp.OwnerPoint).MapStation = FocusedStation) then begin 3142 // Disconnect up 3143 CurrentTrackPoint := TrackStationUp; 3144 if Assigned(TrackStationUp) then 3145 TrackStationUp := TrackStationUp.GetUp; 3146 Line.DisconnectStation(TLineStation(CurrentTrackPoint.OwnerPoint)); 3394 if MovableTracks then begin 3395 // Disconnect up 3396 CurrentTrackPoint := TrackStationUp; 3397 if Assigned(TrackStationUp) then 3398 TrackStationUp := TrackStationUp.GetUp; 3399 Line.DisconnectStation(TLineStation(CurrentTrackPoint.OwnerPoint)); 3400 end; 3147 3401 end else 3148 3402 if Assigned(Line) and ((not Line.IsCircular) or ((TrackStationDown <> nil) and (TrackStationUp <> nil))) and … … 3361 3615 else TrackStationUp := nil; 3362 3616 end; 3617 3618 if not MovableTracks and (Assigned(TrackStationDown) and Assigned(TrackStationUp)) then begin 3619 TrackStationDown := nil; 3620 TrackStationUp := nil; 3621 SelectedLine := nil; 3622 end; 3623 3363 3624 Track.Free; 3364 3625 Exit; … … 3491 3752 end; 3492 3753 AvailableImprovements := [miCarriage, miLine, miTerminal]; 3493 ShapeCount := 3;3754 DestinationCount := 3; 3494 3755 3495 3756 // Start with 3 stations with each different shape … … 3497 3758 for I := 0 to InitialStationCount - 1 do begin 3498 3759 NewStation := Stations.AddNew; 3499 if I = 0 then NewStation. Shape := ssSquare3500 else if I = 1 then NewStation. Shape := ssCircle3501 else if I = 2 then NewStation. Shape := ssTriangle;3760 if I = 0 then NewStation.DestinationIndex := Integer(ssSquare) 3761 else if I = 1 then NewStation.DestinationIndex := Integer(ssCircle) 3762 else if I = 2 then NewStation.DestinationIndex := Integer(ssTriangle); 3502 3763 end; 3503 3764 … … 3534 3795 HighestServedPassengerCount := ReadIntegerWithDefault('HighestPassengers', 0); 3535 3796 HighestServedDaysCount := ReadIntegerWithDefault('HighestDays', 0); 3797 StationStyle := TStationStyle(ReadIntegerWithDefault('StationStyle', Integer(ssShapes))); 3798 VisualStyle := TVisualStyle(ReadIntegerWithDefault('VisualStyle', Integer(vsLondon))); 3799 MovableTracks := ReadBoolWithDefault('MovableTracks', MovableTracks); 3536 3800 Cities.LoadFromRegistry(TRegistryContext.Create(RegistryContext.RootKey, RegistryContext.Key + '\Cities')); 3537 3801 finally … … 3549 3813 WriteInteger('HighestPassengers', HighestServedPassengerCount); 3550 3814 WriteInteger('HighestDays', HighestServedDaysCount); 3815 WriteInteger('StationStyle', Integer(StationStyle)); 3816 WriteInteger('VisualStyle', Integer(VisualStyle)); 3817 WriteBool('MovableTracks', MovableTracks); 3551 3818 Cities.SaveToRegistry(TRegistryContext.Create(RegistryContext.RootKey, RegistryContext.Key + '\Cities')); 3552 3819 finally … … 3625 3892 begin 3626 3893 inherited; 3894 MovableTracks := True; 3627 3895 Colors := TColors.Create; 3628 3896 Colors.Init(FDarkMode); … … 3639 3907 MenuCareer := TMenu.Create; 3640 3908 MenuGame := TMenu.Create; 3909 MenuCustomGame := TMenu.Create; 3641 3910 Menu := MenuMain; 3642 3911 InitMenus; … … 3699 3968 FreeAndNil(MenuMain); 3700 3969 FreeAndNil(MenuOptions); 3970 FreeAndNil(MenuCustomGame); 3701 3971 FreeAndNil(MenuCareer); 3702 3972 FreeAndNil(MenuGame);
Note:
See TracChangeset
for help on using the changeset viewer.