16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 19:49:19 +02:00

build 190223. doorstep cab control devices, door control system logic tweaks and fixes

This commit is contained in:
tmj-fstate
2019-02-24 02:26:53 +01:00
parent b72e237ab1
commit 8da3a9a74f
17 changed files with 176 additions and 83 deletions

View File

@@ -123,12 +123,13 @@ TButton::Turn( bool const State ) {
}
}
void TButton::Update() {
void TButton::Update( bool const Power ) {
if( ( bData != nullptr )
&& ( *bData != m_state ) ) {
auto const state { Power && ( bData ? *bData : m_state ) };
m_state = ( *bData );
if( state != m_state ) {
m_state = state;
play();
}

View File

@@ -30,7 +30,7 @@ public:
bool Active() {
return ( ( pModelOn != nullptr )
|| ( pModelOff != nullptr ) ); }
void Update();
void Update( bool const Power = true );
bool Init( std::string const &asName, TModel3d const *pModel, bool bNewOn = false );
void Load( cParser &Parser, TDynamicObject const *Owner );
void AssignBool(bool const *bValue);

View File

@@ -3274,6 +3274,10 @@ void TController::Doors( bool const Open, int const Side ) {
// the train conductor, if present, handles door operation also for human-driven trains
pVehicle->MoverParameters->OperateDoors( side::right, false );
pVehicle->MoverParameters->OperateDoors( side::left, false );
if( pVehicle->MoverParameters->Doors.permit_needed ) {
pVehicle->MoverParameters->PermitDoors( side::right, false );
pVehicle->MoverParameters->PermitDoors( side::left, false );
}
}
auto *vehicle = pVehicles[ 0 ]; // pojazd na czole składu
@@ -4184,11 +4188,12 @@ TController::UpdateSituation(double dt) {
{
// HACK: vehicle order in the consist is based on intended travel direction
// if our actual travel direction doesn't match that, we should be scanning from the other end of the consist
auto *frontvehicle { pVehicles[ ( mvOccupied->V * iDirection >= 0 ? end::front : end::rear ) ] };
// we cast to int to avoid getting confused by microstutters
auto *frontvehicle { pVehicles[ ( static_cast<int>( mvOccupied->V ) * iDirection >= 0 ? end::front : end::rear ) ] };
int routescandirection;
// for moving vehicle determine heading from velocity; for standing fall back on the set direction
if( ( std::abs( frontvehicle->MoverParameters->V ) > 0.1 ? // ignore potential micro-stutters in oposite direction during "almost stop"
if( ( std::abs( frontvehicle->MoverParameters->V ) > 0.5 ? // ignore potential micro-stutters in oposite direction during "almost stop"
frontvehicle->MoverParameters->V > 0.0 :
( pVehicle->DirectionGet() == frontvehicle->DirectionGet() ?
iDirection > 0 :

View File

@@ -2745,10 +2745,13 @@ bool TDynamicObject::Update(double dt, double dt1)
auto const amax = RapidMult * std::min(FmaxPN / masamax, MoverParameters->MED_amax);
auto const doorisopen {
( false == MoverParameters->Doors.instances[ side::right ].is_closed )
|| ( false == MoverParameters->Doors.instances[ side::left ].is_closed ) };
( false == MoverParameters->Doors.instances[ side::left ].is_closed )
|| ( false == MoverParameters->Doors.instances[ side::right ].is_closed )
|| ( MoverParameters->Doors.permit_needed
&& ( MoverParameters->Doors.instances[ side::left ].open_permit
|| MoverParameters->Doors.instances[ side::right ].open_permit ) ) };
if ((MoverParameters->Vel < 0.5) && (MoverParameters->BrakePress > 0.2) || doorisopen )
if ((MoverParameters->Vel < 0.5) && (MoverParameters->BrakePress > 0.2 || doorisopen))
{
MoverParameters->ShuntMode = true;
}
@@ -3822,15 +3825,6 @@ void TDynamicObject::RenderSounds() {
}
}
}
// doorstep sounds
if( door.step_position < 1.f ) {
for( auto &doorsounds : m_doorsounds ) {
if( doorsounds.placement == side ) {
doorsounds.step_open.play( sound_flags::exclusive );
doorsounds.step_close.stop();
}
}
}
}
if( true == door.is_closing ) {
// door sounds can start playing before the door begins moving but shouldn't cease once the door closes
@@ -3843,15 +3837,22 @@ void TDynamicObject::RenderSounds() {
}
}
}
// doorstep sounds are played only when the doorstep is moving
if( ( door.step_position > 0.f )
&& ( door.step_position < 1.f ) ) {
for( auto &doorsounds : m_doorsounds ) {
if( doorsounds.placement == side ) {
// determine left side doors from their offset
doorsounds.step_close.play( sound_flags::exclusive );
doorsounds.step_open.stop();
}
}
// doorstep sounds
if( door.step_unfolding ) {
for( auto &doorsounds : m_doorsounds ) {
if( doorsounds.placement == side ) {
doorsounds.step_open.play( sound_flags::exclusive );
doorsounds.step_close.stop();
}
}
}
if( door.step_folding ) {
for( auto &doorsounds : m_doorsounds ) {
if( doorsounds.placement == side ) {
// determine left side doors from their offset
doorsounds.step_close.play( sound_flags::exclusive );
doorsounds.step_open.stop();
}
}
}

View File

@@ -360,21 +360,35 @@ void TGauge::AssignInt(int *iValue)
iData = iValue;
};
void TGauge::AssignBool(bool *bValue)
{
m_datatype = 'b';
bData = bValue;
};
void TGauge::UpdateValue()
{ // ustawienie wartości docelowej z parametru
switch (m_datatype)
{ // to nie jest zbyt optymalne, można by zrobić osobne funkcje
case 'f':
UpdateValue( *fData );
break;
case 'd':
UpdateValue( *dData );
break;
case 'i':
UpdateValue( *iData );
break;
default:
break;
case 'f': {
UpdateValue( *fData );
break;
}
case 'd': {
UpdateValue( *dData );
break;
}
case 'i': {
UpdateValue( *iData );
break;
}
case 'b': {
UpdateValue( ( *bData ? 1.f : 0.f ) );
break;
}
default: {
break;
}
}
};

View File

@@ -48,6 +48,7 @@ public:
void AssignFloat(float *fValue);
void AssignDouble(double *dValue);
void AssignInt(int *iValue);
void AssignBool(bool *bValue);
void UpdateValue();
// returns offset of submodel associated with the button from the model centre
glm::vec3 model_offset() const;
@@ -82,6 +83,7 @@ private:
float *fData;
double *dData { nullptr };
int *iData;
bool *bData;
};
int m_soundtype { 0 }; // toggle between exclusive and multiple sound generation
sound_source m_soundtemplate { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // shared properties for control's sounds

View File

@@ -723,6 +723,8 @@ private:
bool is_closing { false }; // the door is currently closing
bool is_opening { false }; // the door is currently opening
bool is_open { false }; // the door is fully open
bool step_folding { false }; // the doorstep is currently closing
bool step_unfolding { false }; // the doorstep is currently opening
};
struct door_data {
@@ -748,6 +750,7 @@ private:
std::vector<int> permit_presets; // permit presets selectable with preset switch
// ld inputs
bool lock_enabled { true };
bool step_enabled { true };
// internal data
int permit_preset { -1 }; // curent position of preset selection switch
// vehicle parts
@@ -1493,6 +1496,7 @@ public:
bool LoadingDone(double LSpeed, std::string const &Loadname);
bool PermitDoors( side const Door, bool const State = true, range_t const Notify = range_t::consist );
bool ChangeDoorPermitPreset( int const Change, range_t const Notify = range_t::consist );
bool PermitDoorStep( bool const State, range_t const Notify = range_t::consist );
bool OperateDoors( side const Door, bool const State, range_t const Notify = range_t::consist );
bool LockDoors( bool const State, range_t const Notify = range_t::consist );
bool signal_departure( bool const State, range_t const Notify = range_t::consist ); // toggles departure warning

View File

@@ -4956,8 +4956,9 @@ double TMoverParameters::TractionForce( double dt ) {
}
dtrans = Hamulec->GetEDBCP();
if( ( ( false == Doors.instances[ side::left ].is_closed )
|| ( false == Doors.instances[ side::right ].is_closed ) ) ) {
if( ( false == Doors.instances[ side::left ].is_closed )
|| ( false == Doors.instances[ side::right ].is_closed )
|| ( Doors.permit_needed && ( Doors.instances[ side::left ].open_permit || Doors.instances[ side::right ].open_permit ) ) ) {
DynamicBrakeFlag = true;
}
else if (((dtrans < 0.25) && (LocHandle->GetCP() < 0.25) && (AnPos < 0.01)) ||
@@ -6637,6 +6638,27 @@ bool TMoverParameters::ChangeDoorPermitPreset( int const Change, range_t const N
return ( Doors.permit_preset != initialstate );
}
bool TMoverParameters::PermitDoorStep( bool const State, range_t const Notify ) {
auto const initialstate { Doors.step_enabled };
Doors.step_enabled = State;
if( Notify != range_t::local ) {
// wysłanie wyłączenia do pozostałych?
SendCtrlToNext(
"DoorStep",
( State == true ?
1 :
0 ),
CabNo,
( Notify == range_t::unit ?
coupling::control | coupling::permanent :
coupling::control ) );
}
return ( Doors.step_enabled != initialstate );
}
bool TMoverParameters::PermitDoors( side const Door, bool const State, range_t const Notify ) {
bool const initialstate { Doors.instances[Door].open_permit };
@@ -6719,6 +6741,8 @@ bool TMoverParameters::OperateDoors( side const Door, bool const State, range_t
// toggle door lock
bool TMoverParameters::LockDoors( bool const State, range_t const Notify ) {
auto const initialstate { Doors.lock_enabled };
Doors.lock_enabled = State;
if( Notify != range_t::local ) {
// wysłanie wyłączenia do pozostałych?
@@ -6733,7 +6757,7 @@ bool TMoverParameters::LockDoors( bool const State, range_t const Notify ) {
coupling::control ) );
}
return true;
return ( Doors.lock_enabled != initialstate );
}
// toggles departure warning
@@ -6799,7 +6823,8 @@ TMoverParameters::update_doors( double const Deltatime ) {
door.is_open =
( door.position >= Doors.range )
&& ( door.step_position >= ( Doors.step_range != 0.f ? 1.f : 0.f ) );
&& ( ( false == Doors.step_enabled )
|| ( door.step_position >= ( Doors.step_range != 0.f ? 1.f : 0.f ) ) );
door.is_closed =
( door.position <= 0.f )
&& ( door.step_position <= 0.f );
@@ -6833,6 +6858,19 @@ TMoverParameters::update_doors( double const Deltatime ) {
&& ( true == Battery )
&& ( false == openrequest )
&& ( door.is_closing || closerequest );
door.step_unfolding = (
( Doors.step_range != 0.f )
&& ( Doors.step_enabled )
&& ( false == Doors.is_locked )
&& ( door.step_position < 1.f )
&& ( door.is_opening ) );
door.step_folding = (
( door.step_position > 0.f ) // is unfolded
&& ( ( false == Doors.step_enabled ) // we lost permission to stay open or our door is calling the shots
|| ( Doors.permit_needed ?
( false == door.open_permit ) :
door.is_closing ) )
&& ( ( door.close_delay > Doors.close_delay ) || door.position <= 0.f ) ); // door is about to close, or already done
if( true == door.is_opening ) {
door.auto_timer = (
@@ -6840,17 +6878,14 @@ TMoverParameters::update_doors( double const Deltatime ) {
( remoteopencontrol && door.remote_open && Doors.auto_include_remote ) ? Doors.auto_duration :
-1.f );
}
// doors
if( ( true == door.is_opening )
&& ( door.position < Doors.range ) ) {
if( true == door.is_opening ) {
// open door
if( ( TrainType == dt_EZT )
|| ( TrainType == dt_DMU ) ) {
// multi-unit vehicles typically open door only after unfolding the doorstep
if( ( Doors.step_range == 0.f ) // no wait if no doorstep
|| ( Doors.step_type == 2 ) // no wait for rotating doorstep
|| ( door.step_position == 1.f ) ) {
if( ( false == door.step_unfolding ) // no wait if no doorstep
|| ( Doors.step_type == 2 ) ) { // no wait for rotating doorstep
door.position = std::min<float>(
Doors.range,
door.position + Doors.open_rate * Deltatime );
@@ -6863,8 +6898,7 @@ TMoverParameters::update_doors( double const Deltatime ) {
}
door.close_delay = 0.f;
}
if( ( true == door.is_closing )
&& ( door.position > 0.f ) ) {
if( true == door.is_closing ) {
// close door
door.close_delay += Deltatime;
if( door.close_delay > Doors.close_delay ) {
@@ -6874,22 +6908,18 @@ TMoverParameters::update_doors( double const Deltatime ) {
}
}
// doorsteps
if( ( true == door.is_opening )
&& ( Doors.step_range != 0.f )
&& ( door.step_position < 1.f ) ) {
if( door.step_unfolding ) {
// unfold left doorstep
door.step_position = std::min<float>(
1.f,
door.step_position + Doors.step_rate * Deltatime );
}
if( ( true == door.is_closing )
&& ( door.step_position > 0.f )
&& ( door.close_delay > Doors.close_delay ) ) {
if( door.step_folding ) {
// fold left doorstep
if( ( TrainType == dt_EZT )
|| ( TrainType == dt_DMU ) ) {
// multi-unit vehicles typically fold the doorstep only after closing the door
if( door.position == 0.f ) {
if( door.position <= 0.f ) {
door.step_position = std::max<float>(
0.f,
door.step_position - Doors.step_rate * Deltatime );
@@ -9640,6 +9670,13 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
false );
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
}
else if( Command == "DoorStep" ) {
Doors.step_enabled = (
CValue1 == 1 ?
true :
false );
OK = SendCtrlToNext( Command, CValue1, CValue2, Couplertype );
}
else if( Command == "DepartureSignal" ) {
DepartureSignal = (
CValue1 == 1 ?

View File

@@ -138,28 +138,17 @@ TButton &TCab::Button(int n)
}
};
void TCab::Update()
void TCab::Update( bool const Power )
{ // odczyt parametrów i ustawienie animacji submodelom
/*
int i;
for (i = 0; i < iGauges; ++i)
{ // animacje izometryczne
ggList[i].UpdateValue(); // odczyt parametru i przeliczenie na kąt
ggList[i].Update(); // ustawienie animacji
}
for (i = 0; i < iButtons; ++i)
{ // animacje dwustanowe
btList[i].Update(); // odczyt parametru i wybór submodelu
}
*/
for( auto &gauge : ggList ) {
// animacje izometryczne
gauge.UpdateValue(); // odczyt parametru i przeliczenie na kąt
gauge.Update(); // ustawienie animacji
}
for( auto &button : btList ) {
// animacje dwustanowe
button.Update(); // odczyt parametru i wybór submodelu
button.Update( Power ); // odczyt parametru i wybór submodelu
}
};
@@ -333,6 +322,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::doorcloseright, &TTrain::OnCommand_doorcloseright },
{ user_command::dooropenall, &TTrain::OnCommand_dooropenall },
{ user_command::doorcloseall, &TTrain::OnCommand_doorcloseall },
{ user_command::doorsteptoggle, &TTrain::OnCommand_doorsteptoggle },
{ user_command::carcouplingincrease, &TTrain::OnCommand_carcouplingincrease },
{ user_command::carcouplingdisconnect, &TTrain::OnCommand_carcouplingdisconnect },
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
@@ -4598,6 +4588,13 @@ void TTrain::OnCommand_doorcloseall( TTrain *Train, command_data const &Command
}
}
void TTrain::OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
Train->mvOccupied->PermitDoorStep( false == Train->mvOccupied->Doors.step_enabled );
}
}
void TTrain::OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command ) {
if( ( true == FreeFlyModeFlag )
@@ -5308,7 +5305,7 @@ bool TTrain::Update( double const Deltatime )
ggClockHInd.Update();
}
Cabine[iCabn].Update(); // nowy sposób ustawienia animacji
Cabine[iCabn].Update( mvControlled->Battery || mvControlled->ConverterFlag ); // nowy sposób ustawienia animacji
if (ggZbS.SubModel)
{
ggZbS.UpdateValue(mvOccupied->Handle->GetCP());
@@ -7678,7 +7675,8 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
// TODO: move viable dedicated lights to the automatic light array
std::unordered_map<std::string, bool *> const autolights = {
{ "i-doorpermit_left:", &mvOccupied->Doors.instances[side::left].open_permit },
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ side::right ].open_permit }
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ side::right ].open_permit },
{ "i-doorstep:", &mvOccupied->Doors.step_enabled }
};
{
auto lookup = autolights.find( Label );
@@ -7835,14 +7833,31 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "universal8:", ggUniversals[ 8 ] },
{ "universal9:", ggUniversals[ 9 ] }
};
auto lookup = gauges.find( Label );
if( lookup != gauges.end() ) {
lookup->second.Load( Parser, DynamicObject);
m_controlmapper.insert( lookup->second, lookup->first );
return true;
{
auto lookup = gauges.find( Label );
if( lookup != gauges.end() ) {
lookup->second.Load( Parser, DynamicObject );
m_controlmapper.insert( lookup->second, lookup->first );
return true;
}
}
// TODO: move viable dedicated gauges to the automatic array
std::unordered_map<std::string, bool *> const autoboolgauges = {
{ "doorstep_sw:", &mvOccupied->Doors.step_enabled }
};
{
auto lookup = autoboolgauges.find( Label );
if( lookup != autoboolgauges.end() ) {
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna lampka
gauge.Load( Parser, DynamicObject );
gauge.AssignBool( lookup->second );
m_controlmapper.insert( gauge, lookup->first );
return true;
}
}
// ABu 090305: uniwersalne przyciski lub inne rzeczy
else if( Label == "mainctrlact:" ) {
if( Label == "mainctrlact:" ) {
ggMainCtrlAct.Load( Parser, DynamicObject);
}
// SEKCJA WSKAZNIKOW
@@ -8032,6 +8047,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
}
}
}
else if( Label == "clock_seconds:" ) {
ggClockSInd.Load( Parser, DynamicObject );
}
else if (Label == "evoltage:")
{
// woltomierz napiecia silnikow

View File

@@ -32,7 +32,7 @@ class TCab {
public:
// methods
void Load(cParser &Parser);
void Update();
void Update( bool const Power );
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
TButton &Button( int n = -1 ); // pobranie adresu obiektu
// members
@@ -51,7 +51,7 @@ public:
private:
// members
std::vector<TGauge> ggList;
std::deque<TGauge> ggList; // need a container which doesn't invalidate references
std::vector<TButton> btList;
};
@@ -323,6 +323,7 @@ class TTrain
static void OnCommand_doorcloseright( TTrain *Train, command_data const &Command );
static void OnCommand_dooropenall( TTrain *Train, command_data const &Command );
static void OnCommand_doorcloseall( TTrain *Train, command_data const &Command );
static void OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command );
static void OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command );
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );

View File

@@ -152,6 +152,7 @@ commanddescription_sequence Commands_descriptions = {
{ "doorcloseleft", command_target::vehicle },
{ "doorcloseright", command_target::vehicle },
{ "doorcloseall", command_target::vehicle },
{ "doorsteptoggle", command_target::vehicle },
{ "departureannounce", command_target::vehicle },
{ "doorlocktoggle", command_target::vehicle },
{ "pantographcompressorvalvetoggle", command_target::vehicle },

View File

@@ -145,6 +145,7 @@ enum class user_command {
doorcloseleft,
doorcloseright,
doorcloseall,
doorsteptoggle,
departureannounce,
doorlocktoggle,
pantographcompressorvalvetoggle,

View File

@@ -154,6 +154,7 @@ driverkeyboard_input::default_bindings() {
// doorcloseleft,
// doorcloseright,
{ user_command::doorcloseall, GLFW_KEY_SLASH | keymodifier::control },
// doorsteptoggle,
{ user_command::departureannounce, GLFW_KEY_SLASH },
{ user_command::doorlocktoggle, GLFW_KEY_S | keymodifier::control },
{ user_command::pantographcompressorvalvetoggle, GLFW_KEY_V | keymodifier::control },

View File

@@ -584,6 +584,9 @@ drivermouse_input::default_bindings() {
{ "dooralloff_sw:", {
user_command::doorcloseall,
user_command::none } },
{ "doorstep_sw:", {
user_command::doorsteptoggle,
user_command::none } },
{ "departure_signal_bt:", {
user_command::departureannounce,
user_command::none } },

View File

@@ -109,6 +109,7 @@ init() {
"right door (close)",
"all doors (open)",
"all doors (close)",
"doorstep",
"departure signal",
"upper headlight",
"left headlight",
@@ -252,6 +253,7 @@ init() {
"drzwi prawe (zamknij)",
"drzwi (otworz)",
"drzwi (zamknij)",
"stopien drzwi",
"sygnal odjazdu",
"reflektor gorny",
"reflektor lewy",
@@ -366,6 +368,7 @@ init() {
"doorrightoff_sw:",
"doorallon_sw:",
"dooralloff_sw:",
"doorstep_sw:",
"departure_signal_bt:",
"upperlight_sw:",
"leftlight_sw:",

View File

@@ -98,6 +98,7 @@ enum string {
cab_doorrightoff_sw,
cab_doorallon_sw,
cab_dooralloff_sw,
cab_doorstep_sw,
cab_departure_signal_bt,
cab_upperlight_sw,
cab_leftlight_sw,

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 19
#define VERSION_MINOR 215
#define VERSION_MINOR 223
#define VERSION_REVISION 0