Esempio n. 1
0
        private static List <SignalDrawLight> ReadDrawLights(STFReader stf)
        {
            stf.MustMatchBlockStart();
            int count = stf.ReadInt(null);
            List <SignalDrawLight> drawLights = new List <SignalDrawLight>(count);

            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("drawlight", () => {
                    if (drawLights.Count >= drawLights.Capacity)
                    {
                        STFException.TraceWarning(stf, "Skipped extra DrawLight");
                    }
                    else
                    {
                        drawLights.Add(new SignalDrawLight(stf));
                    }
                }),
            });
            return(drawLights);
        }
Esempio n. 2
0
        public ServiceTraffics(STFReader stf)
        {
            int   arrivalTime      = 0;
            int   departTime       = 0;
            int   skipCount        = 0;
            float distanceDownPath = 0f;
            int   platformStartID  = 0;

            stf.MustMatchBlockStart();
            Name = stf.ReadString();
            Time = stf.ReadInt(null);   // Cannot use stt.ReadFloat(STFReader.Units.Time, null) as number will be followed by "arrivaltime"
            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("arrivaltime", () => { arrivalTime = (int)stf.ReadFloatBlock(STFReader.Units.Time, null); }),
                new STFReader.TokenProcessor("departtime", () => { departTime = (int)stf.ReadFloatBlock(STFReader.Units.Time, null); }),
                new STFReader.TokenProcessor("skipcount", () => { skipCount = stf.ReadIntBlock(null); }),
                new STFReader.TokenProcessor("distancedownpath", () => { distanceDownPath = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
                new STFReader.TokenProcessor("platformstartid", () => { platformStartID = stf.ReadIntBlock(null);
                                                                        Add(new ServiceTrafficItem(arrivalTime, departTime, skipCount, distanceDownPath, platformStartID, this)); }),
            });
        }
Esempio n. 3
0
        internal PlayerTraffics(STFReader stf)
        {
            int   arrivalTime      = 0;
            int   departTime       = 0;
            int   skipCount        = 0;
            float distanceDownPath = 0f;
            int   platformStartID;

            stf.MustMatchBlockStart();
            Time = (int)stf.ReadFloat(STFReader.Units.Time, null);
            // Clumsy parsing. You only get a new Player_Traffic_Item in the list after a PlatformStartId is met.
            // Blame lies with Microsoft for poor design of syntax.
            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("arrivaltime", () => { arrivalTime = (int)stf.ReadFloatBlock(STFReader.Units.Time, null); }),
                new STFReader.TokenProcessor("departtime", () => { departTime = (int)stf.ReadFloatBlock(STFReader.Units.Time, null); }),
                new STFReader.TokenProcessor("skipcount", () => { skipCount = stf.ReadIntBlock(null); }),
                new STFReader.TokenProcessor("distancedownpath", () => { distanceDownPath = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
                new STFReader.TokenProcessor("platformstartid", () => { platformStartID = stf.ReadIntBlock(null);
                                                                        Add(new ServiceTrafficItem(arrivalTime, departTime, skipCount, distanceDownPath, platformStartID)); }),
            });
        }
Esempio n. 4
0
        public TrackPath(STFReader stf)
        {
            stf.MustMatchBlockStart();
            DynamicSectionIndex = stf.ReadUInt(null);
            uint sectionNumber = stf.ReadUInt(null);

            TrackSections = new uint[sectionNumber];
            for (int i = 0; i < sectionNumber; ++i)
            {
                string token = stf.ReadString();
                if (token == ")")
                {
                    STFException.TraceWarning(stf, "Missing track section");
                    return;   // there are many TSECTION.DAT's with missing sections so we will accept this error
                }
                if (!uint.TryParse(token, out TrackSections[i]))
                {
                    STFException.TraceWarning(stf, "Invalid track section " + token);
                }
            }
            stf.SkipRestOfBlock();
        }
Esempio n. 5
0
 public SectionIndex(STFReader stf)
 {
     stf.MustMatchBlockStart();
     SectionsCount = stf.ReadUInt(null);
     offset        = new Vector3(stf.ReadFloat(null), stf.ReadFloat(null), -stf.ReadFloat(null));
     AngularOffset = stf.ReadFloat(null);
     TrackSections = new uint[SectionsCount];
     for (int i = 0; i < SectionsCount; ++i)
     {
         string token = stf.ReadString();
         if (token == ")")
         {
             STFException.TraceWarning(stf, "Missing track section");
             return;   // there are many TSECTION.DAT's with missing sections so we will accept this error
         }
         if (!uint.TryParse(token, out TrackSections[i]))
         {
             STFException.TraceWarning(stf, "Invalid track section " + token);
         }
     }
     stf.SkipRestOfBlock();
 }
Esempio n. 6
0
 public LightState(STFReader stf)
 {
     stf.MustMatchBlockStart();
     stf.ParseBlock(new[] {
         new STFReader.TokenProcessor("duration", () => { Duration = stf.ReadFloatBlock(STFReader.Units.None, null); }),
         new STFReader.TokenProcessor("lightcolour", () => { Color = stf.ReadHexBlock(null); }),
         new STFReader.TokenProcessor("position", () => { Position = stf.ReadVector3Block(STFReader.Units.None, Vector3.Zero); }),
         new STFReader.TokenProcessor("radius", () => { Radius = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
         new STFReader.TokenProcessor("azimuth", () => { Azimuth = stf.ReadVector3Block(STFReader.Units.None, Vector3.Zero); }),
         new STFReader.TokenProcessor("elevation", () => { Elevation = stf.ReadVector3Block(STFReader.Units.None, Vector3.Zero); }),
         new STFReader.TokenProcessor("transition", () => { Transition = 1 <= stf.ReadFloatBlock(STFReader.Units.None, 0); }),
         new STFReader.TokenProcessor("angle", () => { Angle = stf.ReadFloatBlock(STFReader.Units.None, null); }),
     });
     // Color byte order changed in XNA 4 from BGRA to RGBA
     Color = new Color()
     {
         B = (byte)(Color),
         G = (byte)(Color >> 8),
         R = (byte)(Color >> 16),
         A = (byte)(Color >> 24)
     }.PackedValue;
 }
        public static Interpolator CreateInterpolator(this STFReader stf)
        {
            if (null == stf)
            {
                throw new ArgumentNullException(nameof(stf));
            }

            List <double> list = new List <double>();

            stf.MustMatchBlockStart();
            while (!stf.EndOfBlock())
            {
                list.Add(stf.ReadFloat(STFReader.Units.Any, null));
            }
            if (list.Count % 2 == 1)
            {
                STFException.TraceWarning(stf, "Ignoring extra odd value in Interpolator list.");
            }
            int n = list.Count / 2;

            if (n < 2)
            {
                STFException.TraceWarning(stf, "Interpolator must have at least two value pairs.");
            }
            double[] xArray = new double[n];
            double[] yArray = new double[n];
            for (int i = 0; i < n; i++)
            {
                xArray[i] = list[2 * i];
                yArray[i] = list[2 * i + 1];
                if (i > 0 && xArray[i - 1] >= xArray[i])
                {
                    STFException.TraceWarning(stf, "Interpolator x values must be increasing.");
                }
            }
            return(new Interpolator(xArray, yArray));
        }
Esempio n. 8
0
        public override SBR ReadSubBlock()
        {
            UnicodeBlockReader block = new UnicodeBlockReader
            {
                stf = stf
            };

            string token = stf.ReadItem();

            if (token == "(")
            {
                // ie 310.eng Line 349  (#_fire temp, fire mass, water mass, boil ...
                block.ID = TokenID.Comment;
                return(block);
            }

            // parse token
            block.ID = GetTokenID(token);

            if (token == ")")
            {
                TraceWarning("Ignored extra close bracket");
                return(block);
            }

            // now look for optional label, ie matrix MAIN ( ....
            token = stf.ReadItem();

            if (token != "(")
            {
                block.Label = token;
                stf.MustMatchBlockStart();
            }

            return(block);
        }
        public static Interpolator2D CreateInterpolator2D(this STFReader stf)
        {
            if (null == stf)
            {
                throw new ArgumentNullException(nameof(stf));
            }

            List <double>       xlist = new List <double>();
            List <Interpolator> ilist = new List <Interpolator>();

            stf.MustMatchBlockStart();
            while (!stf.EndOfBlock())
            {
                xlist.Add(stf.ReadFloat(STFReader.Units.Any, null));
                ilist.Add(stf.CreateInterpolator());
            }
            stf.SkipRestOfBlock();
            int n = xlist.Count;

            if (n < 2)
            {
                STFException.TraceWarning(stf, "Interpolator must have at least two x values.");
            }
            double[]       xArray = new double[n];
            Interpolator[] yArray = new Interpolator[n];
            for (int i = 0; i < n; i++)
            {
                xArray[i] = xlist[i];
                yArray[i] = ilist[i];
                if (i > 0 && xArray[i - 1] >= xArray[i])
                {
                    STFException.TraceWarning(stf, " Interpolator x values must be increasing.");
                }
            }
            return(new Interpolator2D(xArray, yArray));
        }
Esempio n. 10
0
        public Lights(STFReader stf)
        {
            stf.MustMatchBlockStart();
            stf.ReadInt(null); // count; ignore this because its not always correct
            stf.ParseBlock(new[] {
                new STFReader.TokenProcessor("light", () => { Add(new Light(Count, stf)); }),
            });
            if (Count == 0)
            {
                throw new InvalidDataException("lights with no lights");
            }

            // MSTSBin created reverse headlight cones automatically, so we shall do so too.
            List <Light> reverseLights = new List <Light>();

            foreach (var light in this)
            {
                if (light.Type == LightType.Cone)
                {
                    reverseLights.Add(new Light(light, true));
                }
            }
            this.AddRange(reverseLights);
        }
Esempio n. 11
0
 internal override void Update(STFReader stf)
 {
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("eventtypeallstops", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Type = EventType.AllStops; }),
         new STFReader.TokenProcessor("eventtypeassembletrain", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Type = EventType.AssembleTrain; }),
         new STFReader.TokenProcessor("eventtypeassembletrainatlocation", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Type = EventType.AssembleTrainAtLocation; }),
         new STFReader.TokenProcessor("eventtypedropoffwagonsatlocation", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Type = EventType.DropOffWagonsAtLocation; }),
         new STFReader.TokenProcessor("eventtypepickuppassengers", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Type = EventType.PickUpPassengers; }),
         new STFReader.TokenProcessor("eventtypepickupwagons", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Type = EventType.PickUpWagons; }),
         new STFReader.TokenProcessor("eventtypereachspeed", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Type = EventType.ReachSpeed; }),
         new STFReader.TokenProcessor("id", () => { ID = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("activation_level", () => { ActivationLevel = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("outcomes", () =>
         {
             if (Outcomes == null)
             {
                 Outcomes = new Outcomes(stf);
             }
             else
             {
                 Outcomes.Update(stf);
             }
         }),
         new STFReader.TokenProcessor("texttodisplayoncompletioniftriggered", () => { TextToDisplayOnCompletionIfTriggered = stf.ReadStringBlock(""); }),
         new STFReader.TokenProcessor("texttodisplayoncompletionifnotriggered", () => { TextToDisplayOnCompletionIfNotTriggered = stf.ReadStringBlock(""); }),
         new STFReader.TokenProcessor("name", () => { Name = stf.ReadStringBlock(""); }),
         new STFReader.TokenProcessor("wagon_list", () => { WorkOrderWagons = new WorkOrderWagons(stf); }),
         new STFReader.TokenProcessor("sidingitem", () => { SidingId = (uint)stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("speed", () => { SpeedMpS = stf.ReadFloatBlock(STFReader.Units.Speed, null); }),
         new STFReader.TokenProcessor("reversable_event", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Reversible = true; }),
         // Also support the correct spelling !
         new STFReader.TokenProcessor("reversible_event", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); Reversible = true; }),
         new STFReader.TokenProcessor("ortscontinue", () => { OrtsContinue = stf.ReadIntBlock(0); }),
         new STFReader.TokenProcessor("ortsactsoundfile", () => OrtsActivitySoundProcessor(stf)),
     });
 }
Esempio n. 12
0
 internal TimeActivityEvent(STFReader stf)
 {
     stf.MustMatchBlockStart();
     Update(stf);
 }
Esempio n. 13
0
 private ApproachControlLimits ReadApproachControlDetails(STFReader stf)
 {
     stf.MustMatchBlockStart();
     return(new ApproachControlLimits(stf));
 }
Esempio n. 14
0
        /// <summary>
        /// Default constructor used during file parsing.
        /// </summary>
        /// <param name="stf">The STFreader containing the file stream</param>
        /// <param name="orMode">Process SignalType for ORTS mode (always set NumClearAhead_ORTS only)</param>
        public SignalType(STFReader stf, bool orMode)
            : this()
        {
            stf.MustMatchBlockStart();
            Name = stf.ReadString().ToLowerInvariant();
            int    numClearAhead     = -2;
            int    numdefs           = 0;
            string ortsFunctionType  = string.Empty;
            string ortsNormalSubType = string.Empty;

            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("ortsscript", () => { Script = stf.ReadStringBlock("").ToLowerInvariant(); }),
                new STFReader.TokenProcessor("signalfntype", () => {
                    if (orMode)
                    {
                        ortsFunctionType = ReadOrtsFunctionType(stf);
                    }
                    else
                    {
                        FunctionType = ReadFunctionType(stf);
                    }
                }),
                new STFReader.TokenProcessor("signallighttex", () => { LightTextureName = stf.ReadStringBlock("").ToLowerInvariant(); }),
                new STFReader.TokenProcessor("signallights", () => { Lights = ReadLights(stf); }),
                new STFReader.TokenProcessor("signaldrawstates", () => { DrawStates = ReadDrawStates(stf); }),
                new STFReader.TokenProcessor("signalaspects", () => { Aspects = ReadAspects(stf); }),
                new STFReader.TokenProcessor("approachcontrolsettings", () => { ApproachControlDetails = ReadApproachControlDetails(stf); }),
                new STFReader.TokenProcessor("signalnumclearahead", () => { numClearAhead = numClearAhead >= -1 ? numClearAhead : stf.ReadIntBlock(null); numdefs++; }),
                new STFReader.TokenProcessor("semaphoreinfo", () => { SemaphoreInfo = stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("ortsdayglow", () => { DayGlow = stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("ortsnightglow", () => { NightGlow = stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("ortsdaylight", () => { DayLight = stf.ReadBoolBlock(true); }),
                new STFReader.TokenProcessor("ortsnormalsubtype", () => { ortsNormalSubType = ReadOrtsNormalSubType(stf); }),
                new STFReader.TokenProcessor("ortsonofftime", () => { TransitionTime = stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("sigflashduration", () => {
                    stf.MustMatchBlockStart();
                    FlashTimeOn  = stf.ReadFloat(STFReader.Units.None, null);
                    FlashTimeOff = stf.ReadFloat(STFReader.Units.None, null);
                    stf.SkipRestOfBlock();
                }),
                new STFReader.TokenProcessor("signalflags", () => {
                    stf.MustMatchBlockStart();
                    while (!stf.EndOfBlock())
                    {
                        switch (stf.ReadString().ToLower())
                        {
                        case "abs": Abs = true; break;

                        case "no_gantry": NoGantry = true; break;

                        case "semaphore": Semaphore = true; break;

                        default: stf.StepBackOneItem(); STFException.TraceInformation(stf, "Skipped unknown SignalType flag " + stf.ReadString()); break;
                        }
                    }
                }),
            });

            if (orMode)
            {
                // set related MSTS function type
                OrtsFunctionTypeIndex = OrSignalTypes.Instance.FunctionTypes.FindIndex(i => StringComparer.OrdinalIgnoreCase.Equals(i, ortsFunctionType));
                if (!EnumExtension.GetValue(ortsFunctionType, out SignalFunction functionType))
                {
                    FunctionType = SignalFunction.Info;
                }
                else
                {
                    FunctionType = functionType;
                }

                // set index for Normal Subtype
                OrtsNormalSubTypeIndex = OrSignalTypes.Instance.NormalSubTypes.FindIndex(i => StringComparer.OrdinalIgnoreCase.Equals(i, ortsNormalSubType));

                // set SNCA
                NumClearAhead_MSTS = -2;
                NumClearAhead_ORTS = numClearAhead;
            }
            else
            {
                // set defaulted OR function type
                OrtsFunctionTypeIndex = (int)FunctionType;

                // set SNCA
                NumClearAhead_MSTS = numdefs == 1 ? numClearAhead : -2;
                NumClearAhead_ORTS = numdefs == 2 ? numClearAhead : -2;
            }
        }
Esempio n. 15
0
 internal RouteStart(STFReader stf)
 {
     stf.MustMatchBlockStart();
     location = new WorldLocation(stf.ReadInt(null), stf.ReadInt(null), stf.ReadFloat(null), 0f, stf.ReadFloat(null));
     stf.SkipRestOfBlock();
 }
Esempio n. 16
0
 internal Route(STFReader stf)
 {
     stf.MustMatchBlockStart();
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("routeid", () => { RouteID = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("name", () => { Name = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("filename", () => { FileName = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("description", () => { Description = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("maxlinevoltage", () => { MaxLineVoltage = stf.ReadFloatBlock(STFReader.Units.None, null); }),
         new STFReader.TokenProcessor("routestart", () => { RouteStart = new RouteStart(stf); }),
         new STFReader.TokenProcessor("environment", () => { Environment = new Environment(stf); }),
         new STFReader.TokenProcessor("milepostunitskilometers", () => { MilepostUnitsMetric = true; }),
         new STFReader.TokenProcessor("electrified", () => { Electrified = stf.ReadBoolBlock(false); }),
         new STFReader.TokenProcessor("overheadwireheight", () => { OverheadWireHeight = stf.ReadFloatBlock(STFReader.Units.Distance, 6.0f); }),
         new STFReader.TokenProcessor("speedlimit", () => { SpeedLimit = stf.ReadFloatBlock(STFReader.Units.Speed, 500.0f); }),
         new STFReader.TokenProcessor("defaultcrossingsms", () => { DefaultCrossingSMS = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("defaultcoaltowersms", () => { DefaultCoalTowerSMS = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("defaultdieseltowersms", () => { DefaultDieselTowerSMS = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("defaultwatertowersms", () => { DefaultWaterTowerSMS = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("defaultsignalsms", () => { DefaultSignalSMS = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("temprestrictedspeed", () => { TempRestrictedSpeed = stf.ReadFloatBlock(STFReader.Units.Speed, -1f); }),
         // values for tunnel operation
         new STFReader.TokenProcessor("ortssingletunnelarea", () => { SingleTunnelAreaM2 = stf.ReadFloatBlock(STFReader.Units.AreaDefaultFT2, null); }),
         new STFReader.TokenProcessor("ortssingletunnelperimeter", () => { SingleTunnelPerimeterM = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
         new STFReader.TokenProcessor("ortsdoubletunnelarea", () => { DoubleTunnelAreaM2 = stf.ReadFloatBlock(STFReader.Units.AreaDefaultFT2, null); }),
         new STFReader.TokenProcessor("ortsdoubletunnelperimeter", () => { DoubleTunnelPerimeterM = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
         // if > 0 indicates distance from track without forest trees
         new STFReader.TokenProcessor("ortsuserpreferenceforestcleardistance", () => { ForestClearDistance = stf.ReadFloatBlock(STFReader.Units.Distance, 0); }),
         // if true removes forest trees also from roads
         new STFReader.TokenProcessor("ortsuserpreferenceremoveforesttreesfromroads", () => { RemoveForestTreesFromRoads = stf.ReadBoolBlock(false); }),
         // values for superelevation
         new STFReader.TokenProcessor("ortstracksuperelevation", () => { SuperElevationHgtpRadiusM = stf.CreateInterpolator(); }),
         // images
         new STFReader.TokenProcessor("graphic", () => { Thumbnail = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("loadingscreen", () => { LoadingScreen = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("ortsloadingscreenwide", () => { LoadingScreenWide = stf.ReadStringBlock(null); }),
         // values for OHLE
         new STFReader.TokenProcessor("ortsdoublewireenabled", () => { DoubleWireEnabled = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("ortsdoublewireheight", () => { DoubleWireHeight = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
         new STFReader.TokenProcessor("ortstriphaseenabled", () => { TriphaseEnabled = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("ortstriphasewidth", () => { TriphaseWidth = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
         // default sms file for turntables and transfertables
         new STFReader.TokenProcessor("ortsdefaultturntablesms", () => { DefaultTurntableSMS = stf.ReadStringBlock(null); }),
         // sms file number in Ttype.dat when train over switch
         new STFReader.TokenProcessor("ortsswitchsmsnumber", () => { SwitchSMSNumber = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("ortscurvesmsnumber", () => { CurveSMSNumber = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("ortscurveswitchsmsnumber", () => { CurveSwitchSMSNumber = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("ortsopendoorsinaitrains", () => { OpenDoorsInAITrains = stf.ReadBoolBlock(false); }),
     });
     //TODO This should be changed to STFException.TraceError() with defaults values created
     if (RouteID == null)
     {
         throw new STFException(stf, "Missing RouteID");
     }
     if (Name == null)
     {
         throw new STFException(stf, "Missing Name");
     }
     if (Description == null)
     {
         throw new STFException(stf, "Missing Description");
     }
     if (RouteStart == null)
     {
         throw new STFException(stf, "Missing RouteStart");
     }
     if (ForestClearDistance == 0 && RemoveForestTreesFromRoads)
     {
         Trace.TraceWarning("You must define also ORTSUserPreferenceForestClearDistance to avoid trees on roads");
     }
 }
Esempio n. 17
0
        public static Interpolator2D CreateInterpolator2D(this STFReader stf, bool tab)
        {
            List <double>       xlist = new List <double>();
            List <Interpolator> ilist = new List <Interpolator>();

            bool errorFound = false;

            if (tab)
            {
                stf.MustMatchBlockStart();
                int numOfRows = stf.ReadInt(0);
                if (numOfRows < 2)
                {
                    STFException.TraceWarning(stf, "Interpolator must have at least two rows.");
                    errorFound = true;
                }
                int    numOfColumns = stf.ReadInt(0);
                string header       = stf.ReadString().ToLower();
                if (header == "throttle")
                {
                    stf.MustMatchBlockStart();
                    int numOfThrottleValues = 0;
                    while (!stf.EndOfBlock())
                    {
                        xlist.Add(stf.ReadFloat(STFReader.Units.None, 0f));
                        ilist.Add(new Interpolator(numOfRows));
                        numOfThrottleValues++;
                    }
                    if (numOfThrottleValues != (numOfColumns - 1))
                    {
                        STFException.TraceWarning(stf, "Interpolator throttle vs. num of columns mismatch.");
                        errorFound = true;
                    }

                    if (numOfColumns < 3)
                    {
                        STFException.TraceWarning(stf, "Interpolator must have at least three columns.");
                        errorFound = true;
                    }

                    int    numofData  = 0;
                    string tableLabel = stf.ReadString().ToLower();
                    if (tableLabel == "table")
                    {
                        stf.MustMatchBlockStart();
                        for (int i = 0; i < numOfRows; i++)
                        {
                            float x = stf.ReadFloat(STFReader.Units.SpeedDefaultMPH, 0);
                            numofData++;
                            for (int j = 0; j < numOfColumns - 1; j++)
                            {
                                if (j >= ilist.Count)
                                {
                                    STFException.TraceWarning(stf, "Interpolator throttle vs. num of columns mismatch. (missing some throttle values)");
                                    errorFound = true;
                                }
                                ilist[j][x] = stf.ReadFloat(STFReader.Units.Force, 0);
                                numofData++;
                            }
                        }
                        stf.SkipRestOfBlock();
                    }
                    else
                    {
                        STFException.TraceWarning(stf, "Interpolator didn't find a table to load.");
                        errorFound = true;
                    }
                    //check the table for inconsistencies

                    foreach (Interpolator checkMe in ilist)
                    {
                        if (checkMe.Size != numOfRows)
                        {
                            STFException.TraceWarning(stf, "Interpolator has found a mismatch between num of rows declared and num of rows given.");
                            errorFound = true;
                        }
                        double dx = (checkMe.MaxX() - checkMe.MinX()) * 0.1f;
                        if (dx <= 0f)
                        {
                            STFException.TraceWarning(stf, "Interpolator has found X data error - x values must be increasing. (Possible row number mismatch)");
                            errorFound = true;
                        }
                        else
                        {
                            for (double x = checkMe.MinX(); x <= checkMe.MaxX(); x += dx)
                            {
                                if (double.IsNaN(checkMe[x]))
                                {
                                    STFException.TraceWarning(stf, "Interpolator has found X data error - x values must be increasing. (Possible row number mismatch)");
                                    errorFound = true;
                                    break;
                                }
                            }
                        }
                    }

                    if (numofData != (numOfRows * numOfColumns))
                    {
                        STFException.TraceWarning(stf, "Interpolator has found a mismatch: num of data doesn't fit the header information.");
                        errorFound = true;
                    }
                }
                else
                {
                    STFException.TraceWarning(stf, "Interpolator must have a 'throttle' header row.");
                    errorFound = true;
                }
                stf.SkipRestOfBlock();
            }
            else
            {
                stf.MustMatchBlockStart();
                while (!stf.EndOfBlock())
                {
                    xlist.Add(stf.ReadFloat(STFReader.Units.Any, null));
                    ilist.Add(stf.CreateInterpolator());
                }
            }


            int n = xlist.Count;

            if (n < 2)
            {
                STFException.TraceWarning(stf, "Interpolator must have at least two x values.");
                errorFound = true;
            }
            double[]       xArray = new double[n];
            Interpolator[] yArray = new Interpolator[n];
            for (int i = 0; i < n; i++)
            {
                xArray[i] = xlist[i];
                yArray[i] = ilist[i];
                if (i > 0 && xArray[i - 1] >= xArray[i])
                {
                    STFException.TraceWarning(stf, "Interpolator x values must be increasing.");
                }
            }
            if (errorFound)
            {
                STFException.TraceWarning(stf, "Errors found in the Interpolator definition!!! The Interpolator will not work correctly!");
            }

            Interpolator2D result = new Interpolator2D(xArray, yArray);

            return(result);
        }
Esempio n. 18
0
 public ActionActivityEvent(STFReader stf)
 {
     stf.MustMatchBlockStart();
     Update(stf);
 }
Esempio n. 19
0
        public float FullStaticCentreOfGravityM_Y     = -9999; // get centre of gravity after adjusted for freight animation

        public FreightAnimationStatic(STFReader stf)
        {
            stf.MustMatch("(");
            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("subtype", () =>
                {
                    var typeString = stf.ReadStringBlock(null);
                    switch (typeString)
                    {
                    default:
                        SubType = FreightAnimationStatic.Type.DEFAULT;
                        break;
                    }
                }),
                new STFReader.TokenProcessor("shape", () => { ShapeFileName = stf.ReadStringBlock(null); }),
                new STFReader.TokenProcessor("freightweight", () => { FreightWeight = stf.ReadFloatBlock(STFReader.Units.Mass, 0); }),
                new STFReader.TokenProcessor("offset", () => {
                    stf.MustMatchBlockStart();
                    XOffset = stf.ReadFloat(STFReader.Units.Distance, 0);
                    YOffset = stf.ReadFloat(STFReader.Units.Distance, 0);
                    ZOffset = stf.ReadFloat(STFReader.Units.Distance, 0);
                    stf.MustMatchBlockEnd();
                }),
                new STFReader.TokenProcessor("flip", () => { Flipped = stf.ReadBoolBlock(true); }),
                new STFReader.TokenProcessor("visibility", () => {
                    for (int index = 0; index < 3; index++)
                    {
                        Visibility[index] = false;
                    }
                    foreach (var visibilityPlace in stf.ReadStringBlock("").ToLower().Replace(" ", "").Split(','))
                    {
                        switch (visibilityPlace)
                        {
                        case "outside":
                            Visibility[(int)VisibleFrom.Outside] = true;
                            break;

                        case "cab2d":
                            Visibility[(int)VisibleFrom.Cab2D] = true;
                            break;

                        case "cab3d":
                            Visibility[(int)VisibleFrom.Cab3D] = true;
                            break;

                        default:
                            break;
                        }
                    }
                }),
                // additions to manage consequences of variable weight on friction and brake forces
                new STFReader.TokenProcessor("fullortsdavis_a", () => { FullStaticORTSDavis_A = stf.ReadFloatBlock(STFReader.Units.Force, -1); }),
                new STFReader.TokenProcessor("fullortsdavis_b", () => { FullStaticORTSDavis_B = stf.ReadFloatBlock(STFReader.Units.Resistance, -1); }),
                new STFReader.TokenProcessor("fullortsdavis_c", () => { FullStaticORTSDavis_C = stf.ReadFloatBlock(STFReader.Units.ResistanceDavisC, -1); }),
                new STFReader.TokenProcessor("fullortswagonfrontalarea", () => { FullStaticORTSWagonFrontalAreaM2 = stf.ReadFloatBlock(STFReader.Units.AreaDefaultFT2, -1); }),
                new STFReader.TokenProcessor("fullortsdavisdragconstant", () => { FullStaticORTSDavisDragConstant = stf.ReadFloatBlock(STFReader.Units.Any, -1); }),
                new STFReader.TokenProcessor("fullmaxbrakeforce", () => { FullStaticMaxBrakeForceN = stf.ReadFloatBlock(STFReader.Units.Force, -1); }),
                new STFReader.TokenProcessor("fullmaxhandbrakeforce", () => { FullStaticMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.Units.Force, -1); }),
                new STFReader.TokenProcessor("fullcentreofgravity_y", () => { FullStaticCentreOfGravityM_Y = stf.ReadFloatBlock(STFReader.Units.Distance, -1); })
            });
        }