Advertisement
agmike

Код лока в RTS

Aug 26th, 2014
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 42.07 KB | None | 0 0
  1. //---------------------------------------------------------------------------
  2.  
  3. #include <windows.h>
  4. #include <math>
  5. #include "ts.h"
  6.  
  7. #define BRAKE_STR_RATE 1.8
  8. #define TR_CURRENT_C 272.0
  9. #define BRAKE_MR_RATIO    0.005
  10. #define BRAKE_PIPE_RATE_CHARGE 2.5
  11. #define BRAKE_UR_RATE_CHARGE   0.3
  12. #define BRAKE_PIPE_RATE 0.4
  13. #define BRAKE_PIPE_EMERGENCY -1.2
  14. #define PIPE_DISCHARGE_SLOW -0.005
  15. #define UR_DISCHARGE2     0.003
  16.  
  17. #define BATTERY_DEADLINE 9.7
  18.  
  19. #pragma argsused
  20.  
  21. int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
  22. {
  23.         return 1;
  24. }
  25. //---------------------------------------------------------------------------
  26.  
  27.  
  28. FreeAnimation *FindAnim(Cabin *cab,wchar_t *name){
  29.  for(UINT i=0;i<cab->NumAnim;i++)
  30.   if(!lstrcmpiW(name,cab->Anims[i].name))
  31.    return &cab->Anims[i];
  32.  return NULL;
  33. };
  34.  
  35. FreeAnimation *FindAnim(const Locomotive *loco,wchar_t *name){
  36.  for(USHORT i=0;i<loco->NumAnim;i++)
  37.   if(!lstrcmpiW(name,loco->Anims[i].name))
  38.    return &loco->Anims[i];
  39.  return NULL;
  40. };
  41.  
  42.  
  43. //---------------------------------------------------------------------------
  44.  
  45.  
  46.  
  47. bool IsHP(UINT Position){
  48.  if(
  49.   Position==0||Position%4==1
  50.  )
  51.   return true;
  52.  return false;
  53. };
  54.  
  55. UINT IsLocoOn(ElectricEngine *eng,Cabin *cab){
  56.  UINT LocoOn=0;
  57.  if(eng->var[10]<BATTERY_DEADLINE)
  58.   return 0;
  59.  if(!cab->SwitchSub(0,0))
  60.   LocoOn|=1;
  61.  if(!cab->SwitchSub(0,2))
  62.   LocoOn|=2;
  63.  if(!cab->SwitchSub(0,1))
  64.   LocoOn|=4;
  65.  if(cab->Switch(18))
  66.   LocoOn|=8;
  67.  if(cab->Switch(14))
  68.   LocoOn|=16;
  69.  return LocoOn;
  70. };
  71.  
  72. inline float ComputeForce(UINT &Throttle,float &VelMax,float &diff){
  73.  float q=0.0,d=0.0;
  74.  /*switch(Throttle){
  75.   case 1:q=295000.0;d=-65000;break;
  76.   case 2:q=455000.0;d=-80000;break;
  77.   case 3:q=535000.0;d=-80000;break;
  78.   case 4:q=540500.0;d=-70000;break;
  79.   case 5:q=580000.0;d=-65000;break;
  80.   case 6:q=630000.0;d=-65000;break;
  81.   case 7:q=755000.0;d=-65000;break;
  82.   case 8:q=835000.0;d=-75000;break;
  83.   case 9:q=900000.0;d=-75000;break;
  84.   case 10:q=942000.0;d=-75000;break;
  85.   case 11:q=1024000.0;d=-80000;break;
  86.   case 12:q=1100000.0;d=-85000;break;
  87.   case 13:q=1115000.0;d=-85000;break;
  88.   case 14:q=1100000.0;d=-85000;break;
  89.   case 15:q=1100000.0;d=-85000;break;
  90.   case 16:q=1125000.0;d=-85000;break;
  91.   case 17:q=1125000.0;d=-75000;break;
  92.   case 18:q=1125000.0;d=-65000;break;
  93.   case 19:q=1100000.0;d=-50025;break;
  94.   case 20:q=1100000.0;d=-50000;break;
  95.   case 21:q=1100000.0;d=-45000;break;
  96.   case 22:q=1100000.0;d=-40000;break;
  97.   case 23:q=1100000.0;d=-37500;break;
  98.   case 24:q=1100000.0;d=-35000;break;
  99.   case 25:q=1100000.0;d=-33750;break;
  100.   case 26:q=1100000.0;d=-32500;break;
  101.   case 27:q=1100000.0;d=-32500;break;
  102.   case 28:q=1100000.0;d=-32500;break;
  103.   case 29:q=1100000.0;d=-32500;break;
  104.   case 30:q=1100000.0;d=-30000;break;
  105.   case 31:q=1100000.0;d=-27500;break;
  106.   case 32:q=1100000.0;d=-25000;break;
  107.   case 33:q=1150000.0;d=-22500;break;
  108.  };*/
  109.  if(VelMax<1.0)
  110.   q=100000.0/VelMax;
  111.  else
  112.   q=100000.0/(VelMax*VelMax);
  113.  if(q<0.0)q=0.0;
  114.  
  115.  return q;
  116. };
  117.  
  118.  
  119. void SwitchGV(const ElectricLocomotive *loco,ElectricEngine *eng,UINT State){
  120.  FreeAnimation *anim;
  121.  if(!loco||!eng)
  122.   return;
  123.  if(eng->MainSwitch==(unsigned char)State)
  124.   return;
  125.  //UINT *Flags=(UINT *)&eng->var[0];
  126.  //UINT *BackSecFlags=NULL;
  127.  //if(loco->NumSlaves)
  128.   //BackSecFlags=(UINT *)&loco->Slaves[0]->locoA->var[0];
  129.  
  130.  if(eng->MainSwitch!=signed(State))
  131.   if(loco->Flags&4)
  132.    if(eng->sound)
  133.     eng->sound->PostTrigger(103);
  134.  eng->MainSwitch=State;
  135.  
  136.  anim=FindAnim(loco,L"GV");
  137.  if(anim)
  138.   anim->AnimateTo=State;
  139. };
  140.  
  141. void SwitchLights(const Locomotive *loco,int Condition){
  142.  switch(Condition){
  143.   case 20:
  144.    loco->SwitchLight(0,false,0.0,0);
  145.    loco->SwitchLight(1,false,0.0,0);
  146.    loco->SwitchLight(2,false,0.0,0);
  147.    loco->SwitchLight(3,false,0.0,0);
  148.    loco->SwitchLight(4,false,0.0,0);
  149.    loco->SwitchLight(5,false,0.0,0);
  150.    loco->SwitchLight(6,false,0.0,0);
  151.    loco->SwitchLight(7,false,0.0,0);
  152.   break;
  153.   case 0:
  154.    loco->SwitchLight(0,false,0.0,0);
  155.    loco->SwitchLight(1,false,0.0,0);
  156.    loco->SwitchLight(6,false,0.0,0);
  157.    loco->SwitchLight(7,false,0.0,0);
  158.    /*
  159.    loco->lights[0].Flags&=~8;
  160.    loco->lights[1].Flags&=~8;
  161.    loco->lights[2].Flags&=~8;
  162.    loco->lights[3].Flags&=~8;
  163.    loco->lights[4].Flags&=~8;
  164.    loco->lights[5].Flags&=~8;
  165.    loco->lights[6].Flags&=~8;
  166.    loco->lights[7].Flags&=~8;
  167.    */
  168.   break;
  169.   case 1:
  170.    loco->SwitchLight(0,true,0.0,0);
  171.    loco->SwitchLight(1,false,0.0,0);
  172.    loco->SwitchLight(6,true,0.0,0);
  173.    loco->SwitchLight(7,false,0.0,0);
  174.    /*
  175.    loco->lights[0].Flags|=8;
  176.    loco->lights[1].Flags&=~8;
  177.    loco->lights[2].Flags|=8;
  178.    loco->lights[3].Flags|=8;
  179.    loco->lights[4].Flags&=~8;
  180.    loco->lights[5].Flags&=~8;
  181.    loco->lights[6].Flags|=8;
  182.    loco->lights[7].Flags&=~8;
  183.    */
  184.   break;
  185.   case 2:
  186.    loco->SwitchLight(0,false,0.0,0);
  187.    loco->SwitchLight(1,true,0.0,0);
  188.    loco->SwitchLight(6,false,0.0,0);
  189.    loco->SwitchLight(7,true,0.0,0);
  190.    /*
  191.    loco->lights[0].Flags&=~8;
  192.    loco->lights[1].Flags|=8;
  193.    loco->lights[2].Flags&=~8;
  194.    loco->lights[3].Flags&=~8;
  195.    loco->lights[4].Flags|=8;
  196.    loco->lights[5].Flags|=8;
  197.    loco->lights[6].Flags&=~8;
  198.    loco->lights[7].Flags|=8;
  199.    */
  200.   break;
  201.   case 3:
  202.    loco->SwitchLight(14,true,0.0,0);
  203.    //loco->lights[14].Flags|=8;
  204.   break;
  205.   case 4:
  206.    loco->SwitchLight(14,false,0.0,0);
  207.    //loco->lights[14].Flags&=~8;
  208.   break;
  209.   //Left
  210.   case 5:
  211.    loco->SwitchLight(2,true,0.0,0xffffae5f);
  212.   break;
  213.   case 6:
  214.    loco->SwitchLight(2,true,0.0,0xf0ff0000);
  215.   break;
  216.   case 7:
  217.    loco->SwitchLight(2,false,0.0,0);
  218.   break;
  219.   //Right
  220.   case 8:
  221.    loco->SwitchLight(3,true,0.0,0xffffae5f);
  222.   break;
  223.   case 9:
  224.    loco->SwitchLight(3,true,0.0,0xf0ff0000);
  225.   break;
  226.   case 10:
  227.    loco->SwitchLight(3,false,0.0,0);
  228.   break;
  229.  };
  230. };
  231.  
  232. /*
  233.  
  234.  Stack Variables
  235.  
  236.  1 - unsigned long Flags
  237.   1bite
  238.    1bit - is on PP
  239.    2bit - Compressor On
  240.    3bit - protection incurred
  241.    4bit - MV1
  242.    5bit - MV2
  243.    6bit - Compressor enabled(for slave section)
  244.    7bit - enable train pipe pressure maintenance
  245.    8bit - battery charging
  246.  
  247.   2bite
  248.    1bit - brake applied(SMS)
  249.    2bit - MV stream started
  250.    3bit - Sanding
  251.    4bit - battery down
  252.    5bit - RZ
  253.    6bit - enable radiostation on start
  254.  
  255.  
  256.  
  257.  2 - throttle switch counter
  258.  
  259.  3 - [VACANT]
  260.  
  261.  4 - main timer
  262.  
  263.  5 - Sanding timer
  264.  
  265.  6 - EPK Timer
  266.  
  267.  7 - Previous Signal Aspect
  268.  
  269.  8 - EPK State
  270.  
  271.  9 - EPK Timer2(blinkers)
  272.  
  273.  10 - Battery Charge
  274.  
  275.  11 - Battery Charging Rate
  276.  
  277.  12 - previous force
  278.  
  279.  13 - previous line voltage
  280.  
  281.  14 - RZ timer
  282.  
  283.  15 - Wheelslip blinker timer
  284.  
  285.  Sound Triggers
  286.  
  287.  4,5 - sander on/off
  288.  14 - brake applied
  289.  54 - brake released
  290.  45 - MV1 start
  291.  46 - MV1 release
  292.  56,57 - EPK sound on,off
  293.  101 - Compressor start
  294.  102 - Compressor release
  295.  103 - GV
  296.  104 - radio on
  297.  105 - radio off
  298.  106 - EPK reset
  299.  
  300.  
  301. */
  302.  
  303.  
  304. extern "C" bool __export Init
  305.  (ElectricEngine *eng,ElectricLocomotive *loco,unsigned long State,
  306.         float time,float AirTemperature)
  307. {
  308.  UINT *Flags=(UINT *)&eng->var[0];
  309.  Cabin *cab=eng->cab;
  310.  loco->HandbrakeValue=0.0;
  311.  eng->HandbrakePercent=0;
  312.  eng->DynamicBrakePercent=0;
  313.  eng->Sanding=0;
  314.  eng->BrakeSystemsEngaged=1;
  315.  eng->BrakeForce=0.0;
  316.  eng->var[0]=0;
  317.  eng->var[1]=0;
  318.  eng->ChargingRate=0;
  319.  eng->TrainPipeRate=0;
  320.  eng->var[3]=GetTickCount();
  321.  eng->var[4]=0.0;
  322.  eng->AuxilaryRate=0.0;
  323.  eng->var[5]=0.0;
  324.  eng->var[6]=0.0;
  325.  eng->var[7]=0.0;
  326.  eng->var[10]=40.0;
  327.  eng->var[12]=0.0;
  328.  eng->var[13]=0.0;
  329.  switch(State&0xFF){
  330.   case 0:
  331.    //Loco is static, without wagons
  332.    loco->MainResPressure=3.0;
  333.    if(!((State>>8)&1)){
  334.     cab->Switches[3].SetState=1;
  335.     cab->Switches[3].State=1;
  336.    }else{
  337.     loco->LocoFlags|=1;
  338.    };
  339.    loco->TrainPipePressure=4.0;
  340.    loco->AuxiliaryPressure=5.2;
  341.    eng->UR=4.0;
  342.    eng->Power=0;
  343.    eng->Force=0;
  344.    loco->BrakeCylinderPressure=2.0;
  345.    eng->IndependentBrakeValue=4.0;
  346.    eng->TrainPipeRate=0.0;
  347.    eng->ThrottlePosition=0;
  348.    eng->Reverse=0;
  349.    eng->ALSNOn=0;
  350.    eng->MainSwitch=0;
  351.    eng->Panto=0;
  352.   break;
  353.   case 1:
  354.    //Loco is static, with wagons
  355.    if((State>>8)&1){
  356.     loco->LocoFlags|=1;
  357.    };
  358.    cab->SetSwitch(3,2,true);
  359.    cab->SetSwitch(0,0,0,true);
  360.    cab->SetSwitch(0,1,0,true);
  361.    cab->SetSwitch(0,2,0,true);
  362.    loco->MainResPressure=7.0;
  363.    loco->TrainPipePressure=5.0;
  364.    loco->AuxiliaryPressure=5.2;
  365.    eng->UR=4.0;
  366.    eng->Power=0;
  367.    eng->Force=0;
  368.    loco->BrakeCylinderPressure=0.0;
  369.    eng->IndependentBrakeValue=4.0;
  370.    eng->TrainPipeRate=0.0;
  371.    eng->ThrottlePosition=0;
  372.    eng->Reverse=0;
  373.    eng->ALSNOn=0;
  374.    eng->MainSwitch=0;
  375.    eng->Panto=0;
  376.    *Flags|=32<<8;
  377.   break;
  378.   case 2:
  379.   case 3:
  380.    //Loco is moving
  381.    if((State>>8)&1){
  382.     loco->LocoFlags|=1;
  383.     if((loco->Velocity<0.0) ^ (loco->LibParam==1)){
  384.      cab->SetSwitch(1,1,false);
  385.     }else{
  386.      cab->SetSwitch(1,3,false);
  387.     };
  388.    };
  389.    if((loco->Velocity<0.0) ^ (loco->LibParam==1)){
  390.      eng->Reverse=-1;
  391.    }else{
  392.      eng->Reverse=1;
  393.    };
  394.    if(loco->Flags&1)
  395.     eng->Reverse=-eng->Reverse;
  396.  
  397.    cab->SetSwitch(2,1,true);
  398.    cab->SetSwitch(3,1,true);
  399.    cab->SetSwitch(9,1,true);
  400.    cab->SetSwitch(10,1,true);
  401.    cab->SetSwitch(11,1,true);
  402.    cab->SetSwitch(12,1,true);
  403.    cab->SetSwitch(13,1,true);
  404.    cab->SetSwitch(14,1,true);
  405.    cab->SetSwitch(15,1,true);
  406.    cab->SetSwitch(18,1,true);
  407.    cab->SetSwitch(19,1,true);
  408.    cab->SetSwitch(21,1,true);
  409.    cab->SetSwitch(23,1,true);
  410.    cab->SetSwitch(0,0,0,true);
  411.    cab->SetSwitch(0,1,0,true);
  412.    cab->SetSwitch(0,2,0,true);
  413.    loco->MainResPressure=8.5;
  414.    loco->TrainPipePressure=5.2;
  415.    loco->AuxiliaryPressure=5.0;
  416.    eng->UR=5.0;
  417.    eng->Power=0;
  418.    eng->Force=0;
  419.    loco->BrakeCylinderPressure=0.0;
  420.    eng->IndependentBrakeValue=0.0;
  421.    eng->TrainPipeRate=0.0;
  422.    eng->ThrottlePosition=0;
  423.    eng->ALSNOn=0;
  424.    eng->MainSwitch=1;
  425.    eng->Panto=1;
  426.    eng->var[13]=25000.0;
  427.    *Flags|=32<<8;
  428.   break;
  429.  };
  430.  
  431.  return true;
  432.  
  433. };
  434.  
  435. extern "C" void __export  ChangeLoco
  436. (Locomotive *loco,const Locomotive *Prev,unsigned long State)
  437. {
  438.  
  439.  if(!Prev)
  440.   loco->LocoFlags|=1;
  441.  else if(!Prev->locoA->cab->Switch(18)||Prev->locoA->cab->SwitchSub(0,0)||
  442.   Prev->locoA->cab->SwitchSub(0,1)
  443.  ){
  444.   if(!Prev->locoA->cab->Switch(1))
  445.    loco->LocoFlags|=1;
  446.  };
  447.  
  448.  /*if(!(loco->LocoFlags&1)&&loco->locoA->sound){
  449.   ULONG *Flags=(ULONG *)&loco->locoA->var[0];
  450.  
  451.  };*/
  452.  
  453. };
  454.  
  455. extern "C" void __export  LostMaster
  456. (Locomotive *loco,const Locomotive *Prev,unsigned long State)
  457. {
  458.  UINT &Flags=*(UINT *)&loco->locoA->var[0];
  459.  Flags&=~1272;
  460. };
  461.  
  462.  
  463. extern "C" bool __export CanWorkWith(const Locomotive *loco,const wchar_t *Type){
  464.  
  465.  if(!lstrcmpiW(Type,L"vl80k"))
  466.   return true;
  467.  
  468.  return false;
  469. };
  470.  
  471.  
  472. extern "C" bool __export  CanSwitch(const ElectricLocomotive *loco,const ElectricEngine *eng,
  473.         unsigned int SwitchID,unsigned int SetState)
  474. {
  475.  
  476.  switch(SwitchID){
  477.   case 0:
  478.    eng->var[1]=0;
  479.    if(eng->sound)
  480.     eng->sound->PostTrigger(16);
  481.   break;
  482.   case 1:
  483.    UINT *Flags;
  484.    Flags=(UINT *)&eng->var[0];
  485.    if(SetState>3&&((*Flags&1)||!eng->ThrottlePosition))
  486.     return false;
  487.    if(eng->ThrottlePosition&&SetState<3)
  488.     return false;
  489.    if(eng->cab->Switch(0)>1&&SetState<3)
  490.     return false;
  491.    if(eng->sound)
  492.     eng->sound->PostTrigger(15);
  493.   break;
  494.   case 2:
  495.    if(eng->sound)
  496.     eng->sound->PostTrigger(17);
  497.   break;
  498.   case 3:
  499.    if(eng->sound)
  500.     eng->sound->PostTrigger(17);
  501.   break;
  502.   case 7:
  503.    if(SetState&&eng->sound)
  504.     eng->sound->PostTrigger(48);
  505.   break;
  506.   case 42:
  507.    if(SetState&&eng->sound)
  508.     eng->sound->PostTrigger(48);
  509.   break;
  510.  };
  511.  
  512.  if(eng->sound){
  513.   if(SwitchID>7&&SwitchID!=42)
  514.    eng->sound->PostTrigger(26);
  515.  };
  516.  
  517.  return true;
  518.  
  519. };
  520.  
  521.  
  522. extern "C" void __export Switched(const ElectricLocomotive *loco,ElectricEngine *eng,
  523.         unsigned int SwitchID,unsigned int PrevState)
  524. {
  525.  
  526.  ElectricLocomotive *BackSec=NULL;
  527.  if(loco->NumSlaves)
  528.   BackSec=(ElectricLocomotive *)loco->Slaves[0];
  529.  UINT *Flags=(UINT *)&eng->var[0],*BackSecFlags;
  530.  if(BackSec)
  531.   BackSecFlags=(UINT *)&BackSec->loco->var[0];
  532.  FreeAnimation *anim;
  533.  UINT iv,LocoOn=IsLocoOn(eng,eng->cab);
  534.  
  535.  if(SwitchID==28)
  536.   SwitchID=6;
  537.  else if(SwitchID==29)
  538.   SwitchID=5;
  539.  else if(SwitchID==32)
  540.   SwitchID=27;
  541.  else if(SwitchID==34)
  542.   SwitchID=25;
  543.  else if(SwitchID==39)
  544.   SwitchID=35;
  545.  else if(SwitchID==40)
  546.   SwitchID=36;
  547.  else if(SwitchID==42)
  548.   SwitchID=7;
  549.  
  550.  
  551.  switch(SwitchID){
  552.   case 0:
  553.    if(!(loco->LocoFlags&1))
  554.     break;
  555.    if((LocoOn&13)!=13)
  556.     break;
  557.    if(eng->cab->Switches[1].State>3)
  558.     break;
  559.    if(eng->cab->Switches[0].State<3){
  560.     eng->var[1]=GetTickCount();
  561.    }else if(eng->cab->Switches[0].State==3){
  562.     eng->var[1]=0;
  563.     if(PrevState==4&&eng->ThrottlePosition){
  564.      eng->ThrottlePosition--;
  565.     };
  566.    }else if(eng->cab->Switches[0].State==6){
  567.     eng->var[1]=0;
  568.     if(PrevState==5&&eng->ThrottlePosition<33){
  569.      eng->ThrottlePosition++;
  570.     };
  571.    }else if(eng->cab->Switches[0].State==7){
  572.     eng->var[1]=GetTickCount();
  573.    }else
  574.     eng->var[1]=0;
  575.  
  576.    if(BackSec)
  577.     iv=IsLocoOn(BackSec->loco,BackSec->cab);
  578.  
  579.    if(IsHP(eng->ThrottlePosition)){
  580.     *Flags&=~1;
  581.     if(BackSec&&((iv&5)==5))
  582.      *BackSecFlags&=~1;
  583.    }else{
  584.     *Flags|=1;
  585.     if(BackSec&&((iv&5)==5))
  586.      *BackSecFlags|=1;
  587.    };
  588.  
  589.    if(BackSec&&((iv&5)==5))
  590.     BackSec->loco->ThrottlePosition=eng->ThrottlePosition;
  591.   break;
  592.   case 1:
  593.    if(!(loco->LocoFlags&1))
  594.     break;
  595.    switch(eng->cab->Switches[1].State){
  596.     case 0:eng->Reverse=0;break;
  597.     case 2:eng->Reverse=0;break;
  598.     case 1:eng->Reverse=loco->LibParam==0?-1:1;break;
  599.     case 3:eng->Reverse=loco->LibParam==0?1:-1;break;
  600.    };
  601.    //if(loco->Flags&1)
  602.     //eng->Reverse=-eng->Reverse;
  603.    if(BackSec&&((iv&5)==5)){
  604.     BackSec->loco->Reverse=eng->Reverse;
  605.    };
  606.   break;
  607.   case 2:
  608.    if(eng->sound)
  609.     eng->sound->PostTrigger(17);
  610.    if(!(loco->LocoFlags&1))
  611.     return;
  612.    switch(eng->cab->Switches[2].State){
  613.     case 0:
  614.      eng->IndependentBrakeValue=0.0;
  615.     break;
  616.     case 1:
  617.      eng->IndependentBrakeValue=loco->IndependentBrakePressure;
  618.     break;
  619.     case 2:
  620.      if(eng->IndependentBrakeValue<1.0)
  621.       eng->IndependentBrakeValue=1.0;
  622.     break;
  623.     case 3:
  624.      if(eng->IndependentBrakeValue<2.0)
  625.       eng->IndependentBrakeValue=2.0;
  626.     break;
  627.     case 4:
  628.      if(eng->IndependentBrakeValue<3.0)
  629.       eng->IndependentBrakeValue=3.0;
  630.     break;
  631.     case 5:
  632.      if(eng->IndependentBrakeValue<4.0)
  633.       eng->IndependentBrakeValue=4.0;
  634.     break;
  635.    };
  636.    if(BackSec)
  637.     BackSec->loco->IndependentBrakeValue=eng->IndependentBrakeValue;
  638.   break;
  639.   case 3:
  640.   break;
  641.   case 4:
  642.  
  643.   break;
  644.   case 5:
  645.    iv=eng->cab->Switch(5)||eng->cab->Switch(29)?10:11;
  646.    if((LocoOn&13)!=13)iv=11;
  647.    if(eng->sound)
  648.     eng->sound->PostTrigger(iv);
  649.    if(loco->sound)
  650.     loco->sound->PostTrigger(iv);
  651.   break;
  652.   case 6:
  653.    iv=eng->cab->Switch(6)||eng->cab->Switch(28)?8:9;
  654.    if((LocoOn&13)!=13)iv=9;
  655.    if(eng->sound)
  656.     eng->sound->PostTrigger(iv);
  657.    if(loco->sound)
  658.     loco->sound->PostTrigger(iv);
  659.   break;
  660.   case 7:
  661.    eng->var[5]=0.0;
  662.   break;
  663.   case 8:
  664.  
  665.   break;
  666.   case 16:
  667.    if(eng->cab->Switches[16].State&&(LocoOn&1))
  668.     SwitchLights((Locomotive *)loco,2);
  669.    else
  670.     if(eng->cab->Switches[17].State&&(LocoOn&1))
  671.      SwitchLights((Locomotive *)loco,1);
  672.     else
  673.      SwitchLights((Locomotive *)loco,0);
  674.   break;
  675.   case 17:
  676.    if(eng->cab->Switch(17)&&(LocoOn&1))
  677.     if(eng->cab->Switch(16))
  678.      SwitchLights((Locomotive *)loco,2);
  679.     else
  680.      SwitchLights((Locomotive *)loco,1);
  681.    else
  682.     SwitchLights((Locomotive *)loco,0);
  683.   break;
  684.   case 18:
  685.    if((loco->LocoFlags&1)&&((LocoOn&13)!=13)){
  686.     SwitchGV(loco,eng,0);
  687.     //eng->Panto=0;
  688.     if(BackSec){
  689.      SwitchGV(BackSec,BackSec->loco,0);
  690.      //BackSec->loco->Panto=0;
  691.     };
  692.    };
  693.    /*if(BackSec){
  694.     if((LocoOn&13)==13)
  695.      BackSec->SwitchLight(14,true);
  696.     else
  697.      BackSec->SwitchLight(14,false);
  698.    };*/
  699.   break;
  700.   case 22:
  701.    if(!(loco->LocoFlags&1))
  702.     return;
  703.    if((LocoOn&13)!=13)
  704.     return;
  705.    if(eng->ThrottlePosition){
  706.     *Flags|=4;
  707.     return;
  708.    };
  709.    if(eng->cab->Switches[23].State){
  710.     SwitchGV(loco,eng,1);
  711.     *Flags&=~4;
  712.     if(BackSec)SwitchGV(BackSec,BackSec->loco,1);
  713.    };
  714.   break;
  715.   case 23:
  716.    if(!(loco->LocoFlags&1))
  717.     return;
  718.    if((LocoOn&13)!=13)
  719.     return;
  720.    if(!eng->cab->Switches[23].State){
  721.     SwitchGV(loco,eng,0);
  722.     if(BackSec)SwitchGV(BackSec,BackSec->loco,0);
  723.    };
  724.   break;
  725.   case 24:
  726.    anim=FindAnim(eng->cab,L"wiper");
  727.    //anim=&eng->cab->Anims[0];
  728.    if(anim){
  729.     if(eng->cab->Switches[24].State&&(LocoOn&1))
  730.      anim->Flags|=1;
  731.     else
  732.      anim->Flags&=~1;
  733.    };
  734.    anim=FindAnim(loco,L"wiper");
  735.    if(anim){
  736.     if(eng->cab->Switches[24].State&&(LocoOn&1))
  737.      anim->Flags|=1;
  738.     else
  739.      anim->Flags&=~1;
  740.    };
  741.   break;
  742.   case 25:
  743.    if(eng->cab->NumTexChanges){
  744.     iv=1;
  745.     if(!eng->cab->Switch(25)&&!eng->cab->Switch(34))
  746.      iv=0;
  747.     if(!(LocoOn&1))
  748.      iv=0;
  749.     eng->cab->Tex->SetState=iv;
  750.    };
  751.   break;
  752.   case 26:
  753.    if(eng->cab->NumLights>2){
  754.     iv=eng->cab->Switches[26].State;
  755.     if(!(LocoOn&1))iv=0;
  756.     eng->cab->Light[1].State=iv;
  757.     eng->cab->Light[2].State=iv;
  758.    };
  759.   break;
  760.   case 27:
  761.    if(eng->cab->NumLights){
  762.     iv=eng->cab->Switch(32);
  763.     iv+=eng->cab->Switch(27)*2;
  764.     if(!(LocoOn&1))iv=0;
  765.     eng->cab->SetLightState(0,iv,0,iv<2?1.0:0.7);
  766.    };
  767.   break;
  768.   case 35:
  769.    if((LocoOn&1)&&eng->cab->Switch(35)){
  770.     if(eng->cab->Switch(39))
  771.      SwitchLights(loco,5);
  772.     else
  773.      SwitchLights(loco,6);
  774.    }else
  775.     SwitchLights(loco,7);
  776.   break;
  777.   case 36:
  778.    if((LocoOn&1)&&eng->cab->Switch(36)){
  779.     if(eng->cab->Switch(40))
  780.      SwitchLights(loco,8);
  781.     else
  782.      SwitchLights(loco,9);
  783.    }else
  784.     SwitchLights(loco,10);
  785.   break;
  786.   case 200:
  787.    Switched(loco,eng,16,0);
  788.    Switched(loco,eng,17,0);
  789.    Switched(loco,eng,24,0);
  790.    Switched(loco,eng,25,0);
  791.    Switched(loco,eng,26,0);
  792.    Switched(loco,eng,27,0);
  793.    Switched(loco,eng,35,0);
  794.    Switched(loco,eng,36,0);
  795.    if(eng->cab->SwitchSub(0,0)||!(LocoOn&1)){
  796.      if(eng->sound) eng->sound->PostTrigger(105);
  797.    }else{
  798.      if(eng->sound) eng->sound->PostTrigger(104);
  799.    };
  800.   break;
  801.  };
  802. };
  803.  
  804.  
  805.  
  806. extern "C" void __export Run
  807.  (ElectricEngine *eng,const ElectricLocomotive *loco,unsigned long State,
  808.         float time,float AirTemperature)
  809. {
  810.  
  811.  ElectricLocomotive *BackSec=NULL;
  812.  if(loco->NumSlaves&&(loco->LocoFlags&1))
  813.   BackSec=(ElectricLocomotive *)loco->Slaves[0];
  814.  
  815.  UINT ctime;
  816.  UINT LocoOn=0,BackOn,v1;
  817.  Cabin *cab=eng->cab,*cabBack=NULL;
  818.  /*
  819.  LocoOn
  820.  1bite
  821.   1bit - battery on
  822.   2bit - charging on
  823.   3bit - control circuits
  824.   4bit - control circuits switch
  825.   5bit - compressor is on
  826.  
  827.   if the battery charge is low LocoOn==0
  828.  */
  829.  
  830.  UINT *Flags=(UINT *)&eng->var[0],*BackSecFlags;
  831.  float Pressure,Compressor=1.0,Vel;
  832.  if(BackSec){
  833.   BackSecFlags=(UINT *)&BackSec->loco->var[0];
  834.   *BackSecFlags&=~32;
  835.   cabBack=BackSec->cab;
  836.   BackOn=IsLocoOn(BackSec->loco,cabBack);
  837.  };
  838.  
  839.  if(loco->LocoFlags&1){
  840.   eng->Power=0;
  841.   eng->Force=0;
  842.   if(loco->NumEngines){
  843.    eng->EngineForce[0]=0;
  844.    eng->EngineVoltage[0]=0;
  845.    eng->EngineCurrent[0]=0;
  846.   };
  847.   if(BackSec){
  848.    BackSec->loco->Power=0;
  849.    BackSec->loco->Force=0;
  850.    BackSec->loco->BrakeForce=0.0;
  851.    if(BackSec->NumEngines){
  852.     BackSec->loco->EngineForce[0]=0;
  853.     BackSec->loco->EngineVoltage[0]=0;
  854.     BackSec->loco->EngineCurrent[0]=0;
  855.    };
  856.   };
  857.  };
  858.  
  859.  LocoOn=IsLocoOn(eng,cab);
  860.  
  861.  
  862.  if(loco->LocoFlags&1){
  863.  
  864.   //Rasing pantographs on both sections
  865.   v1=0; eng->Panto=0;
  866.   if((LocoOn&1)&&cab->Switch(21)){
  867.    v1|=4;
  868.    if(cab->Switch(20))
  869.     v1|=loco->LibParam?1:2;
  870.    if(cab->Switch(19))
  871.     v1|=loco->LibParam?2:1;
  872.   };
  873.   if(cabBack){
  874.    BackSec->loco->Panto=0;
  875.    if((BackOn&1)&&cabBack->Switch(21)){
  876.     if(cabBack->Switch(20))
  877.      v1|=BackSec->LibParam?1:2;
  878.     if(cabBack->Switch(19))
  879.      v1|=BackSec->LibParam?2:1;
  880.    };
  881.    if(BackOn&1)
  882.     BackSec->loco->Panto|=v1&3;
  883.   };
  884.   eng->Panto|=v1&3;
  885.  
  886.   //Enabling MV1,MV2,MV3,MV4
  887.   if(cab->Switch(13))
  888.    *Flags|=8;
  889.   else
  890.    *Flags&=~8;
  891.   if(cab->Switch(12))
  892.    *Flags|=16;
  893.   else
  894.    *Flags&=~16;
  895.   if(BackSec){
  896.    if(cab->Switch(11))
  897.     *BackSecFlags|=8;
  898.    else
  899.     *BackSecFlags&=~8;
  900.    if(cab->Switch(10))
  901.     *BackSecFlags|=16;
  902.    else
  903.     *BackSecFlags&=~16;
  904.   };
  905.  };
  906.  
  907.  
  908.  
  909.  
  910.  //Swtching GV off, if the circuits are off
  911.  if(((LocoOn&5)!=5)&&eng->MainSwitch){
  912.   SwitchGV(loco,eng,0);
  913.   if(BackSec)
  914.    SwitchGV(BackSec,BackSec->loco,0);
  915.  };
  916.  
  917.  //Determining power source: catenary or socket
  918.  float LineVoltage=loco->LineVoltage;
  919.  bool CurrentOn=LineVoltage>19000,ExtSrc=false;
  920.  if(!CurrentOn&&!eng->MainSwitch){
  921.   if(eng->ExternalPowerSource){
  922.    ExtSrc=true;
  923.    LineVoltage=eng->ExternalPowerSourceVoltage;
  924.    CurrentOn=true;
  925.    Compressor*=eng->ExternalPowerSource/40000.0;
  926.   };
  927.  };
  928.  
  929.  //GV off due to low voltage or DC
  930.  if(eng->MainSwitch&&((!loco->LineFreq||!CurrentOn)||LineVoltage>30000.0)&&loco->PantoRaised){
  931.   SwitchGV(loco,eng,0);
  932.   //if(BackSec)SwitchGV(BackSec,BackSec->loco,0);
  933.   *Flags|=4;
  934.  };
  935.  
  936.  //GV off due to line voltage drop or raise
  937.  if(eng->MainSwitch&&
  938.   ((eng->var[13]<19000.0&&LineVoltage>19000.0)||(eng->var[13]>19000.0&&LineVoltage<19000.0)))
  939.  {
  940.   SwitchGV(loco,eng,0);
  941.   if(BackSec)SwitchGV(BackSec,BackSec->loco,0);
  942.  };
  943.  eng->var[13]=loco->LineVoltage;
  944.  
  945.  //GV off due to open doors in VVK
  946.  if(eng->MainSwitch&&(cab->IsDoorOpened(5)||cab->IsDoorOpened(6)||cab->IsDoorOpened(7))){
  947.   SwitchGV(loco,eng,0);
  948.   *Flags|=4;
  949.  };
  950.  
  951.  //Battery usage and charging
  952.  eng->var[11]=0.0;
  953.  if(LocoOn&1){
  954.   *Flags&=~2048;
  955.   if(loco->IsLightOn(0))
  956.    eng->var[11]-=0.011;
  957.   if(loco->IsLightOn(1))
  958.    eng->var[11]-=0.024;
  959.   if(cab->Switch(16))
  960.    eng->var[11]-=0.001;
  961.   if(cab->Switch(17))
  962.    eng->var[11]-=0.0006;
  963.   if(cab->Switch(27))
  964.    eng->var[11]-=0.001;
  965.   else if(cab->Switch(33))
  966.    eng->var[11]-=0.0006;
  967.   if(cab->Switch(30))
  968.    eng->var[11]-=0.04;
  969.   else if(cab->Switch(31))
  970.    eng->var[11]-=0.028;
  971.   if(cab->Switch(41)||cab->Switch(43))
  972.    eng->var[11]-=0.008;
  973.   if(cab->Switch(44))
  974.    eng->var[11]-=0.01;
  975.   if(cab->Switch(45))
  976.    eng->var[11]-=0.01;
  977.   if(cab->Switch(46))
  978.    eng->var[11]-=0.01;
  979.   if(cab->Switch(47))
  980.    eng->var[11]-=0.01;
  981.  
  982.   if(LocoOn&4){
  983.    eng->var[11]-=0.002;
  984.    if((LocoOn&8)||eng->MainSwitch){
  985.     eng->var[11]-=0.004;
  986.     if(cab->Switch(9))
  987.      eng->var[11]-=0.0008;
  988.    };
  989.   };
  990.  
  991.   if((LocoOn&2)){
  992.    if(eng->MainSwitch&&CurrentOn){
  993.     if(eng->var[10]<69.0||(*Flags&128)){
  994.      if(eng->var[10]>74.2)
  995.       *Flags&=~128;
  996.      else{
  997.       *Flags|=128;
  998.       eng->var[11]=(74.2-eng->var[10])*0.004;
  999.       if(eng->var[11]>0.15)
  1000.        eng->var[11]=0.15;
  1001.       if(eng->var[11]<0.0)
  1002.        eng->var[11]=0.0;
  1003.      };
  1004.     };
  1005.    }else if(ExtSrc&&eng->var[10]<62.0){
  1006.     eng->var[11]+=0.002*(62.0-eng->var[10]);
  1007.     if(eng->var[10]>61.0)
  1008.      eng->var[11]=0.0;
  1009.    };
  1010.   };
  1011.  }else if((LocoOn&2)&&eng->ExternalPowerSource&&eng->var[10]<62.0){
  1012.   eng->var[11]=0.005*(62.0-eng->var[10])/40.0;
  1013.  };
  1014.  eng->var[10]+=eng->var[11]*time;
  1015.  if(eng->var[10]<BATTERY_DEADLINE&&!(*Flags&2048)){
  1016.   Switched(loco,eng,200,0);
  1017.   *Flags|=2048;
  1018.  };
  1019.  
  1020.  if(*Flags&(32<<8)){
  1021.   if(eng->sound)
  1022.    eng->sound->PostTrigger(104);
  1023.   *Flags&=~(32<<8);
  1024.  };
  1025.  
  1026.  
  1027.  //Автонабор/сброс
  1028.  if((loco->LocoFlags&1)&&((LocoOn&13)==13)&&eng->var[1]>1){
  1029.   ctime=GetTickCount()-eng->var[1];
  1030.   if(ctime>500.0&&eng->cab->SwitchSet(1)<4){
  1031.    if(ctime>1000.0)
  1032.     eng->var[1]=GetTickCount();
  1033.    else
  1034.     eng->var[1]+=ctime;
  1035.    switch(eng->cab->Switches[0].State){
  1036.     case 1:
  1037.      if(eng->ThrottlePosition)
  1038.       eng->ThrottlePosition--;
  1039.      else
  1040.       eng->var[1]=0;
  1041.     break;
  1042.     case 2:
  1043.      if(eng->ThrottlePosition)
  1044.       eng->ThrottlePosition--;
  1045.      else
  1046.       eng->var[1]=0;
  1047.     break;
  1048.     case 0:
  1049.      SwitchGV(loco,eng,0);
  1050.      if(eng->ThrottlePosition)
  1051.       eng->ThrottlePosition--;
  1052.      if(BackSec)
  1053.       SwitchGV(BackSec,BackSec->loco,eng->MainSwitch);
  1054.     break;
  1055.     case 7:
  1056.      if(eng->ThrottlePosition<33)
  1057.       eng->ThrottlePosition++;
  1058.     break;
  1059.    };
  1060.  
  1061.    if(IsHP(eng->ThrottlePosition)){
  1062.     *Flags&=~1;
  1063.     if(BackSec)
  1064.      *BackSecFlags&=~1;
  1065.    }else{
  1066.     *Flags|=1;
  1067.     if(BackSec)
  1068.      *BackSecFlags|=1;
  1069.    };
  1070.  
  1071.    if(BackSec&&((BackOn&5)==5)){
  1072.     BackSec->loco->ThrottlePosition=eng->ThrottlePosition;
  1073.    };
  1074.   };
  1075.  };
  1076.  
  1077.  //Возврат главного контроллера
  1078.  switch(cab->Switch(0)){
  1079.   case 0:
  1080.    if(!GetAsyncKeyState(cab->Switches[0].Key[2])&&!GetAsyncKeyState(VK_LBUTTON))
  1081.     cab->SetSwitch(0,1,false);
  1082.   break;
  1083.   case 7:
  1084.    if(!GetAsyncKeyState(cab->Switches[0].Key[0])&&!GetAsyncKeyState(VK_LBUTTON))
  1085.     cab->SetSwitch(0,6,false);
  1086.   break;
  1087.  };
  1088.  
  1089.  
  1090.  eng->MainResRate=0.0;
  1091.  if(loco->MainResPressure>2.4){
  1092.   if(cab->Switches[3].State<4)
  1093.    eng->MainResRate=-5e-4*loco->MainResPressure;
  1094.  };
  1095.  
  1096.  if(CurrentOn&&(eng->MainSwitch||ExtSrc)){
  1097.  
  1098.    if(BackSec){
  1099.     if(((LocoOn&29)==29))
  1100.      *BackSecFlags|=32;
  1101.    };
  1102.  
  1103.    //Compressor
  1104.    if((*Flags&32)||(((LocoOn&29)==29)&&(loco->LocoFlags&1))){
  1105.     if(!(*Flags&2)&&loco->MainResPressure<6.0){
  1106.      *Flags|=2;
  1107.      if(eng->sound)
  1108.       eng->sound->PostTrigger(101);
  1109.     };
  1110.     if(*Flags&2)
  1111.      if(loco->MainResPressure>9.0){
  1112.       *Flags&=~2;
  1113.       if(eng->sound)
  1114.        eng->sound->PostTrigger(102);
  1115.      }else{
  1116.       eng->MainResRate=0.04*(11.0-loco->MainResPressure);
  1117.       if(!loco->LineVoltage&&ExtSrc&&eng->ExternalPowerSource<40000.0){
  1118.        eng->MainResRate*=eng->ExternalPowerSource/40000.0;
  1119.       };
  1120.      };
  1121.    }else if(*Flags&2){
  1122.     if(eng->sound)
  1123.      eng->sound->PostTrigger(102);
  1124.     *Flags&=~2;
  1125.    };
  1126.  
  1127.  
  1128.   if(loco->LocoFlags&1){
  1129.    //Throttle
  1130.    if(eng->Reverse&&(cab->Switch(15)||ExtSrc)&&cab->Switch(0)>1)
  1131.    {
  1132.  
  1133.      float Velocity=loco->Velocity*eng->Reverse;
  1134.      float VelMax=-3.525+eng->ThrottlePosition*0.245;
  1135.      float SetForce=0.0;
  1136.      int shunt = 0;
  1137.  
  1138.      if(eng->cab->Switches[1].State>3){
  1139.       shunt =eng->cab->Switches[1].State-3;
  1140.      };
  1141.  
  1142.      if(Velocity==VelMax)Velocity+=0.1;
  1143.      Velocity=Velocity-VelMax;
  1144.      if(Velocity<=0.01)
  1145.       SetForce=400000.0;
  1146.      else{
  1147.       SetForce = (340000.0*eng->ThrottlePosition)/
  1148.                 (Velocity*Velocity*pow(0.978,eng->ThrottlePosition)) +
  1149.                 shunt*468750.0/Velocity;
  1150.      };
  1151.      SetForce*=eng->Reverse*(LineVoltage/26000.0);
  1152.  
  1153.      eng->Force=eng->var[12];
  1154.      if(eng->Force<SetForce){
  1155.       eng->Force+=(10000.0+(SetForce-eng->Force)*0.6)*time;
  1156.       if(eng->Force>SetForce)
  1157.        eng->Force=SetForce;
  1158.      }else if(eng->Force>SetForce){
  1159.       eng->Force-=30000.0*time;
  1160.       if(eng->Force<SetForce)
  1161.        eng->Force=SetForce;
  1162.      };
  1163.      eng->Power=eng->ThrottlePosition*28.8*(LineVoltage/26000.0)*fabs(eng->Force/TR_CURRENT_C)*4.0;
  1164.  
  1165.      if(!loco->LineVoltage&&ExtSrc){
  1166.       if(eng->Power&&eng->Power>eng->ExternalPowerSource)
  1167.        eng->Force*=eng->ExternalPowerSource/eng->Power;
  1168.        if(*Flags&2){
  1169.         eng->MainResRate*=0.55;
  1170.         eng->Power*=0.45;
  1171.         eng->Force*=0.45;
  1172.        };
  1173.      };
  1174.  
  1175.      if(loco->NumEngines){
  1176.       eng->EngineForce[0]=eng->Force/4.0;
  1177.       eng->EngineVoltage[0]=eng->ThrottlePosition*26.5*(LineVoltage/26000.0);
  1178.       eng->EngineCurrent[0]=fabs(eng->Force/TR_CURRENT_C);
  1179.       if(eng->EngineCurrent[0])
  1180.        eng->EngineCurrent[0]+=50.0;
  1181.       if(eng->cab->Switches[1].State>3)
  1182.        eng->EngineCurrent[0]*=1.0+(eng->cab->Switches[1].State-3)*0.05;
  1183.       //if(eng->Wheelslip)
  1184.        //eng->EngineCurrent[0]*=1.01+float(GetTickCount()%10)/200.0;
  1185.       if(eng->EngineCurrent[0]>1400.0||loco->BrakeCylinderPressure>3.0){
  1186.        SwitchGV(loco,eng,0);
  1187.        *Flags|=4;
  1188.        eng->Force=0;
  1189.        eng->Power=0;
  1190.        eng->EngineForce[0]=0;
  1191.        eng->EngineVoltage[0]=0;
  1192.        eng->EngineCurrent[0]=0;
  1193.        if(BackSec)
  1194.         SwitchGV(BackSec,BackSec->loco,0);
  1195.       };
  1196.      };
  1197.  
  1198.    };
  1199.   };
  1200.  }else{
  1201.    if(*Flags&2){
  1202.     *Flags&=~2;
  1203.     if(eng->sound)
  1204.      eng->sound->PostTrigger(102);
  1205.    };
  1206.  };
  1207.  eng->PowerConsuming=eng->Power;
  1208.  if((LocoOn&12)==12)
  1209.   eng->PowerConsuming+=500.0;
  1210.  if(*Flags&2)
  1211.   eng->PowerConsuming+=40000;
  1212.  eng->var[12]=eng->Force;
  1213.  
  1214.  
  1215.  if(BackSec){
  1216.   if(BackSec->loco->MainSwitch){
  1217.    BackSec->loco->Power=eng->Power;
  1218.    BackSec->loco->Force=eng->Force;
  1219.    if(BackSec->NumEngines){
  1220.     BackSec->loco->EngineForce[0]=eng->EngineForce[0];
  1221.     BackSec->loco->EngineCurrent[0]=eng->EngineCurrent[0];
  1222.     BackSec->loco->EngineVoltage[0]=eng->EngineVoltage[0];
  1223.    };
  1224.   };
  1225.  };
  1226.  
  1227.  if(loco->NumEngines){
  1228.   if(eng->sound){
  1229.    eng->sound->Var2[0]=(eng->EngineCurrent[0]/800.0)*100.0;
  1230.   };
  1231.   if(loco->sound){
  1232.    loco->sound->Var2[0]=(eng->EngineCurrent[0]/800.0)*100.0;
  1233.   };
  1234.   if(eng->EngineVoltage[0]>875.0){
  1235.    *Flags|=4096;
  1236.    eng->var[14]+=time*(eng->EngineVoltage[0]-875.0)*0.02;
  1237.    if(eng->var[14]>90.0){
  1238.     SwitchGV(loco,eng,0);
  1239.     if(BackSec) SwitchGV(BackSec,BackSec->loco,0);
  1240.     *Flags|=4;
  1241.    };
  1242.   }else{
  1243.    *Flags&=~4096;
  1244.    eng->var[14]=0.0;
  1245.   };
  1246.   eng->EngineForce[1]=eng->EngineForce[0];
  1247.   eng->EngineCurrent[1]=eng->EngineCurrent[0];
  1248.   eng->EngineVoltage[1]=eng->EngineVoltage[0];
  1249.   eng->EngineForce[2]=eng->EngineForce[0];
  1250.   eng->EngineCurrent[2]=eng->EngineCurrent[0];
  1251.   eng->EngineVoltage[2]=eng->EngineVoltage[0];
  1252.   eng->EngineForce[3]=eng->EngineForce[0];
  1253.   eng->EngineCurrent[3]=eng->EngineCurrent[0];
  1254.   eng->EngineVoltage[3]=eng->EngineVoltage[0];
  1255.  };
  1256.  
  1257.  
  1258.  //Loco brake
  1259.  if(eng->IndependentBrakeValue>loco->MainResPressure)
  1260.   eng->IndependentBrakeValue=loco->MainResPressure;
  1261.  if(eng->IndependentBrakeValue>loco->IndependentBrakePressure)
  1262.   eng->MainResRate-=0.02;
  1263.  
  1264.  //Train brake
  1265.  eng->TrainPipeRate=0.0;
  1266.  if(loco->LocoFlags&1){
  1267.   if(BackSec)*BackSecFlags&=~64;
  1268.   switch(cab->Switches[3].State){
  1269.    case 0:
  1270.     if(eng->var[5]<45.0){
  1271.      if(!cab->Switches[3].SetState)
  1272.       eng->UR+=BRAKE_UR_RATE_CHARGE*time;
  1273.      if(eng->UR>loco->MainResPressure)
  1274.       eng->UR=loco->MainResPressure;
  1275.      if(loco->TrainPipePressure<eng->UR)
  1276.       eng->TrainPipeRate=(eng->UR-loco->TrainPipePressure)*1.5;
  1277.      if(BackSec){
  1278.       BackSec->loco->UR=eng->UR;
  1279.       *BackSecFlags|=64;
  1280.      };
  1281.     };
  1282.    break;
  1283.    case 1:
  1284.     if(eng->var[5]<45.0){
  1285.      if(eng->UR<5.0){
  1286.       float rate=(loco->MainResPressure-eng->UR)*2.0;
  1287.       if(rate<0.0)rate=0.0;
  1288.       if(rate>BRAKE_UR_RATE_CHARGE)rate=BRAKE_UR_RATE_CHARGE;
  1289.       eng->UR+=rate*time;
  1290.      }else
  1291.       if(loco->BrakeCylinderPressure>0.0&&(eng->UR-loco->TrainPipePressure)<0.1)
  1292.        eng->UR+=0.15*time;
  1293.      if(eng->UR>loco->MainResPressure)
  1294.       eng->UR=loco->MainResPressure;
  1295.      if(eng->UR>loco->TrainPipePressure)
  1296.       eng->UR-=0.003*time;
  1297.      if(loco->TrainPipePressure<eng->UR-0.01){
  1298.       eng->TrainPipeRate=(eng->UR-loco->TrainPipePressure)/BRAKE_PIPE_RATE_CHARGE;
  1299.      }else if(loco->TrainPipePressure>eng->UR){
  1300.       eng->TrainPipeRate=(eng->UR-loco->TrainPipePressure)/BRAKE_PIPE_RATE_CHARGE;
  1301.       if(eng->TrainPipeRate<-BRAKE_PIPE_RATE)
  1302.        eng->TrainPipeRate=-BRAKE_PIPE_RATE;
  1303.      };
  1304.      if(BackSec){
  1305.       BackSec->loco->UR=eng->UR;
  1306.       *BackSecFlags|=64;
  1307.      };
  1308.     };
  1309.    break;
  1310.    case 2:
  1311.     if(eng->UR>loco->MainResPressure)
  1312.      eng->UR=loco->MainResPressure;
  1313.     if(loco->TrainPipePressure>eng->UR)
  1314.      eng->TrainPipeRate=eng->UR-loco->TrainPipePressure;
  1315.     if(eng->TrainPipeRate<-BRAKE_PIPE_RATE)
  1316.      eng->TrainPipeRate=-BRAKE_PIPE_RATE;
  1317.     if(eng->TrainPipeRate>PIPE_DISCHARGE_SLOW)
  1318.      eng->TrainPipeRate=PIPE_DISCHARGE_SLOW;
  1319.     if(BackSec)
  1320.      BackSec->loco->UR=eng->UR;
  1321.    break;
  1322.    case 3:
  1323.     if(eng->UR>loco->MainResPressure)
  1324.      eng->UR=loco->MainResPressure;
  1325.     if(loco->TrainPipePressure>eng->UR)
  1326.      eng->TrainPipeRate=eng->UR-loco->TrainPipePressure;
  1327.     else if(eng->UR-loco->TrainPipePressure>0.1)
  1328.      eng->TrainPipeRate=0.05;
  1329.     if(eng->TrainPipeRate<-BRAKE_PIPE_RATE)
  1330.      eng->TrainPipeRate=-BRAKE_PIPE_RATE;
  1331.     if(BackSec)
  1332.      BackSec->loco->UR=eng->UR;
  1333.    break;
  1334.    case 4:
  1335.     if(cab->Switches[3].SetState!=4)
  1336.      break;
  1337.     eng->UR-=0.3*time;
  1338.     if(eng->UR>loco->MainResPressure)
  1339.      eng->UR=loco->MainResPressure;
  1340.     if(eng->UR<0)
  1341.      eng->UR=0;
  1342.     eng->TrainPipeRate=-0.25;
  1343.     if(BackSec)
  1344.      BackSec->loco->UR=eng->UR;
  1345.     //if(eng->TrainPipeRate<-BRAKE_PIPE_RATE)
  1346.      //eng->TrainPipeRate=-BRAKE_PIPE_RATE;
  1347.    break;
  1348.    case 5:
  1349.     eng->UR+=BRAKE_PIPE_EMERGENCY*1.2*time;
  1350.     if(eng->UR>loco->MainResPressure)
  1351.      eng->UR=loco->MainResPressure;
  1352.     if(eng->UR<0)
  1353.      eng->UR=0;
  1354.     eng->TrainPipeRate=BRAKE_PIPE_EMERGENCY;
  1355.     if(BackSec)
  1356.      BackSec->loco->UR=eng->UR;
  1357.    break;
  1358.   };
  1359.  
  1360.   //EPK
  1361.   if(eng->Reverse && (LocoOn&13==13) &&
  1362.      (cab->Switch(9)||cab->Switch(38)) && (loco->Velocity>0.1||loco->Velocity<-0.1))
  1363.   {
  1364.    UINT Aspect=eng->cab->Signal.Aspect[0];
  1365.    if(Aspect!=unsigned(eng->var[6]) || eng->var[7]==2.0)
  1366.    {
  1367.     if(Aspect>unsigned(eng->var[6]) && Aspect!=SIGASP_BLOCK_OBSTRUCTED && Aspect>SIGASP_STOP_AND_PROCEED){
  1368.      eng->var[7]=0.0;
  1369.      eng->var[8]=0.0;
  1370.      if(eng->sound)
  1371.       eng->sound->PostTrigger(106);
  1372.     }else{
  1373.      if(eng->var[7]<2.0){
  1374.       eng->var[7]=2.0;
  1375.       eng->var[8]=0.01;
  1376.       if(Aspect==SIGASP_STOP_AND_PROCEED || Aspect==SIGASP_RESTRICTING)
  1377.        eng->var[5]=35.0-time*0.5;
  1378.       else
  1379.        eng->var[5]=30.0;
  1380.      };
  1381.      if(!eng->var[5]){
  1382.       eng->var[7]=0.0;
  1383.       eng->var[8]=0.0;
  1384.       loco->PostTriggerBoth(57);
  1385.      }else{
  1386.       if(eng->var[5]<35.0&&eng->var[5]+time>=35.0)
  1387.        loco->PostTriggerBoth(56);
  1388.       eng->var[5]+=time;
  1389.       if(eng->var[5]>45.0){
  1390.        eng->TrainPipeRate=BRAKE_PIPE_EMERGENCY;
  1391.       };
  1392.      };
  1393.     };
  1394.    }else if(Aspect>=SIGASP_APPROACH_1&&Aspect<SIGASP_CLEAR_1){
  1395.     eng->var[5]+=time;
  1396.     if(eng->var[5]>30.0){
  1397.      eng->var[8]=0.01;
  1398.      eng->var[7]=2.0;
  1399.     };
  1400.    }else if(Aspect<SIGASP_APPROACH_1 || Aspect==SIGASP_BLOCK_OBSTRUCTED){
  1401.     eng->var[5]+=time;
  1402.     if(eng->var[5]>30.0){
  1403.      if(eng->var[7]<1.0)
  1404.       eng->var[7]=1.0;
  1405.      if(eng->var[5]>=35.0&&eng->var[5]-time<35.0)
  1406.       loco->PostTriggerBoth(56);
  1407.      if(eng->var[5]>45.0){
  1408.       eng->TrainPipeRate=BRAKE_PIPE_EMERGENCY;
  1409.      };
  1410.     }else{
  1411.      if(eng->var[7])
  1412.       loco->PostTriggerBoth(57);
  1413.      eng->var[7]=0.0;
  1414.     };
  1415.    }else{
  1416.     if(eng->var[7])
  1417.      loco->PostTriggerBoth(57);
  1418.     eng->var[5]=0.0;
  1419.     eng->var[7]=0.0;
  1420.    };
  1421.    eng->var[6]=Aspect;
  1422.   }else{
  1423.    if(eng->var[7])
  1424.     loco->PostTriggerBoth(57);
  1425.    eng->var[5]=0.0;
  1426.    eng->var[7]=0.0;
  1427.   };
  1428.  
  1429.   //Sanding
  1430.   if(((LocoOn&13)==13)&&
  1431.    (eng->cab->Switches[8].State||eng->cab->Switches[4].State)
  1432.   )
  1433.    eng->Sanding=1;
  1434.   else
  1435.    eng->Sanding=0;
  1436.   if(BackSec){
  1437.    BackSec->loco->Sanding=eng->Sanding;
  1438.   };
  1439.  
  1440.  }else{
  1441.   if((*Flags&64)){
  1442.    if(eng->UR>loco->MainResPressure)
  1443.     eng->UR=loco->MainResPressure;
  1444.    if(eng->UR>loco->TrainPipePressure)
  1445.     eng->UR-=0.002*time;
  1446.    if(loco->TrainPipePressure<eng->UR)
  1447.     eng->TrainPipeRate=(eng->UR-loco->TrainPipePressure)/BRAKE_PIPE_RATE_CHARGE;
  1448.   };
  1449.  };
  1450.  
  1451.  if(eng->sound){
  1452.   if((loco->BrakeCylinderPressure>0.0||loco->IndependentBrakePressure>0.0)&&!(*Flags&256)){
  1453.    eng->sound->PostTrigger(14);
  1454.    if(loco->sound)
  1455.     loco->sound->PostTrigger(14);
  1456.    *Flags|=256;
  1457.   };
  1458.   if((*Flags&256)&&!loco->BrakeCylinderPressure&&!loco->IndependentBrakePressure){
  1459.    eng->sound->PostTrigger(54);
  1460.    if(loco->sound)
  1461.     loco->sound->PostTrigger(54);
  1462.    *Flags&=~256;
  1463.   };
  1464.  };
  1465.  
  1466.  //----Sounds adjustment:
  1467.  //Sanding
  1468.  if(eng->Sanding&&!(*Flags&1024)){
  1469.   *Flags|=1024;
  1470.   if(eng->sound)
  1471.    eng->sound->PostTrigger(4);
  1472.  }else if(!eng->Sanding&&(*Flags&1024)){
  1473.   *Flags&=~1024;
  1474.   if(eng->sound)
  1475.    eng->sound->PostTrigger(5);
  1476.  };
  1477.  //Turning on and off MV stream
  1478.  if(*Flags&512){
  1479.   if((!(*Flags&8)&&!(*Flags&16))||!eng->MainSwitch||!CurrentOn){
  1480.    if(eng->sound)
  1481.     eng->sound->PostTrigger(46);
  1482.    if(loco->sound)
  1483.     loco->sound->PostTrigger(46);
  1484.    *Flags&=~512;
  1485.   };
  1486.  }else{
  1487.   if(((*Flags&8)||(*Flags&16))&&eng->MainSwitch&&CurrentOn){
  1488.    if(eng->sound)
  1489.     eng->sound->PostTrigger(45);
  1490.    if(loco->sound)
  1491.     loco->sound->PostTrigger(45);
  1492.    *Flags|=512;
  1493.   };
  1494.  };
  1495.  Pressure=loco->BrakeCylinderPressure>loco->IndependentBrakePressure?
  1496.           loco->BrakeCylinderPressure:
  1497.           loco->IndependentBrakePressure;
  1498.  Pressure/=6.0;
  1499.  Vel=fabs(loco->Velocity);
  1500.  if(Vel<1.5)
  1501.   Pressure+=0.5*(1.5-Vel)*fabs(loco->Acceleration)/0.08;
  1502.  if(Vel<0.2)
  1503.   Pressure*=Vel*5;
  1504.  if(eng->sound){
  1505.   eng->sound->Var4[0]=Compressor;
  1506.   eng->sound->Var5[0]=Pressure;
  1507.  };
  1508.  if(loco->sound){
  1509.   loco->sound->Var4[0]=Compressor;
  1510.  };
  1511.  
  1512.  //Setting up the displays
  1513.  if((State>>8)&1){
  1514.  
  1515.   //ЩР
  1516.   if(LocoOn&1){
  1517.    if(cab->SwitchSub(0,4)){
  1518.     if(LocoOn&4){
  1519.      if(eng->MainSwitch&&CurrentOn&&eng->var[11]>=0.0)
  1520.       cab->SetSwitch(0,6,80.0,false);
  1521.      else
  1522.       cab->SetSwitch(0,6,eng->var[10],false);
  1523.     }else
  1524.      cab->SetSwitch(0,6,0.0,false);
  1525.    }else
  1526.     cab->SetSwitch(0,6,eng->var[10],false);
  1527.    cab->SetSwitch(0,7,eng->var[11]*10.0,false);
  1528.   }else{
  1529.    cab->SetSwitch(0,6,0.0,false);
  1530.    cab->SetSwitch(0,7,0.0,false);
  1531.   };
  1532.  
  1533.   cab->SetDisplayValue(0,Vel);
  1534.   if(eng->Wheelslip)
  1535.    cab->SetDisplayValue(0,Vel*(1.0+float(GetTickCount()%10)/50.0));
  1536.  
  1537.   if(loco->LineVoltage&&eng->MainSwitch)
  1538.    cab->SetDisplayValue(1,loco->LineVoltage);
  1539.   else
  1540.    cab->SetDisplayValue(1,0);
  1541.  
  1542.   if(loco->NumEngines)
  1543.    cab->SetDisplayValue(2,eng->EngineVoltage[0]);
  1544.   else
  1545.    cab->SetDisplayValue(2,eng->ThrottlePosition*40.0);
  1546.  
  1547.   if(BackSec){
  1548.    if(BackSec->NumEngines)
  1549.     cab->SetDisplayValue(3,BackSec->loco->EngineCurrent[0]);
  1550.    else
  1551.     cab->SetDisplayValue(3,BackSec->loco->Force/TR_CURRENT_C);
  1552.   }else
  1553.    cab->SetDisplayValue(3,0);
  1554.  
  1555.   if(loco->NumEngines)
  1556.    cab->SetDisplayValue(4,eng->EngineCurrent[0]);
  1557.   else
  1558.    cab->SetDisplayValue(4,eng->Force/TR_CURRENT_C);
  1559.  
  1560.   if(eng->ThrottlePosition>17)
  1561.    cab->SetDisplayValue(5,eng->ThrottlePosition+5);
  1562.   else if(eng->ThrottlePosition>13)
  1563.    cab->SetDisplayValue(5,eng->ThrottlePosition+2);
  1564.   else if(eng->ThrottlePosition)
  1565.    cab->SetDisplayValue(5,eng->ThrottlePosition+1);
  1566.   else
  1567.    cab->SetDisplayValue(5,0);
  1568.  
  1569.   cab->SetDisplayValue(7,loco->MainResPressure);
  1570.   cab->SetHint(7,-1);
  1571.   if(loco->MainResPressure<6.0)
  1572.    cab->SetHint(7,0);
  1573.   if(eng->MainResRate>0.0)
  1574.    cab->SetHint(7,1);
  1575.  
  1576.   cab->SetDisplayValue(
  1577.    6,
  1578.    loco->BrakeCylinderPressure>loco->IndependentBrakePressure?
  1579.    loco->BrakeCylinderPressure:
  1580.    loco->IndependentBrakePressure
  1581.   );
  1582.   if(!cab->DisplayValue(6))
  1583.    cab->SetHint(6,0);
  1584.   else
  1585.    cab->SetHint(6,-1);
  1586.  
  1587.   cab->SetDisplayValue(8,loco->TrainPipePressure);
  1588.  
  1589.   cab->SetDisplayValue(9,eng->UR);
  1590.  
  1591.   if(((LocoOn&13)==13)&&(loco->LocoFlags&1)){
  1592.    eng->cab->Displays[10].State=!(eng->MainSwitch&&CurrentOn&&(*Flags&24));
  1593.    eng->cab->Displays[11].State=!(eng->MainSwitch&&CurrentOn&&(*Flags&24));
  1594.    eng->cab->Displays[12].State=!(*Flags&1);
  1595.    eng->cab->Displays[13].State=!(eng->MainSwitch&&CurrentOn&&(*Flags&24));
  1596.    eng->cab->Displays[14].State=!eng->MainSwitch;
  1597.    if(BackSec){
  1598.     eng->cab->Displays[15].State=!(BackSec->loco->MainSwitch&&CurrentOn&&(*BackSecFlags&24));
  1599.     eng->cab->Displays[16].State=!(BackSec->loco->MainSwitch&&CurrentOn&&(*BackSecFlags&24));
  1600.     eng->cab->Displays[17].State=!(*BackSecFlags&1);
  1601.     eng->cab->Displays[18].State=!(BackSec->loco->MainSwitch&&CurrentOn&&(*BackSecFlags&24));
  1602.     eng->cab->Displays[19].State=!BackSec->loco->MainSwitch;
  1603.    }else{
  1604.     eng->cab->Displays[15].State=1;
  1605.     eng->cab->Displays[16].State=1;
  1606.     eng->cab->Displays[17].State=0;
  1607.     eng->cab->Displays[18].State=1;
  1608.     eng->cab->Displays[19].State=1;
  1609.    };
  1610.    if(eng->cab->Switch(9)||eng->cab->Switch(38))
  1611.     eng->ALSNOn=1;
  1612.    else
  1613.     eng->ALSNOn=0;
  1614.    if(eng->cab->Switch(37))
  1615.     eng->ALSNOn=0xFFFF;
  1616.  
  1617.    if(CurrentOn&&eng->MainSwitch&&(*Flags&24))
  1618.     cab->SetDisplayState(20,0);
  1619.    else
  1620.     cab->SetDisplayState(20,1);
  1621.    if(eng->MainSwitch&&eng->cab->Switches[15].State&&
  1622.         (!BackSec||BackSec->loco->MainSwitch)
  1623.    )
  1624.     eng->cab->Displays[21].State=1;
  1625.    else
  1626.     eng->cab->Displays[21].State=0;
  1627.    if(eng->var[11]<=0.0)
  1628.     eng->cab->Displays[22].State=1;
  1629.    else
  1630.     eng->cab->Displays[22].State=0;
  1631.    if(*Flags&4100)
  1632.     cab->SetDisplayState(23,1);
  1633.    else
  1634.     cab->SetDisplayState(23,0);
  1635.    if(eng->Wheelslip){
  1636.     cab->SetDisplayState(25,eng->var[15]>0.5?0:1);
  1637.     eng->var[15]+=time;
  1638.     if(eng->var[15]>1.0)
  1639.      eng->var[15]-=1.0;
  1640.    }else if(eng->Sanding&&loco->SandLeft>0.0){
  1641.     cab->SetDisplayState(25,1);
  1642.     eng->var[15]=0.0;
  1643.    }else{
  1644.     eng->var[15]=0.0;
  1645.     cab->SetDisplayState(25,0);
  1646.    };
  1647.   }else{
  1648.    eng->cab->Displays[10].State=0;
  1649.    eng->cab->Displays[11].State=0;
  1650.    eng->cab->Displays[12].State=0;
  1651.    eng->cab->Displays[13].State=0;
  1652.    eng->cab->Displays[14].State=0;
  1653.    eng->cab->Displays[15].State=0;
  1654.    eng->cab->Displays[16].State=0;
  1655.    eng->cab->Displays[17].State=0;
  1656.    eng->cab->Displays[18].State=0;
  1657.    eng->cab->Displays[19].State=0;
  1658.    eng->cab->Displays[20].State=0;
  1659.    eng->cab->Displays[21].State=0;
  1660.    eng->cab->Displays[22].State=0;
  1661.    eng->cab->Displays[23].State=0;
  1662.    eng->cab->Displays[25].State=0;
  1663.    eng->ALSNOn=0;
  1664.   };
  1665.  
  1666.   eng->cab->SetDisplayValue(29,5.0);
  1667.   if(LocoOn&1)
  1668.    eng->cab->SetDisplayValue(30,eng->var[10]);
  1669.   else
  1670.    eng->cab->SetDisplayValue(30,0.0);
  1671.  
  1672.   cab->SetHint(12,cab->DisplayState(12));
  1673.   cab->SetHint(17,cab->DisplayState(17));
  1674.  
  1675.  
  1676.   if((loco->LocoFlags&1)&&((LocoOn&13)==13)&&cab->Switch(0)<2)
  1677.    eng->cab->Displays[24].State=1;
  1678.   else
  1679.    eng->cab->Displays[24].State=0;
  1680.  
  1681.   //eng->cab->Displays[23].State=*Flags&4;
  1682.  
  1683.   //PSS
  1684.   if(eng->var[7]){
  1685.    if(eng->var[7]<2.0){
  1686.     eng->cab->Displays[26].State=1;
  1687.     eng->cab->Displays[27].State=1;
  1688.     eng->cab->Displays[28].State=0;
  1689.    }else{
  1690.     eng->var[8]+=time;
  1691.     if(eng->var[8]>2.0)eng->var[8]-=2.0;
  1692.     eng->cab->Displays[26].State=eng->var[8]>1.0?0:1;
  1693.     eng->cab->Displays[27].State=0;
  1694.     eng->cab->Displays[28].State=eng->var[8]>1.0?0:1;
  1695.    };
  1696.   }else{
  1697.    eng->cab->Displays[26].State=0;
  1698.    eng->cab->Displays[27].State=0;
  1699.    eng->cab->Displays[28].State=0;
  1700.   };
  1701.  
  1702.  };
  1703.  
  1704. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement