コード例 #1
0
        /// <summary>Is called when the train passes a beacon.</summary>
        /// <param name="data">The beacon data.</param>
        public void SetBeacon(BeaconData data)
        {
            switch (data.Type)
            {
            case -16777214:
                // ATC speed limit (.Limit command)
                double limit    = (data.Optional & 4095);
                double position = (data.Optional >> 12);
                var    item     = new CompatibilityLimit(limit, position);
                if (!trackLimits.Contains(item))
                {
                    trackLimits.Add(item);
                }
                break;

            case -16777215:
                // ATC track compatibility
                ATCSection = (data.Optional >= 1 && data.Optional <= 3);
                break;
            }
        }
コード例 #2
0
        /// <summary>Is called when a beacon is passed.</summary>
        /// <param name="beacon">The beacon data.</param>
        internal override void SetBeacon(BeaconData beacon)
        {
            switch (beacon.Type)
            {
            case -16777215:
                if (beacon.Optional >= 0 & beacon.Optional <= 3)
                {
                    this.CompatibilityState = (CompatibilityStates)beacon.Optional;
                }
                break;

            case -16777214:
            {
                double             limit    = (double)(beacon.Optional & 4095) / 3.6;
                double             position = (beacon.Optional >> 12);
                CompatibilityLimit item     = new CompatibilityLimit(limit, position);
                if (!this.CompatibilityLimits.Contains(item))
                {
                    this.CompatibilityLimits.Add(item);
                }
            }
            break;
            }
        }
コード例 #3
0
ファイル: AtsP.cs プロジェクト: City-busz/OpenBVE
        /// <summary>Is called when a beacon is passed.</summary>
        /// <param name="beacon">The beacon data.</param>
        internal override void SetBeacon(BeaconData beacon)
        {
            if (this.State != States.Disabled & this.State != States.Suppressed & this.State != States.Initializing)
            {
                switch (beacon.Type)
                {
                case 0:
                case 1:
                    // --- P -> S ---
                    if (beacon.Optional == 0)
                    {
                        if (this.State == States.Normal | this.State == States.Pattern | this.State == States.Brake)
                        {
                            SwitchToSx();
                        }
                    }
                    break;

                case 3:
                case 4:
                    // --- P pattern / P immediate stop ---
                    this.Position = this.Train.State.Location;
                    if (this.State != States.Service & this.State != States.Emergency)
                    {
                        if (this.State == States.Standby & (beacon.Type != 3 | beacon.Optional != -1))
                        {
                            SwitchToP(States.Normal);
                        }
                        if (this.State != States.Standby)
                        {
                            double position = this.Position + beacon.Signal.Distance - this.SignalOffset;
                            bool   update   = false;
                            if (this.SignalPattern.Position == double.MaxValue)
                            {
                                update = true;
                            }
                            else if (position > this.SignalPattern.Position - 30.0)
                            {
                                update = true;
                            }
                            if (update)
                            {
                                if (beacon.Signal.Aspect == 0)
                                {
                                    this.SignalPattern.SetRedSignal(position);
                                    if (beacon.Type != 3 & beacon.Signal.Distance < 50.0 & !BrakeRelease)
                                    {
                                        SwitchToP(States.Emergency);
                                    }
                                }
                                else
                                {
                                    this.SignalPattern.SetGreenSignal(position);
                                }
                            }
                        }
                    }
                    break;
                }
            }
            switch (beacon.Type)
            {
            case -16777213:
                // --- compatibility temporary pattern ---
            {
                double             limit    = (double)(beacon.Optional & 4095) / 3.6;
                double             position = (beacon.Optional >> 12);
                CompatibilityLimit item     = new CompatibilityLimit(limit, position);
                if (!this.CompatibilityLimits.Contains(item))
                {
                    this.CompatibilityLimits.Add(item);
                }
            }
            break;

            case -16777212:
                // --- compatibility permanent pattern ---
                if (beacon.Optional == 0)
                {
                    this.CompatibilityPermanentPattern.Clear();
                }
                else
                {
                    double limit = (double)beacon.Optional / 3.6;
                    this.CompatibilityPermanentPattern.SetLimit(limit, double.MinValue);
                }
                break;
            }
        }
コード例 #4
0
ファイル: AtsP.cs プロジェクト: sladen/openbve
 /// <summary>Is called when a beacon is passed.</summary>
 /// <param name="beacon">The beacon data.</param>
 internal override void SetBeacon(BeaconData beacon)
 {
     if (this.State != States.Disabled & this.State != States.Suppressed & this.State != States.Initializing) {
         switch (beacon.Type) {
             case 0:
             case 1:
                 // --- P -> S ---
                 if (beacon.Optional == 0) {
                     if (this.State == States.Normal | this.State == States.Pattern | this.State == States.Brake) {
                         SwitchToSx();
                     }
                 }
                 break;
             case 3:
             case 4:
                 // --- P pattern / P immediate stop ---
                 this.Position = this.Train.State.Location;
                 if (this.State != States.Service & this.State != States.Emergency) {
                     if (this.State == States.Standby & (beacon.Type != 3 | beacon.Optional != -1)) {
                         SwitchToP(States.Normal);
                     }
                     if (this.State != States.Standby) {
                         if (beacon.Signal.Aspect == 0) {
                             this.SignalPattern.SetSignal(this.Position + beacon.Signal.Distance - SignalOffset);
                             if (beacon.Type != 3 & beacon.Signal.Distance < 50.0 & !BrakeRelease) {
                                 SwitchToP(States.Emergency);
                             }
                         } else {
                             this.SignalPattern.Clear();
                         }
                     }
                 }
                 break;
         }
     }
     switch (beacon.Type) {
         case -16777213:
             // --- compatibility temporary pattern ---
             {
                 double limit = (double)(beacon.Optional & 4095) / 3.6;
                 double position = (beacon.Optional >> 12);
                 CompatibilityLimit item = new CompatibilityLimit(limit, position);
                 if (!this.CompatibilityLimits.Contains(item)) {
                     this.CompatibilityLimits.Add(item);
                 }
             }
             break;
         case -16777212:
             // --- compatibility permanent pattern ---
             if (beacon.Optional == 0) {
                 this.CompatibilityPermanentPattern.Clear();
             } else {
                 double limit = (double)beacon.Optional / 3.6;
                 this.CompatibilityPermanentPattern.SetLimit(limit, double.MinValue);
             }
             break;
     }
 }
コード例 #5
0
        /// <summary>Is called when a beacon is passed.</summary>
        /// <param name="beacon">The beacon data.</param>
        internal override void SetBeacon(BeaconData beacon)
        {
            if (this.State != States.Disabled & this.State != States.Suppressed & this.State != States.Initializing)
            {
                switch (beacon.Type)
                {
                case 3:
                case 4:
                case 5:
                    // --- P signal pattern / P immediate stop ---
                    this.Position = this.Train.State.Location;
                    if (this.State != States.Service & this.State != States.Emergency)
                    {
                        if (this.State == States.Standby & beacon.Optional != -1)
                        {
                            SwitchToP(States.Normal);
                        }
                        if (this.State != States.Standby)
                        {
                            double location = this.Train.State.Location + beacon.Signal.Distance;
                            int    aspect   = beacon.Signal.Aspect;
                            if (aspect < 0 | aspect >= 10)
                            {
                                aspect = 0;
                            }
                            if (aspect == 0)
                            {
                                const double tolerance = 5.0;
                                bool         add       = true;
                                for (int i = 0; i < this.SignalPatterns.Count; i++)
                                {
                                    if (Math.Abs(this.SignalPatterns[i].Position - location) < tolerance)
                                    {
                                        this.SignalPatterns[i].SetRedSignal(location);
                                        add = false;
                                    }
                                }
                                if (add)
                                {
                                    var pattern = new Pattern(this);
                                    pattern.SetRedSignal(location);
                                    this.SignalPatterns.Add(pattern);
                                    this.Patterns.Add(pattern);
                                }
                                if (!this.BrakeRelease)
                                {
                                    if (beacon.Type == 4)
                                    {
                                        SwitchToP(States.Emergency);
                                    }
                                    else if (beacon.Type == 5)
                                    {
                                        SwitchToP(States.Service);
                                    }
                                }
                            }
                            else
                            {
                                const double tolerance = 5.0;
                                for (int i = 0; i < this.SignalPatterns.Count; i++)
                                {
                                    if (Math.Abs(this.SignalPatterns[i].Position - location) < tolerance)
                                    {
                                        this.Patterns.Remove(this.SignalPatterns[i]);
                                        this.SignalPatterns[i] = this.SignalPatterns[this.SignalPatterns.Count - 1];
                                        this.SignalPatterns.RemoveAt(this.SignalPatterns.Count - 1);
                                        i--;
                                    }
                                }
                            }
                        }
                    }
                    break;

                case 6:
                    // --- P divergence speed limit ---
                {
                    int distance = beacon.Optional / 1000;
                    if (distance > 0)
                    {
                        if (this.State == States.Standby)
                        {
                            SwitchToP(States.Normal);
                        }
                        this.Position = this.Train.State.Location;
                        int speed = beacon.Optional % 1000;
                        this.DivergencePattern.SetLimit((double)speed / 3.6, this.Position + distance);
                    }
                }
                break;

                case 7:
                    // --- P permanent speed limit ---
                    this.Position = this.Train.State.Location;
                    if (beacon.Optional > 0)
                    {
                        if (this.State == States.Standby)
                        {
                            SwitchToP(States.Normal);
                        }
                        this.RoutePermanentPattern.SetLimit((double)beacon.Optional / 3.6, double.MinValue);
                    }
                    else
                    {
                        SwitchToP(States.Emergency);
                    }
                    break;

                case 8:
                    // --- P downslope speed limit ---
                {
                    int distance = beacon.Optional / 1000;
                    if (distance > 0)
                    {
                        if (this.State == States.Standby)
                        {
                            SwitchToP(States.Normal);
                        }
                        this.Position = this.Train.State.Location;
                        int speed = beacon.Optional % 1000;
                        this.DownslopePattern.SetLimit((double)speed / 3.6, this.Position + distance);
                    }
                }
                break;

                case 9:
                    // --- P curve speed limit ---
                {
                    int distance = beacon.Optional / 1000;
                    if (distance > 0)
                    {
                        if (this.State == States.Standby)
                        {
                            SwitchToP(States.Normal);
                        }
                        this.Position = this.Train.State.Location;
                        int speed = beacon.Optional % 1000;
                        this.CurvePattern.SetLimit((double)speed / 3.6, this.Position + distance);
                    }
                }
                break;

                case 10:
                    // --- P temporary speed limit / P->S (IIYAMA style) ---
                {
                    int left  = beacon.Optional / 1000;
                    int right = beacon.Optional % 1000;
                    if (left != 0)
                    {
                        if (this.State == States.Standby)
                        {
                            SwitchToP(States.Normal);
                        }
                        this.Position = this.Train.State.Location;
                        this.TemporaryPattern.SetLimit((double)right / 3.6, this.Position + left);
                    }
                    else if (left == 0 & right != 0)
                    {
                        this.Position = this.Train.State.Location;
                        this.SwitchToAtsSxPosition = this.Position + right;
                    }
                }
                break;

                case 16:
                    // --- P divergence limit released ---
                    if (beacon.Optional == 0)
                    {
                        this.Position = this.Train.State.Location;
                        this.DivergencePattern.Clear();
                    }
                    break;

                case 18:
                    // --- P downslope limit released ---
                    if (beacon.Optional == 0)
                    {
                        this.Position = this.Train.State.Location;
                        this.DownslopePattern.Clear();
                    }
                    break;

                case 19:
                    // --- P curve limit released ---
                    if (beacon.Optional == 0)
                    {
                        this.Position = this.Train.State.Location;
                        this.CurvePattern.Clear();
                    }
                    break;

                case 20:
                    // --- P temporary limit released ---
                    if (beacon.Optional == 0)
                    {
                        this.Position = this.Train.State.Location;
                        this.TemporaryPattern.Clear();
                    }
                    break;

                case 25:
                    // --- P/S system switch ---
                    if (beacon.Optional == 0)
                    {
                        // --- Sx only ---
                        this.Position = this.Train.State.Location;
                        if (this.State == States.Normal | this.State == States.Pattern | this.State == States.Brake | this.State == States.Service | this.State == States.Emergency)
                        {
                            this.SwitchToAtsSxPosition = this.Position;
                        }
                    }
                    else if (beacon.Optional == 1)
                    {
                        // --- P only ---
                        this.Position = this.Train.State.Location;
                        if (this.State == States.Standby)
                        {
                            SwitchToP(States.Normal);
                        }
                        if (this.AtsSxPMode)
                        {
                            this.AtsSxPMode = false;
                            if (this.Train.AtsSx != null & !this.Blocked)
                            {
                                this.Train.Sounds.AtsPBell.Play();
                            }
                        }
                    }
                    else if (beacon.Optional == 2)
                    {
                        // --- Sx/P ---
                        this.Position = this.Train.State.Location;
                        if (this.State == States.Standby)
                        {
                            SwitchToP(States.Normal);
                        }
                        if (!this.AtsSxPMode)
                        {
                            this.AtsSxPMode = true;

                            if (this.Train.AtsSx != null & !this.Blocked)
                            {
                                this.Train.Sounds.AtsPBell.Play();
                            }
                        }
                    }
                    break;
                }
            }
            switch (beacon.Type)
            {
            case -16777213:
                // --- compatibility temporary pattern ---
            {
                double limit    = (double)(beacon.Optional & 4095) / 3.6;
                double position = (double)(beacon.Optional >> 12);
                var    item     = new CompatibilityLimit(limit, position);
                if (!this.CompatibilityLimits.Contains(item))
                {
                    this.CompatibilityLimits.Add(item);
                    this.CompatibilityLimitsNeedsSort = true;
                }
            }
            break;

            case -16777212:
                // --- compatibility permanent pattern ---
                if (beacon.Optional == 0)
                {
                    this.CompatibilityPermanentPattern.Clear();
                }
                else
                {
                    double limit = (double)beacon.Optional / 3.6;
                    this.CompatibilityPermanentPattern.SetLimit(limit, double.MinValue);
                }
                break;
            }
        }
コード例 #6
0
 /// <summary>Is called every frame.</summary>
 /// <param name="data">The data.</param>
 /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param>
 internal override void Elapse(ElapseData data, ref bool blocking)
 {
     // --- behavior ---
     if (this.CompatibilityLimitsNeedsSort)
     {
         CompatibilityLimit.Sort(this, this.CompatibilityLimits);
         this.CompatibilityLimitsNeedsSort = false;
     }
     this.Blocked = blocking;
     if (this.State == States.Suppressed)
     {
         if (data.Handles.BrakeNotch <= this.Train.Specs.BrakeNotches)
         {
             this.InitializationCountdown = DurationOfInitialization;
             this.State = States.Initializing;
         }
     }
     if (this.State == States.Initializing)
     {
         this.InitializationCountdown -= data.ElapsedTime.Seconds;
         if (this.InitializationCountdown <= 0.0)
         {
             this.State                 = States.Standby;
             this.BrakeRelease          = false;
             this.SwitchToAtsSxPosition = double.MaxValue;
             foreach (var pattern in this.Patterns)
             {
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.WarningPattern)
                 {
                     pattern.Clear();
                 }
             }
             this.Train.Sounds.AtsPBell.Play();
         }
     }
     if (BrakeRelease)
     {
         BrakeReleaseCountdown -= data.ElapsedTime.Seconds;
         if (BrakeReleaseCountdown <= 0.0)
         {
             BrakeRelease = false;
             this.Train.Sounds.AtsPBell.Play();
         }
     }
     if (this.State != States.Disabled & this.State != States.Initializing)
     {
         this.Position += data.Vehicle.Speed.MetersPerSecond * data.ElapsedTime.Seconds;
     }
     if (blocking)
     {
         if (this.State != States.Disabled & this.State != States.Suppressed)
         {
             this.State = States.Standby;
         }
     }
     else
     {
         if (this.State == States.Normal | this.State == States.Pattern | this.State == States.Brake)
         {
             bool brake   = false;
             bool warning = false;
             bool normal  = true;
             if (this.DivergencePattern.Position > double.MinValue & this.DivergencePattern.Position < double.MaxValue)
             {
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) < this.DivergencePattern.BrakePattern)
                 {
                     double distance = this.DivergencePattern.Position - this.Position;
                     if (distance < -50.0)
                     {
                         this.DivergencePattern.Clear();
                     }
                 }
             }
             this.UpdateCompatibilityTemporarySpeedPattern();
             foreach (var pattern in this.Patterns)
             {
                 pattern.Perform(this);
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.WarningPattern - 1.0 / 3.6)
                 {
                     normal = false;
                 }
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.WarningPattern)
                 {
                     warning = true;
                 }
                 if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.BrakePattern)
                 {
                     brake = true;
                 }
             }
             for (int i = 0; i < this.SignalPatterns.Count; i++)
             {
                 if (this.SignalPatterns[i].Position > double.MinValue & this.SignalPatterns[i].Position < double.MaxValue)
                 {
                     if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) < this.DivergencePattern.BrakePattern)
                     {
                         double distance = this.DivergencePattern.Position - this.Position;
                         if (distance < -50.0)
                         {
                             this.Patterns.Remove(this.SignalPatterns[i]);
                             this.SignalPatterns[i] = this.SignalPatterns[this.SignalPatterns.Count - 1];
                             this.SignalPatterns.RemoveAt(this.SignalPatterns.Count - 1);
                             i--;
                         }
                     }
                 }
             }
             if (BrakeRelease)
             {
                 brake = false;
             }
             if (brake & this.State != States.Brake)
             {
                 this.State = States.Brake;
                 this.Train.Sounds.AtsPBell.Play();
             }
             else if (warning & this.State == States.Normal)
             {
                 this.State = States.Pattern;
                 this.Train.Sounds.AtsPBell.Play();
             }
             else if (!brake & !warning & normal & (this.State == States.Pattern | this.State == States.Brake))
             {
                 this.State = States.Normal;
                 this.Train.Sounds.AtsPBell.Play();
             }
             if (this.State == States.Brake)
             {
                 if (data.Handles.BrakeNotch < this.Train.Specs.BrakeNotches)
                 {
                     data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches;
                 }
             }
             if (this.Position > this.SwitchToAtsSxPosition & this.State != States.Brake & this.State != States.Service & this.State != States.Emergency)
             {
                 SwitchToSx();
             }
         }
         else if (this.State == States.Service)
         {
             if (data.Handles.BrakeNotch < this.Train.Specs.BrakeNotches)
             {
                 data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches;
             }
         }
         else if (this.State == States.Emergency)
         {
             data.Handles.BrakeNotch = this.Train.Specs.BrakeNotches + 1;
         }
         if (!this.AtsSxPMode & (this.State == States.Normal | this.State == States.Pattern | this.State == States.Brake | this.State == States.Service | this.State == States.Emergency))
         {
             blocking = true;
         }
         if (this.State != States.Disabled & this.Train.Doors != DoorStates.None)
         {
             data.Handles.PowerNotch = 0;
         }
     }
     // --- panel ---
     if (this.State != States.Disabled & this.State != States.Suppressed)
     {
         this.Train.Panel[2]   = 1;
         this.Train.Panel[259] = 1;
     }
     if (this.State == States.Pattern | this.State == States.Brake | this.State == States.Service | this.State == States.Emergency)
     {
         this.Train.Panel[3]   = 1;
         this.Train.Panel[260] = 1;
     }
     if (this.State == States.Brake | this.State == States.Service | this.State == States.Emergency)
     {
         this.Train.Panel[5]   = 1;
         this.Train.Panel[262] = 1;
     }
     if (this.State != States.Disabled & this.State != States.Suppressed & this.State != States.Standby)
     {
         this.Train.Panel[6]   = 1;
         this.Train.Panel[263] = 1;
     }
     if (this.State == States.Initializing)
     {
         this.Train.Panel[7]   = 1;
         this.Train.Panel[264] = 1;
     }
     if (this.State == States.Disabled)
     {
         this.Train.Panel[50] = 1;
     }
     if (this.State != States.Disabled & this.State != States.Suppressed & this.State != States.Standby & this.BrakeRelease)
     {
         this.Train.Panel[4]   = 1;
         this.Train.Panel[261] = 1;
     }
     // --- debug ---
     if (this.State == States.Normal | this.State == States.Pattern | this.State == States.Brake | this.State == States.Service | this.State == States.Emergency)
     {
         var builder = new StringBuilder();
         for (int i = 0; i < this.SignalPatterns.Count; i++)
         {
             this.SignalPatterns[i].AddToStringBuilder(i.ToString() + ":", builder);
         }
         this.DivergencePattern.AddToStringBuilder("分岐/D:", builder);
         this.TemporaryPattern.AddToStringBuilder("臨時/T:", builder);
         this.CurvePattern.AddToStringBuilder("曲線/C:", builder);
         this.DownslopePattern.AddToStringBuilder("勾配/S:", builder);
         this.RoutePermanentPattern.AddToStringBuilder("最高/Max:", builder);
         this.TrainPermanentPattern.AddToStringBuilder("電車/Train:", builder);
         if (this.SwitchToAtsSxPosition != double.MaxValue)
         {
             if (builder.Length != 0)
             {
                 builder.Append(", ");
             }
             builder.Append("Sx@" + (this.SwitchToAtsSxPosition - this.Position).ToString("0"));
         }
         this.CompatibilityTemporaryPattern.AddToStringBuilder("CompTemp", builder);
         this.CompatibilityPermanentPattern.AddToStringBuilder("CompPerm", builder);
         if (builder.Length == 0)
         {
             data.DebugMessage = this.State.ToString();
         }
         else
         {
             data.DebugMessage = this.State.ToString() + " - " + builder.ToString();
         }
     }
 }
コード例 #7
0
ファイル: Atc.cs プロジェクト: sladen/openbve
 /// <summary>Is called when a beacon is passed.</summary>
 /// <param name="beacon">The beacon data.</param>
 internal override void SetBeacon(BeaconData beacon)
 {
     switch (beacon.Type) {
         case -16777215:
             if (beacon.Optional >= 0 & beacon.Optional <= 3) {
                 this.CompatibilityState = (CompatibilityStates)beacon.Optional;
             }
             break;
         case -16777214:
             {
                 double limit = (double)(beacon.Optional & 4095) / 3.6;
                 double position = (beacon.Optional >> 12);
                 CompatibilityLimit item = new CompatibilityLimit(limit, position);
                 if (!this.CompatibilityLimits.Contains(item)) {
                     this.CompatibilityLimits.Add(item);
                 }
             }
             break;
     }
 }