public MSTSWagonViewer(Viewer viewer, MSTSWagon car) : base(viewer, car) { string steamTexture = viewer.Simulator.BasePath + @"\GLOBAL\TEXTURES\smokemain.ace"; string dieselTexture = viewer.Simulator.BasePath + @"\GLOBAL\TEXTURES\dieselsmoke.ace"; // Particle Drawers called in Wagon so that wagons can also have steam effects. ParticleDrawers = ( from effect in MSTSWagon.EffectData select new KeyValuePair <string, List <ParticleEmitterViewer> >(effect.Key, new List <ParticleEmitterViewer>( from data in effect.Value select new ParticleEmitterViewer(viewer, data, car.WorldPosition)))).ToDictionary(kvp => kvp.Key, kvp => kvp.Value); // Initaialise particle viewers for special steam effects foreach (var emitter in ParticleDrawers) { // Exhaust for steam heating boiler if (emitter.Key.ToLowerInvariant() == "heatingsteamboilerfx") { HeatingSteamBoiler.AddRange(emitter.Value); } foreach (var drawer in HeatingSteamBoiler) { drawer.Initialize(dieselTexture); } // Exhaust for HEP/Power Generator if (emitter.Key.ToLowerInvariant() == "wagongeneratorfx") { WagonGenerator.AddRange(emitter.Value); } foreach (var drawer in WagonGenerator) { drawer.Initialize(dieselTexture); } // Smoke for wood/coal fire if (emitter.Key.ToLowerInvariant() == "wagonsmokefx") { WagonSmoke.AddRange(emitter.Value); } foreach (var drawer in WagonSmoke) { drawer.Initialize(steamTexture); } // Steam leak in heating hose if (emitter.Key.ToLowerInvariant() == "heatinghosefx") { HeatingHose.AddRange(emitter.Value); } foreach (var drawer in HeatingHose) { drawer.Initialize(steamTexture); } } var wagonFolderSlash = Path.GetDirectoryName(car.WagFilePath) + @"\"; TrainCarShape = car.MainShapeFileName != string.Empty ? new PoseableShape(viewer, wagonFolderSlash + car.MainShapeFileName + '\0' + wagonFolderSlash, car.WorldPosition, ShapeFlags.ShadowCaster) : new PoseableShape(viewer, null, car.WorldPosition); // This insection initialises the MSTS style freight animation - can either be for a coal load, which will adjust with usage, or a static animation, such as additional shape. if (car.FreightShapeFileName != null) { car.HasFreightAnim = true; FreightShape = new AnimatedShape(viewer, wagonFolderSlash + car.FreightShapeFileName + '\0' + wagonFolderSlash, new WorldPosition(car.WorldPosition), ShapeFlags.ShadowCaster); // Reproducing MSTS "bug" of not allowing tender animation in case both minLevel and maxLevel are 0 or maxLevel < minLevel // Applies to both a standard tender locomotive or a tank locomotive (where coal load is on same "wagon" as the locomotive - for the coal load on a tender or tank locomotive - in operation it will raise or lower with caol usage if (MSTSWagon.WagonType == TrainCar.WagonTypes.Tender || MSTSWagon is MSTSSteamLocomotive) { var NonTenderSteamLocomotive = MSTSWagon as MSTSSteamLocomotive; if ((MSTSWagon.WagonType == TrainCar.WagonTypes.Tender || MSTSWagon is MSTSLocomotive && (MSTSWagon.EngineType == TrainCar.EngineTypes.Steam && NonTenderSteamLocomotive.IsTenderRequired == 0.0)) && MSTSWagon.FreightAnimMaxLevelM != 0 && MSTSWagon.FreightAnimFlag > 0 && MSTSWagon.FreightAnimMaxLevelM > MSTSWagon.FreightAnimMinLevelM) { // Force allowing animation: if (FreightShape.SharedShape.LodControls.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects[0].ShapePrimitives.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects[0].ShapePrimitives[0].Hierarchy.Length > 0) { FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects[0].ShapePrimitives[0].Hierarchy[0] = 1; } } } } if (car.InteriorShapeFileName != null) { InteriorShape = new AnimatedShape(viewer, wagonFolderSlash + car.InteriorShapeFileName + '\0' + wagonFolderSlash, car.WorldPosition, ShapeFlags.Interior, 30.0f); } RunningGear = new AnimatedPart(TrainCarShape); Pantograph1 = new AnimatedPart(TrainCarShape); Pantograph2 = new AnimatedPart(TrainCarShape); Pantograph3 = new AnimatedPart(TrainCarShape); Pantograph4 = new AnimatedPart(TrainCarShape); LeftDoor = new AnimatedPart(TrainCarShape); RightDoor = new AnimatedPart(TrainCarShape); Mirrors = new AnimatedPart(TrainCarShape); Wipers = new AnimatedPart(TrainCarShape); UnloadingParts = new AnimatedPart(TrainCarShape); Bell = new AnimatedPart(TrainCarShape); if (car.FreightAnimations != null) { FreightAnimations = new FreightAnimationsViewer(viewer, car, wagonFolderSlash); } LoadCarSounds(wagonFolderSlash); //if (!(MSTSWagon is MSTSLocomotive)) // LoadTrackSounds(); Viewer.SoundProcess.AddSoundSource(this, new TrackSoundSource(MSTSWagon, Viewer)); // Determine if it has first pantograph. So we can match unnamed panto parts correctly for (var i = 0; i < TrainCarShape.Hierarchy.Length; i++) { if (TrainCarShape.SharedShape.MatrixNames[i].Contains('1')) { if (TrainCarShape.SharedShape.MatrixNames[i].ToUpper().StartsWith("PANTO")) { HasFirstPanto = true; break; } } } // Check bogies and wheels to find out what we have. for (var i = 0; i < TrainCarShape.Hierarchy.Length; i++) { if (TrainCarShape.SharedShape.MatrixNames[i].Equals("BOGIE1")) { bogieMatrix1 = i; numBogie1 += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("BOGIE2")) { bogieMatrix2 = i; numBogie2 += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("BOGIE")) { bogieMatrix1 = i; } // For now, the total axle count consisting of axles that are part of the bogie are being counted. if (TrainCarShape.SharedShape.MatrixNames[i].Contains("WHEELS")) { if (TrainCarShape.SharedShape.MatrixNames[i].Length == 8) { var tpmatrix = TrainCarShape.SharedShape.GetParentMatrix(i); if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS11") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS12") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS13") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS21") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS22") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS23") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS11") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS12") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS13") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS21") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS21") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS23") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } } } } // Match up all the matrices with their parts. for (var i = 0; i < TrainCarShape.Hierarchy.Length; i++) { if (TrainCarShape.Hierarchy[i] == -1) { MatchMatrixToPart(car, i, 0); } } car.SetUpWheels(); // If we have two pantographs, 2 is the forwards pantograph, unlike when there's only one. if (!car.Flipped && !Pantograph1.Empty() && !Pantograph2.Empty()) { AnimatedPart.Swap(ref Pantograph1, ref Pantograph2); } Pantograph1.SetState(MSTSWagon.Pantographs[1].CommandUp); Pantograph2.SetState(MSTSWagon.Pantographs[2].CommandUp); if (MSTSWagon.Pantographs.List.Count > 2) { Pantograph3.SetState(MSTSWagon.Pantographs[3].CommandUp); } if (MSTSWagon.Pantographs.List.Count > 3) { Pantograph4.SetState(MSTSWagon.Pantographs[4].CommandUp); } LeftDoor.SetState(MSTSWagon.DoorLeftOpen); RightDoor.SetState(MSTSWagon.DoorRightOpen); Mirrors.SetState(MSTSWagon.MirrorOpen); UnloadingParts.SetState(MSTSWagon.UnloadingPartsOpen); InitializeUserInputCommands(); }
public MSTSWagonViewer(Viewer viewer, MSTSWagon car) : base(viewer, car) { var wagonFolderSlash = Path.GetDirectoryName(car.WagFilePath) + @"\"; TrainCarShape = car.MainShapeFileName != string.Empty ? new PoseableShape(viewer, wagonFolderSlash + car.MainShapeFileName + '\0' + wagonFolderSlash, car.WorldPosition, ShapeFlags.ShadowCaster) : new PoseableShape(viewer, null, car.WorldPosition); if (car.FreightShapeFileName != null) { car.HasFreightAnim = true; FreightShape = new AnimatedShape(viewer, wagonFolderSlash + car.FreightShapeFileName + '\0' + wagonFolderSlash, new WorldPosition(car.WorldPosition), ShapeFlags.ShadowCaster); // Reproducing MSTS "bug" of not allowing tender animation in case both minLevel and maxLevel are 0 or maxLevel < minLevel if (MSTSWagon.WagonType == TrainCar.WagonTypes.Tender && MSTSWagon.FreightAnimMaxLevelM != 0 && MSTSWagon.FreightAnimFlag > 0 && MSTSWagon.FreightAnimMaxLevelM > MSTSWagon.FreightAnimMinLevelM) { // Force allowing animation: if (FreightShape.SharedShape.LodControls.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects[0].ShapePrimitives.Length > 0 && FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects[0].ShapePrimitives[0].Hierarchy.Length > 0) { FreightShape.SharedShape.LodControls[0].DistanceLevels[0].SubObjects[0].ShapePrimitives[0].Hierarchy[0] = 1; } } } if (car.InteriorShapeFileName != null) { InteriorShape = new AnimatedShape(viewer, wagonFolderSlash + car.InteriorShapeFileName + '\0' + wagonFolderSlash, car.WorldPosition, ShapeFlags.Interior, 30.0f); } RunningGear = new AnimatedPart(TrainCarShape); Pantograph1 = new AnimatedPart(TrainCarShape); Pantograph2 = new AnimatedPart(TrainCarShape); LeftDoor = new AnimatedPart(TrainCarShape); RightDoor = new AnimatedPart(TrainCarShape); Mirrors = new AnimatedPart(TrainCarShape); Wipers = new AnimatedPart(TrainCarShape); UnloadingParts = new AnimatedPart(TrainCarShape); if (car.FreightAnimations != null) { FreightAnimations = new FreightAnimationsViewer(viewer, car, wagonFolderSlash); } LoadCarSounds(wagonFolderSlash); //if (!(MSTSWagon is MSTSLocomotive)) // LoadTrackSounds(); Viewer.SoundProcess.AddSoundSource(this, new TrackSoundSource(MSTSWagon, Viewer)); // Determine if it has first pantograph. So we can match unnamed panto parts correctly for (var i = 0; i < TrainCarShape.Hierarchy.Length; i++) { if (TrainCarShape.SharedShape.MatrixNames[i].Contains('1')) { if (TrainCarShape.SharedShape.MatrixNames[i].ToUpper().StartsWith("PANTO")) { HasFirstPanto = true; break; } } } // Check bogies and wheels to find out what we have. for (var i = 0; i < TrainCarShape.Hierarchy.Length; i++) { if (TrainCarShape.SharedShape.MatrixNames[i].Equals("BOGIE1")) { bogieMatrix1 = i; numBogie1 += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("BOGIE2")) { bogieMatrix2 = i; numBogie2 += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("BOGIE")) { bogieMatrix1 = i; numBogie += 1; } // For now, the total axle count consisting of axles that are part of the bogie are being counted. if (TrainCarShape.SharedShape.MatrixNames[i].Contains("WHEELS")) { if (TrainCarShape.SharedShape.MatrixNames[i].Length == 8) { var tpmatrix = TrainCarShape.SharedShape.GetParentMatrix(i); if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS11") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS12") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS13") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS21") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS22") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS23") && tpmatrix == bogieMatrix1) { bogie1Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS11") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS12") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS13") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS21") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS21") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } if (TrainCarShape.SharedShape.MatrixNames[i].Equals("WHEELS23") && tpmatrix == bogieMatrix2) { bogie2Axles += 1; } } } } // Match up all the matrices with their parts. for (var i = 0; i < TrainCarShape.Hierarchy.Length; i++) { if (TrainCarShape.Hierarchy[i] == -1) { MatchMatrixToPart(car, i, 0); } } car.SetUpWheels(); // If we have two pantographs, 2 is the forwards pantograph, unlike when there's only one. if (!car.Flipped && !Pantograph1.Empty() && !Pantograph2.Empty()) { AnimatedPart.Swap(ref Pantograph1, ref Pantograph2); } Pantograph1.SetState(MSTSWagon.Pantographs[1].CommandUp); Pantograph2.SetState(MSTSWagon.Pantographs[2].CommandUp); LeftDoor.SetState(MSTSWagon.DoorLeftOpen); RightDoor.SetState(MSTSWagon.DoorRightOpen); Mirrors.SetState(MSTSWagon.MirrorOpen); UnloadingParts.SetState(MSTSWagon.UnloadingPartsOpen); InitializeUserInputCommands(); }