Changeset 17
- Timestamp:
- Mar 27, 2015, 11:19:18 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UEngine.pas
r16 r17 17 17 TMetroLine = class; 18 18 TMetroTrains = class; 19 20 { TMetroStation } 21 22 TMetroStation = class 19 TTrackPoint = class; 20 TLineStation = class; 21 22 { TMapStation } 23 24 TMapStation = class 23 25 private 24 26 public … … 29 31 Lines: TMetroLines; 30 32 ShapeDistance: array[TStationShape] of Integer; 31 function GetBestStationForShape(Shape: TStationShape; Check: TMetroStation; 32 CurrentStationIndex: Integer): Boolean; 33 function GetBestStationForShape(Shape: TStationShape; Check, Current: TLineStation): Boolean; 33 34 constructor Create; 34 35 destructor Destroy; override; 35 36 end; 36 37 37 { TM etroStations }38 39 TM etroStations = class(TObjectList)38 { TMapStations } 39 40 TMapStations = class(TObjectList) 40 41 Engine: TEngine; 41 function AddNew: TMetroStation; 42 function AddNew: TMapStation; 43 end; 44 45 TLineStation = class 46 Line: TMetroLine; 47 MapStation: TMapStation; 48 TrackPoint: TTrackPoint; 49 end; 50 51 { TLineStations } 52 53 TLineStations = class(TObjectList) 54 Line: TMetroLine; 55 function SearchMapStation(Station: TMapStation): TLineStation; 42 56 end; 43 57 44 58 TTrackPoint = class 45 59 Line: TMetroLine; 46 StationIndex: Integer;60 LineStation: TLineStation; 47 61 Point: TPoint; 48 62 Pending: Boolean; … … 58 72 Engine: TEngine; 59 73 Color: TColor; 60 Stations: TMetroStations;74 LineStations: TLineStations; 61 75 Trains: TMetroTrains; 62 76 TrackPoints: TTrackPoints; 63 procedure ConnectStation(Station: TM etroStation);64 procedure DisconnectStation(Station: TM etroStation);65 procedure AddTrack(P1, P2: TPoint; StationIndex: Integer);77 procedure ConnectStation(Station: TMapStation); 78 procedure DisconnectStation(Station: TMapStation); 79 procedure RouteTrack(TP1, TP2: TTrackPoint); 66 80 function GetTrackLength: Integer; 67 function GetStationTrackPos( StationIndex: Integer): Integer;81 function GetStationTrackPos(LineStation: TLineStation): Integer; 68 82 constructor Create; 69 83 destructor Destroy; override; … … 84 98 private 85 99 LastPosDelta: Integer; 86 function GetTargetStation: TMetroStation;87 100 public 88 101 Passengers: TMetroPassengers; … … 93 106 InStation: Boolean; 94 107 StationStopTime: TDateTime; 95 TargetStation Index: Integer;108 TargetStation: TLineStation; 96 109 function GetPosition: TPoint; 97 110 function GetAngle: Double; 98 111 constructor Create; 99 112 destructor Destroy; override; 100 property TargetStation: TMetroStation read GetTargetStation;101 113 end; 102 114 … … 112 124 Engine: TEngine; 113 125 Shape: TStationShape; 114 Station: TM etroStation;126 Station: TMapStation; 115 127 Train: TMetroTrain; 116 128 end; … … 138 150 private 139 151 LastMousePos: TPoint; 140 LastSelectedStation: TM etroStation;152 LastSelectedStation: TMapStation; 141 153 MouseHold: Boolean; 142 154 LastNewStationTime: TDateTime; … … 149 161 FTime: TDateTime; 150 162 function GetExistStationShapes: TStationShapeSet; 151 function GetStationOnPos(Pos: TPoint): TM etroStation;163 function GetStationOnPos(Pos: TPoint): TMapStation; 152 164 function GetLineOnPos(Pos: TPoint): TMetroLine; 153 165 procedure DrawLine(Canvas: TCanvas; Pos: TPoint); … … 157 169 procedure DrawTrains(Canvas: TCanvas); 158 170 procedure ComputeShapeDistance; 159 procedure ComputeShapeDistanceStation(Station: TM etroStation;171 procedure ComputeShapeDistanceStation(Station: TMapStation; 160 172 UpdatedShape: TStationShape; Distance: Integer); 161 173 procedure TrainMovement; 174 function GetUnusedLine: TMetroLine; 162 175 public 163 176 Passengers: TMetroPassengers; 164 Stations: TM etroStations;177 Stations: TMapStations; 165 178 Lines: TMetroLines; 166 179 Trains: TMetroTrains; … … 169 182 View: TView; 170 183 SelectedLine: TMetroLine; 171 SelectedStation: TM etroStation;184 SelectedStation: TMapStation; 172 185 ServedPassengerCount: Integer; 173 186 State: TGameState; … … 206 219 UGeometric; 207 220 221 { TLineStations } 222 223 function TLineStations.SearchMapStation(Station: TMapStation): TLineStation; 224 var 225 I: Integer; 226 begin 227 I := 0; 228 while (I < Count) and (TLineStation(Items[I]).MapStation <> Station) do Inc(I); 229 if I < Count then Result := TLineStation(Items[I]) 230 else Result := nil; 231 end; 232 208 233 { TMetroPassengers } 209 234 … … 243 268 end; 244 269 245 { TM etroStations }246 247 function TM etroStations.AddNew: TMetroStation;270 { TMapStations } 271 272 function TMapStations.AddNew: TMapStation; 248 273 var 249 274 D: Integer; … … 256 281 Step = 20; 257 282 begin 258 Result := TM etroStation.Create;283 Result := TMapStation.Create; 259 284 Result.Engine := Engine; 260 285 Angle := Random * 2 * Pi; … … 267 292 MinD := High(Integer); 268 293 for I := 0 to Engine.Stations.Count - 1 do begin 269 D := Distance(TM etroStation(Engine.Stations[I]).Position, Result.Position);294 D := Distance(TMapStation(Engine.Stations[I]).Position, Result.Position); 270 295 if D < MinD then MinD := D; 271 296 end; … … 301 326 { TMetroLine } 302 327 303 procedure TMetroLine.ConnectStation(Station: TM etroStation);328 procedure TMetroLine.ConnectStation(Station: TMapStation); 304 329 var 305 330 Train: TMetroTrain; 331 NewTrackPoint: TTrackPoint; 332 NewLineStation: TLineStation; 333 begin 334 NewLineStation := TLineStation.Create; 335 NewLineStation.Line := Self; 336 NewLineStation.MapStation := Station; 337 LineStations.Add(NewLineStation); 338 Station.Lines.Add(Self); 339 340 NewTrackPoint := TTrackPoint.Create; 341 NewTrackPoint.LineStation := NewLineStation; 342 NewTrackPoint.Point := Station.Position; 343 NewTrackPoint.Line := TrackPoints.Line; 344 TrackPoints.Add(NewTrackPoint); 345 346 NewLineStation.TrackPoint := NewTrackPoint; 347 348 if LineStations.Count >= 2 then 349 RouteTrack(TLineStation(LineStations[LineStations.Count - 2]).TrackPoint, NewLineStation.TrackPoint); 350 351 // Place one train if at least two stations present 352 if (LineStations.Count = 2) then begin 353 Train := Engine.Trains.GetUnusedTrain; 354 if Assigned(Train) then begin 355 Train.Line := Self; 356 Train.TargetStation := TLineStation(LineStations[0]); 357 Trains.Add(Train); 358 end; 359 end; 360 Engine.ComputeShapeDistance; 361 end; 362 363 procedure TMetroLine.DisconnectStation(Station: TMapStation); 364 var 365 I: Integer; 306 366 StationIndex: Integer; 307 NewTrackPoint: TTrackPoint; 308 begin 309 Stations.Add(Station); 310 Station.Lines.Add(Self); 311 StationIndex := Stations.Count - 1; 312 if Stations.Count = 1 then begin 313 NewTrackPoint := TTrackPoint.Create; 314 NewTrackPoint.StationIndex := StationIndex; 315 NewTrackPoint.Point := Station.Position; 316 NewTrackPoint.Line := TrackPoints.Line; 317 TrackPoints.Add(NewTrackPoint); 318 end else begin 319 if Stations.Count > 1 then 320 AddTrack(TMetroStation(Stations[Stations.Count - 2]).Position, Station.Position, StationIndex); 321 // Place one train if at least two stations present 322 if (Stations.Count = 2) then begin 323 Train := Engine.Trains.GetUnusedTrain; 324 if Assigned(Train) then begin 325 Train.Line := Self; 326 Train.TargetStationIndex := 0; 327 Trains.Add(Train); 328 end; 329 end; 330 end; 331 Engine.ComputeShapeDistance; 332 end; 333 334 procedure TMetroLine.DisconnectStation(Station: TMetroStation); 335 var 336 I: Integer; 337 StationIndex: Integer; 338 begin 339 if (Stations.Count > 0) and (Stations.Last = Station) then begin 340 StationIndex := Stations.Count - 1; 341 Stations.Delete(StationIndex); 367 begin 368 if (LineStations.Count > 0) and (TLineStation(LineStations.Last).MapStation = Station) then begin 369 StationIndex := LineStations.Count - 1; 370 LineStations.Delete(StationIndex); 342 371 Station.Lines.Remove(Self); 343 if Stations.Count > 0 then begin372 if LineStations.Count > 0 then begin 344 373 while (TrackPoints.Count > 0) and (not ComparePoint(TTrackPoint(TrackPoints.Last).Point, 345 T MetroStation(Stations.Last).Position)) do374 TLineStation(LineStations.Last).MapStation.Position)) do 346 375 TrackPoints.Delete(TrackPoints.Count - 1); 347 376 end else TrackPoints.Clear; 377 348 378 // Remove trains if less then two stations 349 if Stations.Count < 2 then379 if LineStations.Count < 2 then 350 380 for I := Trains.Count - 1 downto 0 do begin 351 381 TMetroTrain(Trains[I]).Line := nil; … … 356 386 end; 357 387 358 procedure TMetroLine.AddTrack(P1, P2: TPoint; StationIndex: Integer); 359 var 388 procedure TMetroLine.RouteTrack(TP1, TP2: TTrackPoint); 389 var 390 NewTrackPoint: TTrackPoint; 360 391 Delta: TPoint; 361 NewTrackPoint: TTrackPoint; 362 begin 392 P1, P2: TPoint; 393 Index1, Index2: Integer; 394 begin 395 Index1 := TrackPoints.IndexOf(TP1); 396 Index2 := TrackPoints.IndexOf(TP2); 397 if Index2 <> Index1 + 1 then 398 raise Exception.Create('Supported only two neighbor track points for routing'); 399 P1 := TTrackPoint(TrackPoints[Index1]).Point; 400 P2 := TTrackPoint(TrackPoints[Index2]).Point; 401 NewTrackPoint := TTrackPoint.Create; 402 NewTrackPoint.Line := Self; 363 403 Delta := Point(P2.X - P1.X, P2.Y - P1.Y); 364 404 if Abs(Delta.X) > Abs(Delta.Y) then begin 365 NewTrackPoint := TTrackPoint.Create;366 NewTrackPoint.Line := TrackPoints.Line;367 405 NewTrackPoint.Point := Point(P2.X - Sign(Delta.X) * Abs(Delta.Y), P1.Y); 368 NewTrackPoint.StationIndex := StationIndex - 1;369 TrackPoints.Add(NewTrackPoint);370 406 end else begin 371 NewTrackPoint := TTrackPoint.Create;372 NewTrackPoint.Line := TrackPoints.Line;373 407 NewTrackPoint.Point := Point(P1.X, P2.Y - Sign(Delta.Y) * Abs(Delta.X)); 374 NewTrackPoint.StationIndex := StationIndex - 1; 375 TrackPoints.Add(NewTrackPoint); 376 end; 377 NewTrackPoint := TTrackPoint.Create; 378 NewTrackPoint.Line := TrackPoints.Line; 379 NewTrackPoint.Point := P2; 380 NewTrackPoint.StationIndex := StationIndex; 381 TrackPoints.Add(NewTrackPoint); 408 end; 409 TrackPoints.Insert(Index1 + 1, NewTrackPoint); 382 410 end; 383 411 … … 392 420 end; 393 421 394 function TMetroLine.GetStationTrackPos( StationIndex: Integer): Integer;422 function TMetroLine.GetStationTrackPos(LineStation: TLineStation): Integer; 395 423 var 396 424 I: Integer; … … 400 428 if I > 0 then 401 429 Result := Result + Distance(TTrackPoint(TrackPoints[I]).Point, TTrackPoint(TrackPoints[I - 1]).Point); 402 if TTrackPoint(TrackPoints[I]). StationIndex = StationIndexthen Break;430 if TTrackPoint(TrackPoints[I]).LineStation = LineStation then Break; 403 431 end; 404 432 end; … … 406 434 constructor TMetroLine.Create; 407 435 begin 408 Stations := TMetroStations.Create;409 Stations.OwnsObjects := False;436 LineStations := TLineStations.Create; 437 LineStations.OwnsObjects := False; 410 438 Trains := TMetroTrains.Create; 411 439 Trains.OwnsObjects := False; … … 418 446 TrackPoints.Free; 419 447 Trains.Free; 420 Stations.Free;448 LineStations.Free; 421 449 inherited Destroy; 422 450 end; … … 425 453 begin 426 454 Result := False; 427 if Stations.Count >= 2 then428 Result := ( Stations.Last = Stations.First);455 if LineStations.Count >= 2 then 456 Result := (TLineStation(LineStations.Last).MapStation = TLineStation(LineStations.First).MapStation); 429 457 end; 430 458 431 459 { TMetroTrain } 432 433 function TMetroTrain.GetTargetStation: TMetroStation;434 begin435 Result := nil;436 if Assigned(Line) then437 if (TargetStationIndex >= 0) and (TargetStationIndex < Line.Stations.Count) then438 Result := TMetroStation(Line.Stations[TargetStationIndex]);439 end;440 460 441 461 function TMetroTrain.GetPosition: TPoint; … … 502 522 end; 503 523 504 { TM etroStation }505 506 function TM etroStation.GetBestStationForShape(Shape: TStationShape;507 Check : TMetroStation; CurrentStationIndex: Integer): Boolean;524 { TMapStation } 525 526 function TMapStation.GetBestStationForShape(Shape: TStationShape; 527 Check, Current: TLineStation): Boolean; 508 528 var 509 529 I: Integer; … … 513 533 DirectionUp: Boolean; 514 534 DirectionDown: Boolean; 515 NextStationUp: T MetroStation;516 NextStationDown: T MetroStation;535 NextStationUp: TLineStation; 536 NextStationDown: TLineStation; 517 537 begin 518 538 Distance := High(Integer); 519 539 for I := 0 to Lines.Count - 1 do 520 540 with TMetroLine(Lines[I]) do begin 521 StationIndex := CurrentStationIndex;541 StationIndex := LineStations.IndexOf(Current); 522 542 if IsCircular then begin 523 543 DirectionUp := False; … … 528 548 end; 529 549 if StationIndex = 0 then 530 NextStationDown := T MetroStation(Stations[Stations.Count - 2])550 NextStationDown := TLineStation(LineStations[LineStations.Count - 2]) 531 551 else 532 552 if StationIndex > 0 then 533 NextStationDown := T MetroStation(Stations[StationIndex - 1]);534 535 if (StationIndex >= 0) and (StationIndex = Stations.Count - 1) then536 NextStationUp := T MetroStation(Stations[1])553 NextStationDown := TLineStation(LineStations[StationIndex - 1]); 554 555 if (StationIndex >= 0) and (StationIndex = LineStations.Count - 1) then 556 NextStationUp := TLineStation(LineStations[1]) 537 557 else 538 if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then539 NextStationUp := T MetroStation(Stations[StationIndex + 1]);558 if (StationIndex >= 0) and (StationIndex < LineStations.Count - 1) then 559 NextStationUp := TLineStation(LineStations[StationIndex + 1]); 540 560 end else begin 541 561 if StationIndex > 0 then begin 542 562 DirectionDown := True; 543 NextStationDown := T MetroStation(Stations[StationIndex - 1])563 NextStationDown := TLineStation(LineStations[StationIndex - 1]) 544 564 end else DirectionDown := False; 545 if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then begin565 if (StationIndex >= 0) and (StationIndex < LineStations.Count - 1) then begin 546 566 DirectionUp := True; 547 NextStationUp := T MetroStation(Stations[StationIndex + 1]);567 NextStationUp := TLineStation(LineStations[StationIndex + 1]); 548 568 end else DirectionUp := False; 549 569 end; 550 if DirectionDown and (NextStationDown. ShapeDistance[Shape] <> -1) and551 (NextStationDown. ShapeDistance[Shape] < Distance) then begin552 Distance := NextStationDown. ShapeDistance[Shape];553 end; 554 if DirectionUp and (NextStationUp. ShapeDistance[Shape] <> -1) and555 (NextStationUp. ShapeDistance[Shape] < Distance) then begin556 Distance := NextStationUp. ShapeDistance[Shape];557 end; 558 end; 559 Result := Check. ShapeDistance[Shape] = Distance;560 end; 561 562 constructor TM etroStation.Create;570 if DirectionDown and (NextStationDown.MapStation.ShapeDistance[Shape] <> -1) and 571 (NextStationDown.MapStation.ShapeDistance[Shape] < Distance) then begin 572 Distance := NextStationDown.MapStation.ShapeDistance[Shape]; 573 end; 574 if DirectionUp and (NextStationUp.MapStation.ShapeDistance[Shape] <> -1) and 575 (NextStationUp.MapStation.ShapeDistance[Shape] < Distance) then begin 576 Distance := NextStationUp.MapStation.ShapeDistance[Shape]; 577 end; 578 end; 579 Result := Check.MapStation.ShapeDistance[Shape] = Distance; 580 end; 581 582 constructor TMapStation.Create; 563 583 begin 564 584 Passengers := TMetroPassengers.Create; … … 568 588 end; 569 589 570 destructor TM etroStation.Destroy;590 destructor TMapStation.Destroy; 571 591 begin 572 592 Lines.Free; … … 583 603 Result := []; 584 604 for I := 0 to Stations.Count - 1 do 585 with TM etroStation(Stations[I]) do begin605 with TMapStation(Stations[I]) do begin 586 606 Result := Result + [Shape]; 587 607 end; 588 608 end; 589 609 590 function TEngine.GetStationOnPos(Pos: TPoint): TM etroStation;610 function TEngine.GetStationOnPos(Pos: TPoint): TMapStation; 591 611 var 592 612 I: Integer; … … 595 615 begin 596 616 I := 0; 597 while (I < Stations.Count) and (Distance(TM etroStation(Stations[I]).Position, Pos) > ClickDistance) do Inc(I);598 if I < Stations.Count then Result := TM etroStation(Stations[I])617 while (I < Stations.Count) and (Distance(TMapStation(Stations[I]).Position, Pos) > ClickDistance) do Inc(I); 618 if I < Stations.Count then Result := TMapStation(Stations[I]) 599 619 else Result := nil; 600 620 end; … … 727 747 // Reset all distances 728 748 for I := 0 to Stations.Count - 1 do 729 with TM etroStation(Stations[I]) do begin749 with TMapStation(Stations[I]) do begin 730 750 for S := Low(ShapeDistance) to High(ShapeDistance) do 731 751 ShapeDistance[S] := -1; … … 735 755 // Distace 0 means that station is final target 736 756 for I := 0 to Stations.Count - 1 do 737 with TM etroStation(Stations[I]) do begin738 ComputeShapeDistanceStation(TM etroStation(Stations[I]), Shape, 0);739 end; 740 end; 741 742 procedure TEngine.ComputeShapeDistanceStation(Station: TM etroStation;757 with TMapStation(Stations[I]) do begin 758 ComputeShapeDistanceStation(TMapStation(Stations[I]), Shape, 0); 759 end; 760 end; 761 762 procedure TEngine.ComputeShapeDistanceStation(Station: TMapStation; 743 763 UpdatedShape: TStationShape; Distance: Integer); 744 764 var … … 756 776 with TMetroLine(Lines[I]) do 757 777 for StationIndex := 0 to Stations.Count - 1 do 758 if TM etroStation(Stations[StationIndex]) = Station then begin778 if TMapStation(Stations[StationIndex]) = Station then begin 759 779 if not IsCircular then begin 760 780 // Update for all adjecent stations 761 781 if StationIndex > 0 then 762 ComputeShapeDistanceStation(TM etroStation(Stations[StationIndex - 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);782 ComputeShapeDistanceStation(TMapStation(Stations[StationIndex - 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1); 763 783 if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then 764 ComputeShapeDistanceStation(TM etroStation(Stations[StationIndex + 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);784 ComputeShapeDistanceStation(TMapStation(Stations[StationIndex + 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1); 765 785 end else begin 766 786 // If circular then trains might go in single direction so passengers … … 775 795 if DirectionUp then begin 776 796 if StationIndex = 0 then 777 ComputeShapeDistanceStation(TM etroStation(Stations[Stations.Count - 2]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);797 ComputeShapeDistanceStation(TMapStation(Stations[Stations.Count - 2]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1); 778 798 if StationIndex > 0 then 779 ComputeShapeDistanceStation(TM etroStation(Stations[StationIndex - 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);799 ComputeShapeDistanceStation(TMapStation(Stations[StationIndex - 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1); 780 800 end; 781 801 if DirectionDown then begin 782 802 if (StationIndex >= 0) and (StationIndex = Stations.Count - 1) then 783 ComputeShapeDistanceStation(TM etroStation(Stations[1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);803 ComputeShapeDistanceStation(TMapStation(Stations[1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1); 784 804 if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then 785 ComputeShapeDistanceStation(TM etroStation(Stations[StationIndex + 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);805 ComputeShapeDistanceStation(TMapStation(Stations[StationIndex + 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1); 786 806 end; 787 807 end; … … 794 814 var 795 815 I: Integer; 796 CurrentStationIndex: Integer; 797 CurrentStation: TMetroStation; 816 CurrentStation: TLineStation; 798 817 P: Integer; 799 818 Passenger: TMetroPassenger; 800 819 PosDelta: Integer; 820 TargetStationIndex: Integer; 801 821 begin 802 822 // Move trains … … 806 826 if InStation then begin 807 827 if (Now - StationStopTime) > OneSecond then begin 808 CurrentStationIndex := TargetStationIndex; 809 if CurrentStationIndex >= Line.Stations.Count then 810 CurrentStationIndex := Line.Stations.Count - 1; 811 CurrentStation := nil; 812 if Assigned(Line) then 813 if (CurrentStationIndex >= 0) and (CurrentStationIndex < Line.Stations.Count) then 814 CurrentStation := TMetroStation(Line.Stations[CurrentStationIndex]); 828 CurrentStation := TargetStation; 815 829 816 830 // Choose next target station 817 TargetStationIndex := TargetStationIndex+ Direction;831 TargetStationIndex := Line.LineStations.IndexOf(TargetStation) + Direction; 818 832 if TargetStationIndex < 0 then begin 819 if Line. Stations.Last = Line.Stations.Firstthen begin820 TargetStationIndex := Line. Stations.Count - 2;821 TrackPos := Line.GetStationTrackPos( Line.Stations.Count - 1);833 if Line.IsCircular then begin 834 TargetStationIndex := Line.LineStations.Count - 2; 835 TrackPos := Line.GetStationTrackPos(TLineStation(Line.LineStations.Last)); 822 836 end else begin 823 837 TargetStationIndex := 1; 824 838 Direction := -Direction; 825 839 end; 826 end else if TargetStationIndex >= Line. Stations.Count then begin827 if Line. Stations.Last = Line.Stations.Firstthen begin840 end else if TargetStationIndex >= Line.LineStations.Count then begin 841 if Line.IsCircular then begin 828 842 TargetStationIndex := 1; 829 843 TrackPos := 0; 830 844 end else begin 831 TargetStationIndex := Line. Stations.Count - 2;845 TargetStationIndex := Line.LineStations.Count - 2; 832 846 Direction := -Direction; 833 847 end; 834 848 end; 849 TargetStation := TLineStation(Line.LineStations[TargetStationIndex]); 835 850 836 851 // Unload passengers in target station 837 if Assigned(CurrentStation) and (CurrentStationIndex < Line.Stations.Count)then852 if Assigned(CurrentStation) then 838 853 for P := Passengers.Count - 1 downto 0 do begin 839 if TMetroPassenger(Passengers[P]).Shape = CurrentStation. Shape then begin854 if TMetroPassenger(Passengers[P]).Shape = CurrentStation.MapStation.Shape then begin 840 855 Passenger := TMetroPassenger(Passengers[P]); 841 856 Passengers.Delete(P); … … 845 860 end; 846 861 // Unload passengers to change line 847 if Assigned(CurrentStation) and (CurrentStationIndex < Line.Stations.Count)then862 if Assigned(CurrentStation) then 848 863 for P := Passengers.Count - 1 downto 0 do begin 849 if not CurrentStation. GetBestStationForShape(TMetroPassenger(Passengers[P]).Shape,850 TargetStation, CurrentStation Index) then begin864 if not CurrentStation.MapStation.GetBestStationForShape(TMetroPassenger(Passengers[P]).Shape, 865 TargetStation, CurrentStation) then begin 851 866 Passenger := TMetroPassenger(Passengers[P]); 852 867 Passengers.Delete(P); 853 CurrentStation. Passengers.Add(Passenger);854 Passenger.Station := CurrentStation ;868 CurrentStation.MapStation.Passengers.Add(Passenger); 869 Passenger.Station := CurrentStation.MapStation; 855 870 end; 856 871 end; 857 872 858 873 // Load new passengers 859 if Assigned(CurrentStation) and (CurrentStationIndex < Line.Stations.Count)then860 for P := CurrentStation. Passengers.Count - 1 downto 0 do begin874 if Assigned(CurrentStation) then 875 for P := CurrentStation.MapStation.Passengers.Count - 1 downto 0 do begin 861 876 if (Passengers.Count < TrainPassengerCount) then begin 862 Passenger := TMetroPassenger(CurrentStation.Passengers[P]); 863 if CurrentStation.GetBestStationForShape(Passenger.Shape, TargetStation, CurrentStationIndex) then begin 877 Passenger := TMetroPassenger(CurrentStation.MapStation.Passengers[P]); 878 if CurrentStation.MapStation.GetBestStationForShape(Passenger.Shape, 879 TargetStation, CurrentStation) then begin 864 880 Passenger.Station := nil; 865 CurrentStation. Passengers.Delete(P);881 CurrentStation.MapStation.Passengers.Delete(P); 866 882 Passengers.Add(Passenger); 867 883 Passenger.Train := TMetroTrain(Trains[I]); … … 870 886 end; 871 887 872 LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation Index));888 LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation)); 873 889 InStation := False; 874 890 end; 875 891 end else begin 876 TrackPos := TrackPos + Direction * TrainSpeed; 877 if TrackPos < 0 then begin 878 if Line.Stations.First = Line.Stations.Last then TrackPos := Line.GetTrackLength 879 else TrackPos := 0; 880 end else 881 if TrackPos > Line.GetTrackLength then begin 882 if Line.Stations.First = Line.Stations.Last then TrackPos := 0 883 else TrackPos := Line.GetTrackLength; 892 TrackPos := TrackPos + Direction * TrainSpeed; 893 if TrackPos < 0 then begin 894 if Line.IsCircular then TrackPos := Line.GetTrackLength 895 else TrackPos := 0; 896 end else 897 if TrackPos > Line.GetTrackLength then begin 898 if Line.IsCircular then TrackPos := 0 899 else TrackPos := Line.GetTrackLength; 900 end; 901 PosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation)); 902 if PosDelta >= LastPosDelta then begin 903 // We are getting far from station, stop at station 904 TrackPos := Line.GetStationTrackPos(TargetStation); 905 InStation := True; 906 StationStopTime := Now; 907 end; 908 LastPosDelta := PosDelta; 884 909 end; 885 PosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStationIndex)); 886 if PosDelta >= LastPosDelta then begin 887 // We are getting far from station, stop at station 888 TrackPos := Line.GetStationTrackPos(TargetStationIndex); 889 InStation := True; 890 StationStopTime := Now; 891 end; 892 LastPosDelta := PosDelta; 893 end; 894 end; 895 end; 910 end; 911 end; 912 end; 913 914 function TEngine.GetUnusedLine: TMetroLine; 915 var 916 I: Integer; 917 begin 918 I := 0; 919 while (I < Lines.Count) and (TMetroLine(Lines[I]).TrackPoints.Count > 0) do Inc(I); 920 if I < Lines.Count then Result := TMetroLine(Lines[I]) 921 else Result := nil; 896 922 end; 897 923 … … 998 1024 LastNewPassengerTime := Now; 999 1025 for I := 0 to Stations.Count - 1 do 1000 with TM etroStation(Stations[I]) do1026 with TMapStation(Stations[I]) do 1001 1027 if Random < NewPassengerProbability then begin 1002 1028 Passenger := Self.Passengers.AddNew; 1003 Passenger.Station := TM etroStation(Stations[I]);1029 Passenger.Station := TMapStation(Stations[I]); 1004 1030 Passengers.Add(Passenger); 1005 1031 … … 1014 1040 // Game over 1015 1041 for I := 0 to Stations.Count - 1 do 1016 with TM etroStation(Stations[I]) do begin1042 with TMapStation(Stations[I]) do begin 1017 1043 if Passengers.Count > MaxWaitingPassengers then State := gsGameOver; 1018 1044 end; … … 1024 1050 procedure TEngine.MouseMove(Position: TPoint); 1025 1051 var 1026 Station: TM etroStation;1052 Station: TMapStation; 1027 1053 begin 1028 1054 LastMousePos := Position; … … 1031 1057 Station := GetStationOnPos(Position); 1032 1058 if not Assigned(LastSelectedStation) and Assigned(Station) then begin 1033 if (SelectedLine. Stations.IndexOf(Station) = -1) then begin1059 if (SelectedLine.LineStations.SearchMapStation(Station) = nil) then begin 1034 1060 SelectedLine.ConnectStation(Station); 1035 1061 SelectedStation := Station; 1036 1062 end else 1037 if (SelectedLine. Stations.Count > 0) and (SelectedLine.Stations.Last= Station) then begin1063 if (SelectedLine.LineStations.Count > 0) and (TLineStation(SelectedLine.LineStations.Last).MapStation = Station) then begin 1038 1064 SelectedLine.DisconnectStation(Station); 1039 SelectedStation := TMetroStation(SelectedLine.Stations.Last); 1040 end else if (SelectedLine.Stations.Count > 0) and (SelectedLine.Stations.First = Station) then begin 1065 if SelectedLine.LineStations.Count > 0 then 1066 SelectedStation := TLineStation(SelectedLine.LineStations.Last).MapStation 1067 else SelectedStation := nil; 1068 end else if (SelectedLine.LineStations.Count > 0) and (TLineStation(SelectedLine.LineStations.First).MapStation = Station) then begin 1041 1069 SelectedLine.ConnectStation(Station); 1042 1070 SelectedStation := Station; … … 1050 1078 procedure TEngine.MouseUp(Button: TMouseButton; Position: TPoint); 1051 1079 var 1052 Station: TM etroStation;1080 Station: TMapStation; 1053 1081 Line: TMetroLine; 1054 1082 I: Integer; … … 1073 1101 procedure TEngine.MouseDown(Button: TMouseButton; Position: TPoint); 1074 1102 var 1075 Station: TM etroStation;1103 Station: TMapStation; 1076 1104 Line: TMetroLine; 1077 1105 I: Integer; 1106 NewLine: TMetroLine; 1078 1107 begin 1079 1108 if Button = mbLeft then begin … … 1087 1116 if not Assigned(SelectedLine) then 1088 1117 for I := 0 to Lines.Count - 1 do 1089 if TMetroLine(Lines[I]). Stations.Count = 0 then begin1118 if TMetroLine(Lines[I]).LineStations.Count = 0 then begin 1090 1119 SelectedLine := TMetroLine(Lines[I]); 1091 1120 Break; … … 1099 1128 Exit; 1100 1129 end; 1130 1131 // New track creation from selected station as start 1132 Station := GetStationOnPos(Position); 1133 if Assigned(Station) then begin 1134 NewLine := GetUnusedLine; 1135 if Assigned(NewLine) then begin 1136 NewLine.ConnectStation(Station); 1137 SelectedStation := Station; 1138 LastSelectedStation := Station; 1139 end; 1140 end; 1101 1141 end; 1102 1142 end; … … 1106 1146 NewTrain: TMetroTrain; 1107 1147 I: Integer; 1108 NewStation: TM etroStation;1148 NewStation: TMapStation; 1109 1149 InitialStationCount: Integer; 1110 1150 begin … … 1143 1183 constructor TEngine.Create; 1144 1184 begin 1145 Stations := TM etroStations.Create;1185 Stations := TMapStations.Create; 1146 1186 Stations.Engine := Self; 1147 1187 Lines := TMetroLines.Create; … … 1243 1283 Canvas.Pen.Width := 5; 1244 1284 for I := 0 to Stations.Count - 1 do 1245 with TM etroStation(Stations[I]) do begin1285 with TMapStation(Stations[I]) do begin 1246 1286 Canvas.Pen.Style := psSolid; 1247 1287 if Assigned(SelectedLine) and (Lines.IndexOf(SelectedLine) <> -1) then begin
Note:
See TracChangeset
for help on using the changeset viewer.