/// <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("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; } }
public 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 abstract void Parse(string lowercasetoken, STFReader stf);
public MSTSNotch(float v, int s, string type, STFReader stf) { Value = v; Smooth = s == 0 ? false : true; NotchStateType = ControllerState.Dummy; // Default to a dummy controller state if no valid alternative state used string lower = type.ToLower(); if (lower.StartsWith("trainbrakescontroller")) { lower = lower.Substring(21); } if (lower.StartsWith("enginebrakescontroller")) { lower = lower.Substring(22); } if (lower.StartsWith("brakemanbrakescontroller")) { lower = lower.Substring(24); } switch (lower) { case "dummy": break; case ")": break; case "releasestart": NotchStateType = ControllerState.Release; break; case "fullquickreleasestart": NotchStateType = ControllerState.FullQuickRelease; break; case "runningstart": NotchStateType = ControllerState.Running; break; case "selflapstart": NotchStateType = ControllerState.SelfLap; break; case "holdstart": NotchStateType = ControllerState.Hold; break; case "straightbrakingreleaseonstart": NotchStateType = ControllerState.StraightReleaseOn; break; case "straightbrakingreleaseoffstart": NotchStateType = ControllerState.StraightReleaseOff; break; case "straightbrakingreleasestart": NotchStateType = ControllerState.StraightRelease; break; case "straightbrakinglapstart": NotchStateType = ControllerState.StraightLap; break; case "straightbrakingapplystart": NotchStateType = ControllerState.StraightApply; break; case "straightbrakingapplyallstart": NotchStateType = ControllerState.StraightApplyAll; break; case "straightbrakingemergencystart": NotchStateType = ControllerState.StraightEmergency; break; case "holdlappedstart": NotchStateType = ControllerState.Lap; break; case "neutralhandleoffstart": NotchStateType = ControllerState.Neutral; break; case "graduatedselflaplimitedstart": NotchStateType = ControllerState.GSelfLap; break; case "graduatedselflaplimitedholdingstart": NotchStateType = ControllerState.GSelfLapH; break; case "applystart": NotchStateType = ControllerState.Apply; break; case "continuousservicestart": NotchStateType = ControllerState.ContServ; break; case "suppressionstart": NotchStateType = ControllerState.Suppression; break; case "fullservicestart": NotchStateType = ControllerState.FullServ; break; case "emergencystart": NotchStateType = ControllerState.Emergency; break; case "minimalreductionstart": NotchStateType = ControllerState.MinimalReduction; break; case "epapplystart": NotchStateType = ControllerState.EPApply; break; case "epholdstart": NotchStateType = ControllerState.SelfLap; break; case "smeholdstart": NotchStateType = ControllerState.SMESelfLap; break; case "smeonlystart": NotchStateType = ControllerState.SMEOnly; break; case "smefullservicestart": NotchStateType = ControllerState.SMEFullServ; break; case "smereleasestart": NotchStateType = ControllerState.SMEReleaseStart; break; case "vacuumcontinuousservicestart": NotchStateType = ControllerState.VacContServ; break; case "vacuumapplycontinuousservicestart": NotchStateType = ControllerState.VacApplyContServ; break; case "manualbrakingstart": NotchStateType = ControllerState.ManualBraking; break; case "brakenotchstart": NotchStateType = ControllerState.BrakeNotch; break; case "overchargestart": NotchStateType = ControllerState.Overcharge; break; case "slowservicestart": NotchStateType = ControllerState.SlowService; break; default: STFException.TraceInformation(stf, "Skipped unknown notch type " + type); break; } }
public InterpolatorDiesel2D(STFReader stf, bool tab) { // <CSComment> TODO: probably there is some other stf.SkipRestOfBlock() that should be removed </CSComment> List <float> xlist = new List <float>(); List <Interpolator> ilist = new List <Interpolator>(); bool errorFound = false; if (tab) { stf.MustMatch("("); 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.MustMatch("("); 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.MustMatch("("); 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.GetSize() != numOfRows) { STFException.TraceWarning(stf, "Interpolator has found a mismatch between num of rows declared and num of rows given."); errorFound = true; } float 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 (float x = checkMe.MinX(); x <= checkMe.MaxX(); x += dx) { if ((checkMe[x] == float.NaN)) { 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.MustMatch("("); while (!stf.EndOfBlock()) { xlist.Add(stf.ReadFloat(STFReader.UNITS.Any, null)); ilist.Add(new Interpolator(stf)); } } int n = xlist.Count; if (n < 2) { STFException.TraceWarning(stf, "Interpolator must have at least two x values."); errorFound = true; } X = new float[n]; Y = new Interpolator[n]; Size = n; for (int i = 0; i < n; i++) { X[i] = xlist[i]; Y[i] = ilist[i]; if (i > 0 && X[i - 1] >= X[i]) { STFException.TraceWarning(stf, "Interpolator x values must be increasing."); } } //stf.SkipRestOfBlock(); if (errorFound) { STFException.TraceWarning(stf, "Errors found in the Interpolator definition!!! The Interpolator will not work correctly!"); } }
public void Parse(string lowercasetoken, STFReader stf) { switch (lowercasetoken) { case "engine(trainbrakescontrollermaxsystempressure": case "engine(enginebrakescontrollermaxsystempressure": MaxPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break; case "engine(trainbrakescontrollermaxreleaserate": case "engine(enginebrakescontrollermaxreleaserate": ReleaseRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break; case "engine(trainbrakescontrollermaxquickreleaserate": case "engine(enginebrakescontrollermaxquickreleaserate": QuickReleaseRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break; case "engine(trainbrakescontrollermaxapplicationrate": case "engine(enginebrakescontrollermaxapplicationrate": ApplyRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break; case "engine(trainbrakescontrolleremergencyapplicationrate": case "engine(enginebrakescontrolleremergencyapplicationrate": EmergencyRatePSIpS = stf.ReadFloatBlock(STFReader.UNITS.PressureRateDefaultPSIpS, null); break; case "engine(trainbrakescontrollerfullservicepressuredrop": case "engine(enginebrakescontrollerfullservicepressuredrop": FullServReductionPSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break; case "engine(trainbrakescontrollerminpressurereduction": case "engine(enginebrakescontrollerminpressurereduction": MinReductionPSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, null); break; case "engine(enginecontrollers(brake_train": case "engine(enginecontrollers(brake_engine": stf.MustMatch("("); MinimumValue = stf.ReadFloat(STFReader.UNITS.None, null); MaximumValue = stf.ReadFloat(STFReader.UNITS.None, null); StepSize = stf.ReadFloat(STFReader.UNITS.None, null); CurrentValue = stf.ReadFloat(STFReader.UNITS.None, null); string token = stf.ReadItem(); // s/b numnotches if (string.Compare(token, "NumNotches", true) != 0) // handle error in gp38.eng where extra parameter provided before NumNotches statement { stf.ReadItem(); } stf.MustMatch("("); stf.ReadInt(null); stf.ParseBlock(new STFReader.TokenProcessor[] { new STFReader.TokenProcessor("notch", () => { stf.MustMatch("("); float value = stf.ReadFloat(STFReader.UNITS.None, null); int smooth = stf.ReadInt(null); string type = stf.ReadString(); Notches.Add(new MSTSNotch(value, smooth, type, stf)); if (type != ")") { stf.SkipRestOfBlock(); } }), }); break; case "engine(ortstrainbrakecontroller": case "engine(ortsenginebrakecontroller": if (Locomotive.Train as AITrain == null) { ScriptName = stf.ReadStringBlock(null); } break; } }
/// <summary> /// Reads RailDriver calibration data from a ModernCalibration.rdm file /// This file is not in the usual STF format, but the STFReader can handle it okay. /// </summary> /// <param name="basePath"></param> void ReadCalibrationData(string basePath) { string file = basePath + "\\ModernCalibration.rdm"; if (!File.Exists(file)) { RegistryKey RK = Registry.LocalMachine.OpenSubKey("SOFTWARE\\PI Engineering\\PIBUS"); if (RK != null) { string dir = (string)RK.GetValue("RailDriver", null, RegistryValueOptions.None); if (dir != null) { file = dir + "\\..\\controller\\ModernCalibration.rdm"; } } if (!File.Exists(file)) { SetLEDs(0, 0, 0); Trace.TraceWarning("Cannot find RailDriver calibration file {0}", file); return; } } // TODO: This is... kinda weird and cool at the same time. STF parsing being used on RailDriver's calebration file. Probably should be a dedicated parser, though. STFReader reader = new STFReader(file, false); while (!reader.Eof) { string token = reader.ReadItem(); if (token == "Position") { string name = reader.ReadItem(); int min = -1; int max = -1; while (token != "}") { token = reader.ReadItem(); if (token == "Min") { min = reader.ReadInt(-1); } else if (token == "Max") { max = reader.ReadInt(-1); } } if (min >= 0 && max >= 0) { float v = .5f * (min + max); switch (name) { case "Full Reversed": FullReversed = v; break; case "Neutral": Neutral = v; break; case "Full Forward": FullForward = v; break; case "Full Throttle": FullThrottle = v; break; case "Throttle Idle": ThrottleIdle = v; break; case "Dynamic Brake": DynamicBrake = v; break; case "Dynamic Brake Setup": DynamicBrakeSetup = v; break; case "Auto Brake Released": AutoBrakeRelease = v; break; case "Full Auto Brake (CS)": FullAutoBrake = v; break; case "Emergency Brake (EMG)": EmergencyBrake = v; break; case "Independent Brake Released": IndependentBrakeRelease = v; break; case "Bail Off Engaged (in Released position)": BailOffEngagedRelease = v; break; case "Independent Brake Full": IndependentBrakeFull = v; break; case "Bail Off Engaged (in Full position)": BailOffEngagedFull = v; break; case "Bail Off Disengaged (in Released position)": BailOffDisengagedRelease = v; break; case "Bail Off Disengaged (in Full position)": BailOffDisengagedFull = v; break; case "Rotary Switch 1-Position 1(OFF)": Rotary1Position1 = v; break; case "Rotary Switch 1-Position 2(SLOW)": Rotary1Position2 = v; break; case "Rotary Switch 1-Position 3(FULL)": Rotary1Position3 = v; break; case "Rotary Switch 2-Position 1(OFF)": Rotary2Position1 = v; break; case "Rotary Switch 2-Position 2(DIM)": Rotary2Position2 = v; break; case "Rotary Switch 2-Position 3(FULL)": Rotary2Position3 = v; break; default: STFException.TraceInformation(reader, "Skipped unknown calibration value " + name); break; } } } } }
public void Parse(string lowercasetoken, STFReader stf) { mstsParams.Parse(lowercasetoken, stf); }
public void Parse(string lowercasetoken, STFReader stf) { string temp = ""; switch (lowercasetoken) { case "engine(gearboxnumberofgears": GearBoxNumberOfGears = stf.ReadIntBlock(1); initLevel++; break; case "engine(gearboxdirectdrivegear": GearBoxDirectDriveGear = stf.ReadIntBlock(1); break; // initLevel++; break; case "engine(gearboxoperation": temp = stf.ReadStringBlock("manual"); switch (temp) { case "manual": GearBoxOperation = GearBoxOperation.Manual; break; case "automatic": GearBoxOperation = GearBoxOperation.Automatic; break; case "semiautomatic": GearBoxOperation = GearBoxOperation.Semiautomatic; break; } initLevel++; break; case "engine(gearboxenginebraking": temp = stf.ReadStringBlock("none"); switch (temp) { case "none": GearBoxEngineBraking = GearBoxEngineBraking.None; break; case "all_gears": GearBoxEngineBraking = GearBoxEngineBraking.AllGears; break; case "direct_drive": GearBoxEngineBraking = GearBoxEngineBraking.DirectDrive; break; } initLevel++; break; case "engine(gearboxmaxspeedforgears": temp = stf.ReadItem(); if (temp == ")") { stf.StepBackOneItem(); } if (temp == "(") { GearBoxMaxSpeedForGearsMpS.Clear(); for (int i = 0; i < GearBoxNumberOfGears; i++) { GearBoxMaxSpeedForGearsMpS.Add(stf.ReadFloat(STFReader.UNITS.SpeedDefaultMPH, 10.0f)); } stf.SkipRestOfBlock(); initLevel++; } break; case "engine(gearboxmaxtractiveforceforgears": temp = stf.ReadItem(); if (temp == ")") { stf.StepBackOneItem(); } if (temp == "(") { GearBoxMaxTractiveForceForGearsN.Clear(); for (int i = 0; i < GearBoxNumberOfGears; i++) { GearBoxMaxTractiveForceForGearsN.Add(stf.ReadFloat(STFReader.UNITS.Force, 10000.0f)); } stf.SkipRestOfBlock(); initLevel++; } break; case "engine(gearboxoverspeedpercentageforfailure": GearBoxOverspeedPercentageForFailure = stf.ReadFloatBlock(STFReader.UNITS.None, 150f); break; // initLevel++; break; case "engine(gearboxbackloadforce": GearBoxBackLoadForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, 0f); break; case "engine(gearboxcoastingforce": GearBoxCoastingForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, 0f); break; case "engine(gearboxupgearproportion": GearBoxUpGearProportion = stf.ReadFloatBlock(STFReader.UNITS.None, 0.85f); break; // initLevel++; break; case "engine(gearboxdowngearproportion": GearBoxDownGearProportion = stf.ReadFloatBlock(STFReader.UNITS.None, 0.25f); break; // initLevel++; break; default: break; } }
/// <summary> /// Parses parameters from the stf reader /// </summary> /// <param name="stf">Reference to the stf reader</param> /// <param name="loco">Reference to the locomotive</param> public virtual void Parse(STFReader stf, MSTSDieselLocomotive loco) { locomotive = loco; stf.MustMatch("("); bool end = false; while (!end) { string lowercasetoken = stf.ReadItem().ToLower(); switch (lowercasetoken) { case "idlerpm": IdleRPM = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.IdleRPM; break; case "maxrpm": MaxRPM = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.MaxRPM; break; case "startingrpm": StartingRPM = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.StartingRPM; break; case "startingconfirmrpm": StartingConfirmationRPM = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.StartingConfirmRPM; break; case "changeuprpmps": ChangeUpRPMpS = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.ChangeUpRPMpS; break; case "changedownrpmps": ChangeDownRPMpS = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.ChangeDownRPMpS; break; case "rateofchangeuprpmpss": RateOfChangeUpRPMpSS = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.RateOfChangeUpRPMpSS; break; case "rateofchangedownrpmpss": RateOfChangeDownRPMpSS = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.RateOfChangeDownRPMpSS; break; case "maximalpower": MaximalPowerW = stf.ReadFloatBlock(STFReader.UNITS.Power, 0); initLevel |= SettingsFlags.MaximalPowerW; break; case "idleexhaust": InitialExhaust = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.IdleExhaust; break; case "maxexhaust": MaxExhaust = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.MaxExhaust; break; case "exhaustdynamics": ExhaustAccelIncrease = stf.ReadFloatBlock(STFReader.UNITS.None, 0); initLevel |= SettingsFlags.ExhaustDynamics; break; case "exhaustdynamicsdown": ExhaustDecelReduction = stf.ReadFloatBlock(STFReader.UNITS.None, null); initLevel |= SettingsFlags.ExhaustDynamics; break; case "exhaustcolor": ExhaustSteadyColor.PackedValue = stf.ReadHexBlock(Color.Gray.PackedValue); initLevel |= SettingsFlags.ExhaustColor; break; case "exhausttransientcolor": ExhaustTransientColor.PackedValue = stf.ReadHexBlock(Color.Black.PackedValue); initLevel |= SettingsFlags.ExhaustTransientColor; break; case "dieselpowertab": DieselPowerTab = new Interpolator(stf); initLevel |= SettingsFlags.DieselPowerTab; break; case "dieselconsumptiontab": DieselConsumptionTab = new Interpolator(stf); initLevel |= SettingsFlags.DieselConsumptionTab; break; case "throttlerpmtab": ThrottleRPMTab = new Interpolator(stf); initLevel |= SettingsFlags.ThrottleRPMTab; break; case "dieseltorquetab": DieselTorqueTab = new Interpolator(stf); initLevel |= SettingsFlags.DieselTorqueTab; break; case "minoilpressure": DieselMinOilPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, 40f); initLevel |= SettingsFlags.MinOilPressure; break; case "maxoilpressure": DieselMaxOilPressurePSI = stf.ReadFloatBlock(STFReader.UNITS.PressureDefaultPSI, 120f); initLevel |= SettingsFlags.MaxOilPressure; break; case "maxtemperature": DieselMaxTemperatureDeg = stf.ReadFloatBlock(STFReader.UNITS.TemperatureDifference, 100f); initLevel |= SettingsFlags.MaxTemperature; break; case "cooling": EngineCooling = (Cooling)stf.ReadIntBlock((int)Cooling.Proportional); initLevel |= SettingsFlags.Cooling; break; //ReadInt changed to ReadIntBlock case "temptimeconstant": DieselTempTimeConstantSec = stf.ReadFloatBlock(STFReader.UNITS.Time, 720f); initLevel |= SettingsFlags.TempTimeConstant; break; case "opttemperature": DieselOptimalTemperatureDegC = stf.ReadFloatBlock(STFReader.UNITS.TemperatureDifference, 95f); initLevel |= SettingsFlags.OptTemperature; break; case "idletemperature": DieselIdleTemperatureDegC = stf.ReadFloatBlock(STFReader.UNITS.TemperatureDifference, 75f); initLevel |= SettingsFlags.IdleTemperature; break; default: end = true; break; } } }
public AttributeProcessor(object setWhom, FieldInfo fi, STFReader stf, object defaultValue) { fieldInfo = fi; Processor = () => { switch (fieldInfo.FieldType.Name.ToUpperInvariant()) { case "INT": case "INT32": { int?i = defaultValue as int?; fieldInfo.SetValue(setWhom, stf.ReadIntBlock(i)); break; } case "BOOL": case "BOOLEAN": { bool?b = defaultValue as bool?; fieldInfo.SetValue(setWhom, stf.ReadBoolBlock(b.Value)); break; } case "STRING": { string s = defaultValue as string; fieldInfo.SetValue(setWhom, stf.ReadStringBlock(s)); break; } case "FLOAT": case "SINGLE": { float?f = defaultValue as float?; fieldInfo.SetValue(setWhom, stf.ReadFloatBlock(STFReader.Units.Any, f)); break; } case "DOUBLE": { double?d = defaultValue as double?; fieldInfo.SetValue(setWhom, stf.ReadDoubleBlock(d)); break; } case "VECTOR3": { Vector3 v3 = (defaultValue as string).ParseVector3(); { fieldInfo.SetValue(setWhom, stf.ReadVector3Block(STFReader.Units.Any, v3)); } break; } case "VECTOR4": { Vector4 v4 = (defaultValue as string).ParseVector4(); { stf.ReadVector4Block(STFReader.Units.Any, ref v4); fieldInfo.SetValue(setWhom, v4); } break; } case "COLOR": { Color c = (defaultValue as string).ParseColor(); { Vector4 v4 = new Vector4(-1); stf.ReadVector4Block(STFReader.Units.Any, ref v4); if (v4.W == -1) { c.A = 255; c.R = v4.X == -1 ? c.R : (byte)v4.X; c.G = v4.Y == -1 ? c.G : (byte)v4.Y; c.B = v4.Z == -1 ? c.B : (byte)v4.Z; } else { c.A = v4.X == -1 ? c.A : (byte)v4.X; c.R = v4.Y == -1 ? c.R : (byte)v4.Y; c.G = v4.Z == -1 ? c.G : (byte)v4.Z; c.B = v4.W == -1 ? c.B : (byte)v4.W; } fieldInfo.SetValue(setWhom, c); } break; } } }; }
/// <summary> /// Creates a set of auxiliaries connected to the locomotive, based on stf reader parameters /// </summary> /// <param name="loco">Host locomotive</param> /// <param name="stf">Reference to the ENG file reader</param> public DieselEngines(MSTSDieselLocomotive loco, STFReader stf) { Locomotive = loco; Parse(stf, loco); }
public UnicodeFileReader(Stream inputStream, string fileName, Encoding encoding) { FileName = fileName; stf = new STFReader(inputStream, fileName, encoding, false); }
public MSTSStageController(STFReader f) : base(f) { }
private ApproachControlLimits ReadApproachControlDetails(STFReader stf) { stf.MustMatchBlockStart(); return(new ApproachControlLimits(stf)); }
public virtual void Update(STFReader stf) { }
public void Parse(STFReader stf) { Parse(stf.Tree.ToLower(), stf); }
public TimeActivityEvent(STFReader stf) { stf.MustMatchBlockStart(); Update(stf); }
public void Parse(STFReader f) { throw new NotImplementedException("Parse not suported by SimpleController"); }
public Outcomes(STFReader stf) { Update(stf); }
public MSTSNotchController(STFReader stf) { Parse(stf); }
public bool StaticFreightAnimationsPresent = false; // Flag to indicate that a continuous freight animation is present public FreightAnimations(STFReader stf, MSTSWagon wagon) { stf.MustMatch("("); bool empty = true; stf.ParseBlock(new[] { new STFReader.TokenProcessor("mstsfreightanimenabled", () => { MSTSFreightAnimEnabled = stf.ReadBoolBlock(true); }), new STFReader.TokenProcessor("wagonemptyweight", () => { WagonEmptyWeight = stf.ReadFloatBlock(STFReader.UNITS.Mass, -1); }), new STFReader.TokenProcessor("loadingstartdelay", () => { UnloadingStartDelay = stf.ReadFloatBlock(STFReader.UNITS.None, 0); }), new STFReader.TokenProcessor("unloadingstartdelay", () => { UnloadingStartDelay = stf.ReadFloatBlock(STFReader.UNITS.None, 0); }), new STFReader.TokenProcessor("isgondola", () => { IsGondola = stf.ReadBoolBlock(false); }), // additions to manage consequences of variable weight on friction and brake forces new STFReader.TokenProcessor("emptyortsdavis_a", () => { EmptyORTSDavis_A = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("emptyortsdavis_b", () => { EmptyORTSDavis_B = stf.ReadFloatBlock(STFReader.UNITS.Resistance, -1); }), new STFReader.TokenProcessor("emptyortsdavis_c", () => { EmptyORTSDavis_C = stf.ReadFloatBlock(STFReader.UNITS.ResistanceDavisC, -1); }), new STFReader.TokenProcessor("emptyortswagonfrontalarea", () => { EmptyORTSWagonFrontalAreaM2 = stf.ReadFloatBlock(STFReader.UNITS.AreaDefaultFT2, -1); }), new STFReader.TokenProcessor("emptyortsdavisdragconstant", () => { EmptyORTSDavisDragConstant = stf.ReadFloatBlock(STFReader.UNITS.Any, -1); }), new STFReader.TokenProcessor("emptymaxbrakeforce", () => { EmptyMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("emptymaxhandbrakeforce", () => { EmptyMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("emptycentreofgravity_y", () => { EmptyCentreOfGravityM_Y = stf.ReadFloatBlock(STFReader.UNITS.Distance, -1); }), new STFReader.TokenProcessor("freightanimcontinuous", () => { Animations.Add(new FreightAnimationContinuous(stf, wagon)); FullPhysicsContinuousOne = Animations.Last() as FreightAnimationContinuous; if (wagon.WeightLoadController == null) { wagon.WeightLoadController = new MSTSNotchController(0, 1, 0.01f); } if ((Animations.Last() as FreightAnimationContinuous).FullAtStart) { if (empty) { empty = false; FreightType = wagon.IntakePointList.Last().Type; LoadedOne = Animations.Last() as FreightAnimationContinuous; FreightWeight += LoadedOne.FreightWeightWhenFull; LoadedOne.LoadPerCent = 100; } else { (Animations.Last() as FreightAnimationContinuous).FullAtStart = false; Trace.TraceWarning("The wagon can't be full with two different materials, only first is retained"); } } ContinuousFreightAnimationsPresent = true; }), new STFReader.TokenProcessor("freightanimstatic", () => { Animations.Add(new FreightAnimationStatic(stf)); StaticFreightWeight += (Animations.Last() as FreightAnimationStatic).FreightWeight; StaticFreightAnimationsPresent = true; FullPhysicsStaticOne = Animations.Last() as FreightAnimationStatic; }), /* new STFReader.TokenProcessor("freightanimdiscrete", ()=> * { * ORTSFreightAnims.Add(new FreightAnimDiscrete(stf)); * if ((ORTSFreightAnims.Last() as FreightAnimDiscrete).LoadedAtStart) * { * if (empty) * { * empty = false; * DiscreteLoadedOne = ORTSFreightAnims.Last() as FreightAnimDiscrete; * FreightWeight += DiscreteLoadedOne.LoadWeight; * } * else * { * (ORTSFreightAnims.Last() as FreightAnimContinuous).FullAtStart = false; * Trace.TraceWarning("The wagon can't be full with two different materials, only first is retained"); * } * } * }),*/ }); }
public static Interpolator2D CreateInterpolator2D(this STFReader stf, bool tab) { if (null == stf) { throw new ArgumentNullException(nameof(stf)); } 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(); if ("throttle".Equals(header, StringComparison.OrdinalIgnoreCase)) { 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(); if ("table".Equals(tableLabel, StringComparison.OrdinalIgnoreCase)) { stf.MustMatchBlockStart(); for (int i = 0; i < numOfRows; i++) { float x = stf.ReadFloat(STFReader.Units.Speed, 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); }
internal TrackSections(STFReader stf) { AddRouteStandardTrackSections(stf); }
public MovingTable(STFReader stf, Simulator simulator) { Simulator = simulator; }
internal TrackShapes(STFReader stf) { AddRouteTrackShapes(stf); }
public RouteStart(STFReader stf) { stf.MustMatchBlockStart(); location = new WorldLocation(stf.ReadInt(null), stf.ReadInt(null), stf.ReadFloat(null), 0f, stf.ReadFloat(null)); stf.SkipRestOfBlock(); }
public Tr_RouteFile(STFReader stf) { stf.MustMatch("("); 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", () => { if (RouteStart == null) { RouteStart = new RouteStart(stf); } }), new STFReader.TokenProcessor("environment", () => { Environment = new TRKEnvironment(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); }), // values for superelevation new STFReader.TokenProcessor("ortstracksuperelevation", () => { SuperElevationHgtpRadiusM = new Interpolator(stf); }), // 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 new STFReader.TokenProcessor("ortsdefaultturntablesms", () => { DefaultTurntableSMS = stf.ReadStringBlock(null); }), }); //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"); } }