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); }
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)); }), }); }
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)); }), }); }
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(); }
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(); }
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)); }
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)); }
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); }
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)), }); }
internal TimeActivityEvent(STFReader stf) { stf.MustMatchBlockStart(); Update(stf); }
private ApproachControlLimits ReadApproachControlDetails(STFReader stf) { stf.MustMatchBlockStart(); return(new ApproachControlLimits(stf)); }
/// <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; } }
internal RouteStart(STFReader stf) { stf.MustMatchBlockStart(); location = new WorldLocation(stf.ReadInt(null), stf.ReadInt(null), stf.ReadFloat(null), 0f, stf.ReadFloat(null)); stf.SkipRestOfBlock(); }
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"); } }
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); }
public ActionActivityEvent(STFReader stf) { stf.MustMatchBlockStart(); Update(stf); }
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); }) }); }