Changeset 20 for trunk


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:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk

    • Property svn:ignore
      •  

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

    r3 r20  
    1717      <StringTable ProductVersion=""/>
    1818    </VersionInfo>
    19     <BuildModes Count="1">
    20       <Item1 Name="Default" Default="True"/>
     19    <BuildModes Count="2">
     20      <Item1 Name="Debug" Default="True"/>
     21      <Item2 Name="Release">
     22        <CompilerOptions>
     23          <Version Value="11"/>
     24          <Target>
     25            <Filename Value="BigMetro"/>
     26          </Target>
     27          <SearchPaths>
     28            <IncludeFiles Value="$(ProjOutDir)"/>
     29            <UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
     30          </SearchPaths>
     31          <Parsing>
     32            <SyntaxOptions>
     33              <SyntaxMode Value="Delphi"/>
     34              <CStyleOperator Value="False"/>
     35              <AllowLabel Value="False"/>
     36              <CPPInline Value="False"/>
     37            </SyntaxOptions>
     38          </Parsing>
     39          <CodeGeneration>
     40            <SmartLinkUnit Value="True"/>
     41            <Optimizations>
     42              <OptimizationLevel Value="3"/>
     43            </Optimizations>
     44          </CodeGeneration>
     45          <Linking>
     46            <Debugging>
     47              <GenerateDebugInfo Value="False"/>
     48            </Debugging>
     49            <Options>
     50              <Win32>
     51                <GraphicApplication Value="True"/>
     52              </Win32>
     53            </Options>
     54          </Linking>
     55        </CompilerOptions>
     56      </Item2>
    2157    </BuildModes>
    2258    <PublishOptions>
     
    83119        <StackChecks Value="True"/>
    84120      </Checks>
    85       <VerifyObjMethodCallValidity Value="True"/>
    86121    </CodeGeneration>
    87122    <Linking>
     123      <Debugging>
     124        <UseHeaptrc Value="True"/>
     125      </Debugging>
    88126      <Options>
    89127        <Win32>
     
    92130      </Options>
    93131    </Linking>
     132    <Other>
     133      <CustomOptions Value="-dDEBUG"/>
     134    </Other>
    94135  </CompilerOptions>
    95136  <Debugging>
  • trunk/BigMetro.lpr

    r3 r20  
    88  {$ENDIF}{$ENDIF}
    99  Interfaces, // this includes the LCL widgetset
    10   Forms, UFormMain, UEngine, UGeometric
     10  Forms, SysUtils, UFormMain, UEngine, UGeometric
    1111  { you can add units after this };
    1212
    1313{$R *.res}
    1414
     15{$IFDEF DEBUG}
     16const
     17  HeapTraceLog = 'heaptrclog.trc';
     18{$ENDIF}
     19
    1520begin
     21  {$IFDEF DEBUG}
     22  // Heap trace
     23  DeleteFile(ExtractFilePath(ParamStr(0)) + HeapTraceLog);
     24  SetHeapTraceOutput(ExtractFilePath(ParamStr(0)) + HeapTraceLog);
     25  {$ENDIF}
     26
    1627  RequireDerivedFormResource := True;
    1728  Application.Initialize;
  • 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.