public SignalShapeHead(Viewer viewer, SignalShape signalShape, int index, SignalHead signalHead, Orts.Formats.Msts.SignalItem mstsSignalItem, Orts.Formats.Msts.SignalShape.SignalSubObj mstsSignalSubObj) { Viewer = viewer; SignalShape = signalShape; #if DEBUG_SIGNAL_SHAPES Index = index; #endif SignalHead = signalHead; for (int mindex = 0; mindex <= signalShape.SharedShape.MatrixNames.Count - 1; mindex++) { string MatrixName = signalShape.SharedShape.MatrixNames[mindex]; if (String.Equals(MatrixName, mstsSignalSubObj.MatrixName)) MatrixIndices.Add(mindex); } if (!viewer.SIGCFG.SignalTypes.ContainsKey(mstsSignalSubObj.SignalSubSignalType)) return; var mstsSignalType = viewer.SIGCFG.SignalTypes[mstsSignalSubObj.SignalSubSignalType]; if (SignalTypes.ContainsKey(mstsSignalType.Name)) SignalTypeData = SignalTypes[mstsSignalType.Name]; else SignalTypeData = SignalTypes[mstsSignalType.Name] = new SignalTypeData(viewer, mstsSignalType); if (SignalTypeData.Semaphore) { // Check whether we have to correct the Semaphore position indexes following the strange rule of MSTS // Such strange rule is that, if there are only two animation steps in the related .s file, MSTS behaves as follows: // a SemaphorePos (2) in sigcfg.dat is executed as SemaphorePos (1) // a SemaphorePos (1) in sigcfg.dat is executed as SemaphorePos (0) // a SemaphorePos (0) in sigcfg.dat is executed as SemaphorePos (0) // First we check if there are only two animation steps if (signalShape.SharedShape.Animations != null && signalShape.SharedShape.Animations.Count != 0 && MatrixIndices.Count > 0 && signalShape.SharedShape.Animations[0].anim_nodes[MatrixIndices[0]].controllers.Count != 0 && signalShape.SharedShape.Animations[0].anim_nodes[MatrixIndices[0]].controllers[0].Count == 2) { // OK, now we check if maximum SemaphorePos is 2 (we won't correct if there are only SemaphorePos 1 and 0, // because they would both be executed as SemaphorePos (0) accordingly to above law, therefore leading to a static semaphore) float maxIndex = float.MinValue; foreach (SignalAspectData drAsp in SignalTypeData.DrawAspects.Values) { if (drAsp.SemaphorePos > maxIndex) maxIndex = drAsp.SemaphorePos; } if (maxIndex == 2) { // in this case we modify the SemaphorePositions for compatibility with MSTS. foreach (SignalAspectData drAsp in SignalTypeData.DrawAspects.Values) { switch ((int)drAsp.SemaphorePos) { case 2: drAsp.SemaphorePos = 1; break; case 1: drAsp.SemaphorePos = 0; break; default: break; } } if (!SignalTypeData.AreSemaphoresReindexed) { Trace.TraceInformation("Reindexing semaphore entries of signal type {0} for compatibility with MSTS", mstsSignalType.Name); SignalTypeData.AreSemaphoresReindexed = true; } } } foreach (int mindex in MatrixIndices) { if (mindex == 0 && (signalShape.SharedShape.Animations == null || signalShape.SharedShape.Animations.Count == 0 || signalShape.SharedShape.Animations[0].anim_nodes[mindex].controllers.Count == 0)) continue; AnimatedPart SemaphorePart = new AnimatedPart(signalShape); SemaphorePart.AddMatrix(mindex); SemaphoreParts.Add(SemaphorePart); } if (Viewer.Simulator.TRK.Tr_RouteFile.DefaultSignalSMS != null) { var soundPath = Viewer.Simulator.RoutePath + @"\\sound\\" + Viewer.Simulator.TRK.Tr_RouteFile.DefaultSignalSMS; try { Sound = new SoundSource(Viewer, SignalShape.Location.WorldLocation, Events.Source.MSTSSignal, soundPath); Viewer.SoundProcess.AddSoundSources(this, new List<SoundSourceBase>() { Sound }); } catch (Exception error) { Trace.WriteLine(new FileLoadException(soundPath, error)); } } } #if DEBUG_SIGNAL_SHAPES Console.Write(" HEAD type={0,-8} lights={1,-2} sem={2}", SignalTypeData.Type, SignalTypeData.Lights.Count, SignalTypeData.Semaphore); #endif }
public SignalShapeHead(Viewer viewer, SignalShape signalShape, int index, SignalHead signalHead, Orts.Formats.Msts.SignalItem mstsSignalItem, Orts.Formats.Msts.SignalShape.SignalSubObj mstsSignalSubObj) { Viewer = viewer; SignalShape = signalShape; #if DEBUG_SIGNAL_SHAPES Index = index; #endif SignalHead = signalHead; for (int mindex = 0; mindex <= signalShape.SharedShape.MatrixNames.Count - 1; mindex++) { string MatrixName = signalShape.SharedShape.MatrixNames[mindex]; if (String.Equals(MatrixName, mstsSignalSubObj.MatrixName)) { MatrixIndices.Add(mindex); } } if (!viewer.SIGCFG.SignalTypes.ContainsKey(mstsSignalSubObj.SignalSubSignalType)) { return; } var mstsSignalType = viewer.SIGCFG.SignalTypes[mstsSignalSubObj.SignalSubSignalType]; if (SignalTypes.ContainsKey(mstsSignalType.Name)) { SignalTypeData = SignalTypes[mstsSignalType.Name]; } else { SignalTypeData = SignalTypes[mstsSignalType.Name] = new SignalTypeData(viewer, mstsSignalType); } if (SignalTypeData.Semaphore) { foreach (int mindex in MatrixIndices) { AnimatedPart SemaphorePart = new AnimatedPart(signalShape); SemaphorePart.AddMatrix(mindex); SemaphoreParts.Add(SemaphorePart); } if (Viewer.Simulator.TRK.Tr_RouteFile.DefaultSignalSMS != null) { var soundPath = Viewer.Simulator.RoutePath + @"\\sound\\" + Viewer.Simulator.TRK.Tr_RouteFile.DefaultSignalSMS; try { Sound = new SoundSource(Viewer, SignalShape.Location.WorldLocation, Events.Source.MSTSSignal, soundPath); Viewer.SoundProcess.AddSoundSources(this, new List <SoundSourceBase>() { Sound }); } catch (Exception error) { Trace.WriteLine(new FileLoadException(soundPath, error)); } } } #if DEBUG_SIGNAL_SHAPES Console.Write(" HEAD type={0,-8} lights={1,-2} sem={2}", SignalTypeData.Type, SignalTypeData.Lights.Count, SignalTypeData.Semaphore); #endif }