Changeset 19


Ignore:
Timestamp:
Apr 1, 2015, 1:21:27 AM (10 years ago)
Author:
chronos
Message:
  • Modified: User can now enlarge line from both ends as well as between stations.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UEngine.pas

    r18 r19  
    5656  end;
    5757
     58  { TTrackPoint }
     59
    5860  TTrackPoint = class
    5961    Line: TMetroLine;
     
    6163    Point: TPoint;
    6264    Pending: Boolean;
     65    function GetDown: TTrackPoint;
     66    function GetUp: TTrackPoint;
    6367  end;
    6468
     
    7579
    7680  TMetroLine = class
     81  private
     82    procedure UpdateEndingLines;
     83  public
    7784    Engine: TEngine;
    7885    Color: TColor;
     
    8087    Trains: TMetroTrains;
    8188    TrackPoints: TTrackPoints;
    82     procedure ConnectStation(Station: TMapStation);
    83     procedure DisconnectStation(Station: TMapStation);
     89    procedure ConnectStation(Station: TMapStation; LineStationDown, LineStationUp: TLineStation);
     90    procedure DisconnectStation(LineStation: TLineStation);
    8491    procedure RouteTrack(TP1, TP2: TTrackPoint);
     92    procedure RemoteTrackBetween(TP1, TP2: TTrackPoint);
    8593    function GetTrackLength: Integer;
    8694    function GetStationTrackPos(LineStation: TLineStation): Integer;
     
    219227  MetroLineThickness = 13;
    220228  TrackClickDistance = 20;
     229  EndStationLength = 50;
    221230
    222231implementation
     
    224233uses
    225234  UGeometric;
     235
     236{ TTrackPoint }
     237
     238function TTrackPoint.GetDown: TTrackPoint;
     239var
     240  NewIndex: Integer;
     241begin
     242  NewIndex := LineStation.Line.LineStations.IndexOf(LineStation) - 1;
     243  if NewIndex >= 0 then Result := TLineStation(LineStation.Line.LineStations[NewIndex]).TrackPoint
     244    else Result := nil;
     245end;
     246
     247function TTrackPoint.GetUp: TTrackPoint;
     248var
     249  NewIndex: Integer;
     250begin
     251  NewIndex := LineStation.Line.LineStations.IndexOf(LineStation) + 1;
     252  if NewIndex < LineStation.Line.LineStations.Count then
     253    Result := TLineStation(LineStation.Line.LineStations[NewIndex]).TrackPoint
     254    else Result := nil;
     255end;
    226256
    227257{ TLineStations }
     
    332362{ TMetroLine }
    333363
    334 procedure TMetroLine.ConnectStation(Station: TMapStation);
     364procedure TMetroLine.UpdateEndingLines;
     365var
     366  Index: Integer;
     367  NewTrackPoint: TTrackPoint;
     368  Angle: Double;
     369  EndPoint: TPoint;
     370begin
     371  if LineStations.Count >= 2 then begin
     372    Index := TrackPoints.IndexOf(TLineStation(LineStations.First).TrackPoint);
     373    if Index = 0 then begin
     374      NewTrackPoint := TTrackPoint.Create;
     375      NewTrackPoint.Line := Self;
     376      TrackPoints.Insert(0, NewTrackPoint);
     377    end;
     378    Index := TrackPoints.IndexOf(TLineStation(LineStations.Last).TrackPoint);
     379    if Index = TrackPoints.Count - 1 then begin
     380      NewTrackPoint := TTrackPoint.Create;
     381      NewTrackPoint.Line := Self;
     382      TrackPoints.Insert(TrackPoints.Count, NewTrackPoint);
     383    end;
     384
     385    Angle := arctan2((TTrackPoint(TrackPoints[2]).Point.Y - TTrackPoint(TrackPoints[1]).Point.Y),
     386      (TTrackPoint(TrackPoints[2]).Point.X - TTrackPoint(TrackPoints[1]).Point.X));
     387    EndPoint := Point(Round(TTrackPoint(TrackPoints[1]).Point.X - EndStationLength * Cos(Angle)),
     388      Round(TTrackPoint(TrackPoints[1]).Point.Y - EndStationLength * Sin(Angle)));
     389    TTrackPoint(TrackPoints.First).Point := EndPoint;
     390
     391    Angle := arctan2((TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.Y - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Point.Y),
     392      (TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.X - TTrackPoint(TrackPoints[TrackPoints.Count - 3]).Point.X));
     393    EndPoint := Point(Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.X + EndStationLength * Cos(Angle)),
     394      Round(TTrackPoint(TrackPoints[TrackPoints.Count - 2]).Point.Y + EndStationLength * Sin(Angle)));
     395    TTrackPoint(TrackPoints.Last).Point := EndPoint;
     396  end;
     397end;
     398
     399procedure TMetroLine.ConnectStation(Station: TMapStation; LineStationDown, LineStationUp: TLineStation);
    335400var
    336401  Train: TMetroTrain;
    337402  NewTrackPoint: TTrackPoint;
    338403  NewLineStation: TLineStation;
    339 begin
     404  Index: Integer;
     405begin
     406  if not Assigned(LineStationDown) and not Assigned(LineStationUp) and (LineStations.Count > 0) then
     407    raise Exception.Create('No old line station to connect new station');
    340408  NewLineStation := TLineStation.Create;
    341409  NewLineStation.Line := Self;
    342410  NewLineStation.MapStation := Station;
    343   LineStations.Add(NewLineStation);
     411  Index := 0;
     412  if Assigned(LineStationDown) then Index := LineStations.IndexOf(LineStationDown) + 1
     413    else if Assigned(LineStationDown) then Index := LineStations.IndexOf(LineStationUp);
     414  LineStations.Insert(Index, NewLineStation);
    344415  Station.Lines.Add(Self);
    345416
     
    348419  NewTrackPoint.Point := Station.Position;
    349420  NewTrackPoint.Line := TrackPoints.Line;
    350   TrackPoints.Add(NewTrackPoint);
    351 
     421  Index := 0;
     422  if Assigned(LineStationDown) then Index := TrackPoints.IndexOf(LineStationDown.TrackPoint) + 1
     423    else if Assigned(LineStationUp) then Index := TrackPoints.IndexOf(LineStationUp.TrackPoint);
     424  TrackPoints.Insert(Index, NewTrackPoint);
    352425  NewLineStation.TrackPoint := NewTrackPoint;
    353426
    354   if LineStations.Count >= 2 then
    355     RouteTrack(TLineStation(LineStations[LineStations.Count - 2]).TrackPoint, NewLineStation.TrackPoint);
     427  if Assigned(LineStationDown) then
     428    RouteTrack(NewLineStation.TrackPoint.GetDown, NewLineStation.TrackPoint);
     429  if Assigned(LineStationUp) then
     430    RouteTrack(NewLineStation.TrackPoint, NewLineStation.TrackPoint.GetUp);
    356431
    357432  // Place one train if at least two stations present
     
    364439    end;
    365440  end;
     441  UpdateEndingLines;
    366442  Engine.ComputeShapeDistance;
    367443end;
    368444
    369 procedure TMetroLine.DisconnectStation(Station: TMapStation);
    370 var
    371   I: Integer;
    372   StationIndex: Integer;
    373 begin
    374   if (LineStations.Count > 0) and (TLineStation(LineStations.Last).MapStation = Station) then begin
    375     StationIndex := LineStations.Count - 1;
    376     LineStations.Delete(StationIndex);
    377     Station.Lines.Remove(Self);
    378     if LineStations.Count > 0 then begin
    379       while (TrackPoints.Count > 0) and (not ComparePoint(TTrackPoint(TrackPoints.Last).Point,
    380         TLineStation(LineStations.Last).MapStation.Position)) do
    381         TrackPoints.Delete(TrackPoints.Count - 1);
    382     end else TrackPoints.Clear;
    383 
    384     // Remove trains if less then two stations
    385     if LineStations.Count < 2 then
    386       for I := Trains.Count - 1 downto 0 do begin
    387         TMetroTrain(Trains[I]).Line := nil;
    388         Trains.Delete(I);
    389       end;
    390   end;
     445procedure TMetroLine.DisconnectStation(LineStation: TLineStation);
     446var
     447  I: Integer;
     448  Index: Integer;
     449begin
     450  // Delete old trackpoints
     451
     452  Index := TrackPoints.IndexOf(LineStation.TrackPoint) - 1;
     453  while (Index >= 0) and (not Assigned(TTrackPoint(TrackPoints[Index]).LineStation)) do begin
     454    TrackPoints.Delete(Index);
     455    Dec(Index);
     456  end;
     457  Index := Index + 1;
     458  TrackPoints.Delete(Index);
     459  while (Index < TrackPoints.Count) and (not Assigned(TTrackPoint(TrackPoints[Index]).LineStation)) do
     460    TrackPoints.Delete(Index);
     461
     462  LineStation.MapStation.Lines.Remove(Self);
     463  Index := LineStations.IndexOf(LineStation);
     464  LineStations.Delete(Index);
     465
     466  // Remove trains if less then two stations
     467  if LineStations.Count < 2 then
     468  for I := Trains.Count - 1 downto 0 do begin
     469    TMetroTrain(Trains[I]).Line := nil;
     470    Trains.Delete(I);
     471  end;
     472  UpdateEndingLines;
    391473  Engine.ComputeShapeDistance;
    392474end;
     
    399481  Index1, Index2: Integer;
    400482begin
     483  RemoteTrackBetween(TP1, TP2);
    401484  Index1 := TrackPoints.IndexOf(TP1);
    402485  Index2 := TrackPoints.IndexOf(TP2);
    403   if Index2 <> Index1 + 1 then
    404     raise Exception.Create('Supported only two neighbor track points for routing');
    405486  P1 := TTrackPoint(TrackPoints[Index1]).Point;
    406487  P2 := TTrackPoint(TrackPoints[Index2]).Point;
     
    414495  end;
    415496  TrackPoints.Insert(Index1 + 1, NewTrackPoint);
     497end;
     498
     499procedure TMetroLine.RemoteTrackBetween(TP1, TP2: TTrackPoint);
     500var
     501  Index1, Index2: Integer;
     502  Temp: Integer;
     503  I: Integer;
     504begin
     505  Index1 := TrackPoints.IndexOf(TP1);
     506  Index2 := TrackPoints.IndexOf(TP2);
     507  if (Index1 = -1) then
     508    raise Exception.Create('TrackPoint1 not found');
     509  if (Index2 = -1) then
     510    raise Exception.Create('TrackPoint2 not found');
     511  if Index1 > Index2 then begin
     512    Temp := Index1;
     513    Index1 := Index2;
     514    Index2 := Temp;
     515  end;
     516  for I := 1 to Index2 - Index1 - 1 do
     517    TrackPoints.Delete(Index1 + 1);
    416518end;
    417519
     
    9971099procedure TEngine.Tick;
    9981100const
    999   NewStationPeriod = OneSecond * 20;
    1000   NewPassengerPeriod = OneSecond;
    1001   NewPassengerProbability = 0.1;
     1101  NewStationPeriod = 20 * OneSecond;
     1102  NewPassengerPeriod = 0.3 * OneSecond;
     1103  NewPassengerProbability = 0.01;
    10021104var
    10031105  Passenger: TMetroPassenger;
     
    10581160  FocusedStation: TMapStation;
    10591161  Line: TMetroLine;
     1162  LineStationDown: TLineStation;
     1163  LineStationUp: TLineStation;
     1164  CurrentTrackPoint: TTrackPoint;
    10601165begin
    10611166  LastMousePos := Position;
    10621167  if MouseHold then begin
    1063     if Assigned(TrackStationDown) then begin
    10641168      FocusedStation := GetStationOnPos(Position);
     1169      if Assigned(TrackStationDown) then Line := TrackStationDown.Line;
     1170      if Assigned(TrackStationUp) then Line := TrackStationUp.Line;
    10651171      if not Assigned(LastFocusedStation) and Assigned(FocusedStation) then begin
    1066         if (TrackStationDown.Line.LineStations.SearchMapStation(FocusedStation) = nil) then begin
    1067           TrackStationDown.Line.ConnectStation(FocusedStation);
    1068           TrackStationDown := TTrackPoint(TrackStationDown.Line.TrackPoints.Last);
     1172        if Assigned(TrackStationDown) and (TrackStationDown.LineStation.MapStation = FocusedStation) then begin
     1173          // Disconnect down
     1174          CurrentTrackPoint := TrackStationDown;
     1175          TrackStationDown := TrackStationDown.GetDown;
     1176          Line.DisconnectStation(CurrentTrackPoint.LineStation);
    10691177        end else
    1070         if (SelectedLine.TrackPoints.Count > 0) and (TLineStation(TrackStationDown.Line.LineStations.Last).MapStation = FocusedStation) then begin
    1071           Line := TrackStationDown.Line;
    1072           TrackStationDown.Line.DisconnectStation(FocusedStation);
    1073           TrackStationDown := TTrackPoint(Line.TrackPoints.Last);
    1074         end else if (TrackStationDown.Line.LineStations.Count > 0) and (TLineStation(TrackStationDown.Line.LineStations.Last).MapStation = FocusedStation) then begin
    1075           TrackStationDown.Line.ConnectStation(FocusedStation);
     1178        if Assigned(TrackStationUp) and (TrackStationUp.LineStation.MapStation = FocusedStation) then begin
     1179          // Disconnect up
     1180          CurrentTrackPoint := TrackStationUp;
     1181          if Assigned(TrackStationUp) then
     1182            TrackStationUp := TrackStationUp.GetUp;
     1183          Line.DisconnectStation(CurrentTrackPoint.LineStation);
     1184        end else
     1185        if Assigned(Line) and (Line.LineStations.SearchMapStation(FocusedStation) = nil) then begin
     1186          if Assigned(TrackStationDown) then LineStationDown := TrackStationDown.LineStation
     1187            else LineStationDown := nil;
     1188          if Assigned(TrackStationUp) then LineStationUp := TrackStationUp.LineStation
     1189            else LineStationUp := nil;
     1190          Line.ConnectStation(FocusedStation, LineStationDown, LineStationUp);
     1191          if Assigned(TrackStationDown) then TrackStationDown := TrackStationDown.GetUp
     1192            else if Assigned(TrackStationUp) then TrackStationUp := TrackStationUp.GetDown;
     1193        end;
     1194        {else
     1195        if (TrackStationDown.Line.LineStations.Count > 0) and (TLineStation(TrackStationDown.Line.LineStations.Last).MapStation = FocusedStation) then begin
     1196          Line.ConnectStation(FocusedStation, TrackStationDown, TrackStationUp);
    10761197          TrackStationDown := TTrackPoint(TrackStationDown.Line.TrackPoints.Last);
    10771198        end;
     1199        }
    10781200      end;
    10791201      LastFocusedStation := FocusedStation;
    1080     end;
    10811202  end;
    10821203end;
     
    11491270      NewLine := GetUnusedLine;
    11501271      if Assigned(NewLine) then begin
    1151         NewLine.ConnectStation(Station);
     1272        NewLine.ConnectStation(Station, nil, nil);
    11521273        TrackStationDown := TTrackPoint(NewLine.TrackPoints.Last);
    11531274        TrackStationUp := nil;
     
    11731294
    11741295  // Start with 3 stations with each different shape
    1175   InitialStationCount := 30;
     1296  InitialStationCount := 3;
    11761297  for I := 0 to InitialStationCount - 1 do begin
    11771298    NewStation := Stations.AddNew;
     
    11871308  end;
    11881309
    1189   SelectedLine := TMetroLine(Lines[0]);
     1310  SelectedLine := nil;
    11901311  LastNewStationTime := Now;
    11911312  LastNewPassengerTime := Now;
     
    12431364  GameOverReason = 'Overcrowding at this station has forced you to resign as metro manager.';
    12441365  GameOverStatistic = '%d passengers travelled on your metro over %d days.';
    1245   EndStationLength = 50;
    12461366begin
    12471367  Canvas.Brush.Color := $eff0e0;
     
    12581378    for S := 1 to TrackPoints.Count - 1 do begin
    12591379      Canvas.LineTo(TTrackPoint(TrackPoints[S]).Point);
    1260       if (S = TrackPoints.Count - 1) then begin
     1380{      if (S = TrackPoints.Count - 1) then begin
    12611381        Canvas.Pen.EndCap := pecSquare;
    12621382        Angle := arctan2((TTrackPoint(TrackPoints[S]).Point.Y - TTrackPoint(TrackPoints[S - 1]).Point.Y),
     
    12701390          Round(EndPoint.Y + Sin(Angle - Pi / 2) * EndStationLength / 3)));
    12711391        Canvas.Pen.EndCap := pecRound;
    1272       end;
    1273     end;
     1392      end;}
     1393    end;
     1394    {
    12741395    if (TrackPoints.Count > 1) then begin
    12751396      Canvas.Pen.EndCap := pecSquare;
     
    12851406        Round(EndPoint.Y - Sin(Angle - Pi / 2) * EndStationLength / 3)));
    12861407      Canvas.Pen.EndCap := pecRound;
    1287     end;
     1408    end;  }
    12881409  end;
    12891410
Note: See TracChangeset for help on using the changeset viewer.