Changeset 20 for trunk/UEngine.pas


Ignore:
Timestamp:
Apr 3, 2015, 10:40:01 PM (9 years ago)
Author:
chronos
Message:
  • Fixed: Passenger change in station to different line with better shape distance.
  • Fixed: Allow circular lines.
  • Modified: Use internal faster Time for new game events instead normal time.
Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:ignore
      •  

        old new  
        22BigMetro
        33BigMetro.lps
         4heaptrclog.trc
  • trunk/UEngine.pas

    r19 r20  
    3131    Lines: TMetroLines;
    3232    ShapeDistance: array[TStationShape] of Integer;
    33     function GetBestStationForShape(Shape: TStationShape; Check, Current: TLineStation): Boolean;
     33    function IsBestStationForShape(Shape: TStationShape; Check, Current: TLineStation): Boolean;
    3434    constructor Create;
    3535    destructor Destroy; override;
     
    119119    InStation: Boolean;
    120120    StationStopTime: TDateTime;
     121    LastTrainMoveTime: TDateTime;
    121122    TargetStation: TLineStation;
    122123    function GetPosition: TPoint;
     
    218219  TrainSize = 40;
    219220  LineColorsDist = 50;
    220   TrainSpeed = 3;
     221  TrainSpeed = 2000;
    221222  ImagePassengerName = 'Images/Passenger.png';
    222223  ImageLocomotiveName = 'Images/Locomotive.png';
     
    228229  TrackClickDistance = 20;
    229230  EndStationLength = 50;
     231  ShowDistances = False;
     232  //TimePerSecond = (60 * OneMinute);
     233  TimePerSecond = (60 * OneMinute);
    230234
    231235implementation
     
    404408  Index: Integer;
    405409begin
     410  if not Assigned(Station) then
     411    raise Exception.Create('Station have to be defined');
    406412  if not Assigned(LineStationDown) and not Assigned(LineStationUp) and (LineStations.Count > 0) then
    407413    raise Exception.Create('No old line station to connect new station');
     
    462468  LineStation.MapStation.Lines.Remove(Self);
    463469  Index := LineStations.IndexOf(LineStation);
     470
     471  // Remove station from trains
     472  for I := 0 to Trains.Count - 1 do
     473  with TMetroTrain(Trains[I]) do
     474  if TargetStation = LineStation then
     475    TargetStation := TLineStation(LineStations[(Index + 1) mod LineStations.Count]);
     476
    464477  LineStations.Delete(Index);
    465478
     
    543556begin
    544557  LineStations := TLineStations.Create;
    545   LineStations.OwnsObjects := False;
     558  LineStations.OwnsObjects := True;
    546559  Trains := TMetroTrains.Create;
    547560  Trains.OwnsObjects := False;
     
    632645{ TMapStation }
    633646
    634 function TMapStation.GetBestStationForShape(Shape: TStationShape;
     647function TMapStation.IsBestStationForShape(Shape: TStationShape;
    635648  Check, Current: TLineStation): Boolean;
    636649var
     
    643656  NextStationUp: TLineStation;
    644657  NextStationDown: TLineStation;
     658  CurrentLineStation: TLineStation;
    645659begin
    646660  Distance := High(Integer);
    647661  for I := 0 to Lines.Count - 1 do
    648662  with TMetroLine(Lines[I]) do begin
    649     StationIndex := LineStations.IndexOf(Current);
     663    CurrentLineStation := LineStations.SearchMapStation(Current.MapStation);
     664    StationIndex := LineStations.IndexOf(CurrentLineStation);
    650665    if IsCircular then begin
    651666      DirectionUp := False;
     
    685700    end;
    686701  end;
    687   Result := Check.MapStation.ShapeDistance[Shape] = Distance;
     702  Result := (Check.MapStation.ShapeDistance[Shape] <> -1) and (Check.MapStation.ShapeDistance[Shape] <= Distance);
    688703end;
    689704
     
    883898      for I := 0 to Lines.Count - 1 do
    884899      with TMetroLine(Lines[I]) do
    885         for StationIndex := 0 to Stations.Count - 1 do
    886         if TMapStation(Stations[StationIndex]) = Station then begin
     900        for StationIndex := 0 to LineStations.Count - 1 do
     901        if TLineStation(LineStations[StationIndex]).MapStation = Station then begin
    887902        if not IsCircular then begin
    888903          // Update for all adjecent stations
    889904          if StationIndex > 0 then
    890             ComputeShapeDistanceStation(TMapStation(Stations[StationIndex - 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
    891           if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then
    892             ComputeShapeDistanceStation(TMapStation(Stations[StationIndex + 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     905            ComputeShapeDistanceStation(TLineStation(LineStations[StationIndex - 1]).MapStation,
     906            UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     907          if (StationIndex >= 0) and (StationIndex < LineStations.Count - 1) then
     908            ComputeShapeDistanceStation(TLineStation(LineStations[StationIndex + 1]).MapStation,
     909            UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
    893910        end else begin
    894911          // If circular then trains might go in single direction so passengers
     
    903920          if DirectionUp then begin
    904921            if StationIndex = 0 then
    905               ComputeShapeDistanceStation(TMapStation(Stations[Stations.Count - 2]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     922              ComputeShapeDistanceStation(TLineStation(LineStations[Stations.Count - 2]).MapStation,
     923              UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
    906924            if StationIndex > 0 then
    907               ComputeShapeDistanceStation(TMapStation(Stations[StationIndex - 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     925              ComputeShapeDistanceStation(TLineStation(LineStations[StationIndex - 1]).MapStation,
     926              UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
    908927          end;
    909928          if DirectionDown then begin
    910             if (StationIndex >= 0) and (StationIndex = Stations.Count - 1) then
    911               ComputeShapeDistanceStation(TMapStation(Stations[1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
    912             if (StationIndex >= 0) and (StationIndex < Stations.Count - 1) then
    913               ComputeShapeDistanceStation(TMapStation(Stations[StationIndex + 1]), UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     929            if (StationIndex >= 0) and (StationIndex = LineStations.Count - 1) then
     930              ComputeShapeDistanceStation(TLineStation(LineStations[1]).MapStation,
     931              UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
     932            if (StationIndex >= 0) and (StationIndex < LineStations.Count - 1) then
     933              ComputeShapeDistanceStation(TLineStation(LineStations[StationIndex + 1]).MapStation,
     934              UpdatedShape, Station.ShapeDistance[UpdatedShape] + 1);
    914935          end;
    915936        end;
     
    927948  PosDelta: Integer;
    928949  TargetStationIndex: Integer;
     950  PosChange: Integer;
    929951begin
    930952  // Move trains
     
    933955    if Assigned(Line) then begin
    934956      if InStation then begin
    935         if (Now - StationStopTime) > OneSecond then begin
     957        if (Time - StationStopTime) > OneHour then begin
    936958          CurrentStation := TargetStation;
    937959
     
    970992          if Assigned(CurrentStation)  then
    971993          for P := Passengers.Count - 1 downto 0 do begin
    972             if not CurrentStation.MapStation.GetBestStationForShape(TMetroPassenger(Passengers[P]).Shape,
     994            if not CurrentStation.MapStation.IsBestStationForShape(TMetroPassenger(Passengers[P]).Shape,
    973995            TargetStation, CurrentStation) then begin
    974996              Passenger := TMetroPassenger(Passengers[P]);
     
    9801002
    9811003          // Load new passengers
     1004          if Assigned(CurrentStation) and not Assigned(CurrentStation.MapStation) then
     1005            raise Exception.Create('Station have to have MapStation');
    9821006          if Assigned(CurrentStation)  then
    9831007          for P := CurrentStation.MapStation.Passengers.Count - 1 downto 0 do begin
    9841008            if (Passengers.Count < TrainPassengerCount) then begin
    9851009              Passenger := TMetroPassenger(CurrentStation.MapStation.Passengers[P]);
    986               if CurrentStation.MapStation.GetBestStationForShape(Passenger.Shape,
     1010              if CurrentStation.MapStation.IsBestStationForShape(Passenger.Shape,
    9871011            TargetStation, CurrentStation) then begin
    9881012                Passenger.Station := nil;
     
    9961020          LastPosDelta := Abs(TrackPos - Line.GetStationTrackPos(TargetStation));
    9971021          InStation := False;
     1022          LastTrainMoveTime := Time;
    9981023        end;
    9991024      end else begin
    1000         TrackPos := TrackPos + Direction * TrainSpeed;
     1025        PosChange := Trunc(Direction * TrainSpeed * (Time - LastTrainMoveTime));
     1026        TrackPos := TrackPos + PosChange;
     1027        LastTrainMoveTime := Time;
    10011028        if TrackPos < 0 then begin
    10021029          if Line.IsCircular then TrackPos := Line.GetTrackLength
     
    10121039          TrackPos := Line.GetStationTrackPos(TargetStation);
    10131040          InStation := True;
    1014           StationStopTime := Now;
     1041          StationStopTime := Time;
    10151042        end;
    10161043        LastPosDelta := PosDelta;
     
    10941121    end;
    10951122  end;
    1096 
    10971123end;
    10981124
    10991125procedure TEngine.Tick;
    11001126const
    1101   NewStationPeriod = 20 * OneSecond;
     1127  NewStationPeriod = 1;
     1128  NewShapePeriod = 10;
     1129  NewTrainPeriod = 7; // Each week
    11021130  NewPassengerPeriod = 0.3 * OneSecond;
    1103   NewPassengerProbability = 0.01;
     1131  NewPassengerProbability = 0.005;
    11041132var
    11051133  Passenger: TMetroPassenger;
     
    11071135begin
    11081136  if State = gsRunning then begin
    1109     FTime := FTime + (Now - LastTickTime) / OneSecond * (60 * OneMinute);
     1137    FTime := FTime + (Now - LastTickTime) / OneSecond * TimePerSecond;
    11101138
    11111139  // Add new trains
    1112   if (Now - LastNewWeekTime) > 7 then begin
    1113     LastNewWeekTime := Now;
     1140  if (Time - LastNewWeekTime) > NewTrainPeriod then begin
     1141    LastNewWeekTime := Time;
    11141142    Trains.AddNew;
    11151143    // TODO: Show notification screen with confirmation
     
    11171145
    11181146  // Add new shape
    1119   if (Now - LastNewShapeTime) > 10 then begin
    1120     LastNewShapeTime := Now;
     1147  if (Time - LastNewShapeTime) > NewShapePeriod then begin
     1148    LastNewShapeTime := Time;
    11211149    if ShapeCount <= Integer(High(TStationShape)) then Inc(ShapeCount);
    11221150  end;
    11231151
    11241152  // Add new stations
    1125   if (Now - LastNewStationTime) > NewStationPeriod then begin
    1126     LastNewStationTime := Now;
     1153  if (Time - LastNewStationTime) > NewStationPeriod then begin
     1154    LastNewStationTime := Time;
    11271155    Stations.AddNew;
    11281156  end;
    11291157
    11301158  // Add new passengers
    1131   if (Now - LastNewPassengerTime) > NewPassengerPeriod then begin
    1132     LastNewPassengerTime := Now;
     1159  if (Time - LastNewPassengerTime) > NewPassengerPeriod then begin
     1160    LastNewPassengerTime := Time;
    11331161    for I := 0 to Stations.Count - 1 do
    11341162    with TMapStation(Stations[I]) do
     
    11671195  if MouseHold then begin
    11681196      FocusedStation := GetStationOnPos(Position);
     1197      Line := nil;
    11691198      if Assigned(TrackStationDown) then Line := TrackStationDown.Line;
    11701199      if Assigned(TrackStationUp) then Line := TrackStationUp.Line;
    1171       if not Assigned(LastFocusedStation) and Assigned(FocusedStation) then begin
     1200      if Assigned(Line) and not Assigned(LastFocusedStation) and Assigned(FocusedStation) then begin
    11721201        if Assigned(TrackStationDown) and (TrackStationDown.LineStation.MapStation = FocusedStation) then begin
    11731202          // Disconnect down
     
    11831212          Line.DisconnectStation(CurrentTrackPoint.LineStation);
    11841213        end else
    1185         if Assigned(Line) and (Line.LineStations.SearchMapStation(FocusedStation) = nil) then begin
     1214        if Assigned(Line) and ((Line.LineStations.SearchMapStation(FocusedStation) = nil) or
     1215        ((Line.LineStations.Count > 0) and
     1216        ((TLineStation(Line.LineStations.First).MapStation = FocusedStation) or
     1217        (TLineStation(Line.LineStations.Last).MapStation = FocusedStation)))) then begin
    11861218          if Assigned(TrackStationDown) then LineStationDown := TrackStationDown.LineStation
    11871219            else LineStationDown := nil;
     
    11921224            else if Assigned(TrackStationUp) then TrackStationUp := TrackStationUp.GetDown;
    11931225        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);
    1197           TrackStationDown := TTrackPoint(TrackStationDown.Line.TrackPoints.Last);
    1198         end;
    1199         }
    12001226      end;
    12011227      LastFocusedStation := FocusedStation;
     
    12091235  I: Integer;
    12101236begin
    1211   MouseHold := False;
    1212   TrackStationDown := nil;
    1213   TrackStationUp := nil;
    1214 
    12151237  if Button = mbLeft then begin
    12161238
     
    12221244          Exit;
    12231245        end;
     1246
     1247    // Remove single line station on line
     1248    if Assigned(TrackStationDown) and (TrackStationDown.Line.LineStations.Count = 1) then begin
     1249      TrackStationDown.Line.DisconnectStation(TLineStation(TrackStationDown.Line.LineStations.First));
     1250    end;
     1251    if Assigned(TrackStationUp) and (TrackStationUp.Line.LineStations.Count = 1) then begin
     1252      TrackStationUp.Line.DisconnectStation(TLineStation(TrackStationUp.Line.LineStations.First));
     1253    end;
    12241254  end else
    12251255  if Button = mbRight then begin
    12261256    SelectedLine := nil;
    12271257  end;
     1258  MouseHold := False;
     1259  TrackStationDown := nil;
     1260  TrackStationUp := nil;
    12281261end;
    12291262
     
    12681301    Station := GetStationOnPos(Position);
    12691302    if Assigned(Station) then begin
    1270       NewLine := GetUnusedLine;
     1303      if Assigned(SelectedLine) and (SelectedLine.LineStations.Count = 0) then NewLine := SelectedLine
     1304        else NewLine := GetUnusedLine;
    12711305      if Assigned(NewLine) then begin
    12721306        NewLine.ConnectStation(Station, nil, nil);
     
    13021336  end;
    13031337
    1304   for I := 0 to 2 do begin
     1338  for I := 0 to 5 do begin
    13051339    Lines.AddNew;
    13061340    NewTrain := TMetroTrain.Create;
     
    13091343
    13101344  SelectedLine := nil;
    1311   LastNewStationTime := Now;
    1312   LastNewPassengerTime := Now;
    1313   LastNewWeekTime := Now;
    1314   LastNewShapeTime := Now;
     1345  FTime := 0;
     1346  LastNewStationTime := Time;
     1347  LastNewPassengerTime := Time;
     1348  LastNewWeekTime := Time;
     1349  LastNewShapeTime := Time;
    13151350  LastTickTime := Now;
    1316   FTime := 0;
    13171351  State := gsRunning;
    13181352end;
     
    14471481    end;
    14481482
    1449 {
    1450     Canvas.Brush.Style := bsClear;
    1451     Text := '';
    1452     for P := 0 to 2 do
    1453       Text := Text + IntToStr(ShapeDistance[TStationShape(P)]) + ',';
    1454     Canvas.TextOut(Position.X + StationSize div 2, Position.Y + StationSize div 2, Text);
    1455     }
     1483    if ShowDistances then begin
     1484      Canvas.Brush.Style := bsClear;
     1485      Text := '';
     1486      for P := 0 to 5 do
     1487        Text := Text + IntToStr(ShapeDistance[TStationShape(P)]) + ',';
     1488      Canvas.TextOut(Position.X + StationSize div 2, Position.Y + StationSize div 2, Text);
     1489    end;
    14561490  end;
    14571491
Note: See TracChangeset for help on using the changeset viewer.