Advertisement
agmike

Updating xte10m_locomotive.gs

Oct 3rd, 2011
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 77.71 KB | None | 0 0
  1. // xte10m_locomotive.gs
  2.  
  3.  
  4. //    2(3)TE10M script
  5. //
  6. // author: agentmike, agentmike@rambler.ru
  7. //
  8.  
  9. include "x_airdistributor.gs"
  10. include "defaultlocomotivecabin.gs"
  11.  
  12. include "xt10m_systemdata.gs"
  13. include "xt10m_cabin.gs"
  14. include "xt10m_coordinate.gs"
  15.  
  16.  
  17.  
  18. class LocomotiveSystemData
  19. {
  20.     public float[] RPM = new float[15];
  21.     public float[] G = new float[15];
  22.    
  23.     public float rpm = 0.0;
  24.     public float g = 0.0;
  25.     public float Td = 0.0,Tw1 = 0.0,Tw2 = 0.0,To = 0.0,Tto = 0.0;
  26.    
  27.     public float gBase;
  28.     public float gPower;
  29.    
  30.     public ProductQueue fuelQueue,sandQueue;
  31.    
  32.     public float fuelConsumed;
  33.     public float sandConsumed;
  34.    
  35.     public int posSet;
  36.     public int enginePosSet;
  37.     public int tractivePosSet;
  38.    
  39.     public int tractivePos;
  40.     public int enginePos;
  41.    
  42.     public float engineStress;
  43.    
  44.     public bool engineRunning;
  45.     public bool engineServ;
  46.    
  47.     public bool posChange;
  48.    
  49.     public int fuelPumpCircuit;//0 - off, 1 - on
  50.     public int oilPumpCircuit;//3 - ready to init 2 - init
  51.    
  52.     public bool pcSet;
  53.    
  54.     public int fieldDivertState;
  55.    
  56.     public bool sideWaterShuttersOpened,sideOilShuttersOpened,topShuttersOpened,fanRunning;
  57.     public bool compressorRunning;
  58.    
  59.     public float fanRpm;
  60.     public bool braking;
  61.     public bool bpPressureRelay;
  62.     public bool overheat;
  63.     public bool emergencyBraking;
  64.    
  65.     public bool sanding;
  66.     public bool shuntMode;
  67.     public bool typhoon;
  68.     public bool whistle;
  69.    
  70.     public float maxTE = 0.0;
  71.     public float sandingTM = 1.0;
  72.     public float wheelslipTM = 1.0;
  73.     public float sandingEfficiency = 1.0;
  74. };//class LocomotiveSystemData
  75.  
  76.  
  77. class XT10MLocomotive isclass TVRController_Locomotive
  78. {
  79.     void L(string s){ /*Interface.Log(s);*/ }
  80.     void P(string s){ /*Interface.Print(s);*/ }
  81.    
  82.     Asset A,SA,SA3_coupled,SA3_decoupled;
  83.     StringTable ST;
  84.    
  85.     Soup MD;
  86.     Soup wavdb;
  87.    
  88.     public XT10MSystemData sd;
  89.     LocomotiveSystemData lsd;
  90.     public SectionCoordInfo sci;
  91.    
  92.     Bogey[] bogeys;
  93.    
  94.     bool fail;
  95.    
  96.     //User sound volume coefficients
  97.     float uvk_compressor,uvk_fan,uvk_engine,uvk_brakes,uvk_horn;
  98.    
  99.     define int SANDPFX_INDEX = 0;
  100.    
  101.     thread void Main(void);
  102.     thread void Brakes(void);
  103.     thread void Compressor(void);
  104.     thread void PhysicsScheme(void);
  105.     thread void Subsystems(void);
  106.     thread void Fan(void);
  107.     thread void SandExhaust(void);
  108.     thread void Typhoon(void);
  109.     thread void Whistle(void);
  110.    
  111.     public void Init(Asset p_asset);
  112.     public void Update(void);
  113.     public void SetMyData(void);
  114.     public bool LocoControl(void);
  115.     public bool IsControl(void);
  116.     public bool IsIdle(void);
  117.     void SetShuttersState(string shutters,bool state);
  118.     public void Sanding(void);
  119.     public void Horn(void);
  120.    
  121.     public XT10MCabinData CD(void);
  122.     public XT10MCabinData CD2(void);
  123.     void InitSystemData(void);
  124.     public float GetPressureParam(string param);
  125.     public float GetPressureParam(float val);
  126.     public float GetPressureParam(Vehicle vh,string param);
  127.     public int GetMyPosition(void);
  128.     void SetCouplerAttach(int pos, bool type);
  129.     void SetCoupler(int pos, bool direction);
  130.     thread void SendMessage(GameObject dst,string major,string minor,float delay);
  131.    
  132.     final float PlaySoundAndSleep(Asset srcAsset,
  133.                                  string soundFile,
  134.                                  float volume,
  135.                                  float minDistance,
  136.                                  float maxDistance,
  137.                                  GameObject srcObject,
  138.                                  string att)
  139.     {
  140.         World.PlaySound(srcAsset, soundFile, volume, minDistance, maxDistance, srcObject, att);
  141.         float duration = wavdb.GetNamedTagAsFloat(soundFile, 10.0) - 0.05;
  142.         Sleep(duration);
  143.         return duration;
  144.     }
  145.    
  146.     final float GetSoundDuration(string soundFile)
  147.     {
  148.         return wavdb.GetNamedTagAsFloat(soundFile, 10.0);
  149.     }
  150.    
  151.     thread void Subsystems(void)
  152.     {
  153.         Message msg;
  154.         int i;
  155.         Soup sp = A.GetConfigSoup().GetNamedSoup("extensions").GetNamedSoup("engine-setup-298469");
  156.         string[] srpm = Str.Tokens(sp.GetNamedTag("rpm"),",");
  157.         string[] sg = Str.Tokens(sp.GetNamedTag("g"),",");
  158.         for(i=0;i<srpm.size();i++)
  159.         {
  160.             lsd.RPM[i] = Str.ToFloat(srpm[i]);
  161.             L("RPM["+i+"] = "+lsd.RPM[i]);
  162.             lsd.G[i] = Str.ToFloat(sg[i]) / 60.0;
  163.             L("G["+i+"] = "+lsd.G[i]);
  164.         }//for
  165.  
  166.         float fan_t0,fan_dt,fan_delay = 0.2,fan_v,fan_vmax = 0.2,fan_rpm0;
  167.        
  168.         float rpmEndTime;
  169.         float rpmPosSet = 0.0,gPosSet = 0.0;
  170.         int enginePosSet = 0;
  171.        
  172.         bool stressInit = true;
  173.         float stressNormalise = 0.1;
  174.         float stressClc_t0;
  175.        
  176.         float pcUp = 2.0,pcDown = 0.3;
  177.        
  178.         PostMessage(me,"T10MSubsystems-298469","FanMain",0.5);
  179.        
  180.         wait()
  181.         {
  182.             on "T10MSubsystems-298469","TractivePosChange":
  183.             {
  184.                 ClearMessages("T10MSubsystems-298469","TractivePosChange");
  185.                 if(lsd.tractivePos != lsd.tractivePosSet)
  186.                 {
  187.                     lsd.posChange = true;
  188.                 }//if
  189.                 else
  190.                 {
  191.                     lsd.posChange = false;
  192.                     continue;
  193.                 }//else
  194.                 if( (lsd.tractivePosSet > lsd.tractivePos))
  195.                 {
  196.                     lsd.tractivePos++;
  197.                     PostMessage(me,"T10MSubsystems-298469","TractivePosChange",pcUp);
  198.                     continue;
  199.                 }//if
  200.                 else
  201.                 {
  202.                     lsd.tractivePos = lsd.tractivePosSet;
  203.                     PostMessage(me,"T10MSubsystems-298469","TractivePosChange",0.0);
  204.                     continue;
  205.                 }//else
  206.                 continue;
  207.             }//on
  208.             on "T10MSubsystems-298469","ChangeRpm":
  209.             {
  210.                 ClearMessages("T10MSubsystems-298469","ChangeRpm");
  211.                 float t0 = World.GetSeconds();
  212.                 if(rpmEndTime-t0 <= 0.0)
  213.                 {
  214.                     lsd.rpm = rpmPosSet;
  215.                     lsd.enginePos = enginePosSet;
  216.                     continue;
  217.                 }//if
  218.                 float rdt = Math.Fmin(rpmEndTime-t0,0.2);
  219.                 lsd.rpm = (rpmPosSet - lsd.rpm)/(rpmEndTime - t0)*rdt + lsd.rpm;
  220.                 lsd.gBase = (gPosSet - lsd.gBase)/(rpmEndTime - t0)*rdt + lsd.gBase;
  221.                 sd.l.mainShaft = lsd.rpm/850.0;
  222.                 PostMessage(me,"T10MSubsystems-298469","ChangeRpm",rdt);
  223.                 continue;
  224.             }//on
  225.             on "T10MSubsystemsPosition-298469","",msg:
  226.             {
  227.                 ClearMessages("T10MSubsystems-298469","ChangeRpm");
  228.                 string minor = msg.minor,mode;
  229.                 int n_pos;
  230.                 float currSeconds = World.GetSeconds();
  231.                 mode = Str.UnpackString(minor);
  232.                 float timePre = 0.2;
  233.                 if(mode == "S")
  234.                 {
  235.                     string submode = Str.UnpackString(minor);
  236.                     if(submode == "start")
  237.                     {
  238.                         rpmEndTime = currSeconds + 7.0;
  239.                         enginePosSet = 0;
  240.                         rpmPosSet = lsd.RPM[0];
  241.                         gPosSet = lsd.G[0];
  242.                         PostMessage(me,"T10MSubsystems-298469","ChangeRpm",2.0);
  243.                     }//if
  244.                     else if(submode == "stop")
  245.                     {
  246.                         rpmEndTime = currSeconds + 5.0;
  247.                         enginePosSet = 0;
  248.                         rpmPosSet = 0.0;
  249.                         gPosSet = 0.0;
  250.                         PostMessage(me,"T10MSubsystems-298469","ChangeRpm",1.0);
  251.                     }//else if
  252.                 }//if
  253.                 else if(mode == "R")
  254.                 {
  255.                     Str.UnpackInt(minor);//prev pos is unneeded
  256.                     enginePosSet = Str.UnpackInt(minor);
  257.                     rpmPosSet = lsd.RPM[enginePosSet];
  258.                     gPosSet = lsd.G[enginePosSet];
  259.                     rpmEndTime = currSeconds + Str.UnpackFloat(minor) - timePre;
  260.                     PostMessage(me,"T10MSubsystems-298469","ChangeRpm",timePre);
  261.                 }//else if
  262.                 continue;
  263.             }//on
  264.             on "T10MSubsystems-298469","FanMain":
  265.             {
  266.                 if(fan_v>0.1) fan_delay=0.3;
  267.                 else fan_delay = 0.7;
  268.                 PostMessage(me,"T10MSubsystems-298469","FanUpdate",0.0);
  269.                 ClearMessages("T10MSubsystems-298469","FanMain");
  270.                 PostMessage(me,"T10MSubsystems-298469","FanMain",fan_delay);
  271.                 continue;
  272.             }//on
  273.             on "T10MSubsystems-298469","FanUpdate":
  274.             {
  275.                 fan_dt = World.GetSeconds() - fan_t0;
  276.                 fan_t0 = fan_t0 + fan_dt;
  277.                 float fan_rpm = Math.Sqrt(8.0*lsd.fanRpm);
  278.                 fan_v = (fan_rpm-fan_rpm0)/fan_dt;
  279.                 fan_v =  Math.Fmax(-fan_vmax,Math.Fmin(fan_vmax,fan_v));
  280.                 fan_rpm0 = fan_rpm0+(fan_v*fan_dt);
  281.                 if(fan_rpm0 > 0.0)
  282.                 {
  283.                     StartMeshAnimationLoop("fan");
  284.                     SetMeshAnimationSpeed("fan",fan_rpm0);
  285.                 }//if
  286.                 else
  287.                 {
  288.                     StopMeshAnimation("fan");
  289.                     fan_rpm0 = 0.0;
  290.                 }//else
  291.                 continue;
  292.             }//on
  293.             on "TE10-298469","Reset":
  294.             {
  295.                 return;
  296.             }//on
  297.         }//wait
  298.     }//Subsystems
  299.    
  300.     thread void Engine(void)
  301.     {
  302.         float dt;
  303.         bool sendSyncMsg,sync,depMode,engineStop,engineIdle,engineIdling;
  304.         int newPos,currentPos,oldPos,i;
  305.         Message msg;
  306.         XT10MLocomotive[] sects;
  307.        
  308.         bool turbine;
  309.        
  310.         float timeDelay = 0.05;
  311.         float vol = 1.0,minDist = 50.0,maxDist = 600.0;
  312.         string att = "a.engine";
  313.        
  314.         wait()
  315.         {
  316.             on "T10MEngine-298469","OilPumpStart":
  317.             {
  318.                 if(lsd.oilPumpCircuit != 1 and lsd.oilPumpCircuit != 2) continue;
  319.                 dt = 1.095;
  320.                 World.PlaySound(SA,"engine/starter_oilpump_start.wav",vol,minDist,maxDist,me,att);
  321.                 SendMessage(me,"T10MEngine-298469","OilPump",dt-timeDelay);
  322.                 continue;
  323.             }//on
  324.             on "T10MEngine-298469","OilPump":
  325.             {
  326.                 dt = 3.142;
  327.                 World.PlaySound(SA,"engine/starter_oilpump_loop.wav",vol,minDist,maxDist,me,att);
  328.                 if(lsd.oilPumpCircuit != 2)
  329.                 {
  330.                     if(lsd.oilPumpCircuit == 1)
  331.                     {
  332.                         SendMessage(me,"T10MEngine-298469","EngineStart",dt-timeDelay);
  333.                         continue;
  334.                     }//if
  335.                     else
  336.                     {
  337.                         SendMessage(me,"T10MEngine-298469","OilPumpStop",dt-timeDelay);
  338.                         continue;
  339.                     }//else
  340.                 }//if
  341.                 SendMessage(me,"T10MEngine-298469","OilPump",dt-timeDelay);
  342.                 continue;
  343.             }//on
  344.             on "T10MEngine-298469","OilPumpStop":
  345.             {
  346.                 World.PlaySound(SA,"engine/starter_oilpump_stop.wav",vol,minDist,maxDist,me,att);
  347.                 continue;
  348.             }//on
  349.             on "T10MEngine-298469","EngineStart":
  350.             {
  351.                 dt = 13.067;
  352.                 World.PlaySound(SA,"engine/starter_starting.wav",vol,minDist,maxDist,me,att);
  353.                 SendMessage(me,"T10MEngine-298469","EngineStarted",dt-2.0-timeDelay);
  354.                 PostMessage(me,"T10MSubsystemsPosition-298469","S start "+dt,0.0);
  355.                 continue;
  356.             }//on
  357.             on "T10MEngine-298469","EngineStarted":
  358.             {
  359.                 SendMessage(me,"T10MEngine-298469","EngineRun",2.0-timeDelay);
  360.                 PostMessage(me,"T10MAutomates-298469","EngineStarted",0.0);
  361.                 continue;
  362.             }//on
  363.             on "T10MEngine-298469","EngineStop":
  364.             {
  365.                 engineStop = true;
  366.                 sync = false;
  367.                 continue;
  368.             }//on
  369.             on "T10MEngine-298469","EngineStopped":
  370.             {
  371.                 engineStop = false;
  372.                 PostMessage(me,"T10MAutomates-298469","EngineStopped",0.0);
  373.                 if(fail) return;
  374.                 continue;
  375.             }//on
  376.             on "T10MEngine-298469","EngineRun":
  377.             {
  378.                 l_eng_er_start:
  379.                
  380.                 depMode = sync and !sci.IsIndependent() and !sci.IsMaster();
  381.                 //if(!sd.l.runCircuit) engineIdle = true;
  382.                 //if(IsIdle()) engineIdle = true;
  383.                 if(sd.l.powerDrop) engineIdle = true;
  384.                 if(!engineIdle and IsIdle()) engineIdling = true;
  385.                 sendSyncMsg = sci.IsMaster() and (sci.GetActiveSections().size() > 1);
  386.                
  387.                 if(!turbine and currentPos >= 5)
  388.                 {
  389.                     PostMessage(me,"T10MEngine-298469","Turbine",0.0);
  390.                 }//if
  391.                
  392.                 if(engineStop)
  393.                 {
  394.                     if(currentPos > 0)
  395.                     {
  396.                         oldPos = currentPos--;
  397.                         string sound = "engine/"+oldPos+"-"+currentPos+".wav";
  398.                         dt = GetSoundDuration(sound);
  399.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  400.                         SendMessage(me,"T10MEngine-298469","EngineRun",dt-timeDelay);
  401.                         PostMessage(me,"T10MSubsystemsPosition-298469","R "+oldPos+" "+currentPos+" "+dt,0.0);
  402.                         continue;
  403.                     }//if
  404.                     PostMessage(me,"T10MAutomates-298469","EngineStopping",0.0);
  405.                     dt = 18.708;
  406.                     World.PlaySound(SA,"engine/stop.wav",vol,minDist,maxDist,me,att);
  407.                     SendMessage(me,"T10MEngine-298469","EngineStopped",dt-1.0-timeDelay);
  408.                     PostMessage(me,"T10MSubsystemsPosition-298469","S stop "+dt,0.0);
  409.                     continue;
  410.                 }//if
  411.                 else if(engineIdle)
  412.                 {
  413.                     if(!sd.l.powerDrop)
  414.                     {
  415.                         engineIdle = false;
  416.                         goto l_eng_er_start;
  417.                     }//if
  418.                     if(currentPos > 0)
  419.                     {
  420.                         oldPos = currentPos--;
  421.                         string sound = "engine/"+oldPos+"-"+currentPos+".wav";
  422.                         dt = GetSoundDuration(sound);
  423.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  424.                         SendMessage(me,"T10MEngine-298469","EngineRun",dt-timeDelay);
  425.                         PostMessage(me,"T10MSubsystemsPosition-298469","R "+oldPos+" "+currentPos+" "+dt,0.0);
  426.                         continue;
  427.                     }//if
  428.                     dt = 4.558;
  429.                     World.PlaySound(SA,"engine/0.wav",vol,minDist,maxDist,me,att);
  430.                     SendMessage(me,"T10MEngine-298469","EngineRun",dt-timeDelay);
  431.                     PostMessage(me,"T10MSubsystemsPosition-298469","R 0 0 "+dt,0.0);
  432.                     continue;
  433.                 }//else if
  434.                 else if(engineIdling)
  435.                 {
  436.                     if(!IsIdle())
  437.                     {
  438.                         engineIdling = false;
  439.                         goto l_eng_er_start;
  440.                     }//if
  441.                     if(currentPos > 8)
  442.                     {
  443.                         oldPos = currentPos--;
  444.                         string sound = "engine/"+oldPos+"-"+currentPos+".wav";
  445.                         dt = GetSoundDuration(sound);
  446.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  447.                         SendMessage(me,"T10MEngine-298469","EngineRun",dt-timeDelay);
  448.                         PostMessage(me,"T10MSubsystemsPosition-298469","R "+oldPos+" "+currentPos+" "+dt,0.0);
  449.                         continue;
  450.                     }//if
  451.                     if(currentPos < 8)
  452.                     {
  453.                         oldPos = currentPos++;
  454.                         string sound = "engine/"+oldPos+"-"+currentPos+".wav";
  455.                         dt = GetSoundDuration(sound);
  456.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  457.                         SendMessage(me,"T10MEngine-298469","EngineRun",dt-timeDelay);
  458.                         PostMessage(me,"T10MSubsystemsPosition-298469","R "+oldPos+" "+currentPos+" "+dt,0.0);
  459.                         continue;
  460.                     }//if
  461.                     dt = 4.558;
  462.                     World.PlaySound(SA,"engine/0.wav",vol,minDist,maxDist,me,att);
  463.                     SendMessage(me,"T10MEngine-298469","EngineRun",dt-timeDelay);
  464.                     PostMessage(me,"T10MSubsystemsPosition-298469","R 0 0 "+dt,0.0);
  465.                     continue;
  466.                 }//else if
  467.                 else if(depMode)
  468.                 {
  469.                     if(newPos != currentPos)
  470.                     {
  471.                         if(newPos < currentPos)
  472.                         {
  473.                             oldPos = currentPos--;
  474.                         }//if
  475.                         else if(newPos > currentPos)
  476.                         {
  477.                             oldPos = currentPos++;
  478.                         }//else if
  479.                         //dt = World.PlaySound(SA,"engine/"+oldPos+"-"+currentPos+".wav",vol,minDist,maxDist,me,att);
  480.                         string sound = "engine/"+oldPos+"-"+currentPos+".wav";
  481.                         dt = GetSoundDuration(sound);
  482.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  483.                     }//if
  484.                     else
  485.                     {
  486.                         oldPos = currentPos;
  487.                         //dt = World.PlaySound(SA,"engine/"+currentPos+".wav",vol,minDist,maxDist,me,att);
  488.                         string sound = "engine/"+currentPos+".wav";
  489.                         dt = GetSoundDuration(sound);
  490.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  491.                     }//if
  492.                     PostMessage(me,"T10MSubsystemsPosition-298469","R "+oldPos+" "+currentPos+" "+dt,0.0);
  493.                     continue;
  494.                 }//else if
  495.                 else
  496.                 {
  497.                     newPos = lsd.enginePosSet;
  498.                     if(newPos != currentPos)
  499.                     {
  500.                         if(newPos < currentPos)
  501.                         {
  502.                             oldPos = currentPos--;
  503.                         }//if
  504.                         else if(newPos > currentPos)
  505.                         {
  506.                             oldPos = currentPos++;
  507.                         }//else if
  508.                         //dt = World.PlaySound(SA,"engine/"+oldPos+"-"+currentPos+".wav",vol,minDist,maxDist,me,att);
  509.                         string sound = "engine/"+currentPos+".wav";
  510.                         dt = GetSoundDuration(sound);
  511.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  512.                     }//if
  513.                     else
  514.                     {
  515.                         oldPos = currentPos;
  516.                         //dt = World.PlaySound(SA,"engine/"+currentPos+".wav",vol,minDist,maxDist,me,att);
  517.                         string sound = "engine/"+currentPos+".wav";
  518.                         dt = GetSoundDuration(sound);
  519.                         World.PlaySound(SA ,sound, vol, minDist, maxDist, me, att);
  520.                     }//if
  521.                     if(sendSyncMsg)
  522.                     {
  523.                         sects = sci.GetActiveSections();
  524.                         for(i=0;i<sects.size();i++)
  525.                         {
  526.                             if(sects[i] == me or sects[i].sci.IsIndependent()) continue;
  527.                             else SendMessage(sects[i],"T10MEngineSync-298469",currentPos);
  528.                         }//for
  529.                     }//if
  530.                     SendMessage(me,"T10MEngine-298469","EngineRun",dt-timeDelay);
  531.                     PostMessage(me,"T10MSubsystemsPosition-298469","R "+oldPos+" "+currentPos+" "+dt,0.0);
  532.                 }//else
  533.                 continue;
  534.             }//on
  535.             on "T10MEngineSync-298469","",msg:
  536.             {
  537.                 if(!lsd.engineRunning) continue;
  538.                 if(sci.IsIndependent() or sci.IsMaster()) continue;
  539.                 int n_newPos = Str.ToInt(msg.minor);
  540.                 if(((currentPos-1)<=n_newPos) and (n_newPos<=(currentPos+1)))
  541.                 {
  542.                     sync = true;
  543.                     newPos = n_newPos;
  544.                     SendMessage(me,"T10MEngine-298469","EngineRun",0.0);
  545.                 }//if
  546.                 else
  547.                 {
  548.                     if(sync) SendMessage(me,"T10MEngine-298469","EngineRun",0.0);
  549.                     sync = false;
  550.                 }//else
  551.                 continue;
  552.             }//on
  553.             on "T10MEngine-298469","SyncReset":
  554.             {
  555.                 if(sync and depMode and (sci.IsIndependent() or sci.IsMaster()))
  556.                 {
  557.                     SendMessage(me,"T10MEngine-298469","EngineRun",0.0);
  558.                     continue;
  559.                 }//if
  560.                 continue;
  561.             }//on
  562.             on "T10MEngine-298469", "Turbine":
  563.             {
  564.                 float gP = sd.l.generatorCurrent * sd.l.generatorVoltage;
  565.                 float tv_mp = 0.000000286 * gP + 0.486;
  566.                 float tv_ms = 0.006 * Math.Fmax(10.0, Math.Fmin(80.0, lsd.engineStress)) + 0.54;
  567.                 float tv = uvk_engine * tv_mp * tv_ms;
  568.                 string ts = (string)(int)Math.Fmin(15.0, Math.Fmax(0.0, currentPos - 5));
  569.                 string tm = "x", tp = "engine/";
  570.                 float tdt;
  571.                 if(currentPos < 5 or !lsd.engineRunning)
  572.                 {
  573.                     if(turbine)
  574.                         World.PlaySound(SA, tp + "turbo_stop.wav", tv, 40.0, 400.0, me, "a.engine");
  575.                     turbine = false;
  576.                     continue;
  577.                 }//if
  578.                 else if(!turbine)
  579.                 {
  580.                     string sound = tp + "turbo_start.wav";
  581.                     tdt = GetSoundDuration(sound);
  582.                     World.PlaySound(SA, sound, tv, 40.0, 400.0, me, "a.engine");    
  583.                 }
  584.                 else
  585.                 {
  586.                     string sound = tp + "turbo" + ts + tm + ".wav";
  587.                     tdt = GetSoundDuration(sound);
  588.                     World.PlaySound(SA, sound, tv, 40.0, 400.0, me, "a.engine");
  589.                 }
  590.                 turbine = true;
  591.                 SendMessage(me, "T10MEngine-298469", "Turbine", tdt-timeDelay);
  592.                 continue;
  593.             }//on
  594.         }//wait
  595.     }//Engine
  596.    
  597.     thread void Automates(void)
  598.     {
  599.         float dt = 1.2;
  600.        
  601.         float fpcResetTime = 120.0,opcSetTime = 10.0,opcResetTime = 30.0;
  602.         bool aSideWaterShutters,aSideOilShutters,aTopShutters,aFan;//auto
  603.         bool mSideWaterShutters,mSideOilShutters,mTopShutters,mFan;//manual
  604.        
  605.         Sleep(1.0);
  606.        
  607.         wait()
  608.         {
  609.             on "T10MAutomates-298469","FuelPumpCircuit":
  610.             {
  611.                 ClearMessages("T10MAutomates-298469","FuelPumpCircuit");
  612.                
  613.                 bool fpc = CD().mainPlusAtm and CD().mainMinusAtm and CD().dieselRunAtm and CD().fuelPumpAtm and (CD().fuelPump or
  614.                  (CD2().mainPlusAtm and CD2().mainMinusAtm and CD2().dieselRunAtm and CD2().fuelPumpAtm and CD2().fuelPump2));
  615.                
  616.                 if(fpc and (lsd.fuelPumpCircuit > 0)) continue;
  617.                
  618.                 ClearMessages("T10MAutomates-298469","FuelPumpCircuitInit");
  619.                 ClearMessages("T10MAutomates-298469","FuelPumpCircuitSet");
  620.                 ClearMessages("T10MAutomates-298469","FuelPumpCircuitReset");
  621.                
  622.                 if(!fpc)
  623.                 {
  624.                   lsd.fuelPumpCircuit = 0;
  625.                     lsd.oilPumpCircuit = 0;
  626.                     continue;
  627.                 }//if
  628.                
  629.                 if(lsd.engineRunning or lsd.engineServ) continue;
  630.                
  631.                 lsd.fuelPumpCircuit = 1;
  632.                 PostMessage(me,"T10MAutomates-298469","FuelPumpCircuitReset",fpcResetTime);
  633.                
  634.                 PostMessage(me,"T10MAutomates-298469","OilPumpCircuit",0.0);
  635.                 continue;
  636.             }//on
  637.             on "T10MAutomates-298469","FuelPumpCircuitReset":
  638.             {
  639.                 ClearMessages("T10MAutomates-298469","FuelPumpCircuitReset");
  640.                 lsd.fuelPumpCircuit = 0;
  641.                 lsd.oilPumpCircuit = 0;
  642.                 continue;
  643.             }//on
  644.             on "T10MAutomates-298469","OilPumpCircuit":
  645.             {
  646.                 ClearMessages("T10MAutomates-298469","OilPumpCircuit");
  647.                
  648.                 bool opc = lsd.fuelPumpCircuit == 1 and CD().mainPlusAtm and CD().mainMinusAtm and (
  649.                     (CD().controlAtm and !CD().brakeBlock and (CD().reverser == 1 or CD().reverser == -1) and CD().throttle == 0) or
  650.                     (CD2().mainPlusAtm and CD2().mainMinusAtm and CD2().controlAtm and !CD2().brakeBlock and (CD2().reverser == 1 or CD2().reverser == -1) and CD2().throttle == 0));
  651.                
  652.                 if(opc and (lsd.oilPumpCircuit > 0)) continue;
  653.                
  654.                 ClearMessages("T10MAutomates-298469","OilPumpCircuitInit");
  655.                 ClearMessages("T10MAutomates-298469","OilPumpCircuitSet");
  656.                 ClearMessages("T10MAutomates-298469","OilPumpCircuitReset");
  657.                
  658.                 if(!opc)
  659.                 {
  660.                   lsd.oilPumpCircuit = 0;
  661.                     continue;
  662.                 }//if
  663.                
  664.                 if(lsd.engineRunning or lsd.engineServ) continue;
  665.                
  666.                 lsd.oilPumpCircuit = 3;
  667.                 continue;
  668.             }//on
  669.             on "T10MAutomates-298469","OilPumpCircuitStart":
  670.             {
  671.                 ClearMessages("T10MAutomates-298469","OilPumpCircuitStart");
  672.                 if(lsd.engineRunning or lsd.engineServ) continue;
  673.                 if(lsd.fuelPumpCircuit != 1 or lsd.oilPumpCircuit != 3) continue;
  674.                 lsd.oilPumpCircuit = 2;
  675.                 ClearMessages("T10MAutomates-298469","FuelPumpCircuitReset");
  676.                 PostMessage(me,"T10MEngine-298469","OilPumpStart",0.0);
  677.                 PostMessage(me,"T10MAutomates-298469","OilPumpCircuitSet",opcSetTime);
  678.                 continue;
  679.             }//on
  680.             on "T10MAutomates-298469","OilPumpCircuitSet":
  681.             {
  682.                 ClearMessages("T10MAutomates-298469","OilPumpCircuitSet");
  683.                 if(lsd.oilPumpCircuit != 2)
  684.                   continue;
  685.                 lsd.oilPumpCircuit = 1;
  686.                 PostMessage(me,"T10MAutomates-298469","OilPumpCircuitReset",opcResetTime);
  687.                 continue;
  688.             }//on
  689.             on "T10MAutomates-298469","OilPumpCircuitReset":
  690.             {
  691.                 ClearMessages("T10MAutomates-298469","OilPumpCircuitReset");
  692.                 lsd.oilPumpCircuit = 0;
  693.                 continue;
  694.             }//on
  695.             on "T10MAutomates-298469","EngineStart":
  696.             {
  697.                 int i;
  698.                 XT10MLocomotive[] scts = sci.GetActiveSections();
  699.                 for (i = 0; i < scts.size(); i++)
  700.                     if (scts[i].lsd.engineServ)
  701.                       continue;
  702.                
  703.                 ClearMessages("T10MAutomates-298469","FuelPumpCircuitReset");
  704.                 ClearMessages("T10MAutomates-298469","OilPumpCircuitReset");
  705.                
  706.                 lsd.engineServ = true;
  707.                
  708.                 continue;
  709.             }//on
  710.             on "T10MAutomates-298469","EngineStarted":
  711.             {
  712.                 lsd.engineRunning = true;
  713.                 sd.l.engineRunning = true;
  714.                 lsd.engineServ = false;
  715.                
  716.                 lsd.oilPumpCircuit = 0;
  717.                 PostMessage(me,"T10MAutomates-298469","ATRS",0.0);
  718.                 PostMessage(me,"T10MAutomates-298469","Frw 2 ATRS",0.0);
  719.                 PostMessage(me,"T10MAutomates-298469","RunCircuit",0.0);
  720.                
  721.                 PostMessage(me,"T10MAutomates-298469","EngineRun",0.0);
  722.                 continue;
  723.             }//on
  724.             on "T10MAutomates-298469","EngineStop":
  725.             {
  726.                 if(!lsd.engineRunning or lsd.engineServ) continue;
  727.                 lsd.engineServ = true;
  728.                 ClearMessages("T10MAutomates-298469","EngineRun");
  729.                 PostMessage(me,"T10MAutomates-298469","RunCircuit",0.0);
  730.                 PostMessage(me,"T10MEngine-298469","EngineStop",0.0);
  731.                 continue;
  732.             }//on
  733.             on "T10MAutomates-298469","EngineStopping":
  734.             {
  735.                 if(!lsd.engineRunning or !lsd.engineServ) continue;
  736.                 lsd.engineRunning = false;
  737.                 sd.l.engineRunning = false;
  738.                 PostMessage(me,"T10MAutomates-298469","RunCircuit",0.0);
  739.                 PostMessage(me,"T10MAutomates-298469","ATRS",0.0);
  740.                 PostMessage(me,"T10MAutomates-298469","Frw 2 ATRS",0.0);
  741.                 continue;
  742.             }//on
  743.             on "T10MAutomates-298469","EngineStopped":
  744.             {
  745.                 if(lsd.engineRunning or !lsd.engineServ) continue;
  746.                 lsd.engineServ = false;
  747.                 PostMessage(me,"T10MAutomates-298469","RunCircuit",0.0);
  748.                 continue;
  749.             }//on
  750.             on "T10MAutomates-298469","PowerContactors":
  751.             {
  752.                 ClearMessages("T10MAutomates-298469","PowerContactors");
  753.                 ClearMessages("T10MAutomates-298469","PowerContactorsChange");
  754.                 if(lsd.pcSet == sd.l.powerContactors) continue;
  755.                 float changeTime;
  756.                 if(lsd.pcSet)
  757.                 {
  758.                     changeTime = 0.821;
  759.                     World.PlaySound(SA,"electrics/pc_set.wav",1.0,1.0,5.0,me,"b.pk_sound") - 0.4;
  760.                 }//if
  761.                 else
  762.                 {
  763.                     World.PlaySound(SA,"electrics/pc_reset.wav",1.0,1.0,5.0,me,"b.pk_sound");
  764.                     changeTime = 0.3;
  765.                 }//else
  766.                 PostMessage(me,"T10MAutomates-298469","PowerContactorsChange",changeTime);
  767.                 continue;
  768.             }//on
  769.             on "T10MAutomates-298469","PowerContactorsChange":
  770.             {
  771.                 ClearMessages("T10MAutomates-298469","PowerContactorsChange");
  772.                 sd.l.powerContactors = lsd.pcSet;
  773.                 continue;
  774.             }//on
  775.             on "T10MAutomates-298469","EngineRun":
  776.             {
  777.                 ClearMessages("T10MAutomates-298469","EngineRun");
  778.                 if(!lsd.engineRunning) continue;
  779.                 if((lsd.fuelPumpCircuit != 1) or (lsd.fuelQueue.GetQueueCount() < 1))
  780.                 {
  781.                     PostMessage(me,"T10MAutomates-298469","EngineStop",0.0);
  782.                     continue;
  783.                 }//if
  784.                
  785.                 PostMessage(me,"T10MAutomates-298469","ATRS",0.0);
  786.                 PostMessage(me,"T10MAutomates-298469","EngineRun",dt);
  787.                 continue;
  788.             }//on
  789.             on "T10MAutomates-298469","ATRS":
  790.             {
  791.                 bool shuttersOn = CD().shuttersAtm and CD().mainPlusAtm and CD().mainMinusAtm;
  792.                 int controlSectCode = 0;
  793.                 XT10MCabinData sectionCd;
  794.                 int i = 0;
  795.                 for (; i < 4; i++ )
  796.                 {
  797.                     sectionCd = sci.GetSystemData(i).c;
  798.                     if (sectionCd.mainPlusAtm and sectionCd.mainMinusAtm and sectionCd.controlAtm
  799.                         and sectionCd.atrsManualMode and (sectionCd.reverser == 1 or sectionCd.reverser == -1))
  800.                     {
  801.                         if (controlSectCode == 0)
  802.                             controlSectCode = i;
  803.                         else
  804.                             controlSectCode = -1;
  805.                     }
  806.                 }
  807.                
  808.                 bool atrsControl = shuttersOn and controlSectCode <= 0;
  809.                 bool manualControl = shuttersOn and controlSectCode >= 1;
  810.                
  811.                 if (atrsControl)
  812.                 {
  813.                     if (sd.l.Tw_sensor > 72.0) aSideWaterShutters = true;
  814.                     else if (sd.l.Tw_sensor < 66.0) aSideWaterShutters = false;
  815.                    
  816.                     if (sd.l.To_sensor > 72.0) aSideOilShutters = true;
  817.                     else if (sd.l.To_sensor < 66.0) aSideOilShutters = false;
  818.                    
  819.                     if (sd.l.Tw_sensor > 74.0 or sd.l.To_sensor > 74.0) aFan = true;
  820.                     else if (sd.l.Tw_sensor < 72.0 or sd.l.To_sensor < 72.0) aFan = false;
  821.                    
  822.                     aTopShutters = aSideWaterShutters or aSideOilShutters;
  823.                 }
  824.                
  825.                 if (manualControl)
  826.                 {
  827.                     sectionCd = sci.GetSystemData(controlSectCode).c;
  828.                     mSideWaterShutters = sectionCd.sideWaterShutters;
  829.                     mSideOilShutters = sectionCd.sideOilShutters;
  830.                     mTopShutters = sectionCd.topShutters or mSideWaterShutters or mSideOilShutters;
  831.                     mFan = sectionCd.fan;
  832.                 }
  833.                
  834.                 bool topShutters = atrsControl and aTopShutters or manualControl and mTopShutters;
  835.                 bool sideWaterShutters = atrsControl and aSideWaterShutters or manualControl and mSideWaterShutters;
  836.                 bool sideOilShutters = atrsControl and aSideOilShutters or manualControl and mSideOilShutters;
  837.                 bool fan = lsd.engineRunning and (atrsControl and aFan or manualControl and mFan);
  838.                
  839.                 if(topShutters != lsd.topShuttersOpened)
  840.                 {
  841.                     lsd.topShuttersOpened = topShutters;
  842.                     SetShuttersState("top_shutters",topShutters);
  843.                 }
  844.        
  845.                 if(sideWaterShutters != lsd.sideWaterShuttersOpened)
  846.                 {
  847.                     lsd.sideWaterShuttersOpened = sideWaterShutters;
  848.                     SetShuttersState("side_water_shutters",sideWaterShutters);
  849.                 }
  850.                
  851.                 if(sideOilShutters != lsd.sideOilShuttersOpened)
  852.                 {
  853.                     lsd.sideOilShuttersOpened = sideOilShutters;
  854.                     SetShuttersState("side_oil_shutters",sideOilShutters);
  855.                 }
  856.                
  857.                 if(fan != lsd.fanRunning)
  858.                 {
  859.                     lsd.fanRunning = fan;
  860.                     if(fan)
  861.                         Fan();
  862.                 }
  863.                
  864.                 continue;
  865.             }
  866.         }//wait
  867.     }//Automates
  868.    
  869.     void SetShuttersState(string shutters,bool state)
  870.     {
  871.         SetMeshAnimationState(shutters,state);
  872.         World.PlaySound(SA,"equipment/shutters_toggle.wav",1.0,3.0,50.0,me,"a.shutters");
  873.     }//SetShuttersState
  874.    
  875.     thread void Fan(void)
  876.     {
  877.         if(!lsd.fanRunning) return;
  878.         PlaySoundAndSleep(SA,"equipment/fan_start.wav",uvk_fan*0.8,10.0,200.0,me,"a.fan");
  879.         while(lsd.fanRunning)
  880.         {
  881.             PlaySoundAndSleep(SA,"equipment/fan_loop.wav",uvk_fan*0.8,10.0,200.0,me,"a.fan");
  882.         }//while
  883.         World.PlaySound(SA,"equipment/fan_stop.wav",uvk_fan*0.8,10.0,200.0,me,"a.fan");
  884.     }//Fan
  885.    
  886.     public void QUpdate(void)
  887.     {
  888.         if(sci.IsControlsTraction())
  889.             SetEngineSetting("throttle",lsd.tractivePos);
  890.         else if(!sd.l2.tractionCircuit)
  891.             SetEngineSetting("throttle",0.0);
  892.         switch(CD().reverser)
  893.         {
  894.             case 1: SetEngineSetting("reverser",Train.TRACTION_FORWARD);break;
  895.             case -1: SetEngineSetting("reverser",Train.TRACTION_REVERSE);break;
  896.             default: break;
  897.         }//switch
  898.         if(CD().reverser==0 and CD2().reverser==0)
  899.             SetEngineSetting("reverser",Train.TRACTION_NEUTRAL);
  900.        
  901.         if(!CD().brakeBlock)
  902.         {
  903.             SetEngineSetting("train-auto-brake",sd.c.trainBrakeValue);
  904.             SetEngineSetting("loco-auto-brake",sd.c.locomotiveBrakeValue);
  905.             if(sd.c.trainBrake == 6 and !lsd.sanding)
  906.                 Sanding();
  907.            
  908.             if(sd.c.releaseBrakes)
  909.             {
  910.                 GetMyTrain().SetBail();
  911.             }//if
  912.             if(GetBrakePipePressure()>GetAuxReservoirPressure())
  913.             {
  914.                 sd.c.releaseBrakes = false;
  915.             }//if
  916.         }//if
  917.         else if(CD2().brakeBlock)
  918.         {
  919.             SetEngineSetting("train-auto-brake",3.0);
  920.             SetEngineSetting("loco-auto-brake",sd.c.locomotiveBrakeValue);
  921.             sd.c.releaseBrakes = false;
  922.         }//else if
  923.        
  924.         bool traction = sd.l.tractionCircuit;//sd.l.runCircuit and LocoControl();
  925.        
  926.         if(traction)SetWheelslipTractionMultiplier(lsd.wheelslipTM);
  927.         else SetWheelslipTractionMultiplier(1.0);
  928.        
  929.         SetMaximumTractiveEffort(lsd.maxTE * (float)traction);
  930.        
  931.         SetSandingTractionMultiplier(lsd.sandingTM*(float)lsd.sanding + 1.0);
  932.         if(lsd.sanding)
  933.             SetEngineSetting("sanding",1.0);
  934.     }//Update
  935.    
  936.     public void Update(void)
  937.     {
  938.         QUpdate();
  939.         if(sci.s2 != null) sci.s2.QUpdate();
  940.     }//Update
  941.    
  942.     thread void Main(void)
  943.     {
  944.         float timeInterval,bp,er,bc,vel;
  945.         float brkst,brksttime = 1.6;
  946.         int i;
  947.        
  948.         bogeys = GetBogeyList();
  949.        
  950.         //Initial setup
  951.         SetCompressorEfficiency(0.0);
  952.         SetCoupler(GetMyPosition(),GetDirectionRelativeToTrain());
  953.        
  954.         SetSandingTractionMultiplier(1.0);
  955.         for(i=0;i<8;i++)
  956.             SendMessage(me,"pfx","-"+(SANDPFX_INDEX+i));
  957.        
  958.         Sleep(2.0);
  959.         sci.ReCoordinate();
  960.         Sleep(1.0);
  961.         P(sci.Info());
  962.         InitSystemData();
  963.        
  964.         PhysicsScheme();
  965.         Automates();
  966.         Engine();
  967.         Subsystems();
  968.        
  969.         Sleep(1.0);
  970.        
  971.         lsd.wheelslipTM = 0.2;
  972.         lsd.sandingTM = 0.0;
  973.         float dmaxTE = GetDefaultMaximumTractiveEffort();
  974.         lsd.maxTE = dmaxTE;
  975.        
  976.         while(!fail)
  977.         {
  978.             timeInterval = 0.2;
  979.            
  980.             switch(World.GetWeatherType())
  981.             {
  982.                 case World.WEATHER_TYPE_CLEAR: lsd.maxTE = dmaxTE;lsd.sandingEfficiency = 0.8;lsd.wheelslipTM = 0.2;break;
  983.                 case World.WEATHER_TYPE_CLOUDY: lsd.maxTE = dmaxTE;lsd.sandingEfficiency = 0.8;lsd.wheelslipTM = 0.2;break;
  984.                 case World.WEATHER_TYPE_DRIZZLE: lsd.maxTE = 0.85*dmaxTE;lsd.sandingEfficiency = 0.7;lsd.wheelslipTM = 0.16;break;
  985.                 case World.WEATHER_TYPE_RAIN: lsd.maxTE = 0.6*dmaxTE;lsd.sandingEfficiency = 0.6;lsd.wheelslipTM = 0.12;break;
  986.                 case World.WEATHER_TYPE_STORMY: lsd.maxTE = 0.4*dmaxTE;lsd.sandingEfficiency = 0.5;lsd.wheelslipTM = 0.04;break;
  987.                 case World.WEATHER_TYPE_LIGHT_SNOW: lsd.maxTE = 0.9*dmaxTE;lsd.sandingEfficiency = 0.6;lsd.wheelslipTM = 0.18;break;
  988.                 case World.WEATHER_TYPE_MEDIUM_SNOW: lsd.maxTE = 0.8*dmaxTE;lsd.sandingEfficiency = 0.5;lsd.wheelslipTM = 0.14;break;
  989.                 case World.WEATHER_TYPE_HEAVY_SNOW: lsd.maxTE = 0.65*dmaxTE;lsd.sandingEfficiency = 0.4;lsd.wheelslipTM = 0.1;break;
  990.                 default: lsd.maxTE = dmaxTE;lsd.sandingEfficiency = 0.8;lsd.wheelslipTM = 0.2;break;
  991.             }//switch
  992.            
  993.             while(lsd.fuelConsumed >= 1.0)
  994.             {
  995.                 lsd.fuelConsumed = lsd.fuelConsumed - 1.0;
  996.                 lsd.fuelQueue.DestroyProductMatching(null,1);
  997.             }//if
  998.            
  999.             while(lsd.sandConsumed >= 1.0)
  1000.             {
  1001.                 lsd.sandConsumed = lsd.sandConsumed - 1.0;
  1002.                 lsd.sandQueue.DestroyProductMatching(null,1);
  1003.             }//if
  1004.            
  1005.             //Compressor//
  1006.             if(lsd.engineRunning and !lsd.compressorRunning and (GetPressureParam("main-reservoir-pressure") < 750.0))
  1007.             {
  1008.                 lsd.compressorRunning = true;
  1009.                 Compressor();
  1010.             }//if
  1011.            
  1012.             //Braking//
  1013.             if(GetPressureParam("brake-cylinder-pressure") >= 20.0)
  1014.             {
  1015.                 if(!lsd.braking)
  1016.                 {
  1017.                     lsd.braking = true;
  1018.                     Brakes();
  1019.                 }//if
  1020.             }//if
  1021.             else
  1022.             {
  1023.                 lsd.braking = false;
  1024.             }//else
  1025.            
  1026.             brkst = Math.Sqrt((Math.Fmax(0.0,Math.Fmin(400.0,GetPressureParam("brake-cylinder-pressure")))*0.01)*4.0)*(6.0/4.0);
  1027.             for(i=0;i<bogeys.size();i++)
  1028.             {
  1029.                 bogeys[i].SetMeshAnimationFrame("ts",brkst,Math.Fabs(brkst-bogeys[i].GetMeshAnimationFrame("ts"))*brksttime);
  1030.             }//for
  1031.            
  1032.             bp = GetPressureParam("brake-pipe-pressure");
  1033.             er = GetPressureParam("equaliser-pressure");
  1034.             bc = GetPressureParam("brake-cylinder-pressure");
  1035.            
  1036.             if(bc > 30.0+Math.Rand(-5.0,5.0)) sd.l.braking = true;
  1037.             else if(bc < 20.0+Math.Rand(-5.0,5.0)) sd.l.braking = false;
  1038.            
  1039.             if((bp < 480.0+Math.Rand(-10.0,10.0)) and (bc < 40.0+Math.Rand(-5.0,5.0))) sd.l.bpbreak = true;
  1040.             else if((bp > 510.0+Math.Rand(-10.0,10.0)) or (bc > 50.0+Math.Rand(-5.0,5.0))) sd.l.bpbreak = false;
  1041.            
  1042.             if(bp < 350.0) lsd.bpPressureRelay = true;
  1043.             else if(bp > 500.0) lsd.bpPressureRelay = false;
  1044.            
  1045.             bool emg = (!CD().brakeBlock and CD().trainBrake == 6) or (!CD2().brakeBlock and CD2().trainBrake == 6);
  1046.             lsd.emergencyBraking = emg;
  1047.             if(emg and Math.Fabs(GetVelocity()/Train.KPH_TO_MPS)>=10.0)
  1048.             {
  1049.                 lsd.sanding = true;
  1050.                 //Sanding();
  1051.             }//if
  1052.            
  1053.             if((sd.l.Tw_sensor>=96.0+Math.Rand(-2.0,2.0)) or (sd.l.To_sensor>=86.0+Math.Rand(-2.0,2.0))) lsd.overheat = true;
  1054.             else if((sd.l.Tw_sensor<=92.0+Math.Rand(-2.0,2.0)) and (sd.l.To_sensor<=82.0+Math.Rand(-2.0,2.0))) lsd.overheat = false;
  1055.            
  1056.             sd.l.powerDrop = sd.l.bpbreak or lsd.bpPressureRelay or lsd.emergencyBraking or lsd.overheat;
  1057.            
  1058.             sd.l.engineIdle = lsd.engineRunning and IsIdle();
  1059.            
  1060.             bool rc = lsd.engineRunning and !lsd.engineServ and !sd.l.engineIdle and !sd.l.powerDrop;
  1061.             if(sd.l.runCircuit != rc)
  1062.             {
  1063.                 sd.l.runCircuit = rc;
  1064.                 sci.ReInitMaster();
  1065.             }//if
  1066.            
  1067.             if(CD().mainPlusAtm and CD().mainMinusAtm and CD().controlAtm)
  1068.             {
  1069.                 lsd.posSet  = CD().throttle;
  1070.             }//if
  1071.             else if(sci.s2 != null and CD2().mainPlusAtm and CD2().mainMinusAtm and CD2().controlAtm)
  1072.             {
  1073.                 lsd.posSet  = CD2().throttle;
  1074.             }//else if
  1075.             else
  1076.             {
  1077.                 lsd.posSet  = GetEngineSetting("throttle");
  1078.             }//else
  1079.            
  1080.             bool tractionCircuit = sd.l.runCircuit and LocoControl();
  1081.             lsd.enginePosSet = (int)sd.l.runCircuit * lsd.posSet;
  1082.             lsd.tractivePosSet = (int)tractionCircuit * lsd.posSet;
  1083.             bool shuntMode = sd.c.shuntMode and tractionCircuit and lsd.tractivePosSet == 0;
  1084.             if(shuntMode != lsd.shuntMode)
  1085.             {
  1086.                 lsd.shuntMode = shuntMode;
  1087.                 if(shuntMode)
  1088.                     sci.ReResetMaster();
  1089.                 else
  1090.                     sci.ReInitMaster();
  1091.             }
  1092.             if(lsd.shuntMode)
  1093.                 lsd.tractivePosSet = 1;
  1094.            
  1095.             bool pc = lsd.tractivePosSet > 0 and (sd.l.powerContactors or lsd.posSet == 0 or lsd.posSet == 1);
  1096.             if(lsd.pcSet != pc)
  1097.             {
  1098.                 lsd.pcSet = pc;
  1099.                 PostMessage(me,"T10MAutomates-298469","PowerContactors",Math.Rand(0.8,1.1));
  1100.             }//if
  1101.            
  1102.             if(sd.l.powerContactors != sd.l.tractionCircuit)
  1103.             {
  1104.                 sd.l.tractionCircuit = sd.l.powerContactors;
  1105.                 sci.ReInitTraction();
  1106.             }//if
  1107.            
  1108.             if(!lsd.posChange and (lsd.tractivePos != lsd.tractivePosSet))
  1109.             {
  1110.                 PostMessage(me,"T10MSubsystems-298469","TractivePosChange",0.0);
  1111.             }//if
  1112.            
  1113.             QUpdate();
  1114.            
  1115.             Sleep(timeInterval);
  1116.         }//while
  1117.     }//Main
  1118.    
  1119.     thread void PhysicsScheme(void)
  1120.     {
  1121.         //Overload SetMyData(void) to customize parameters
  1122.        
  1123.         //Setting ramdomization
  1124.         float rnd_pb = MD.GetNamedTagAsFloat("trm_random_parameters_mod_base"),rnd_pd = MD.GetNamedTagAsFloat("trm_random_parameters_mod_delta");
  1125.         float rnd_tb = MD.GetNamedTagAsFloat("trm_random_termometer_mod_base"),rnd_td = MD.GetNamedTagAsFloat("trm_random_termometer_mod_delta");
  1126.        
  1127.         //Getting saved params
  1128.         float qn = MD.GetNamedTagAsFloat("trm_qn");
  1129.         float Temin = MD.GetNamedTagAsFloat("trm_temin"),Temax = MD.GetNamedTagAsFloat("trm_temax");
  1130.         float tmin = MD.GetNamedTagAsFloat("trm_tmin"),tmax = MD.GetNamedTagAsFloat("trm_tmax");
  1131.         float kd = MD.GetNamedTagAsFloat("trm_kd"),kw1 = MD.GetNamedTagAsFloat("trm_kw1"),kw2 = MD.GetNamedTagAsFloat("trm_kw2"),ko = MD.GetNamedTagAsFloat("trm_ko");
  1132.         float kw1c = MD.GetNamedTagAsFloat("trm_kw1c"),kw2c = MD.GetNamedTagAsFloat("trm_kw2c"),koc = MD.GetNamedTagAsFloat("trm_koc");
  1133.         float kto = MD.GetNamedTagAsFloat("trm_kto"),kcto = MD.GetNamedTagAsFloat("trm_kcto"),khw = MD.GetNamedTagAsFloat("trm_khw"),kho = MD.GetNamedTagAsFloat("trm_kho");
  1134.         float kceVmin = MD.GetNamedTagAsFloat("trm_kcevmin"),kceV = MD.GetNamedTagAsFloat("trm_kcev"),bceV = MD.GetNamedTagAsFloat("trm_bcev");
  1135.         float kfeTmin = MD.GetNamedTagAsFloat("trm_kfetmin"),kfeT = MD.GetNamedTagAsFloat("trm_kfet"),bfeT = MD.GetNamedTagAsFloat("trm_bfet"),kfeToff = MD.GetNamedTagAsFloat("trm_kfetoff");
  1136.         float kfeNmin = MD.GetNamedTagAsFloat("trm_kfenmin"),kfeN = MD.GetNamedTagAsFloat("trm_kfen"),bfeN = MD.GetNamedTagAsFloat("trm_bfen");
  1137.         float kc0 = MD.GetNamedTagAsFloat("trm_kc0"),kc = 0.77*MD.GetNamedTagAsFloat("trm_kc"),kf = MD.GetNamedTagAsFloat("trm_kf");
  1138.         float kts = MD.GetNamedTagAsFloat("trm_kts"),ktsf = MD.GetNamedTagAsFloat("trm_ktsf"),kss = MD.GetNamedTagAsFloat("trm_kss");
  1139.        
  1140.         kd = kd * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1141.         kw1 = kw1 * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1142.         kw2 = kw2 * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1143.         ko = ko * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1144.         kw1c = kw1c * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1145.         kw2c = kw2c * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1146.         koc = koc * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1147.         kto = kto * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1148.         kcto = kcto * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1149.         khw = khw * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1150.         kho = kho * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1151.         kc0 = kc0 * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1152.         kc = kc * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1153.         kf = kf * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1154.         kts = kts * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1155.         ktsf = ktsf * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1156.         kss = kss * (rnd_pb + Math.Rand(-rnd_pd,rnd_pd));
  1157.        
  1158.         float tw_error = rnd_tb + Math.Rand(-rnd_td,rnd_td);
  1159.         float to_error = rnd_tb + Math.Rand(-rnd_td,rnd_td);
  1160.        
  1161.         //Calculating enviroment temperature
  1162.         float Te,gt;
  1163.         float Te_k1 = ((Temax-Temin)/(tmax-tmin)),Te_b1 = Temin-(Te_k1*tmin);
  1164.         float Te_k2 = ((Temax-Temin)/(tmax-tmin+1.0)),Te_b2 = Temin-(Te_k2*tmin);
  1165.         gt = World.GetGameTime();
  1166.         if((tmax<=gt)and(gt<=tmin))
  1167.         {
  1168.             Te = Te_k1*gt + Te_b1;
  1169.         }//if
  1170.         else
  1171.         {
  1172.             if((0.0<=gt)and(gt<tmax)) gt = 1.0 + gt;
  1173.             Te = Te_k2*gt + Te_b2;
  1174.         }//else
  1175.        
  1176.         //Setting up initial temperature needles values, use "Te" value for env. temperature, otherwise use float value
  1177.         if(MD.GetNamedTag("trm_start_temperature_d") == "Te") lsd.Td=Te+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_d_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_d_delta"));
  1178.         else lsd.Td=MD.GetNamedTagAsFloat("trm_start_temperature_d")+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_d_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_d_delta"));
  1179.         if(MD.GetNamedTag("trm_start_temperature_w1") == "Te") lsd.Tw1=Te+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_w1_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_w1_delta"));
  1180.         else lsd.Tw1 = MD.GetNamedTagAsFloat("trm_start_temperature_w1")+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_w1_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_w1_delta"));
  1181.         if(MD.GetNamedTag("trm_start_temperature_w2") == "Te") lsd.Tw2=Te+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_w2_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_w2_delta"));
  1182.         else lsd.Tw2=MD.GetNamedTagAsFloat("trm_start_temperature_w2")+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_w2_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_w2_delta"));
  1183.         if(MD.GetNamedTag("trm_start_temperature_o") == "Te") lsd.To=Te+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_o_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_o_delta"));
  1184.         else lsd.To=MD.GetNamedTagAsFloat("trm_start_temperature_o")+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_o_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_o_delta"));
  1185.         if(MD.GetNamedTag("trm_start_temperature_to") == "Te") lsd.Tto=Te+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_to_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_to_delta"));
  1186.         else lsd.Tto=MD.GetNamedTagAsFloat("trm_start_temperature_to")+Math.Rand(-MD.GetNamedTagAsFloat("trm_start_temperature_to_delta"),MD.GetNamedTagAsFloat("trm_start_temperature_to_delta"));
  1187.        
  1188.         float dTd,dTw1,dTw2,dTo,dTto;
  1189.         float dt = 0.4;
  1190.         float Ph,Phw1,Phw2,Pho,Pto,Thw1,Tho,kcV,kfT,kfN,kcs1,kcs2,kcf1,kcf2,Pcw1,Pcw2;
  1191.        
  1192.         float Ig,Ug,ek,vel,Fk,UdI;
  1193.         float fd1Off = 0.095,fd1On = 0.202,fd2Off = 0.106,fd2On = 0.223;
  1194.        
  1195.         bool a;
  1196.        
  1197.         while(!fail)
  1198.         {
  1199.             //Recalculating env. temperatures
  1200.             gt = World.GetGameTime();
  1201.             if((tmax<=gt)and(gt<=tmin))
  1202.             {
  1203.                 Te = Te_k1*gt + Te_b1;
  1204.             }//if
  1205.             else
  1206.             {
  1207.                 if((0.0<=gt)and(gt<tmax)) gt = 1.0 + gt;
  1208.                 Te = Te_k2*gt + Te_b2;
  1209.             }//else
  1210.            
  1211.             lsd.gPower = Math.Fabs(GetEngineParam("applied-force")) * Math.Fabs(GetVelocity()) / qn;
  1212.             lsd.g = lsd.gBase + lsd.gPower;
  1213.             lsd.fuelConsumed = lsd.fuelConsumed + lsd.g / 0.83 * dt;
  1214.             lsd.engineStress = Math.Fmax(0.0,lsd.engineStress + (lsd.tractivePos - lsd.enginePos - 0.02)*dt);
  1215.            
  1216.             Ph = qn * lsd.g;
  1217.             L(" TRM @ "+GetName()+" :: g="+lsd.g);
  1218.             Phw1 = khw * ((lsd.Td + (kd*Ph*dt)) - lsd.Tw1);
  1219.             Pho = kho * ((lsd.Td + (kd*Ph*dt)) - lsd.To);
  1220.             dTd = kd * (Ph - Phw1 - Pho) * dt;
  1221.             sd.l.Tw_sensor = tw_error + lsd.Tw1 + (kw1c*Phw1);
  1222.             sd.l.To_sensor = to_error + lsd.To + (koc*Pho);
  1223.            
  1224.             Phw2 = kto * ((lsd.To+(ko*Pho*dt)) - lsd.Tw2);
  1225.             Pho = Pho - Phw2;
  1226.             dTo = ko * Pho * dt;
  1227.             vel = Math.Fabs(GetVelocity()/Train.KPH_TO_MPS);
  1228.             kcV = Math.Fmax(kceVmin,Math.Fmin(1.0,kceV*vel + bceV));//k(vel)
  1229.            
  1230.             if(!lsd.fanRunning) kfT=kfeToff;
  1231.             else if(sd.c.atrsManualMode) kfT=1.0;
  1232.             else kfT = Math.Fmax(kfeTmin,Math.Fmin(1.0,(kfeT*Math.Fmax(sd.l.Tw_sensor,sd.l.To_sensor))+bfeT));//k(T)
  1233.            
  1234.             kfN = Math.Fmax(kfeNmin,Math.Fmin(1.0,kfeN*lsd.rpm+bfeN));//k(rpm)
  1235.            
  1236.             lsd.fanRpm = kfT * kfN;
  1237.                        
  1238.             if(lsd.topShuttersOpened and lsd.sideWaterShuttersOpened) kcs1 = 1.0;
  1239.             else if(lsd.topShuttersOpened) kcs1 = kts;
  1240.             else if(lsd.sideWaterShuttersOpened) kcs1 = kss;
  1241.             else kcs1 = 0.0;
  1242.            
  1243.             if(lsd.topShuttersOpened and lsd.sideWaterShuttersOpened) kcf1 = kf * kfT * kfN;
  1244.             else if(lsd.topShuttersOpened) kcf1 = ktsf * kf * kfT * kfN;
  1245.             else kcf1 = 0.0;
  1246.            
  1247.             if(lsd.topShuttersOpened and lsd.sideOilShuttersOpened) kcs2 = 1.0;
  1248.             else if(lsd.topShuttersOpened) kcs2 = kts;
  1249.             else if(lsd.sideOilShuttersOpened) kcs2 = kss;
  1250.             else kcs2 = 0.0;
  1251.            
  1252.             if(lsd.topShuttersOpened and lsd.sideOilShuttersOpened) kcf2 = kf * kfT * kfN;
  1253.             else if(lsd.topShuttersOpened) kcf2 = ktsf * kf * kfT * kfN;
  1254.             else kcf2 = 0.0;
  1255.            
  1256.             Pcw1 = (kc0 + (kcV*(kcs1+kcf1)*kc)) * ((lsd.Tw1+(kw1*Ph*dt)) - Te);
  1257.             dTw1 = kw1 * (Phw1 - Pcw1) * dt;
  1258.             Pcw2 = (kc0 + (kcV*(kcs2+kcf2)*kc)) * ((lsd.Tw2+(kw2c*Phw2)) - Te);
  1259.             dTw2 = kw2 * (Phw2 - Pcw2) * dt;
  1260.            
  1261.             lsd.Td = lsd.Td + dTd;
  1262.             lsd.Tw1 = lsd.Tw1 + dTw1;
  1263.             lsd.Tw2 = lsd.Tw2 + dTw2;
  1264.             lsd.To = lsd.To + dTo;
  1265.             lsd.Tto = lsd.Tto + dTto;
  1266.            
  1267.             switch(lsd.fieldDivertState)
  1268.             {
  1269.                 case 1: ek = -0.042*vel/3.6 + 31.64;break;
  1270.                 case 2: ek = -0.0036*vel/3.6 + 35.57;break;
  1271.                 default: ek = -0.11*vel/3.6 + 28.12;break;
  1272.             }//switch
  1273.            
  1274.             vel = Math.Fabs(GetVelocity());
  1275.             Fk = (float)sd.l.powerContactors * Math.Fabs(GetEngineParam("applied-force"));
  1276.             float sqrtFk = Math.Sqrt(Fk);
  1277.             Ig = ek*sqrtFk*0.32;// Newtons to kgf
  1278.             if(Ig != 0.0) Ug = (vel+0.01)*Fk/Ig;
  1279.             else Ug = 0.0;
  1280.                
  1281.             sd.l.generatorCurrent = Ig;
  1282.             sd.l.generatorVoltage = Ug;
  1283.            
  1284.             if(Ig != 0.0) UdI = Ug/Ig;
  1285.             else UdI = 0.0;
  1286.             if(lsd.fieldDivertState == 0 and UdI > fd1On)
  1287.                 lsd.fieldDivertState = 1;
  1288.             if(lsd.fieldDivertState == 1 and UdI > fd2On)
  1289.                 lsd.fieldDivertState = 2;
  1290.             if(lsd.fieldDivertState == 1 and UdI < fd1Off)
  1291.                 lsd.fieldDivertState = 0;
  1292.             if(lsd.fieldDivertState == 2 and UdI < fd2Off)
  1293.                 lsd.fieldDivertState = 1;
  1294.            
  1295.             Sleep(dt);
  1296.         }//while
  1297.     }//PhysicsScheme
  1298.    
  1299.     thread void Compressor(void)
  1300.     {
  1301.         float vol = uvk_compressor,mindist = 12.0,maxdist = 200.0;
  1302.         float e1 = 0.6,e2 = 0.2,emin = 0.1,emax = 0.6;
  1303.         float k = (e2-e1)/100.0,b = (17.0*e1-15.0*e2)/2;
  1304.         float endPressure = Math.Rand(848.0,856.0);
  1305.         SetCompressorEfficiency(Math.Fmax(emin,Math.Fmin(emax,k*GetPressureParam("main-reservoir-pressure") + b)));
  1306.         PlaySoundAndSleep(SA,"equipment/compressor_start.wav",vol,mindist,maxdist,me,"a.compressor");
  1307.         while(lsd.engineRunning and (GetPressureParam("main-reservoir-pressure") < endPressure))
  1308.         {
  1309.             SetCompressorEfficiency(Math.Fmax(emin,Math.Fmin(emax,k*GetPressureParam("main-reservoir-pressure") + b)));
  1310.             PlaySoundAndSleep(SA,"equipment/compressor_loop.wav",vol,mindist,maxdist,me,"a.compressor");
  1311.         }//while
  1312.         World.PlaySound(SA,"equipment/compressor_stop.wav",vol,mindist,maxdist,me,"a.compressor");
  1313.         SetCompressorEfficiency(0.0);
  1314.         lsd.compressorRunning = false;
  1315.     }//Compressor
  1316.    
  1317.     thread void Brakes(void)
  1318.     {
  1319.         float vol = uvk_brakes*0.5,mindist = 10.0,maxdist = 120.0;
  1320.         bool braking = false,stopping = false;
  1321.         float accel,v = Math.Fabs(GetVelocity())/Train.KPH_TO_MPS,v0 = Math.Fabs(GetVelocity())/Train.KPH_TO_MPS,t,t0 = World.GetSeconds(),tts;
  1322.         Sleep(0.1);
  1323.        
  1324.         while(v>0.6 and lsd.braking)
  1325.         {
  1326.             v = Math.Fabs(GetVelocity())/Train.KPH_TO_MPS;
  1327.             t = World.GetSeconds();
  1328.             accel = (v-v0)/(t-t0);
  1329.             v0 = v;
  1330.             t0 = t;
  1331.             if(GetPressureParam("brake-cylinder-pressure") > 40.0)
  1332.             {
  1333.                 if(v>0.1 and v<6.0)
  1334.                 {
  1335.                     if(!stopping)
  1336.                     {
  1337.                         stopping = true;
  1338.                         tts = v/accel;
  1339.                         if(3.0<=tts and tts<4.0)
  1340.                         {
  1341.                             World.PlaySound(SA,"outer/brakes_finalstop_3.5.wav",vol,mindist,maxdist,me,"a.bog0");
  1342.                             World.PlaySound(SA,"outer/brakes_finalstop_3.5.wav",vol,mindist,maxdist,me,"a.bog1");
  1343.                         }//if
  1344.                         else if(1.0<tts and tts<1.8)
  1345.                         {
  1346.                             World.PlaySound(SA,"outer/brakes_finalstop_1.5.wav",vol,mindist,maxdist,me,"a.bog0");
  1347.                             World.PlaySound(SA,"outer/brakes_finalstop_1.5.wav",vol,mindist,maxdist,me,"a.bog1");
  1348.                         }//if
  1349.                     }//if
  1350.                 }//if
  1351.                 else stopping = false;
  1352.                 if(!braking)
  1353.                 {
  1354.                     braking = true;
  1355.                     World.PlaySound(SA,"outer/brakes_apl_start.wav",vol,mindist,maxdist,me,"a.bog0");
  1356.                     PlaySoundAndSleep(SA,"outer/brakes_apl_start.wav",vol,mindist,maxdist,me,"a.bog1");
  1357.                     continue;
  1358.                 }//if
  1359.                 World.PlaySound(SA,"outer/brakes_apl_loop.wav",vol,mindist,maxdist,me,"a.bog0");
  1360.                 PlaySoundAndSleep(SA,"outer/brakes_apl_loop.wav",vol,mindist,maxdist,me,"a.bog1");
  1361.             }//if
  1362.             else
  1363.             {
  1364.                 if(braking)
  1365.                 {
  1366.                     braking = false;
  1367.                     World.PlaySound(SA,"outer/brakes_apl_stop.wav",vol,mindist,maxdist,me,"a.bog0");
  1368.                     PlaySoundAndSleep(SA,"outer/brakes_apl_stop.wav",vol,mindist,maxdist,me,"a.bog1");
  1369.                     continue;
  1370.                 }//if
  1371.                 else Sleep(0.4);
  1372.                 stopping = false;
  1373.             }//else
  1374.         }//while
  1375.         if(braking)
  1376.         {
  1377.             World.PlaySound(SA,"outer/brakes_apl_stop.wav",vol,mindist,maxdist,me,"a.bog0");
  1378.             World.PlaySound(SA,"outer/brakes_apl_stop.wav",vol,mindist,maxdist,me,"a.bog1");
  1379.         }//if
  1380.         lsd.braking = false;
  1381.     }//Brakes
  1382.    
  1383.     int GetSandingState(void)//0 - off, 1 - full, 2 - lead axle
  1384.     {
  1385.         bool sOn = CD().mainPlusAtm and CD().mainMinusAtm;// and lsd.engineRunning;
  1386.         if(!sOn) return 0;
  1387.         bool c1 = CD().mainPlusAtm and CD().mainMinusAtm and CD().controlAtm and (CD().reverser == 1 or CD().reverser == -1);
  1388.         bool c2 = CD2().mainPlusAtm and CD2().mainMinusAtm and CD2().controlAtm and (CD2().reverser == 1 or CD2().reverser == -1);
  1389.         bool ctrl = (c1 and !c2) or (!c1 and c2);
  1390.         if(!ctrl) return 0;
  1391.         bool sandingSpeed = Math.Fabs(GetVelocity()/Train.KPH_TO_MPS) >= 10.0;
  1392.         if(c1)
  1393.         {
  1394.             int c1ss = ((int)(CD().sanding or (lsd.emergencyBraking and sandingSpeed)))*1 + ((int)CD().sanding1axle)*2;
  1395.             if(c1ss == 3) return 1;
  1396.             else return c1ss;
  1397.         }//if
  1398.         if(c2) return ((int)(CD2().sanding or (lsd.emergencyBraking and sandingSpeed)))*1;
  1399.         return 0;
  1400.     }//GetSandingState
  1401.    
  1402.     void UnsetSandPfx(void)
  1403.     {
  1404.         int i;
  1405.         for(i=0;i<8;i++)
  1406.             SendMessage(me,"pfx","-"+(SANDPFX_INDEX+i));
  1407.     }//UnsetSandPfx
  1408.    
  1409.     void SetSandPfx(int step)
  1410.     {
  1411.         UnsetSandPfx();
  1412.         bool dir = GetDirectionRelativeToTrain();
  1413.         bool rev = (GetEngineSetting("reverser") == Train.TRACTION_FORWARD);
  1414.         bool exhDir = (dir and !rev) or (!dir and rev);
  1415.         int dirOffset = 0;
  1416.         if(exhDir) dirOffset = 2;
  1417.         int i;
  1418.         for(i=0;i<6;i=i+step)
  1419.             PostMessage(me,"pfx","+"+(SANDPFX_INDEX+i+dirOffset)+"+"+(SANDPFX_INDEX+i+dirOffset+1),0.0);
  1420.     }//SetSandPfx
  1421.    
  1422.     public void Sanding(void)
  1423.     {
  1424.         if(GetSandingState() == 0) return;
  1425.         int i;
  1426.         XT10MLocomotive[] scts = sci.GetSections();
  1427.         for(i=0;i<scts.size();i++)
  1428.             scts[i].SandExhaust();
  1429.     }//Sanding
  1430.    
  1431.     thread void SandExhaust(void)
  1432.     {
  1433.         int ss = GetSandingState();
  1434.         if(lsd.sanding or ss == 0 or lsd.sandQueue.GetQueueCount() < 1) return;
  1435.         lsd.sanding = true;
  1436.         float dt,sandG,vol = 1.0,minDist = 10.0,maxDist = 100.0;
  1437.         string att = "a.bog0";
  1438.         PlaySoundAndSleep(SA,"outer/sanding_vr_start.wav",1.0,2.0,5.0,me,att);
  1439.         PlaySoundAndSleep(SA,"outer/sanding_start.wav",vol,minDist,maxDist,me,att);
  1440.         while(ss != 0)
  1441.         {
  1442.             dt = 0.475;
  1443.             World.PlaySound(SA,"outer/sanding_loop.wav",vol,minDist,maxDist,me,att)-0.06;
  1444.             if(ss == 1)
  1445.             {
  1446.                 SetSandPfx(4);
  1447.                 lsd.sandingTM = lsd.sandingEfficiency;
  1448.                 sandG = 0.6;
  1449.             }//if
  1450.             else if(ss == 2)
  1451.             {
  1452.                 SetSandPfx(8);
  1453.                 lsd.sandingTM = 0.4 * lsd.sandingEfficiency;
  1454.                 sandG = 0.3;
  1455.             }//else if
  1456.             lsd.sandConsumed = lsd.sandConsumed + (sandG*dt);
  1457.             Sleep(dt);
  1458.             ss = GetSandingState();
  1459.         }//while
  1460.         World.PlaySound(SA,"outer/sanding_vr_stop.wav",1.0,2.0,5.0,me,att);
  1461.         World.PlaySound(SA,"outer/sanding_stop.wav",vol,minDist,maxDist,me,att);
  1462.         lsd.sanding = false;
  1463.         lsd.sandingTM = 0.0;
  1464.         UnsetSandPfx();
  1465.     }//SandExhaust
  1466.    
  1467.     thread void Typhoon(void)
  1468.     {
  1469.         if(lsd.typhoon or sd.c.horn != 1)
  1470.             return;
  1471.         lsd.typhoon = true;
  1472.         PlaySoundAndSleep(SA,"outer/typhoon_start.wav",1.0,20.0,900.0,me,"a.horn");
  1473.         while(sd.c.horn == 1)
  1474.             PlaySoundAndSleep(SA,"outer/typhoon_loop.wav",1.0,20.0,900.0,me,"a.horn");
  1475.         lsd.typhoon = false;
  1476.         World.PlaySound(SA,"outer/typhoon_stop.wav",1.0,20.0,900.0,me,"a.horn");
  1477.     }
  1478.    
  1479.     thread void Whistle(void)
  1480.     {
  1481.         if(lsd.whistle or sd.c.horn != -1)
  1482.             return;
  1483.         lsd.whistle = true;
  1484.         PlaySoundAndSleep(SA,"outer/whistle_start.wav",1.0,20.0,900.0,me,"a.horn");
  1485.         while(sd.c.horn == -1)
  1486.             PlaySoundAndSleep(SA,"outer/whistle_loop.wav",1.0,20.0,900.0,me,"a.horn");
  1487.         lsd.whistle = false;
  1488.         World.PlaySound(SA,"outer/whistle_stop.wav",1.0,20.0,900.0,me,"a.horn");
  1489.     }
  1490.    
  1491.     public void Horn(void)
  1492.     {
  1493.         if(sd.c.horn == 1 and !lsd.typhoon)
  1494.             Typhoon();
  1495.         else if(sd.c.horn == -1 and !lsd.whistle)
  1496.             Whistle();
  1497.     }
  1498.    
  1499.     public bool LocoControl(void)
  1500.     {
  1501.         bool lc1 = IsControl();
  1502.         bool lc2 = sci.s2!=null and sci.s2.IsControl();
  1503.         bool lc3 = sci.s3!=null and sci.s3.IsControl();
  1504.         bool lc4 = sci.s4!=null and sci.s4.IsControl();
  1505.         return (lc1 and !lc2 and !lc3 and !lc4)
  1506.          or (!lc1 and lc2 and !lc3 and !lc4)
  1507.          or (!lc1 and !lc2 and lc3 and !lc4)
  1508.          or (!lc1 and !lc2 and !lc3 and lc4);
  1509.     }//LocoControl
  1510.    
  1511.     public bool IsControl(void)
  1512.     {
  1513.         return CD().mainPlusAtm and CD().mainMinusAtm and CD().controlAtm and !CD().brakeBlock and CD().locoControl and CD().epvKey;
  1514.     }//IsControl
  1515.    
  1516.     public bool IsIdle(void)
  1517.     {
  1518.         XT10MCabinData cd = sci.GetTranslatedCabinData(2);
  1519.         bool cdi = cd.mainPlusAtm and cd.mainMinusAtm and cd.controlAtm and cd.locoControl and cd.idle;
  1520.         if(cdi) return true;
  1521.         return false;
  1522.     }//IsIdle
  1523.    
  1524.     void InitSystemData(void)
  1525.     {
  1526.         sd.l = sd.l;
  1527.         sd.c = sd.c;
  1528.         sd.l2 = new XT10MLocomotiveData();
  1529.         if(sci.GetSection(2)!=null) sd.l2 = sci.GetSection(2).sd.l;
  1530.     }//InitSystemData
  1531.    
  1532.     void ATMMessageForward(Message msg)
  1533.     {
  1534.         string minor = msg.minor;
  1535.         if(Str.UnpackString(minor) != "Frw")
  1536.             return;
  1537.         int dstCrd = Str.UnpackInt(minor);
  1538.         string function = Str.UnpackString(minor);
  1539.        
  1540.         XT10MLocomotive dstLoco = sci.GetSection(dstCrd);
  1541.         if(dstLoco != null) PostMessage(dstLoco,"T10MAutomates-298469",function,0.0);
  1542.     }//ATMMessageForward
  1543.    
  1544.     void T10MHandler(Message msg)
  1545.     {
  1546.         if(msg.minor == "EmergencyStop")
  1547.         {
  1548.             PostMessage(me,"T10MAutomates-298469","FuelPumpCircuitReset",0.0);
  1549.             PostMessage(me,"T10MAutomates-298469","Frw 2 FuelPumpCircuitReset",0.0);
  1550.             return;
  1551.         }//if
  1552.     }//T10MHandler
  1553.    
  1554.     void CommonHandler(Message msg)
  1555.     {
  1556.         if(msg.major == "Vehicle" and (msg.minor == "Coupled" or msg.minor == "Decoupled"))
  1557.         {
  1558.             sci.ReCoordinate();
  1559.             InitSystemData();
  1560.             SetCoupler(GetMyPosition(),GetDirectionRelativeToTrain());
  1561.             return;
  1562.         }//if
  1563.        
  1564.         if(msg.major == "Vehicle" and msg.minor == "Derailed")
  1565.         {
  1566.             fail = true;
  1567.             PostMessage(me,"T10M-298469","Failed",0.0);
  1568.         }//if
  1569.     }//CommonHandler
  1570.    
  1571.     public void Init(Asset p_asset)
  1572.     {
  1573.         A = p_asset;
  1574.         inherited(p_asset);
  1575.        
  1576.         SA = A.FindAsset("sound-library");
  1577.        
  1578.         SA3_coupled        = A.FindAsset("SA3-coupled");
  1579.         SA3_decoupled    = A.FindAsset("SA3-uncoupled");
  1580.         //SetCouplerAttach(0,false);
  1581.         //SetCouplerAttach(1,false);
  1582.        
  1583.         Soup vs = A.GetConfigSoup().GetNamedSoup("extensions").GetNamedSoup("sound-vol-setup-298469");
  1584.         uvk_compressor = vs.GetNamedTagAsFloat("compressor");
  1585.         uvk_fan = vs.GetNamedTagAsFloat("fan");
  1586.         uvk_engine = vs.GetNamedTagAsFloat("engine");
  1587.         uvk_brakes = vs.GetNamedTagAsFloat("brakes");
  1588.         uvk_horn = vs.GetNamedTagAsFloat("horn");
  1589.         P(uvk_compressor);
  1590.        
  1591.         lsd = new LocomotiveSystemData();
  1592.        
  1593.         sd = new XT10MSystemData();
  1594.         sd.Init();
  1595.        
  1596.         sci = new SCI_2Sections();
  1597.         sci.Init(me);
  1598.        
  1599.         lsd.fuelQueue = GetQueue("fuel");
  1600.         lsd.sandQueue = GetQueue("sand");
  1601.        
  1602.         wavdb = Constructors.NewSoup();
  1603.         wavdb.SetNamedTag("engine/starter_oilpump_start.wav", 1.095);
  1604.         wavdb.SetNamedTag("engine/starter_oilpump_stop.wav", 1.488);
  1605.         wavdb.SetNamedTag("engine/starter_oilpump_loop.wav", 3.142);
  1606.         wavdb.SetNamedTag("engine/starter_starting.wav", 13.067);
  1607.         wavdb.SetNamedTag("engine/stop.wav", 18.708);
  1608.         wavdb.SetNamedTag("engine/turbo_start.wav", 4.068);
  1609.         wavdb.SetNamedTag("engine/turbo_stop.wav", 4.068);
  1610.         wavdb.SetNamedTag("engine/turbo0x.wav", 4.629);
  1611.         wavdb.SetNamedTag("engine/turbo1x.wav", 4.482);
  1612.         wavdb.SetNamedTag("engine/turbo2x.wav", 4.290);
  1613.         wavdb.SetNamedTag("engine/turbo3x.wav", 4.134);
  1614.         wavdb.SetNamedTag("engine/turbo4x.wav", 3.996);
  1615.         wavdb.SetNamedTag("engine/turbo5x.wav", 3.799);
  1616.         wavdb.SetNamedTag("engine/turbo6x.wav", 3.710);
  1617.         wavdb.SetNamedTag("engine/turbo7x.wav", 3.567);
  1618.         wavdb.SetNamedTag("engine/turbo8x.wav", 3.415);
  1619.         wavdb.SetNamedTag("engine/turbo9x.wav", 3.299);
  1620.         wavdb.SetNamedTag("engine/turbo10x.wav", 3.170);
  1621.         wavdb.SetNamedTag("engine/0-1.wav", 3.553);
  1622.         wavdb.SetNamedTag("engine/0.wav", 4.558);
  1623.         wavdb.SetNamedTag("engine/1-0.wav", 3.553);
  1624.         wavdb.SetNamedTag("engine/1-2.wav", 4.572);
  1625.         wavdb.SetNamedTag("engine/1.wav", 2.975);
  1626.         wavdb.SetNamedTag("engine/2-1.wav", 4.572);
  1627.         wavdb.SetNamedTag("engine/2-3.wav", 8.802);
  1628.         wavdb.SetNamedTag("engine/2.wav", 3.673);
  1629.         wavdb.SetNamedTag("engine/3-2.wav", 8.802);
  1630.         wavdb.SetNamedTag("engine/3-4.wav", 8.923);
  1631.         wavdb.SetNamedTag("engine/3.wav", 5.721);
  1632.         wavdb.SetNamedTag("engine/4-3.wav", 8.923);
  1633.         wavdb.SetNamedTag("engine/4-5.wav", 3.170);
  1634.         wavdb.SetNamedTag("engine/4.wav", 5.672);
  1635.         wavdb.SetNamedTag("engine/5-4.wav", 7.199);
  1636.         wavdb.SetNamedTag("engine/5-6.wav", 6.080);
  1637.         wavdb.SetNamedTag("engine/5.wav", 8.158);
  1638.         wavdb.SetNamedTag("engine/6-5.wav", 6.080);
  1639.         wavdb.SetNamedTag("engine/6-7.wav", 6.597);
  1640.         wavdb.SetNamedTag("engine/6.wav", 5.069);
  1641.         wavdb.SetNamedTag("engine/7-6.wav", 6.597);
  1642.         wavdb.SetNamedTag("engine/7-8.wav", 7.148);
  1643.         wavdb.SetNamedTag("engine/7.wav", 6.868);
  1644.         wavdb.SetNamedTag("engine/8-7.wav", 7.148);
  1645.         wavdb.SetNamedTag("engine/8-9.wav", 6.125);
  1646.         wavdb.SetNamedTag("engine/8.wav", 7.512);
  1647.         wavdb.SetNamedTag("engine/9-8.wav", 6.125);
  1648.         wavdb.SetNamedTag("engine/9-10.wav", 6.072);
  1649.         wavdb.SetNamedTag("engine/9.wav", 6.282);
  1650.         wavdb.SetNamedTag("engine/10-9.wav", 6.072);
  1651.         wavdb.SetNamedTag("engine/10-11.wav", 6.382);
  1652.         wavdb.SetNamedTag("engine/10.wav", 6.364);
  1653.         wavdb.SetNamedTag("engine/11-10.wav", 6.382);
  1654.         wavdb.SetNamedTag("engine/11-12.wav", 6.086);
  1655.         wavdb.SetNamedTag("engine/11.wav", 6.595);
  1656.         wavdb.SetNamedTag("engine/12-11.wav", 6.086);
  1657.         wavdb.SetNamedTag("engine/12-13.wav", 5.504);
  1658.         wavdb.SetNamedTag("engine/12.wav", 2.667);
  1659.         wavdb.SetNamedTag("engine/13-12.wav", 5.504);
  1660.         wavdb.SetNamedTag("engine/13-14.wav", 4.847);
  1661.         wavdb.SetNamedTag("engine/13.wav", 3.980);
  1662.         wavdb.SetNamedTag("engine/14-13.wav", 4.847);
  1663.         wavdb.SetNamedTag("engine/14-15.wav", 6.006);
  1664.         wavdb.SetNamedTag("engine/14.wav", 2.476);
  1665.         wavdb.SetNamedTag("engine/15-14.wav", 6.006);
  1666.         wavdb.SetNamedTag("engine/15.wav", 3.287);
  1667.         wavdb.SetNamedTag("equipment/compressor_start.wav", 0.992);
  1668.         wavdb.SetNamedTag("equipment/compressor_stop.wav", 0.627);
  1669.         wavdb.SetNamedTag("equipment/compressor_loop.wav", 1.435);
  1670.         wavdb.SetNamedTag("equipment/fan_start.wav", 4.373);
  1671.         wavdb.SetNamedTag("equipment/fan_loop.wav", 3.866);
  1672.         wavdb.SetNamedTag("outer/sanding_vr_start.wav", 0.246);
  1673.         wavdb.SetNamedTag("outer/sanding_start.wav", 0.025);
  1674.         wavdb.SetNamedTag("outer/typhoon_start.wav", 0.757);
  1675.         wavdb.SetNamedTag("outer/typhoon_loop.wav", 1.094);
  1676.         wavdb.SetNamedTag("outer/whistle_start.wav", 0.235);
  1677.         wavdb.SetNamedTag("outer/whistle_loop.wav", 0.583);
  1678.         wavdb.SetNamedTag("outer/brakes_apl_start.wav", 0.287);
  1679.         wavdb.SetNamedTag("outer/brakes_apl_loop.wav", 0.730);
  1680.         wavdb.SetNamedTag("outer/brakes_apl_loop.wav", 0.264);
  1681.        
  1682.        
  1683.         SetMyData();
  1684.         Main();
  1685.        
  1686.         //Initial setup
  1687.         AddHandler(me,"Vehicle","Coupled","CommonHandler");
  1688.         AddHandler(me,"Vehicle","Decoupled","CommonHandler");
  1689.         AddHandler(me,"T10MAutomates-298469","","ATMMessageForward");
  1690.         AddHandler(me,"T10M-298469","","T10MHandler");
  1691.         AddHandler(me,"Vehicle","Derailed","CommonHandler");
  1692.         AddHandler(me,"MapObject","View-Details","CommonHandler");
  1693.     }//Init
  1694.    
  1695.     thread void SendMessage(GameObject dst,string major,string minor,float delay)
  1696.     {
  1697.         Sleep(Math.Fmax(0.0,delay-0.005));
  1698.         SendMessage(dst,major,minor);
  1699.     }//SendMessage
  1700.    
  1701.     public XT10MCabinData CD(void)
  1702.     {
  1703.         return sd.c;
  1704.     }//CD
  1705.    
  1706.     public XT10MCabinData CD2(void)
  1707.     {
  1708.         return sci.GetSystemData(2).c;
  1709.     }//CD2
  1710.    
  1711.     public void SetMyData(void)
  1712.     {
  1713.         //if overload, do not forget to call inherited() before all changes (-;
  1714.         MD = Constructors.NewSoup();
  1715.        
  1716.         //param = param * (base + random(-delta,delta))
  1717.         MD.SetNamedTag("trm_random_parameters_mod_base",1.0);
  1718.         MD.SetNamedTag("trm_random_parameters_mod_delta",0.1);
  1719.         //tempInd = tempFact + (base + random(-delta,delta))
  1720.         MD.SetNamedTag("trm_random_termometer_mod_base",0.0);
  1721.         MD.SetNamedTag("trm_random_termometer_mod_delta",12.0);
  1722.         //temp = Te or temp = t + random(-delta,delta)
  1723.         MD.SetNamedTag("trm_start_temperature_d","Te");
  1724.         MD.SetNamedTag("trm_start_temperature_w1","Te");
  1725.         MD.SetNamedTag("trm_start_temperature_w2","Te");
  1726.         MD.SetNamedTag("trm_start_temperature_o","Te");
  1727.         MD.SetNamedTag("trm_start_temperature_to","Te");
  1728.         MD.SetNamedTag("trm_start_temperature_d_delta",12.0);
  1729.         MD.SetNamedTag("trm_start_temperature_w1_delta",12.0);
  1730.         MD.SetNamedTag("trm_start_temperature_w2_delta",12.0);
  1731.         MD.SetNamedTag("trm_start_temperature_o_delta",12.0);
  1732.         MD.SetNamedTag("trm_start_temperature_to_delta",12.0);
  1733.         /*engvol {
  1734.             ev0                "0.3,0.4,0.3,0.4,0.4,0.7,0.8,0.4,0.6,0.7,0.6,0.7,0.4,0.3,0.4,0.5"
  1735.             ev1                "0.3,0.4,0.3,0.4,0.4,0.7,0.8,0.4,0.6,0.7,0.6,0.7,0.4,0.3,0.4,0.5"
  1736.             ev2                "0.3,0.4,0.3,0.4,0.4,0.7,0.8,0.4,0.6,0.7,0.6,0.7,0.4,0.3,0.4,0.5"
  1737.         }*/
  1738.         MD.SetNamedTag("trm_qn",27940000.0);
  1739.         MD.SetNamedTag("trm_kd",0.000000103);
  1740.         MD.SetNamedTag("trm_kw1",0.00000035);
  1741.         MD.SetNamedTag("trm_kw1c",0.00000057);
  1742.         MD.SetNamedTag("trm_kw2",0.00000076);
  1743.         MD.SetNamedTag("trm_kw2c",0.0000057);
  1744.         MD.SetNamedTag("trm_ko",0.0000004);
  1745.         MD.SetNamedTag("trm_koc",0.000018);
  1746.         MD.SetNamedTag("trm_temin",18);
  1747.         MD.SetNamedTag("trm_temax",32);
  1748.         MD.SetNamedTag("trm_tmin",0.75);
  1749.         MD.SetNamedTag("trm_tmax",0.08);
  1750.         MD.SetNamedTag("trm_kto",33460);
  1751.         MD.SetNamedTag("trm_kcto",0.00003);
  1752.         MD.SetNamedTag("trm_khw",117850);
  1753.         MD.SetNamedTag("trm_kho",38000);
  1754.         MD.SetNamedTag("trm_kcevmin",0.6);
  1755.         MD.SetNamedTag("trm_kcev",-0.005);
  1756.         MD.SetNamedTag("trm_bcev",1);
  1757.         MD.SetNamedTag("trm_kfetmin",0.4);
  1758.         MD.SetNamedTag("trm_kfetoff",0.0085);
  1759.         MD.SetNamedTag("trm_kfet",0.075);
  1760.         MD.SetNamedTag("trm_bfet",-5.15);
  1761.         MD.SetNamedTag("trm_kfenmin",0);
  1762.         MD.SetNamedTag("trm_kfen",0.00125);
  1763.         MD.SetNamedTag("trm_bfen",-0.0625);
  1764.         MD.SetNamedTag("trm_kc0",3500);
  1765.         MD.SetNamedTag("trm_kc",40489);
  1766.         MD.SetNamedTag("trm_kts",0.2);
  1767.         MD.SetNamedTag("trm_kss",0.3);
  1768.         MD.SetNamedTag("trm_ktsf",0.3);
  1769.         MD.SetNamedTag("trm_kf",0.4);
  1770.     }//SetMyData
  1771.    
  1772.     public int GetMyPosition(void)
  1773.     {
  1774.         Vehicle[]    vhs;
  1775.        
  1776.         vhs = GetMyTrain().GetVehicles();
  1777.        
  1778.         //only i
  1779.         if (vhs.size() == 1) return 0;
  1780.        
  1781.         //i'm first
  1782.         else if (me == vhs[0]) return 1;
  1783.        
  1784.         //i,m last
  1785.         else if (me == vhs[vhs.size()-1]) return 3;
  1786.        
  1787.         //i'm somewhere in the consist
  1788.         return 2;
  1789.     }
  1790.    
  1791.     void SetCouplerAttach(int pos, bool type)
  1792.     {
  1793.         if (pos == 0)
  1794.         {
  1795.             if (type == true) SetFXAttachment ("front_couple", SA3_coupled);
  1796.             else SetFXAttachment ("front_couple", SA3_decoupled);
  1797.         }
  1798.         else
  1799.         {
  1800.             if (type == true) SetFXAttachment ("back_couple", SA3_coupled);
  1801.             else SetFXAttachment ("back_couple", SA3_decoupled);
  1802.         }
  1803.     }
  1804.    
  1805.     void SetCoupler(int pos, bool direction)
  1806.     {
  1807.         if (pos == 0)
  1808.         {
  1809.             SetCouplerAttach(0,false);
  1810.             SetCouplerAttach(1,false);
  1811.         }
  1812.         else if (pos == 1)
  1813.         {
  1814.             if (direction)
  1815.             {
  1816.                 SetCouplerAttach(0,false);
  1817.                 SetCouplerAttach(1,true);
  1818.             }
  1819.             else
  1820.             {
  1821.                 SetCouplerAttach(0,true);
  1822.                 SetCouplerAttach(1,false);
  1823.             }
  1824.         }
  1825.         else if (pos == 2)
  1826.         {
  1827.             SetCouplerAttach(0,true);
  1828.             SetCouplerAttach(1,true);
  1829.         }
  1830.         else if (pos == 3)
  1831.         {
  1832.             if (direction)
  1833.             {
  1834.                 SetCouplerAttach(0,true);
  1835.                 SetCouplerAttach(1,false);
  1836.             }
  1837.             else
  1838.             {
  1839.                 SetCouplerAttach(0,false);
  1840.                 SetCouplerAttach(1,true);
  1841.             }            
  1842.         }
  1843.     }
  1844.    
  1845.     public float GetPressureParam(string param)
  1846.     {
  1847.         float pressureMultiplier = 1.0 / (0.145 * 0.0000703);
  1848.         float pressureBase = 14.7 * 0.0000703;
  1849.         return pressureMultiplier * (GetEngineParam(param) - pressureBase);
  1850.     }
  1851.     public float GetPressureParam(float val)
  1852.     {
  1853.         float pressureMultiplier = 1.0 / (0.145 * 0.0000703);
  1854.         float pressureBase = 14.7 * 0.0000703;
  1855.  
  1856.         return pressureMultiplier * (val - pressureBase);
  1857.     }
  1858.     public float GetPressureParam(Vehicle vh,string param)
  1859.     {
  1860.         float pressureMultiplier = 1.0 / (0.145 * 0.0000703);
  1861.         float pressureBase = 14.7 * 0.0000703;
  1862.         return pressureMultiplier * (vh.GetEngineParam(param) - pressureBase);
  1863.     }
  1864. };//class XT10MLocomotive
  1865.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement