コード例 #1
0
 public Activation(STFReader stf)
 {
     stf.MustMatch("(");
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("externalcam", () => { ExternalCam = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("cabcam", () => { CabCam = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("passengercam", () => { PassengerCam = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("distance", () => { Distance = stf.ReadFloatBlock(STFReader.UNITS.Distance, Distance); }),
         new STFReader.TokenProcessor("tracktype", () => { TrackType = stf.ReadIntBlock(null); }),
     });
 }
コード例 #2
0
 public ScalabiltyGroup(STFReader stf)
 {
     stf.MustMatch("(");
     DetailLevel = stf.ReadInt(null);
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("activation", () => { Activation = new Activation(stf); }),
         new STFReader.TokenProcessor("deactivation", () => { Deactivation = new Deactivation(stf); }),
         new STFReader.TokenProcessor("streams", () => { Streams = new SMSStreams(stf); }),
         new STFReader.TokenProcessor("volume", () => { Volume = stf.ReadFloatBlock(STFReader.UNITS.None, null); }),
         new STFReader.TokenProcessor("stereo", () => { Stereo = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("ignore3d", () => { Ignore3D = stf.ReadBoolBlock(true); }),
     });
 }
コード例 #3
0
ファイル: FreightAnimations.cs プロジェクト: yinwuu/openrails
        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.MustMatch("(");
                    XOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
                    YOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
                    ZOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
                    stf.MustMatch(")");
                }),
                new STFReader.TokenProcessor("flip", () => { Flipped = stf.ReadBoolBlock(true); }),
                // 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); })
            });
        }
コード例 #4
0
 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.MustMatch("(");
             XOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
             YOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
             ZOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
             stf.MustMatch(")");
         }),
         new STFReader.TokenProcessor("flip", () => { Flipped = stf.ReadBoolBlock(true); }),
     });
 }
コード例 #5
0
        public float FullCentreOfGravityM_Y     = -9999; // get centre of gravity after adjusted for freight animation

        public FreightAnimationContinuous(STFReader stf, MSTSWagon wagon)
        {
            stf.MustMatch("(");
            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("intakepoint", () =>
                {
                    wagon.IntakePointList.Add(new IntakePoint(stf));
                    wagon.IntakePointList.Last().LinkedFreightAnim = this;
                    LinkedIntakePoint = wagon.IntakePointList.Last();
                }),
                new STFReader.TokenProcessor("shape", () => { ShapeFileName = stf.ReadStringBlock(null); }),
                new STFReader.TokenProcessor("maxheight", () => { MaxHeight = stf.ReadFloatBlock(STFReader.UNITS.Distance, 0); }),
                new STFReader.TokenProcessor("minheight", () => { MinHeight = stf.ReadFloatBlock(STFReader.UNITS.Distance, 0); }),
                new STFReader.TokenProcessor("freightweightwhenfull", () => { FreightWeightWhenFull = stf.ReadFloatBlock(STFReader.UNITS.Mass, 0); }),
                new STFReader.TokenProcessor("fullatstart", () => { FullAtStart = stf.ReadBoolBlock(true); }),

                // additions to manage consequences of variable weight on friction and brake forces
                new STFReader.TokenProcessor("fullortsdavis_a", () => { FullORTSDavis_A = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }),
                new STFReader.TokenProcessor("fullortsdavis_b", () => { FullORTSDavis_B = stf.ReadFloatBlock(STFReader.UNITS.Resistance, -1); }),
                new STFReader.TokenProcessor("fullortsdavis_c", () => { FullORTSDavis_C = stf.ReadFloatBlock(STFReader.UNITS.ResistanceDavisC, -1); }),
                new STFReader.TokenProcessor("fullortswagonfrontalarea", () => { FullORTSWagonFrontalAreaM2 = stf.ReadFloatBlock(STFReader.UNITS.AreaDefaultFT2, -1); }),
                new STFReader.TokenProcessor("fullortsdavisdragconstant", () => { FullORTSDavisDragConstant = stf.ReadFloatBlock(STFReader.UNITS.Any, -1); }),
                new STFReader.TokenProcessor("fullmaxbrakeforce", () => { FullMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }),
                new STFReader.TokenProcessor("fullmaxhandbrakeforce", () => { FullMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }),
                new STFReader.TokenProcessor("fullcentreofgravity_y", () => { FullCentreOfGravityM_Y = stf.ReadFloatBlock(STFReader.UNITS.Distance, -1); })
            });
        }
コード例 #6
0
        public virtual void Parse(string lowercasetoken, STFReader stf)
        {
            switch (lowercasetoken)
            {
            case "engine(ortsmasterkey(mode":
                string text = stf.ReadStringBlock("").ToLower();
                if (text == "alwayson")
                {
                    Mode = ModeType.AlwaysOn;
                }
                else if (text == "manual")
                {
                    Mode = ModeType.Manual;
                }
                else
                {
                    STFException.TraceWarning(stf, "Skipped invalid master key mode");
                }
                break;

            case "engine(ortsmasterkey(delayoff":
                DelayS = stf.ReadFloatBlock(STFReader.UNITS.Time, 0f);
                break;

            case "engine(ortsmasterkey(headlightcontrol":
                HeadlightControl = stf.ReadBoolBlock(false);
                break;
            }
        }
コード例 #7
0
ファイル: Track.cs プロジェクト: Reve/ORTS-MG
        public TrackShape(STFReader stf)
        {
            stf.MustMatchBlockStart();
            ShapeIndex = stf.ReadUInt(null);
            int nextPath = 0;

            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("filename", () => { FileName = stf.ReadStringBlock(null); }),
                new STFReader.TokenProcessor("numpaths", () => { SectionIndices = new SectionIndex[PathsNumber = stf.ReadUIntBlock(null)]; }),
                new STFReader.TokenProcessor("mainroute", () => { MainRoute = stf.ReadUIntBlock(null); }),
                new STFReader.TokenProcessor("clearancedist", () => { ClearanceDistance = stf.ReadFloatBlock(STFReader.Units.Distance, null); }),
                new STFReader.TokenProcessor("sectionidx", () => { SectionIndices[nextPath++] = new SectionIndex(stf); }),
                new STFReader.TokenProcessor("tunnelshape", () => { TunnelShape = stf.ReadBoolBlock(true); }),
                new STFReader.TokenProcessor("roadshape", () => { RoadShape = stf.ReadBoolBlock(true); }),
            });
            // TODO - this was removed since TrackShape( 183 ) is blank
            //if( FileName == null )	throw( new STFError( stf, "Missing FileName" ) );
            //if( SectionIdxs == null )	throw( new STFError( stf, "Missing SectionIdxs" ) );
            //if( NumPaths == 0 ) throw( new STFError( stf, "No Paths in TrackShape" ) );
        }
コード例 #8
0
ファイル: RouteFile.cs プロジェクト: xiaomailong/OpenRails
 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); }),
     });
     //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");
     }
 }
コード例 #9
0
 public FreightAnimationContinuous(STFReader stf, MSTSWagon wagon)
 {
     stf.MustMatch("(");
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("intakepoint", () =>
         {
             wagon.IntakePointList.Add(new IntakePoint(stf));
             wagon.IntakePointList.Last().LinkedFreightAnim = this;
             LinkedIntakePoint = wagon.IntakePointList.Last();
         }),
         new STFReader.TokenProcessor("shape", () => { ShapeFileName = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("maxheight", () => { MaxHeight = stf.ReadFloatBlock(STFReader.UNITS.Distance, 0); }),
         new STFReader.TokenProcessor("minheight", () => { MinHeight = stf.ReadFloatBlock(STFReader.UNITS.Distance, 0); }),
         new STFReader.TokenProcessor("freightweightwhenfull", () => { FreightWeightWhenFull = stf.ReadFloatBlock(STFReader.UNITS.Mass, 0); }),
         new STFReader.TokenProcessor("fullatstart", () => { FullAtStart = stf.ReadBoolBlock(true); }),
     });
 }
コード例 #10
0
 public ShapeDescriptor(STFReader stf)
 {
     Name = stf.ReadString(); // Ignore the filename string. TODO: Check if it agrees with the SD file name? Is this important?
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("esd_detail_level", () => { EsdDetailLevel = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("esd_alternative_texture", () => { EsdAlternativeTexture = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("esd_no_visual_obstruction", () => { EsdNoVisualObstruction = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("esd_snapable", () => { EsdSnapable = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("esd_subobj", () => { EsdSubObject = true; stf.SkipBlock(); }),
         new STFReader.TokenProcessor("esd_bounding_box", () => {
             EsdBoundingBox = new EsdBoundingBox(stf);
             if (EsdBoundingBox.Min == null || EsdBoundingBox.Max == null)      // ie quietly handle ESD_Bounding_Box()
             {
                 EsdBoundingBox = null;
             }
         }),
         new STFReader.TokenProcessor("esd_ortssoundfilename", () => { EsdSoundFileName = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("esd_ortsbellanimationfps", () => { EsdBellAnimationFps = stf.ReadFloatBlock(STFReader.Units.Frequency, null); }),
     });
     // TODO - some objects have no bounding box - ie JP2BillboardTree1.sd
     //if (ESD_Bounding_Box == null) throw new STFException(stf, "Missing ESD_Bound_Box statement");
 }
コード例 #11
0
        public AttributeProcessor(object setWhom, FieldInfo fi, STFReader stf, object defaultValue)
        {
            _fi = fi;

            P = () =>
            {
                switch (_fi.FieldType.Name.ToLower())
                {
                case "int":
                case "int32":
                {
                    int?i = defaultValue as int?;
                    _fi.SetValue(setWhom,
                                 stf.ReadIntBlock(i));
                    break;
                }

                case "bool":
                case "boolean":
                {
                    bool?b = defaultValue as bool?;
                    _fi.SetValue(setWhom,
                                 stf.ReadBoolBlock(b.Value));
                    break;
                }

                case "string":
                {
                    string s = defaultValue as string;
                    _fi.SetValue(setWhom,
                                 stf.ReadStringBlock(s));
                    break;
                }

                case "float":
                case "single":
                {
                    float?f = defaultValue as float?;
                    _fi.SetValue(setWhom,
                                 stf.ReadFloatBlock(STFReader.Units.Any, f));
                    break;
                }

                case "double":
                {
                    double?d = defaultValue as double?;
                    _fi.SetValue(setWhom,
                                 stf.ReadDoubleBlock(d));
                    break;
                }

                case "vector3":
                {
                    Vector3 v3 = (defaultValue as string).ParseVector3();
                    {
                        _fi.SetValue(setWhom,
                                     stf.ReadVector3Block(STFReader.Units.Any, v3));
                    }
                    break;
                }

                case "vector4":
                {
                    Vector4 v4 = (defaultValue as string).ParseVector4();
                    {
                        stf.ReadVector4Block(STFReader.Units.Any, ref v4);
                        _fi.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;
                        }
                        _fi.SetValue(setWhom, c);
                    }
                    break;
                }
                }
            };
        }
コード例 #12
0
        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");
 *                      }
 *                  }
 *              }),*/
            });
        }
コード例 #13
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.MustMatch("(");
                    XOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
                    YOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
                    ZOffset = stf.ReadFloat(STFReader.UNITS.Distance, 0);
                    stf.MustMatch(")");
                }),
                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); })
            });
        }
コード例 #14
0
        }                                                // true for humans

        public CarSpawnerList(STFReader stf, string shapePath, string listName)
        {
            ListName = listName;
            var count = stf.ReadInt(null);

            stf.ParseBlock(new STFReader.TokenProcessor[] {
                new STFReader.TokenProcessor("ignorexrotation", () => { IgnoreXRotation = stf.ReadBoolBlock(true); }),
                new STFReader.TokenProcessor("carspawneritem", () => {
                    if (--count < 0)
                    {
                        STFException.TraceWarning(stf, "Skipped extra CarSpawnerItem");
                    }
                    else
                    {
                        CarSpawner dataItem = new CarSpawner(stf, shapePath);
                        if (File.Exists(dataItem.Name))
                        {
                            Add(dataItem);
                        }
                        else
                        {
                            STFException.TraceWarning(stf, $"Non-existent shape file {dataItem.Name} referenced");
                        }
                    }
                }),
            });
            if (count > 0)
            {
                STFException.TraceWarning(stf, count + " missing CarSpawnerItem(s)");
            }
        }
コード例 #15
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");
     }
 }
コード例 #16
0
        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;
                }
                }
            };
        }
コード例 #17
0
        private bool saveConnected  = true; // Transfertable is connected to a track

        internal TransferTable(STFReader stf)
        {
            string animation;
            Matrix location = Matrix.Identity;

            location.M44 = 100_000_000; //WorlPosition not yet defined, will be loaded when loading related tile;
            stf.MustMatch("(");
            stf.ParseBlock(new[] {
                new STFReader.TokenProcessor("wfile", () => {
                    WFile    = stf.ReadStringBlock(null);
                    position = new WorldPosition(int.Parse(WFile.Substring(1, 7), CultureInfo.InvariantCulture), int.Parse(WFile.Substring(8, 7), CultureInfo.InvariantCulture), location);
                }),
                new STFReader.TokenProcessor("uid", () => { UID = stf.ReadIntBlock(-1); }),
                new STFReader.TokenProcessor("animation", () => { animation = stf.ReadStringBlock(null);
                                                                  Animations.Add(animation); }),
                new STFReader.TokenProcessor("verticaltransfer", () => { verticalTransfer = stf.ReadBoolBlock(false); }),
                new STFReader.TokenProcessor("length", () => { Length = stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("xoffset", () => { offset.X = stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("zoffset", () => { offset.Z = -stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("yoffset", () => { offset.Y = stf.ReadFloatBlock(STFReader.Units.None, null); }),
                new STFReader.TokenProcessor("trackshapeindex", () =>
                {
                    TrackShapeIndex = stf.ReadIntBlock(-1);
                    InitializeOffsetsAndTrackNodes();
                }),
            });
        }
コード例 #18
0
            public bool ResetOnResetButton;                     // OverspeedMonitor only

            public MonitoringDevice(STFReader stf)
            {
                stf.MustMatch("(");
                stf.ParseBlock(new STFReader.TokenProcessor[] {
                    new STFReader.TokenProcessor("monitoringdevicemonitortimelimit", () => { MonitorTimeS = stf.ReadFloatBlock(STFReader.UNITS.Time, MonitorTimeS); }),
                    new STFReader.TokenProcessor("monitoringdevicealarmtimelimit", () => { AlarmTimeS = stf.ReadFloatBlock(STFReader.UNITS.Time, AlarmTimeS); }),
                    new STFReader.TokenProcessor("monitoringdevicepenaltytimelimit", () => { PenaltyTimeS = stf.ReadFloatBlock(STFReader.UNITS.Time, PenaltyTimeS); }),
                    new STFReader.TokenProcessor("monitoringdevicecriticallevel", () => { CriticalLevelMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, CriticalLevelMpS); }),
                    new STFReader.TokenProcessor("monitoringdeviceresetlevel", () => { ResetLevelMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, ResetLevelMpS); }),
                    new STFReader.TokenProcessor("monitoringdeviceappliesfullbrake", () => { AppliesFullBrake = stf.ReadBoolBlock(AppliesFullBrake); }),
                    new STFReader.TokenProcessor("monitoringdeviceappliesemergencybrake", () => { AppliesEmergencyBrake = stf.ReadBoolBlock(AppliesEmergencyBrake); }),
                    new STFReader.TokenProcessor("monitoringdeviceappliescutspower", () => { EmergencyCutsPower = stf.ReadBoolBlock(EmergencyCutsPower); }),
                    new STFReader.TokenProcessor("monitoringdeviceappliesshutsdownengine", () => { EmergencyShutsDownEngine = stf.ReadBoolBlock(EmergencyShutsDownEngine); }),
                    new STFReader.TokenProcessor("monitoringdevicealarmtimebeforeoverspeed", () => { AlarmTimeBeforeOverspeedS = stf.ReadFloatBlock(STFReader.UNITS.Time, AlarmTimeBeforeOverspeedS); }),
                    new STFReader.TokenProcessor("monitoringdevicetriggeronoverspeed", () => { TriggerOnOverspeedMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, TriggerOnOverspeedMpS); }),
                    new STFReader.TokenProcessor("monitoringdevicetriggerontrackoverspeed", () => { TriggerOnTrackOverspeed = stf.ReadBoolBlock(TriggerOnTrackOverspeed); }),
                    new STFReader.TokenProcessor("monitoringdevicetriggerontrackoverspeedmargin", () => { TriggerOnTrackOverspeedMarginMpS = stf.ReadFloatBlock(STFReader.UNITS.Speed, TriggerOnTrackOverspeedMarginMpS); }),
                    new STFReader.TokenProcessor("monitoringdeviceresetondirectionneutral", () => { ResetOnDirectionNeutral = stf.ReadBoolBlock(ResetOnDirectionNeutral); }),
                    new STFReader.TokenProcessor("monitoringdeviceresetonresetbutton", () => { ResetOnResetButton = stf.ReadBoolBlock(ResetOnResetButton); }),
                    new STFReader.TokenProcessor("monitoringdeviceresetonzerospeed", () => { ResetOnZeroSpeed = stf.ReadBoolBlock(ResetOnZeroSpeed); }),
                });
            }
コード例 #19
0
 public FreightAnimationDiscrete(STFReader stf)
 {
     stf.MustMatch("(");
     stf.ParseBlock(new STFReader.TokenProcessor[]
     {
         new STFReader.TokenProcessor("subtype", () =>
         {
             var typeString = stf.ReadStringBlock(null);
             switch (typeString)
             {
             default:
                 SubType = FreightAnimationDiscrete.Type.DEFAULT;
                 break;
             }
         }),
         new STFReader.TokenProcessor("shape", () => { ShapeFileName = stf.ReadStringBlock(null); }),
         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("loadweight", () => { LoadWeight = stf.ReadFloatBlock(STFReader.Units.Mass, 0); }),
         new STFReader.TokenProcessor("loadedatstart", () => { LoadedAtStart = stf.ReadBoolBlock(true); }),
     });
 }
コード例 #20
0
 public SDShape(STFReader stf)
 {
     stf.ReadString(); // Ignore the filename string. TODO: Check if it agrees with the SD file name? Is this important?
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("esd_detail_level", () => { ESD_Detail_Level = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("esd_alternative_texture", () => { ESD_Alternative_Texture = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("esd_no_visual_obstruction", () => { ESD_No_Visual_Obstruction = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("esd_snapable", () => { ESD_Snapable = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("esd_subobj", () => { ESD_SubObj = true; stf.SkipBlock(); }),
         new STFReader.TokenProcessor("esd_bounding_box", () => {
             ESD_Bounding_Box = new ESD_Bounding_Box(stf);
             if (ESD_Bounding_Box.Min == null || ESD_Bounding_Box.Max == null)  // ie quietly handle ESD_Bounding_Box()
             {
                 ESD_Bounding_Box = null;
             }
         }),
         new STFReader.TokenProcessor("esd_ortssoundfilename", () => { ESD_SoundFileName = stf.ReadStringBlock(null); }),
     });
     // TODO - some objects have no bounding box - ie JP2BillboardTree1.sd
     //if (ESD_Bounding_Box == null) throw new STFException(stf, "Missing ESD_Bound_Box statement");
 }
コード例 #21
0
        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); }),
                new STFReader.TokenProcessor("freightanimcontinuous", () =>
                {
                    Animations.Add(new FreightAnimationContinuous(stf, wagon));
                    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");
                        }
                    }
                }),
                new STFReader.TokenProcessor("freightanimstatic", () =>
                {
                    Animations.Add(new FreightAnimationStatic(stf));
                    StaticFreightWeight += (Animations.Last() as FreightAnimationStatic).FreightWeight;
                }),

/*                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");
 *                      }
 *                  }
 *              }),*/
            });
        }
コード例 #22
0
        public CVCDiscrete(STFReader stf, string basepath)
        {
//            try
            {
                stf.MustMatch("(");
                stf.ParseBlock(new STFReader.TokenProcessor[] {
                    new STFReader.TokenProcessor("type", () => { ParseType(stf); }),
                    new STFReader.TokenProcessor("position", () => { ParsePosition(stf); }),
                    new STFReader.TokenProcessor("scalerange", () => { ParseScaleRange(stf); }),
                    new STFReader.TokenProcessor("graphic", () => { ParseGraphic(stf, basepath); }),
                    new STFReader.TokenProcessor("style", () => { ParseStyle(stf); }),
                    new STFReader.TokenProcessor("units", () => { ParseUnits(stf); }),
                    new STFReader.TokenProcessor("mousecontrol", () => { MouseControl = stf.ReadBoolBlock(false); }),
                    new STFReader.TokenProcessor("orientation", () => { Orientation = stf.ReadIntBlock(null); }),
                    new STFReader.TokenProcessor("dirincrease", () => { Direction = stf.ReadIntBlock(null); }),

                    new STFReader.TokenProcessor("numframes", () => {
                        stf.MustMatch("(");
                        FramesCount = stf.ReadInt(null);
                        FramesX     = stf.ReadInt(null);
                        FramesY     = stf.ReadInt(null);
                        stf.SkipRestOfBlock();
                    }),
                    // <CJComment> Would like to revise this, as it is difficult to follow and debug.
                    // Can't do that until interaction of ScaleRange, NumFrames, NumPositions and NumValues is more fully specified.
                    // What is needed is samples of data that must be accommodated.
                    // Some decisions appear unwise but they might be a pragmatic solution to a real problem. </CJComment>
                    //
                    // Code accommodates:
                    // - NumValues before NumPositions or the other way round.
                    // - More NumValues than NumPositions and the other way round - perhaps unwise.
                    // - The count of NumFrames, NumValues and NumPositions is ignored - perhaps unwise.
                    // - Abbreviated definitions so that values at intermediate unspecified positions can be omitted.
                    //   Strangely, these values are set to 0 and worked out later when drawing.
                    // Max and min NumValues which don't match the ScaleRange are ignored - perhaps unwise.
                    new STFReader.TokenProcessor("numpositions", () => {
                        stf.MustMatch("(");
                        // If Positions are not filled before by Values
                        bool shouldFill = (Positions.Count == 0);
                        numPositions    = stf.ReadInt(null); // Number of Positions

                        var minPosition   = 0;
                        var positionsRead = 0;
                        while (!stf.EndOfBlock())
                        {
                            int p = stf.ReadInt(null);

                            minPosition = positionsRead == 0 ? p : Math.Min(minPosition, p);  // used to get correct offset
                            positionsRead++;

                            // If Positions are not filled before by Values
                            if (shouldFill)
                            {
                                Positions.Add(p);
                            }
                        }

                        // If positions do not start at 0, add offset to shift them all so they do.
                        // An example of this is RENFE 400 (from http://www.trensim.com/lib/msts/index.php?act=view&id=186)
                        // which has a COMBINED_CONTROL with:
                        //   NumPositions ( 21 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 )
                        // Also handles definitions with position in reverse order, e.g.
                        //   NumPositions ( 5 8 7 2 1 0 )
                        positionsRead++;

                        if (minPosition < 0)
                        {
                            for (int iPos = 0; iPos <= Positions.Count - 1; iPos++)
                            {
                                Positions[iPos] -= minPosition;
                            }
                        }

                        // This is a hack for SLI locomotives which have the positions listed as "1056964608 0 0 0 ...".
                        if (Positions.Any(p => p > 0xFFFF))
                        {
                            STFException.TraceInformation(stf, "Renumbering cab control positions from zero due to value > 0xFFFF");
                            for (var i = 0; i < Positions.Count; i++)
                            {
                                Positions[i] = i;
                            }
                        }

                        // Check if eligible for filling

                        if (Positions.Count > 1 && Positions[0] != 0)
                        {
                            canFill = false;
                        }
                        else
                        {
                            for (var iPos = 1; iPos <= Positions.Count - 1; iPos++)
                            {
                                if (Positions[iPos] > Positions[iPos - 1])
                                {
                                    continue;
                                }
                                canFill = false;
                                break;
                            }
                        }

                        // This is a protection against GP40 locomotives that erroneously have positions pointing beyond frame count limit.

                        if (Positions.Count > 1 && canFill && Positions.Count < FramesCount && Positions[Positions.Count - 1] >= FramesCount && Positions[0] == 0)
                        {
                            STFException.TraceInformation(stf, "Some NumPositions entries refer to non-exisiting frames, trying to renumber");
                            Positions[Positions.Count - 1] = FramesCount - 1;
                            for (var iPos = Positions.Count - 2; iPos >= 1; iPos--)
                            {
                                if ((Positions[iPos] >= FramesCount || Positions[iPos] >= Positions[iPos + 1]))
                                {
                                    Positions[iPos] = Positions[iPos + 1] - 1;
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }),
                    new STFReader.TokenProcessor("numvalues", () => {
                        stf.MustMatch("(");
                        var numValues = stf.ReadDouble(null); // Number of Values
                        while (!stf.EndOfBlock())
                        {
                            double v = stf.ReadDouble(null);
                            // If the Positions are less than expected add new Position(s)
                            while (Positions.Count <= _ValuesRead)
                            {
                                Positions.Add(_ValuesRead);
                            }
                            // Avoid later repositioning, put every value to its Position
                            // But before resize Values if needed
                            if (numValues != numPositions)
                            {
                                while (Values.Count <= Positions[_ValuesRead])
                                {
                                    Values.Add(0);
                                }
                                // Avoid later repositioning, put every value to its Position
                                Values[Positions[_ValuesRead]] = v;
                            }
                            Values.Add(v);
                            _ValuesRead++;
                        }
                    }),
                });

                // If no ACE, just don't need any fixup
                // Because Values are tied to the image Frame to be shown
                if (string.IsNullOrEmpty(ACEFile))
                {
                    return;
                }

                // Now, we have an ACE.

                // If read any Values, or the control requires Values to control
                //     The twostate, tristate, signal displays are not in these
                // Need check the Values collection for validity
                if (_ValuesRead > 0 || ControlStyle == CABViewControlStyles.SPRUNG || ControlStyle == CABViewControlStyles.NOT_SPRUNG ||
                    FramesCount > 0 || (FramesX > 0 && FramesY > 0))
                {
                    // Check max number of Frames
                    if (FramesCount == 0)
                    {
                        // Check valid Frame information
                        if (FramesX == 0 || FramesY == 0)
                        {
                            // Give up, it won't work
                            // Because later we won't know how to display frames from that
                            Trace.TraceWarning("Invalid Frames information given for ACE {0} in {1}", ACEFile, stf.FileName);
                            ACEFile = "";
                            return;
                        }

                        // Valid frames info, set FramesCount
                        FramesCount = FramesX * FramesY;
                    }

                    // Now we have an ACE and Frames for it.

                    // Only shuffle data in following cases

                    if (Values.Count != Positions.Count || (Values.Count < FramesCount & canFill) || (Values.Count > 0 && Values[0] == Values[Values.Count - 1] && Values[0] == 0))
                    {
                        // Fixup Positions and Values collections first

                        // If the read Positions and Values are not match
                        // Or we didn't read Values but have Frames to draw
                        // Do not test if FramesCount equals Values count, we trust in the creator -
                        //     maybe did not want to display all Frames
                        // (If there are more Values than Frames it will checked at draw time)
                        // Need to fix the whole Values
                        if (Positions.Count != _ValuesRead || (FramesCount > 0 && (Values.Count == 0 || Values.Count == 1)))
                        {
                            //This if clause covers among others following cases:
                            // Case 1 (e.g. engine brake lever of Dash 9):
                            //NumFrames ( 22 11 2 )
                            //NumPositions ( 1 0 )
                            //NumValues ( 1 0 )
                            //Orientation ( 1 )
                            //DirIncrease ( 1 )
                            //ScaleRange ( 0 1 )
                            //
                            // Case 2 (e.g. throttle lever of Acela):
                            //NumFrames ( 25 5 5 )
                            //NumPositions ( 0 )
                            //NumValues ( 0 )
                            //Orientation ( 1 )
                            //DirIncrease ( 1 )
                            //ScaleRange ( 0 1 )
                            //
                            // Clear existing
                            Positions.Clear();
                            Values.Clear();

                            // Add the two sure positions, the two ends
                            Positions.Add(0);
                            // We will need the FramesCount later!
                            // We use Positions only here
                            Positions.Add(FramesCount);

                            // Fill empty Values
                            for (int i = 0; i < FramesCount; i++)
                            {
                                Values.Add(0);
                            }
                            Values[0] = MinValue;

                            Values.Add(MaxValue);
                        }
                        else if (Values.Count == 2 && Values[0] == 0 && Values[1] < MaxValue && Positions[0] == 0 && Positions[1] == 1 && Values.Count < FramesCount)
                        {
                            //This if clause covers among others following cases:
                            // Case 1 (e.g. engine brake lever of gp38):
                            //NumFrames ( 18 2 9 )
                            //NumPositions ( 2 0 1 )
                            //NumValues ( 2 0 0.3 )
                            //Orientation ( 0 )
                            //DirIncrease ( 0 )
                            //ScaleRange ( 0 1 )
                            Positions.Add(FramesCount);
                            // Fill empty Values
                            for (int i = Values.Count; i < FramesCount; i++)
                            {
                                Values.Add(Values[1]);
                            }
                            Values.Add(MaxValue);
                        }

                        else
                        {
                            //This if clause covers among others following cases:
                            // Case 1 (e.g. train brake lever of Acela):
                            //NumFrames ( 12 4 3 )
                            //NumPositions ( 5 0 1 9 10 11 )
                            //NumValues ( 5 0 0.2 0.85 0.9 0.95 )
                            //Orientation ( 1 )
                            //DirIncrease ( 1 )
                            //ScaleRange ( 0 1 )
                            //
                            // Fill empty Values
                            int iValues = 1;
                            for (int i = 1; i < FramesCount && i <= Positions.Count - 1 && Values.Count < FramesCount; i++)
                            {
                                var deltaPos = Positions[i] - Positions[i - 1];
                                while (deltaPos > 1 && Values.Count < FramesCount)
                                {
                                    Values.Insert(iValues, 0);
                                    iValues++;
                                    deltaPos--;
                                }
                                iValues++;
                            }

                            // Add the maximums to the end, the Value will be removed
                            // We use Positions only here
                            if (Values.Count > 0 && Values[0] <= Values[Values.Count - 1])
                            {
                                Values.Add(MaxValue);
                            }
                            else if (Values.Count > 0 && Values[0] > Values[Values.Count - 1])
                            {
                                Values.Add(MinValue);
                            }
                        }

                        // OK, we have a valid size of Positions and Values

                        // Now it is the time for checking holes in the given data
                        if ((Positions.Count < FramesCount - 1 && Values[0] <= Values[Values.Count - 1]) || (Values.Count > 1 && Values[0] == Values[Values.Count - 2] && Values[0] == 0))
                        {
                            int j = 1;
                            int p = 0;
                            // Skip the 0 element, that is the default MinValue
                            for (int i = 1; i < Positions.Count; i++)
                            {
                                // Found a hole
                                if (Positions[i] != p + 1)
                                {
                                    // Iterate to the next valid data and fill the hole
                                    for (j = p + 1; j < Positions[i]; j++)
                                    {
                                        // Extrapolate into the hole
                                        Values[j] = MathHelper.Lerp((float)Values[p], (float)Values[Positions[i]], (float)j / (float)Positions[i]);
                                    }
                                }
                                p = Positions[i];
                            }
                        }

                        // Don't need the MaxValue added before, remove it
                        Values.RemoveAt(Values.Count - 1);
                    }
                }

                // MSTS ignores/overrides various settings by the following exceptional cases:
                if (ControlType == CABViewControlTypes.CP_HANDLE)
                {
                    ControlStyle = CABViewControlStyles.NOT_SPRUNG;
                }
                if (ControlType == CABViewControlTypes.PANTOGRAPH || ControlType == CABViewControlTypes.PANTOGRAPH2)
                {
                    ControlStyle = CABViewControlStyles.ONOFF;
                }
                if (ControlType == CABViewControlTypes.HORN || ControlType == CABViewControlTypes.SANDERS || ControlType == CABViewControlTypes.BELL ||
                    ControlType == CABViewControlTypes.RESET)
                {
                    ControlStyle = CABViewControlStyles.WHILE_PRESSED;
                }
                if (ControlType == CABViewControlTypes.DIRECTION && Orientation == 0)
                {
                    Direction = 1 - Direction;
                }
            }
//            catch (Exception error)
//            {
//                if (error is STFException) // Parsing error, so pass it on
//                    throw;
//                else                       // Unexpected error, so provide a hint
//                    throw new STFException(stf, "Problem with NumPositions/NumValues/NumFrames/ScaleRange");
//            } // End of Need check the Values collection for validity
        } // End of Constructor
コード例 #23
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;
            }
        }
コード例 #24
0
 private protected void ParseDisabledIfCabPowerSupplyOff(STFReader stf)
 {
     DisabledIfCabPowerSupplyOff = stf.ReadBoolBlock(false);
 }
コード例 #25
0
 internal override void Update(STFReader stf)
 {
     stf.ParseBlock(new STFReader.TokenProcessor[] {
         new STFReader.TokenProcessor("eventtypelocation", () => { stf.MustMatchBlockStart(); stf.MustMatchBlockEnd(); }),
         new STFReader.TokenProcessor("id", () => { ID = stf.ReadIntBlock(null); }),
         new STFReader.TokenProcessor("ortstriggeringtrain", () => { ParseTrain(stf); }),
         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("name", () => { Name = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("texttodisplayoncompletioniftriggered", () => { TextToDisplayOnCompletionIfTriggered = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("texttodisplayoncompletionifnottriggered", () => { TextToDisplayOnCompletionIfNotTriggered = stf.ReadStringBlock(null); }),
         new STFReader.TokenProcessor("triggeronstop", () => { TriggerOnStop = stf.ReadBoolBlock(true); }),
         new STFReader.TokenProcessor("location", () => {
             stf.MustMatchBlockStart();
             location = new WorldLocation(stf.ReadInt(null), stf.ReadInt(null),
                                          stf.ReadFloat(STFReader.Units.None, null), 0f, stf.ReadFloat(STFReader.Units.None, null));
             RadiusM = stf.ReadFloat(STFReader.Units.Distance, null);
             stf.MustMatchBlockEnd();
         }),
         new STFReader.TokenProcessor("ortscontinue", () => { OrtsContinue = stf.ReadIntBlock(0); }),
         new STFReader.TokenProcessor("ortsactsoundfile", () => OrtsActivitySoundProcessor(stf)),
         new STFReader.TokenProcessor("ortsweatherchange", () => { WeatherChange = new OrtsWeatherChange(stf); }),
     });
 }
コード例 #26
0
        public CarSpawnerBlock(STFReader stf, string shapePath, List <CarSpawnerList> carSpawnerLists, string listName)
        {
            var spawnerDataItems = new List <CarSpawnerItemData>();
            {
                var count = stf.ReadInt(null);
                stf.ParseBlock(new STFReader.TokenProcessor[] {
                    new STFReader.TokenProcessor("ignorexrotation", () => { IgnoreXRotation = stf.ReadBoolBlock(true); }),
                    new STFReader.TokenProcessor("carspawneritem", () => {
                        if (--count < 0)
                        {
                            STFException.TraceWarning(stf, "Skipped extra CarSpawnerItem");
                        }
                        else
                        {
                            var dataItem = new CarSpawnerItemData(stf, shapePath);
                            if (File.Exists(dataItem.name))
                            {
                                spawnerDataItems.Add(dataItem);
                            }
                            else
                            {
                                STFException.TraceWarning(stf, String.Format("Non-existent shape file {0} referenced", dataItem.name));
                            }
                        }
                    }),
                });
                if (count > 0)
                {
                    STFException.TraceWarning(stf, count + " missing CarSpawnerItem(s)");
                }
            }

            CarSpawnerList carSpawnerList = new CarSpawnerList(spawnerDataItems, listName, IgnoreXRotation);

            carSpawnerLists.Add(carSpawnerList);
        }