mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 15:39:19 +02:00
post-merge fixes
This commit is contained in:
34
Driver.cpp
34
Driver.cpp
@@ -3080,8 +3080,8 @@ bool TController::DecBrakeEIM()
|
|||||||
|
|
||||||
bool TController::IncSpeed()
|
bool TController::IncSpeed()
|
||||||
{ // zwiększenie prędkości; zwraca false, jeśli dalej się nie da zwiększać
|
{ // zwiększenie prędkości; zwraca false, jeśli dalej się nie da zwiększać
|
||||||
if( true == tsGuardSignal.is_playing() ) {
|
if( fActionTime < 0.0 ) {
|
||||||
// jeśli gada, to nie jedziemy
|
// gdy jest nakaz poczekać z jazdą, to nie ruszać
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool OK = true;
|
bool OK = true;
|
||||||
@@ -3093,6 +3093,7 @@ bool TController::IncSpeed()
|
|||||||
if (mvOccupied->SpringBrake.IsActive && mvOccupied->SpringBrake.Activate) {
|
if (mvOccupied->SpringBrake.IsActive && mvOccupied->SpringBrake.Activate) {
|
||||||
mvOccupied->SpringBrakeActivate(false);
|
mvOccupied->SpringBrakeActivate(false);
|
||||||
}
|
}
|
||||||
|
// Doors() call can potentially adjust fActionTime
|
||||||
if( fActionTime < 0.0 ) {
|
if( fActionTime < 0.0 ) {
|
||||||
// gdy jest nakaz poczekać z jazdą, to nie ruszać
|
// gdy jest nakaz poczekać z jazdą, to nie ruszać
|
||||||
return false;
|
return false;
|
||||||
@@ -5717,6 +5718,8 @@ TController::UpdateSituation(double dt) {
|
|||||||
// place virtual conductor some distance away
|
// place virtual conductor some distance away
|
||||||
tsGuardSignal.offset( { pVehicle->MoverParameters->Dim.W * -0.75f, 1.7f, std::min( -20.0, -0.2 * fLength ) } );
|
tsGuardSignal.offset( { pVehicle->MoverParameters->Dim.W * -0.75f, 1.7f, std::min( -20.0, -0.2 * fLength ) } );
|
||||||
tsGuardSignal.play( sound_flags::exclusive );
|
tsGuardSignal.play( sound_flags::exclusive );
|
||||||
|
// NOTE: we can't rely on is_playing() check as sound playback is based on distance from local camera
|
||||||
|
fActionTime = -5.0; // niech trochę potrzyma
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// if (iGuardRadio==iRadioChannel) //zgodność kanału
|
// if (iGuardRadio==iRadioChannel) //zgodność kanału
|
||||||
@@ -5727,6 +5730,8 @@ TController::UpdateSituation(double dt) {
|
|||||||
tsGuardSignal.owner( pVehicle );
|
tsGuardSignal.owner( pVehicle );
|
||||||
tsGuardSignal.offset( { 0.f, 2.f, pVehicle->MoverParameters->Dim.L * 0.4f * ( pVehicle->MoverParameters->CabOccupied < 0 ? -1 : 1 ) } );
|
tsGuardSignal.offset( { 0.f, 2.f, pVehicle->MoverParameters->Dim.L * 0.4f * ( pVehicle->MoverParameters->CabOccupied < 0 ? -1 : 1 ) } );
|
||||||
tsGuardSignal.play( sound_flags::exclusive );
|
tsGuardSignal.play( sound_flags::exclusive );
|
||||||
|
// NOTE: we can't rely on is_playing() check as sound playback is based on distance from local camera
|
||||||
|
fActionTime = -5.0; // niech trochę potrzyma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6984,7 +6989,7 @@ void TController::UpdateDelayFlag() {
|
|||||||
|
|
||||||
void TController::TakeControl( bool const Aidriver, bool const Forcevehiclecheck )
|
void TController::TakeControl( bool const Aidriver, bool const Forcevehiclecheck )
|
||||||
{ // przejęcie kontroli przez AI albo oddanie
|
{ // przejęcie kontroli przez AI albo oddanie
|
||||||
if (AIControllFlag == Aidriver)
|
if ((AIControllFlag == Aidriver) && (!Forcevehiclecheck))
|
||||||
return; // już jest jak ma być
|
return; // już jest jak ma być
|
||||||
if (Aidriver) //żeby nie wykonywać dwa razy
|
if (Aidriver) //żeby nie wykonywać dwa razy
|
||||||
{ // teraz AI prowadzi
|
{ // teraz AI prowadzi
|
||||||
@@ -7145,12 +7150,29 @@ TController::TrackBlock() const {
|
|||||||
|
|
||||||
void TController::MoveTo(TDynamicObject *to)
|
void TController::MoveTo(TDynamicObject *to)
|
||||||
{ // przesunięcie AI do innego pojazdu (przy zmianie kabiny)
|
{ // przesunięcie AI do innego pojazdu (przy zmianie kabiny)
|
||||||
// mvOccupied->CabDeactivisation(); //wyłączenie kabiny w opuszczanym
|
if( ( to->Mechanik != nullptr )
|
||||||
pVehicle->Mechanik = to->Mechanik; //żeby się zamieniły, jak jest jakieś drugie
|
&& ( to->Mechanik != this ) ) {
|
||||||
|
// ai controller thunderdome, there can be only one
|
||||||
|
if( to->Mechanik->AIControllFlag ) {
|
||||||
|
if( to->Mechanik->primary() ) {
|
||||||
|
// take over boss duties
|
||||||
|
primary( true );
|
||||||
|
}
|
||||||
|
SafeDelete( to->Mechanik );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// can't quite delete a human
|
||||||
|
if( AIControllFlag ) {
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pVehicle->Mechanik = nullptr;
|
||||||
pVehicle = to;
|
pVehicle = to;
|
||||||
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu
|
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu
|
||||||
pVehicle->Mechanik = this;
|
pVehicle->Mechanik = this;
|
||||||
// iDirection=0; //kierunek jazdy trzeba dopiero zgadnąć
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TController::ControllingSet()
|
void TController::ControllingSet()
|
||||||
|
|||||||
15
DynObj.cpp
15
DynObj.cpp
@@ -2220,17 +2220,6 @@ TDynamicObject::create_controller( std::string const Type, bool const Trainset )
|
|||||||
|
|
||||||
if( Type == "" ) { return; }
|
if( Type == "" ) { return; }
|
||||||
|
|
||||||
if( asName == Global.local_start_vehicle ) {
|
|
||||||
// jeśli pojazd wybrany do prowadzenia
|
|
||||||
if( MoverParameters->EngineType != TEngineType::Dumb ) {
|
|
||||||
// wsadzamy tam sterującego
|
|
||||||
Controller = Humandriver;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// w przeciwnym razie trzeba włączyć pokazywanie kabiny
|
|
||||||
bDisplayCab = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// McZapkie-151102: rozkład jazdy czytany z pliku *.txt z katalogu w którym jest sceneria
|
// McZapkie-151102: rozkład jazdy czytany z pliku *.txt z katalogu w którym jest sceneria
|
||||||
if( ( Type == "1" )
|
if( ( Type == "1" )
|
||||||
|| ( Type == "2" ) ) {
|
|| ( Type == "2" ) ) {
|
||||||
@@ -5539,8 +5528,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
|||||||
for( auto &bogie : m_bogiesounds ) {
|
for( auto &bogie : m_bogiesounds ) {
|
||||||
bogie.start( (
|
bogie.start( (
|
||||||
bogieidx % 2 ?
|
bogieidx % 2 ?
|
||||||
Random( 0.0, 30.0 ) :
|
LocalRandom( 0.0, 30.0 ) :
|
||||||
Random( 50.0, 80.0 ) )
|
LocalRandom( 50.0, 80.0 ) )
|
||||||
* 0.01 );
|
* 0.01 );
|
||||||
++bogieidx;
|
++bogieidx;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ struct global_settings {
|
|||||||
bool ready_to_load { false };
|
bool ready_to_load { false };
|
||||||
std::time_t starting_timestamp = 0; // starting time, in local timezone
|
std::time_t starting_timestamp = 0; // starting time, in local timezone
|
||||||
uint32_t random_seed = 0;
|
uint32_t random_seed = 0;
|
||||||
TDynamicObject *changeDynObj{ nullptr };// info o zmianie pojazdu
|
|
||||||
TCamera pCamera; // parametry kamery
|
TCamera pCamera; // parametry kamery
|
||||||
TCamera pDebugCamera;
|
TCamera pDebugCamera;
|
||||||
std::array<Math3D::vector3, 10> FreeCameraInit; // pozycje kamery
|
std::array<Math3D::vector3, 10> FreeCameraInit; // pozycje kamery
|
||||||
|
|||||||
7
Names.h
7
Names.h
@@ -58,13 +58,6 @@ public:
|
|||||||
|
|
||||||
m_itemmap.erase(lookup);
|
m_itemmap.erase(lookup);
|
||||||
}
|
}
|
||||||
uint32_t find_id( std::string const &Name) const {
|
|
||||||
auto lookup = m_itemmap.find( Name );
|
|
||||||
return (
|
|
||||||
lookup != m_itemmap.end() ?
|
|
||||||
lookup->second :
|
|
||||||
-1 );
|
|
||||||
}
|
|
||||||
void purge (Type_ *Item)
|
void purge (Type_ *Item)
|
||||||
{
|
{
|
||||||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||||||
|
|||||||
44
Train.cpp
44
Train.cpp
@@ -5827,7 +5827,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial
|
if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial
|
||||||
{
|
{
|
||||||
if (fTachoVelocity > 1) // jedzie
|
if (fTachoVelocity > 1) // jedzie
|
||||||
fTachoVelocityJump = fTachoVelocity + (2.0 - Random(3) + Random(3)) * 0.5;
|
fTachoVelocityJump = fTachoVelocity + (2.0 - LocalRandom(3) + LocalRandom(3)) * 0.5;
|
||||||
else
|
else
|
||||||
fTachoVelocityJump = 0; // stoi
|
fTachoVelocityJump = 0; // stoi
|
||||||
fTachoTimer = ff; // juz zmienil
|
fTachoTimer = ff; // juz zmienil
|
||||||
@@ -6049,7 +6049,8 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
if ((mvControlled->CompressorFlag == true) && (mvControlled->CompressorPower == 1) &&
|
if ((mvControlled->CompressorFlag == true) && (mvControlled->CompressorPower == 1) &&
|
||||||
((mvControlled->EngineType == TEngineType::ElectricSeriesMotor) ||
|
((mvControlled->EngineType == TEngineType::ElectricSeriesMotor) ||
|
||||||
(mvControlled->TrainType == dt_EZT)) &&
|
(mvControlled->TrainType == dt_EZT)) &&
|
||||||
(DynamicObject->Controller == Humandriver)) // hunter-110212: poprawka dla EZT
|
(DynamicObject->Controller == Humandriver) // hunter-110212: poprawka dla EZT
|
||||||
|
&& ( false == DynamicObject->Mechanik->AIControllFlag ) )
|
||||||
{ // hunter-091012: poprawka (zmiana warunku z CompressorPower /rozne od 0/ na /rowne 1/)
|
{ // hunter-091012: poprawka (zmiana warunku z CompressorPower /rozne od 0/ na /rowne 1/)
|
||||||
if (fConverterTimer < fConverterPrzekaznik)
|
if (fConverterTimer < fConverterPrzekaznik)
|
||||||
{
|
{
|
||||||
@@ -7496,6 +7497,9 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
|||||||
}
|
}
|
||||||
// reset view angles
|
// reset view angles
|
||||||
pMechViewAngle = { 0.0, 0.0 };
|
pMechViewAngle = { 0.0, 0.0 };
|
||||||
|
|
||||||
|
is_cab_initialized = true; // the attempt may fail, but it's the attempt that counts
|
||||||
|
|
||||||
bool parse = false;
|
bool parse = false;
|
||||||
int cabindex = 0;
|
int cabindex = 0;
|
||||||
DynamicObject->mdKabina = NULL; // likwidacja wskaźnika na dotychczasową kabinę
|
DynamicObject->mdKabina = NULL; // likwidacja wskaźnika na dotychczasową kabinę
|
||||||
@@ -7871,7 +7875,6 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
|||||||
// > Ra: to nie może być tak robione, to zbytnia proteza jest
|
// > Ra: to nie może być tak robione, to zbytnia proteza jest
|
||||||
// indeed, too much hacks...
|
// indeed, too much hacks...
|
||||||
// TODO: cleanup
|
// TODO: cleanup
|
||||||
|
|
||||||
TTrain *target_train = simulation::Trains.find(target->name());
|
TTrain *target_train = simulation::Trains.find(target->name());
|
||||||
if (target_train) {
|
if (target_train) {
|
||||||
// let's try to destroy this TTrain and move to already existing one
|
// let's try to destroy this TTrain and move to already existing one
|
||||||
@@ -7882,18 +7885,22 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
|||||||
Occupied()->CabDeactivisation();
|
Occupied()->CabDeactivisation();
|
||||||
Occupied()->CabOccupied = 0;
|
Occupied()->CabOccupied = 0;
|
||||||
Occupied()->BrakeLevelSet(Occupied()->Handle->GetPos(bh_NP)); //rozwala sterowanie hamulcem GF 04-2016
|
Occupied()->BrakeLevelSet(Occupied()->Handle->GetPos(bh_NP)); //rozwala sterowanie hamulcem GF 04-2016
|
||||||
|
Occupied()->MainCtrlPos = Occupied()->MainCtrlNoPowerPos();
|
||||||
|
Occupied()->ScndCtrlPos = 0;
|
||||||
Dynamic()->MechInside = false;
|
Dynamic()->MechInside = false;
|
||||||
Dynamic()->Controller = AIdriver;
|
Dynamic()->Controller = AIdriver;
|
||||||
|
|
||||||
Dynamic()->bDisplayCab = false;
|
Dynamic()->bDisplayCab = false;
|
||||||
Dynamic()->ABuSetModelShake( {} );
|
Dynamic()->ABuSetModelShake( {} );
|
||||||
|
|
||||||
|
if( Dynamic()->Mechanik ) {
|
||||||
Dynamic()->Mechanik->MoveTo( target );
|
Dynamic()->Mechanik->MoveTo( target );
|
||||||
|
}
|
||||||
|
|
||||||
target_train->Occupied()->LimPipePress = target_train->Occupied()->PipePress;
|
target_train->Occupied()->LimPipePress = target_train->Occupied()->PipePress;
|
||||||
target_train->Occupied()->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
target_train->Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
||||||
target_train->Dynamic()->MechInside = true;
|
target_train->Dynamic()->MechInside = true;
|
||||||
target_train->Dynamic()->Controller = Humandriver;
|
target_train->Dynamic()->Controller = ( target_train->Dynamic()->Mechanik ? !target_train->Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
||||||
} else {
|
} else {
|
||||||
target_train->Dynamic()->bDisplayCab = false;
|
target_train->Dynamic()->bDisplayCab = false;
|
||||||
target_train->Dynamic()->ABuSetModelShake( {} );
|
target_train->Dynamic()->ABuSetModelShake( {} );
|
||||||
@@ -7922,20 +7929,24 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
|||||||
Occupied()->CabDeactivisation();
|
Occupied()->CabDeactivisation();
|
||||||
Occupied()->CabOccupied = 0;
|
Occupied()->CabOccupied = 0;
|
||||||
Occupied()->BrakeLevelSet(Occupied()->Handle->GetPos(bh_NP)); //rozwala sterowanie hamulcem GF 04-2016
|
Occupied()->BrakeLevelSet(Occupied()->Handle->GetPos(bh_NP)); //rozwala sterowanie hamulcem GF 04-2016
|
||||||
|
Occupied()->MainCtrlPos = Occupied()->MainCtrlNoPowerPos();
|
||||||
|
Occupied()->ScndCtrlPos = 0;
|
||||||
Dynamic()->MechInside = false;
|
Dynamic()->MechInside = false;
|
||||||
Dynamic()->Controller = AIdriver;
|
Dynamic()->Controller = AIdriver;
|
||||||
|
|
||||||
Dynamic()->bDisplayCab = false;
|
Dynamic()->bDisplayCab = false;
|
||||||
Dynamic()->ABuSetModelShake( {} );
|
Dynamic()->ABuSetModelShake( {} );
|
||||||
|
|
||||||
|
if( Dynamic()->Mechanik ) {
|
||||||
Dynamic()->Mechanik->MoveTo( target );
|
Dynamic()->Mechanik->MoveTo( target );
|
||||||
|
}
|
||||||
|
|
||||||
DynamicSet(target);
|
DynamicSet(target);
|
||||||
|
|
||||||
Occupied()->LimPipePress = Occupied()->PipePress;
|
Occupied()->LimPipePress = Occupied()->PipePress;
|
||||||
Occupied()->CabActivisation(); // załączenie rozrządu (wirtualne kabiny)
|
Occupied()->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
||||||
Dynamic()->MechInside = true;
|
Dynamic()->MechInside = true;
|
||||||
Dynamic()->Controller = Humandriver;
|
Dynamic()->Controller = ( Dynamic()->Mechanik ? !Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
||||||
} else {
|
} else {
|
||||||
Dynamic()->bDisplayCab = false;
|
Dynamic()->bDisplayCab = false;
|
||||||
Dynamic()->ABuSetModelShake( {} );
|
Dynamic()->ABuSetModelShake( {} );
|
||||||
@@ -7953,6 +7964,7 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
|||||||
// add it back with updated dynamic name
|
// add it back with updated dynamic name
|
||||||
simulation::Trains.insert(this);
|
simulation::Trains.insert(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks whether specified point is within boundaries of the active cab
|
// checks whether specified point is within boundaries of the active cab
|
||||||
@@ -8302,7 +8314,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
|||||||
if( true == mvOccupied->Radio ) {
|
if( true == mvOccupied->Radio ) {
|
||||||
ggRadioButton.PutValue( 1.f );
|
ggRadioButton.PutValue( 1.f );
|
||||||
}
|
}
|
||||||
ggRadioChannelSelector.PutValue( RadioChannel() - 1 );
|
ggRadioChannelSelector.PutValue( ( Dynamic()->Mechanik ? Dynamic()->Mechanik->iRadioChannel : 1 ) - 1 );
|
||||||
// pantographs
|
// pantographs
|
||||||
/*
|
/*
|
||||||
if( mvOccupied->PantSwitchType != "impulse" ) {
|
if( mvOccupied->PantSwitchType != "impulse" ) {
|
||||||
@@ -9262,3 +9274,19 @@ void train_table::update(double dt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TTrain *
|
||||||
|
train_table::find_id( std::uint16_t const Id ) const {
|
||||||
|
|
||||||
|
if( Id == 0 ) { return nullptr; }
|
||||||
|
|
||||||
|
for( TTrain *train : m_items ) {
|
||||||
|
if( !train ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if( train->id() == Id ) {
|
||||||
|
return train;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|||||||
4
Train.h
4
Train.h
@@ -716,6 +716,7 @@ public: // reszta może by?publiczna
|
|||||||
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
// McZapkie: opis kabiny - obszar poruszania sie mechanika oraz zajetosc
|
||||||
std::array<TCab, 3> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
std::array<TCab, 3> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
||||||
int iCabn { 0 }; // 0: mid, 1: front, 2: rear
|
int iCabn { 0 }; // 0: mid, 1: front, 2: rear
|
||||||
|
bool is_cab_initialized { false };
|
||||||
// McZapkie: do poruszania sie po kabinie
|
// McZapkie: do poruszania sie po kabinie
|
||||||
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
||||||
Math3D::vector3 MirrorPosition( bool lewe );
|
Math3D::vector3 MirrorPosition( bool lewe );
|
||||||
@@ -773,7 +774,7 @@ private:
|
|||||||
float fDieselParams[9][10]; // parametry dla silnikow asynchronicznych
|
float fDieselParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||||
// plays provided sound from position of the radio
|
// plays provided sound from position of the radio
|
||||||
void radio_message( sound_source *Message, int const Channel );
|
void radio_message( sound_source *Message, int const Channel );
|
||||||
inline auto const &RadioChannel() const { return Dynamic()->Mechanik->iRadioChannel; }
|
inline auto const RadioChannel() const { return ( Dynamic()->Mechanik ? Dynamic()->Mechanik->iRadioChannel : 1 ); }
|
||||||
inline auto &RadioChannel() { return Dynamic()->Mechanik->iRadioChannel; }
|
inline auto &RadioChannel() { return Dynamic()->Mechanik->iRadioChannel; }
|
||||||
inline TDynamicObject *Dynamic() { return DynamicObject; };
|
inline TDynamicObject *Dynamic() { return DynamicObject; };
|
||||||
inline TDynamicObject const *Dynamic() const { return DynamicObject; };
|
inline TDynamicObject const *Dynamic() const { return DynamicObject; };
|
||||||
@@ -794,6 +795,7 @@ private:
|
|||||||
class train_table : public basic_table<TTrain> {
|
class train_table : public basic_table<TTrain> {
|
||||||
public:
|
public:
|
||||||
void update( double dt );
|
void update( double dt );
|
||||||
|
TTrain *find_id( std::uint16_t const Id ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -167,13 +167,26 @@ void eu07_application::queue_quit() {
|
|||||||
glfwSetWindowShouldClose(m_windows[0], GLFW_TRUE);
|
glfwSetWindowShouldClose(m_windows[0], GLFW_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
eu07_application::is_server() const {
|
||||||
|
|
||||||
|
return ( m_network && m_network->servers );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
eu07_application::is_client() const {
|
||||||
|
|
||||||
|
return ( m_network && m_network->client );
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
eu07_application::run() {
|
eu07_application::run() {
|
||||||
|
auto frame{ 0 };
|
||||||
// main application loop
|
// main application loop
|
||||||
while (!glfwWindowShouldClose( m_windows.front() ) && !m_modestack.empty())
|
while (!glfwWindowShouldClose( m_windows.front() ) && !m_modestack.empty())
|
||||||
{
|
{
|
||||||
Timer::subsystem.mainloop_total.start();
|
Timer::subsystem.mainloop_total.start();
|
||||||
|
glfwPollEvents();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// multiplayer command relaying logic can seem a bit complex
|
// multiplayer command relaying logic can seem a bit complex
|
||||||
@@ -191,6 +204,9 @@ eu07_application::run() {
|
|||||||
int loop_remaining = MAX_NETWORK_PER_FRAME;
|
int loop_remaining = MAX_NETWORK_PER_FRAME;
|
||||||
while (--loop_remaining > 0)
|
while (--loop_remaining > 0)
|
||||||
{
|
{
|
||||||
|
#ifdef EU07_DEBUG_NETSYNC
|
||||||
|
WriteLog( "net: frame " + std::to_string(++frame) + " start", logtype::net );
|
||||||
|
#endif
|
||||||
command_queue::commands_map commands_to_exec;
|
command_queue::commands_map commands_to_exec;
|
||||||
command_queue::commands_map local_commands = simulation::Commands.pop_intercept_queue();
|
command_queue::commands_map local_commands = simulation::Commands.pop_intercept_queue();
|
||||||
double slave_sync;
|
double slave_sync;
|
||||||
@@ -272,7 +288,7 @@ eu07_application::run() {
|
|||||||
float awaiting = m_network->client->get_awaiting_frames();
|
float awaiting = m_network->client->get_awaiting_frames();
|
||||||
|
|
||||||
// TODO: don't meddle with mode progresbar
|
// TODO: don't meddle with mode progresbar
|
||||||
m_modes[m_modestack.top()]->set_progress(100.0f, 100.0f * (received - awaiting) / received);
|
m_modes[m_modestack.top()]->set_progress(100.0f * (received - awaiting) / received);
|
||||||
} else {
|
} else {
|
||||||
m_modes[m_modestack.top()]->set_progress(0.0f, 0.0f);
|
m_modes[m_modestack.top()]->set_progress(0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
@@ -295,8 +311,6 @@ eu07_application::run() {
|
|||||||
if (!GfxRenderer->Render())
|
if (!GfxRenderer->Render())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
glfwPollEvents();
|
|
||||||
|
|
||||||
if (m_modestack.empty())
|
if (m_modestack.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,10 @@ public:
|
|||||||
generate_sync();
|
generate_sync();
|
||||||
void
|
void
|
||||||
queue_quit();
|
queue_quit();
|
||||||
|
bool
|
||||||
|
is_server() const;
|
||||||
|
bool
|
||||||
|
is_client() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
|
|||||||
@@ -386,7 +386,7 @@ command_relay::post(user_command const Command, double const Param1, double cons
|
|||||||
Position = Global.pCamera.Pos;
|
Position = Global.pCamera.Pos;
|
||||||
|
|
||||||
uint32_t combined_recipient = static_cast<uint32_t>( command.target ) | Recipient;
|
uint32_t combined_recipient = static_cast<uint32_t>( command.target ) | Recipient;
|
||||||
command_data commanddata({Command, Action, Param1, Param2, Timer::GetDeltaTime(), FreeFlyModeFlag, Position });
|
command_data commanddata({Command, Action, Param1, Param2, Timer::GetDeltaTime(), Position });
|
||||||
if (Payload)
|
if (Payload)
|
||||||
commanddata.payload = *Payload;
|
commanddata.payload = *Payload;
|
||||||
|
|
||||||
|
|||||||
@@ -324,7 +324,6 @@ struct command_data {
|
|||||||
double param2;
|
double param2;
|
||||||
double time_delta;
|
double time_delta;
|
||||||
|
|
||||||
bool freefly;
|
|
||||||
glm::vec3 location;
|
glm::vec3 location;
|
||||||
|
|
||||||
std::string payload;
|
std::string payload;
|
||||||
|
|||||||
223
drivermode.cpp
223
drivermode.cpp
@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
#include "simulationtime.h"
|
#include "simulationtime.h"
|
||||||
#include "simulationenvironment.h"
|
#include "simulationenvironment.h"
|
||||||
|
#include "scene.h"
|
||||||
#include "lightarray.h"
|
#include "lightarray.h"
|
||||||
#include "particles.h"
|
#include "particles.h"
|
||||||
#include "Train.h"
|
#include "Train.h"
|
||||||
@@ -146,14 +147,15 @@ driver_mode::update() {
|
|||||||
|
|
||||||
double const deltatime = Timer::GetDeltaTime(); // 0.0 gdy pauza
|
double const deltatime = Timer::GetDeltaTime(); // 0.0 gdy pauza
|
||||||
|
|
||||||
if( Global.iPause == 0 ) {
|
|
||||||
// jak pauza, to nie ma po co tego przeliczać
|
|
||||||
simulation::Time.update( deltatime );
|
|
||||||
}
|
|
||||||
simulation::State.update_clocks();
|
simulation::State.update_clocks();
|
||||||
simulation::State.update_scripting_interface();
|
simulation::State.update_scripting_interface();
|
||||||
simulation::Environment.update();
|
simulation::Environment.update();
|
||||||
|
|
||||||
|
if (deltatime != 0.0)
|
||||||
|
{
|
||||||
|
// jak pauza, to nie ma po co tego przeliczać
|
||||||
|
simulation::Time.update( deltatime );
|
||||||
|
|
||||||
// fixed step, simulation time based updates
|
// fixed step, simulation time based updates
|
||||||
// m_primaryupdateaccumulator += dt; // unused for the time being
|
// m_primaryupdateaccumulator += dt; // unused for the time being
|
||||||
m_secondaryupdateaccumulator += deltatime;
|
m_secondaryupdateaccumulator += deltatime;
|
||||||
@@ -229,6 +231,7 @@ driver_mode::update() {
|
|||||||
if (!change_train.empty()) {
|
if (!change_train.empty()) {
|
||||||
TTrain *train = simulation::Trains.find(change_train);
|
TTrain *train = simulation::Trains.find(change_train);
|
||||||
if (train) {
|
if (train) {
|
||||||
|
Global.local_start_vehicle = change_train;
|
||||||
simulation::Train = train;
|
simulation::Train = train;
|
||||||
InOutKey();
|
InOutKey();
|
||||||
m_relay.post(user_command::aidriverdisable, 0.0, 0.0, GLFW_PRESS, 0);
|
m_relay.post(user_command::aidriverdisable, 0.0, 0.0, GLFW_PRESS, 0);
|
||||||
@@ -245,20 +248,7 @@ driver_mode::update() {
|
|||||||
// fixup camera after vehicle switch
|
// fixup camera after vehicle switch
|
||||||
CabView();
|
CabView();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if( Global.changeDynObj ) {
|
|
||||||
// ABu zmiana pojazdu - przejście do innego
|
|
||||||
ChangeDynamic();
|
|
||||||
// move inside, but only if the human is in charge (otherwise we'll get pulled in when ai switches cabs)
|
|
||||||
if( ( simulation::Train != nullptr )
|
|
||||||
&& ( simulation::Train->Dynamic() != nullptr )
|
|
||||||
&& ( simulation::Train->Dynamic()->Mechanik != nullptr )
|
|
||||||
&& ( simulation::Train->Dynamic()->Mechanik->AIControllFlag == false )
|
|
||||||
&& ( true == FreeFlyModeFlag ) ) {
|
|
||||||
InOutKey();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if( simulation::Train != nullptr )
|
if( simulation::Train != nullptr )
|
||||||
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( simulation::Train->Dynamic() );
|
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( simulation::Train->Dynamic() );
|
||||||
else
|
else
|
||||||
@@ -268,6 +258,7 @@ driver_mode::update() {
|
|||||||
simulation::Events.update();
|
simulation::Events.update();
|
||||||
simulation::Region->update_events();
|
simulation::Region->update_events();
|
||||||
simulation::Lights.update();
|
simulation::Lights.update();
|
||||||
|
}
|
||||||
|
|
||||||
// render time routines follow:
|
// render time routines follow:
|
||||||
|
|
||||||
@@ -359,10 +350,10 @@ driver_mode::update() {
|
|||||||
// NOTE: particle system runs on simulation time, but needs actual camera position to determine how to update each particle source
|
// NOTE: particle system runs on simulation time, but needs actual camera position to determine how to update each particle source
|
||||||
simulation::Particles.update();
|
simulation::Particles.update();
|
||||||
|
|
||||||
simulation::is_ready = true;
|
|
||||||
|
|
||||||
GfxRenderer->Update( deltarealtime );
|
GfxRenderer->Update( deltarealtime );
|
||||||
|
|
||||||
|
simulation::is_ready = simulation::is_ready || ( ( simulation::Train != nullptr ) && ( simulation::Train->is_cab_initialized ) ) || ( Global.local_start_vehicle == "ghostview" );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,28 +366,25 @@ driver_mode::enter() {
|
|||||||
simulation::Vehicles.find( Global.local_start_vehicle ) :
|
simulation::Vehicles.find( Global.local_start_vehicle ) :
|
||||||
nullptr ) };
|
nullptr ) };
|
||||||
|
|
||||||
Camera.Init(Global.FreeCameraInit[0], Global.FreeCameraInitAngle[0], nPlayerTrain );
|
Camera.Init(Global.FreeCameraInit[0], Global.FreeCameraInitAngle[0], nullptr );
|
||||||
Global.pCamera = Camera;
|
Global.pCamera = Camera;
|
||||||
Global.pDebugCamera = DebugCamera;
|
Global.pDebugCamera = DebugCamera;
|
||||||
|
|
||||||
|
FreeFlyModeFlag = true;
|
||||||
|
DebugCamera = Camera;
|
||||||
|
|
||||||
if (nPlayerTrain)
|
if (nPlayerTrain)
|
||||||
{
|
{
|
||||||
WriteLog( "Trying to enter player train, \"" + Global.local_start_vehicle + "\"" );
|
WriteLog( "Trying to enter player train, \"" + Global.local_start_vehicle + "\"" );
|
||||||
|
|
||||||
FreeFlyModeFlag = true; // HACK: entervehicle won't work if the simulation thinks we're outside
|
m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0, nPlayerTrain->GetPosition(), &Global.local_start_vehicle );
|
||||||
m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0, nPlayerTrain->GetPosition());
|
|
||||||
change_train = nPlayerTrain->name();
|
change_train = nPlayerTrain->name();
|
||||||
}
|
}
|
||||||
else
|
else if (Global.local_start_vehicle != "ghostview")
|
||||||
{
|
|
||||||
if (Global.local_start_vehicle != "ghostview")
|
|
||||||
{
|
{
|
||||||
|
Global.local_start_vehicle = "ghostview";
|
||||||
Error("Bad scenario: failed to locate player train, \"" + Global.local_start_vehicle + "\"" );
|
Error("Bad scenario: failed to locate player train, \"" + Global.local_start_vehicle + "\"" );
|
||||||
}
|
}
|
||||||
FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie
|
|
||||||
Camera.m_owner = nullptr;
|
|
||||||
DebugCamera = Camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (!Global.bMultiplayer) //na razie włączone
|
// if (!Global.bMultiplayer) //na razie włączone
|
||||||
{ // eventy aktywowane z klawiatury tylko dla jednego użytkownika
|
{ // eventy aktywowane z klawiatury tylko dla jednego użytkownika
|
||||||
@@ -430,8 +418,10 @@ driver_mode::on_key( int const Key, int const Scancode, int const Action, int co
|
|||||||
Global.ctrlState = ( Mods & GLFW_MOD_CONTROL ) ? true : false;
|
Global.ctrlState = ( Mods & GLFW_MOD_CONTROL ) ? true : false;
|
||||||
Global.altState = ( Mods & GLFW_MOD_ALT ) ? true : false;
|
Global.altState = ( Mods & GLFW_MOD_ALT ) ? true : false;
|
||||||
|
|
||||||
|
bool anyModifier = Mods & (GLFW_MOD_SHIFT | GLFW_MOD_CONTROL | GLFW_MOD_ALT);
|
||||||
|
|
||||||
// give the ui first shot at the input processing...
|
// give the ui first shot at the input processing...
|
||||||
if( true == m_userinterface->on_key( Key, Scancode, Action, Mods ) ) { return; }
|
if( !anyModifier && true == m_userinterface->on_key( Key, Scancode, Action, Mods ) ) { return; }
|
||||||
// ...if the input is left untouched, pass it on
|
// ...if the input is left untouched, pass it on
|
||||||
if( true == m_input.keyboard.key( Key, Action ) ) { return; }
|
if( true == m_input.keyboard.key( Key, Action ) ) { return; }
|
||||||
|
|
||||||
@@ -529,9 +519,9 @@ driver_mode::update_camera( double const Deltatime ) {
|
|||||||
Camera.LookAt = controlled->GetPosition() + 0.4 * controlled->VectorUp() * controlled->MoverParameters->Dim.H;
|
Camera.LookAt = controlled->GetPosition() + 0.4 * controlled->VectorUp() * controlled->MoverParameters->Dim.H;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TDynamicObject *d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global.pCamera.Pos, 300, false, false ) );
|
TDynamicObject *d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 300, false, false ) );
|
||||||
if( !d )
|
if( !d )
|
||||||
d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global.pCamera.Pos, 1000, false, false ) ); // dalej szukanie, jesli bliżej nie ma
|
d = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 1000, false, false ) ); // dalej szukanie, jesli bliżej nie ma
|
||||||
|
|
||||||
if( d && pDynamicNearest ) {
|
if( d && pDynamicNearest ) {
|
||||||
// jeśli jakiś jest znaleziony wcześniej
|
// jeśli jakiś jest znaleziony wcześniej
|
||||||
@@ -815,106 +805,32 @@ driver_mode::OnKeyDown(int cKey) {
|
|||||||
}
|
}
|
||||||
case GLFW_KEY_F5: {
|
case GLFW_KEY_F5: {
|
||||||
// przesiadka do innego pojazdu
|
// przesiadka do innego pojazdu
|
||||||
if (!FreeFlyModeFlag)
|
if( !FreeFlyModeFlag ) { break; }
|
||||||
// only available in free fly mode
|
|
||||||
break;
|
|
||||||
|
|
||||||
TDynamicObject *dynamic = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, false, false ) );
|
auto const *targetvehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 50, false, false ) ) };
|
||||||
if (dynamic) {
|
|
||||||
m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0);
|
|
||||||
|
|
||||||
change_train = dynamic->name();
|
if( targetvehicle == nullptr ) { break; }
|
||||||
}
|
if( ( targetvehicle->Mechanik ) &&
|
||||||
|
( false == targetvehicle->Mechanik->AIControllFlag ) ) {
|
||||||
break;
|
// for the time being we don't allow more than one person per vehicle
|
||||||
/*
|
|
||||||
if( false == FreeFlyModeFlag ) {
|
|
||||||
// only available in free fly mode
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDynamicObject *targetvehicle = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, false, false ) );
|
|
||||||
|
|
||||||
if( targetvehicle != nullptr ) {
|
|
||||||
|
|
||||||
if( ( true == DebugModeFlag )
|
if( ( true == DebugModeFlag )
|
||||||
|| ( targetvehicle->MoverParameters->Vel <= 5.0 ) ) {
|
|| ( targetvehicle->MoverParameters->Vel <= 5.0 ) ) {
|
||||||
// works always in debug mode, or for stopped/slow moving vehicles otherwise
|
// works always in debug mode, or for stopped/slow moving vehicles otherwise
|
||||||
if( simulation::Train == nullptr ) {
|
m_relay.post(
|
||||||
simulation::Train = new TTrain(); // jeśli niczym jeszcze nie jeździlismy
|
user_command::entervehicle,
|
||||||
}
|
( Global.ctrlState ? GLFW_MOD_CONTROL : 0 ), // TODO: remove ctrl key mode once manual cab (de)activation is in place,
|
||||||
if( simulation::Train->Dynamic() != nullptr ) {
|
( simulation::Train ? simulation::Train->id() : 0 ),
|
||||||
// jeśli mielismy pojazd
|
GLFW_PRESS,
|
||||||
if( simulation::Train->Dynamic()->Mechanik ) { // na skutek jakiegoś błędu może czasem zniknąć
|
0,
|
||||||
auto const *currentvehicle { simulation::Train->Dynamic() };
|
targetvehicle->GetPosition(),
|
||||||
auto const samevehicle { currentvehicle == targetvehicle };
|
&targetvehicle->name() );
|
||||||
|
change_train = targetvehicle->name();
|
||||||
if( samevehicle ) {
|
|
||||||
// we already control desired vehicle so don't overcomplicate things
|
|
||||||
InOutKey(); // do kabiny
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto const sameconsist {
|
|
||||||
( targetvehicle->ctOwner == currentvehicle->Mechanik )
|
|
||||||
|| ( targetvehicle->ctOwner == currentvehicle->ctOwner ) };
|
|
||||||
auto const isincharge { currentvehicle->Mechanik->primary() };
|
|
||||||
auto const aidriveractive { currentvehicle->Mechanik->AIControllFlag };
|
|
||||||
|
|
||||||
if( !sameconsist && isincharge ) {
|
|
||||||
// oddajemy dotychczasowy AI
|
|
||||||
simulation::Train->Dynamic()->Mechanik->TakeControl( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( !sameconsist ) // we leave behind an ai driver which should be preserved
|
|
||||||
|| ( aidriveractive ) // we want to preserve existing ai driver
|
|
||||||
|| ( targetvehicle->Mechanik != nullptr ) ) { // .changedynobj swaps drivers but we want a takeover not a swap
|
|
||||||
|
|
||||||
if( sameconsist && !aidriveractive ) {
|
|
||||||
// we will be taking over controller in the target vehicle, so get rid of the old one
|
|
||||||
// unless it's an active ai in which case leave it running
|
|
||||||
SafeDelete( simulation::Train->Dynamic()->Mechanik );
|
|
||||||
}
|
|
||||||
// HACK: by resetting owned vehicle we can reuse dynamic==nullptr code branch below
|
|
||||||
// TODO: refactor into utility method
|
|
||||||
simulation::Train->DynamicSet( nullptr );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// we can simply move the 'human' controller to the new vehicle
|
|
||||||
Global.changeDynObj = targetvehicle;
|
|
||||||
// TODO: choose active cab based on camera's location relative to vehicle's location
|
|
||||||
// Global.changeDynObj->MoverParameters->CabOccupied = (
|
|
||||||
// Train->DynamicObject->MoverParameters->Neighbours[ exitdirection ].vehicle_end ?
|
|
||||||
// -1 :
|
|
||||||
// 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( simulation::Train->Dynamic() == nullptr ) {
|
|
||||||
// jeśli niczym jeszcze nie jeździlismy
|
|
||||||
if( simulation::Train->Init( targetvehicle ) ) {
|
|
||||||
// przejmujemy sterowanie
|
|
||||||
if( true == Global.ctrlState ) {
|
|
||||||
// make sure we can take over the consist
|
|
||||||
// TODO: remove ctrl key mode once manual cab (de)activation is in place
|
|
||||||
simulation::Train->Dynamic()->Mechanik->primary( true );
|
|
||||||
}
|
|
||||||
simulation::Train->Dynamic()->Mechanik->TakeControl( false, true );
|
|
||||||
if( true == simulation::Train->Dynamic()->Mechanik->primary() ) {
|
|
||||||
simulation::Train->Occupied()->CabDeactivisation( true ); // potentially left active
|
|
||||||
// simulation::Train->Occupied()->CabOccupied = simulation::Train->Occupied()->CabActive;
|
|
||||||
simulation::Train->Occupied()->CabActivisation();
|
|
||||||
}
|
|
||||||
InOutKey(); // do kabiny
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SafeDelete( simulation::Train ); // i nie ma czym sterować
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
case GLFW_KEY_F6: {
|
case GLFW_KEY_F6: {
|
||||||
// przyspieszenie symulacji do testowania scenerii... uwaga na FPS!
|
// przyspieszenie symulacji do testowania scenerii... uwaga na FPS!
|
||||||
@@ -1176,67 +1092,6 @@ driver_mode::CabView() {
|
|||||||
train->pMechOffset = Camera.m_owneroffset;
|
train->pMechOffset = Camera.m_owneroffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
driver_mode::ChangeDynamic() {
|
|
||||||
|
|
||||||
auto *train { simulation::Train };
|
|
||||||
if( train == nullptr ) { return; }
|
|
||||||
|
|
||||||
auto *vehicle { train->Dynamic() };
|
|
||||||
auto *occupied { train->Occupied() };
|
|
||||||
auto *driver { vehicle->Mechanik };
|
|
||||||
// Ra: to nie może być tak robione, to zbytnia proteza jest
|
|
||||||
if( driver ) {
|
|
||||||
// AI może sobie samo pójść
|
|
||||||
if( false == driver->AIControllFlag ) {
|
|
||||||
// tylko jeśli ręcznie prowadzony
|
|
||||||
// jeśli prowadzi AI, to mu nie robimy dywersji!
|
|
||||||
occupied->CabDeactivisation();
|
|
||||||
occupied->CabOccupied = 0;
|
|
||||||
occupied->BrakeLevelSet( occupied->Handle->GetPos( bh_NP ) ); //rozwala sterowanie hamulcem GF 04-2016
|
|
||||||
occupied->MainCtrlPos = occupied->MainCtrlNoPowerPos();
|
|
||||||
occupied->ScndCtrlPos = 0;
|
|
||||||
vehicle->MechInside = false;
|
|
||||||
vehicle->Controller = AIdriver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
TDynamicObject *temp = Global.changeDynObj;
|
|
||||||
vehicle->bDisplayCab = false;
|
|
||||||
vehicle->ABuSetModelShake( {} );
|
|
||||||
|
|
||||||
if( driver ) // AI może sobie samo pójść
|
|
||||||
if( false == driver->AIControllFlag ) {
|
|
||||||
// tylko jeśli ręcznie prowadzony
|
|
||||||
// przsunięcie obiektu zarządzającego
|
|
||||||
driver->MoveTo( temp );
|
|
||||||
}
|
|
||||||
|
|
||||||
train->DynamicSet( temp );
|
|
||||||
// update helpers
|
|
||||||
train = simulation::Train;
|
|
||||||
vehicle = train->Dynamic();
|
|
||||||
occupied = train->Occupied();
|
|
||||||
driver = vehicle->Mechanik;
|
|
||||||
Global.local_start_vehicle = vehicle->name();
|
|
||||||
if( driver ) // AI może sobie samo pójść
|
|
||||||
if( false == driver->AIControllFlag ) // tylko jeśli ręcznie prowadzony
|
|
||||||
{
|
|
||||||
occupied->LimPipePress = occupied->PipePress;
|
|
||||||
occupied->CabActivisation( true ); // załączenie rozrządu (wirtualne kabiny)
|
|
||||||
vehicle->MechInside = true;
|
|
||||||
vehicle->Controller = Humandriver;
|
|
||||||
}
|
|
||||||
train->InitializeCab(
|
|
||||||
occupied->CabActive,
|
|
||||||
vehicle->asBaseDir + occupied->TypeName + ".mmd" );
|
|
||||||
if( false == FreeFlyModeFlag ) {
|
|
||||||
vehicle->bDisplayCab = true;
|
|
||||||
vehicle->ABuSetModelShake( {} ); // zerowanie przesunięcia przed powrotem?
|
|
||||||
CabView(); // na pozycję mecha
|
|
||||||
}
|
|
||||||
Global.changeDynObj = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
driver_mode::InOutKey()
|
driver_mode::InOutKey()
|
||||||
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
|
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ private:
|
|||||||
void update_camera( const double Deltatime );
|
void update_camera( const double Deltatime );
|
||||||
// handles vehicle change flag
|
// handles vehicle change flag
|
||||||
void OnKeyDown( int cKey );
|
void OnKeyDown( int cKey );
|
||||||
void ChangeDynamic();
|
|
||||||
void InOutKey();
|
void InOutKey();
|
||||||
void CabView();
|
void CabView();
|
||||||
void ExternalView();
|
void ExternalView();
|
||||||
|
|||||||
@@ -181,9 +181,15 @@ driver_ui::render_() {
|
|||||||
}
|
}
|
||||||
if( ImGui::Button( locale::strings[ locale::string::driver_pause_quit ].c_str(), ImVec2( popupwidth, 0 ) ) ) {
|
if( ImGui::Button( locale::strings[ locale::string::driver_pause_quit ].c_str(), ImVec2( popupwidth, 0 ) ) ) {
|
||||||
ImGui::CloseCurrentPopup();
|
ImGui::CloseCurrentPopup();
|
||||||
|
// NOTE: server shuts down entire network, client or standalone instance only shuts down self
|
||||||
|
if( Application.is_server() ) {
|
||||||
command_relay commandrelay;
|
command_relay commandrelay;
|
||||||
commandrelay.post( user_command::quitsimulation, 0.0, 0.0, GLFW_PRESS, 0 );
|
commandrelay.post( user_command::quitsimulation, 0.0, 0.0, GLFW_PRESS, 0 );
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
Application.queue_quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "driveruipanels.h"
|
#include "driveruipanels.h"
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
#include "application.h"
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
#include "simulation.h"
|
#include "simulation.h"
|
||||||
#include "simulationtime.h"
|
#include "simulationtime.h"
|
||||||
@@ -564,34 +565,45 @@ bool
|
|||||||
debug_panel::render_section_scenario() {
|
debug_panel::render_section_scenario() {
|
||||||
|
|
||||||
if( false == render_section( "Scenario", m_scenariolines ) ) { return false; }
|
if( false == render_section( "Scenario", m_scenariolines ) ) { return false; }
|
||||||
|
if( Application.is_client() ) {
|
||||||
|
// NOTE: simulation clients can't adjust scenarion state, this is reserved for the server/standalone instance
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// fog slider
|
// fog slider
|
||||||
{
|
{
|
||||||
auto fogrange = std::log( Global.fFogEnd );
|
auto fogrange = std::log( Global.fFogEnd );
|
||||||
if( ImGui::SliderFloat(
|
if( ImGui::SliderFloat(
|
||||||
( to_string( std::exp( fogrange ), 0, 5 ) + " m###fogend" ).c_str(), &fogrange, std::log( 10.0f ), std::log( 25000.0f ), "Fog distance" ) ) {
|
( to_string( std::exp( fogrange ), 0, 5 ) + " m###fogend" ).c_str(), &fogrange, std::log( 10.0f ), std::log( 25000.0f ), "Fog distance" ) ) {
|
||||||
Global.fFogEnd = clamp( std::exp( fogrange ), 10.0f, 25000.0f );
|
command_relay relay;
|
||||||
|
relay.post(
|
||||||
|
user_command::setweather,
|
||||||
|
clamp( std::exp( fogrange ), 10.0f, 25000.0f ),
|
||||||
|
Global.Overcast,
|
||||||
|
GLFW_PRESS, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// cloud cover slider
|
// cloud cover slider
|
||||||
{
|
{
|
||||||
if( ImGui::SliderFloat(
|
if( ImGui::SliderFloat(
|
||||||
( to_string( Global.Overcast, 2, 5 ) + " (" + Global.Weather + ")###overcast" ).c_str(), &Global.Overcast, 0.0f, 2.0f, "Cloud cover" ) ) {
|
( to_string( Global.Overcast, 2, 5 ) + " (" + Global.Weather + ")###overcast" ).c_str(), &Global.Overcast, 0.0f, 2.0f, "Cloud cover" ) ) {
|
||||||
Global.Overcast = clamp( Global.Overcast, 0.0f, 2.0f );
|
command_relay relay;
|
||||||
simulation::Environment.compute_weather();
|
relay.post(
|
||||||
|
user_command::setweather,
|
||||||
|
Global.fFogEnd,
|
||||||
|
clamp( Global.Overcast, 0.0f, 2.0f ),
|
||||||
|
GLFW_PRESS, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// day of year slider
|
// day of year slider
|
||||||
{
|
{
|
||||||
if( ImGui::SliderFloat( ( to_string( Global.fMoveLight, 0, 5 ) + " (" + Global.Season + ")###movelight" ).c_str(), &Global.fMoveLight, 0.0f, 364.0f, "Day of year" ) ) {
|
if( ImGui::SliderFloat(
|
||||||
Global.fMoveLight = clamp( Global.fMoveLight, 0.0f, 365.0f );
|
( to_string( Global.fMoveLight, 0, 5 ) + " (" + Global.Season + ")###movelight" ).c_str(), &Global.fMoveLight, 0.0f, 364.0f, "Day of year" ) ) {
|
||||||
auto const weather{ Global.Weather };
|
command_relay relay;
|
||||||
simulation::Environment.compute_season( Global.fMoveLight );
|
relay.post(
|
||||||
simulation::Time.init();
|
user_command::setdatetime,
|
||||||
if( weather != Global.Weather ) {
|
clamp( Global.fMoveLight, 0.0f, 365.0f ),
|
||||||
// HACK: force re-calculation of precipitation
|
simulation::Time.data().wHour * 60 + simulation::Time.data().wMinute,
|
||||||
Global.Overcast = clamp( Global.Overcast - 0.0001f, 0.0f, 2.0f );
|
GLFW_PRESS, 0 );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// time of day slider
|
// time of day slider
|
||||||
@@ -605,15 +617,15 @@ debug_panel::render_section_scenario() {
|
|||||||
+ ":"
|
+ ":"
|
||||||
+ std::string( to_string( int( 100 + simulation::Time.data().wMinute ) ).substr( 1, 2 ) ) ) };
|
+ std::string( to_string( int( 100 + simulation::Time.data().wMinute ) ).substr( 1, 2 ) ) ) };
|
||||||
if( ImGui::SliderInt( ( timestring + " (" + Global.Period + ")###simulationtime" ).c_str(), &time, 0, 1439, "Time of day" ) ) {
|
if( ImGui::SliderInt( ( timestring + " (" + Global.Period + ")###simulationtime" ).c_str(), &time, 0, 1439, "Time of day" ) ) {
|
||||||
time = clamp( time, 0, 1439 );
|
command_relay relay;
|
||||||
auto const hour{ std::floor( time / 60 ) };
|
relay.post(
|
||||||
auto const minute{ time % 60 };
|
user_command::setdatetime,
|
||||||
simulation::Time.data().wHour = hour;
|
Global.fMoveLight,
|
||||||
simulation::Time.data().wMinute = minute;
|
clamp( time, 0, 1439 ),
|
||||||
|
GLFW_PRESS, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ void network::server_hello::serialize(std::ostream &stream) const
|
|||||||
{
|
{
|
||||||
sn_utils::ls_uint32(stream, seed);
|
sn_utils::ls_uint32(stream, seed);
|
||||||
sn_utils::ls_int64(stream, timestamp);
|
sn_utils::ls_int64(stream, timestamp);
|
||||||
|
sn_utils::ls_int64(stream, config);
|
||||||
|
sn_utils::s_str(stream, scenario);
|
||||||
}
|
}
|
||||||
|
|
||||||
void network::server_hello::deserialize(std::istream &stream)
|
void network::server_hello::deserialize(std::istream &stream)
|
||||||
{
|
{
|
||||||
seed = sn_utils::ld_uint32(stream);
|
seed = sn_utils::ld_uint32(stream);
|
||||||
timestamp = sn_utils::ld_int64(stream);
|
timestamp = sn_utils::ld_int64(stream);
|
||||||
|
config = sn_utils::ld_int64(stream);
|
||||||
|
scenario = sn_utils::d_str(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ::network::request_command::serialize(std::ostream &stream) const
|
void ::network::request_command::serialize(std::ostream &stream) const
|
||||||
@@ -41,7 +45,6 @@ void ::network::request_command::serialize(std::ostream &stream) const
|
|||||||
sn_utils::ls_float64(stream, data.param2);
|
sn_utils::ls_float64(stream, data.param2);
|
||||||
sn_utils::ls_float64(stream, data.time_delta);
|
sn_utils::ls_float64(stream, data.time_delta);
|
||||||
|
|
||||||
sn_utils::s_bool(stream, data.freefly);
|
|
||||||
sn_utils::s_vec3(stream, data.location);
|
sn_utils::s_vec3(stream, data.location);
|
||||||
|
|
||||||
sn_utils::s_str(stream, data.payload);
|
sn_utils::s_str(stream, data.payload);
|
||||||
@@ -67,7 +70,6 @@ void network::request_command::deserialize(std::istream &stream)
|
|||||||
data.param2 = sn_utils::ld_float64(stream);
|
data.param2 = sn_utils::ld_float64(stream);
|
||||||
data.time_delta = sn_utils::ld_float64(stream);
|
data.time_delta = sn_utils::ld_float64(stream);
|
||||||
|
|
||||||
data.freefly = sn_utils::d_bool(stream);
|
|
||||||
data.location = sn_utils::d_vec3(stream);
|
data.location = sn_utils::d_vec3(stream);
|
||||||
|
|
||||||
data.payload = sn_utils::d_str(stream);
|
data.payload = sn_utils::d_str(stream);
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ struct server_hello : public message
|
|||||||
|
|
||||||
uint32_t seed;
|
uint32_t seed;
|
||||||
int64_t timestamp;
|
int64_t timestamp;
|
||||||
|
int64_t config;
|
||||||
|
std::string scenario;
|
||||||
|
|
||||||
virtual void serialize(std::ostream &stream) const override;
|
virtual void serialize(std::ostream &stream) const override;
|
||||||
virtual void deserialize(std::istream &stream) override;
|
virtual void deserialize(std::istream &stream) override;
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
|
std::uint32_t const EU07_NETWORK_VERSION = 2;
|
||||||
|
|
||||||
namespace network {
|
namespace network {
|
||||||
|
|
||||||
backend_list_t& backend_list() {
|
backend_list_t& backend_list() {
|
||||||
@@ -40,7 +42,7 @@ void network::connection::connected()
|
|||||||
|
|
||||||
if (is_client) {
|
if (is_client) {
|
||||||
client_hello msg;
|
client_hello msg;
|
||||||
msg.version = 1;
|
msg.version = EU07_NETWORK_VERSION;
|
||||||
msg.start_packet = packet_counter;
|
msg.start_packet = packet_counter;
|
||||||
send_message(msg);
|
send_message(msg);
|
||||||
}
|
}
|
||||||
@@ -125,7 +127,7 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
if (msg.type == message::CLIENT_HELLO) {
|
if (msg.type == message::CLIENT_HELLO) {
|
||||||
auto cmd = dynamic_cast<const client_hello&>(msg);
|
auto cmd = dynamic_cast<const client_hello&>(msg);
|
||||||
|
|
||||||
if (cmd.version != 1 // wrong version
|
if (cmd.version != EU07_NETWORK_VERSION // wrong version
|
||||||
|| !Global.ready_to_load) { // not ready yet
|
|| !Global.ready_to_load) { // not ready yet
|
||||||
conn->disconnect();
|
conn->disconnect();
|
||||||
return;
|
return;
|
||||||
@@ -134,6 +136,8 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
server_hello reply;
|
server_hello reply;
|
||||||
reply.seed = Global.random_seed;
|
reply.seed = Global.random_seed;
|
||||||
reply.timestamp = Global.starting_timestamp;
|
reply.timestamp = Global.starting_timestamp;
|
||||||
|
reply.config = 0; // TODO: pass bitfield with state of relevant setting switches
|
||||||
|
reply.scenario = Global.SceneryFile;
|
||||||
conn->state = connection::CATCHING_UP;
|
conn->state = connection::CATCHING_UP;
|
||||||
conn->backbuffer = backbuffer;
|
conn->backbuffer = backbuffer;
|
||||||
conn->backbuffer_pos = 0;
|
conn->backbuffer_pos = 0;
|
||||||
@@ -244,6 +248,8 @@ void network::client::handle_message(std::shared_ptr<connection> conn, const mes
|
|||||||
Global.random_seed = cmd.seed;
|
Global.random_seed = cmd.seed;
|
||||||
Global.random_engine.seed(Global.random_seed);
|
Global.random_engine.seed(Global.random_seed);
|
||||||
Global.starting_timestamp = cmd.timestamp;
|
Global.starting_timestamp = cmd.timestamp;
|
||||||
|
// TODO: configure simulation settings according to received cmd.config
|
||||||
|
Global.SceneryFile = cmd.scenario;
|
||||||
Global.ready_to_load = true;
|
Global.ready_to_load = true;
|
||||||
} else if (Global.random_seed != cmd.seed) {
|
} else if (Global.random_seed != cmd.seed) {
|
||||||
ErrorLog("net: seed mismatch", logtype::net);
|
ErrorLog("net: seed mismatch", logtype::net);
|
||||||
|
|||||||
@@ -58,20 +58,20 @@ smoke_source::particle_emitter::deserialize( cParser &Input ) {
|
|||||||
void
|
void
|
||||||
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
|
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
|
||||||
|
|
||||||
auto const polarangle { glm::radians( Random( inclination[ value_limit::min ], inclination[ value_limit::max ] ) ) }; // theta
|
auto const polarangle { glm::radians( LocalRandom( inclination[ value_limit::min ], inclination[ value_limit::max ] ) ) }; // theta
|
||||||
auto const azimuthalangle { glm::radians( Random( -180, 180 ) ) }; // phi
|
auto const azimuthalangle { glm::radians( LocalRandom( -180, 180 ) ) }; // phi
|
||||||
// convert spherical coordinates to opengl coordinates
|
// convert spherical coordinates to opengl coordinates
|
||||||
auto const launchvector { glm::vec3(
|
auto const launchvector { glm::vec3(
|
||||||
std::sin( polarangle ) * std::sin( azimuthalangle ) * -1,
|
std::sin( polarangle ) * std::sin( azimuthalangle ) * -1,
|
||||||
std::cos( polarangle ),
|
std::cos( polarangle ),
|
||||||
std::sin( polarangle ) * std::cos( azimuthalangle ) ) };
|
std::sin( polarangle ) * std::cos( azimuthalangle ) ) };
|
||||||
auto const launchvelocity { static_cast<float>( Random( velocity[ value_limit::min ], velocity[ value_limit::max ] ) ) };
|
auto const launchvelocity { static_cast<float>( LocalRandom( velocity[ value_limit::min ], velocity[ value_limit::max ] ) ) };
|
||||||
|
|
||||||
Particle.velocity = launchvector * launchvelocity;
|
Particle.velocity = launchvector * launchvelocity;
|
||||||
|
|
||||||
Particle.rotation = glm::radians( Random( 0, 360 ) );
|
Particle.rotation = glm::radians( LocalRandom( 0, 360 ) );
|
||||||
Particle.size = Random( size[ value_limit::min ], size[ value_limit::max ] );
|
Particle.size = LocalRandom( size[ value_limit::min ], size[ value_limit::max ] );
|
||||||
Particle.opacity = Random( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity;
|
Particle.opacity = LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity;
|
||||||
Particle.age = 0;
|
Particle.age = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ scenarioloader_mode::init() {
|
|||||||
// mode-specific update of simulation data. returns: false on error, true otherwise
|
// mode-specific update of simulation data. returns: false on error, true otherwise
|
||||||
bool
|
bool
|
||||||
scenarioloader_mode::update() {
|
scenarioloader_mode::update() {
|
||||||
|
|
||||||
if (!Global.ready_to_load)
|
if (!Global.ready_to_load)
|
||||||
// waiting for network connection
|
// waiting for network connection
|
||||||
return true;
|
return true;
|
||||||
@@ -44,6 +43,7 @@ scenarioloader_mode::update() {
|
|||||||
if (!state) {
|
if (!state) {
|
||||||
WriteLog("using simulation seed: " + std::to_string(Global.random_seed), logtype::generic);
|
WriteLog("using simulation seed: " + std::to_string(Global.random_seed), logtype::generic);
|
||||||
|
|
||||||
|
Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" );
|
||||||
WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." );
|
WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." );
|
||||||
|
|
||||||
timestart = std::chrono::system_clock::now();
|
timestart = std::chrono::system_clock::now();
|
||||||
@@ -78,7 +78,7 @@ scenarioloader_mode::enter() {
|
|||||||
simulation::is_ready = false;
|
simulation::is_ready = false;
|
||||||
|
|
||||||
m_userinterface->set_background( "logo" );
|
m_userinterface->set_background( "logo" );
|
||||||
Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" );
|
Application.set_title( Global.AppName );
|
||||||
m_userinterface->set_progress();
|
m_userinterface->set_progress();
|
||||||
m_userinterface->set_progress( "Loading scenery / Wczytywanie scenerii" );
|
m_userinterface->set_progress( "Loading scenery / Wczytywanie scenerii" );
|
||||||
GfxRenderer->Render();
|
GfxRenderer->Render();
|
||||||
|
|||||||
1
scene.h
1
scene.h
@@ -59,6 +59,7 @@ struct scratch_data {
|
|||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
bool initialized { false };
|
bool initialized { false };
|
||||||
|
bool time_initialized { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
// basic element of rudimentary partitioning scheme for the section. fixed size, no further subdivision
|
// basic element of rudimentary partitioning scheme for the section. fixed size, no further subdivision
|
||||||
|
|||||||
@@ -218,27 +218,57 @@ void state_manager::process_commands() {
|
|||||||
|
|
||||||
if (commanddata.command == user_command::entervehicle) {
|
if (commanddata.command == user_command::entervehicle) {
|
||||||
// przesiadka do innego pojazdu
|
// przesiadka do innego pojazdu
|
||||||
if (!commanddata.freefly)
|
// NOTE: because malformed scenario can have vehicle name duplicates we first try to locate vehicle in world, with name search as fallback
|
||||||
// only available in free fly mode
|
TDynamicObject *targetvehicle = std::get<TDynamicObject *>( simulation::Region->find_vehicle( commanddata.location, 50, false, false ) );
|
||||||
|
if( ( targetvehicle == nullptr ) || ( targetvehicle->name() != commanddata.payload ) ) {
|
||||||
|
targetvehicle = simulation::Vehicles.find( commanddata.payload );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetvehicle)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
TDynamicObject *dynamic = std::get<TDynamicObject *>( simulation::Region->find_vehicle( commanddata.location, 50, false, false ) );
|
auto *senderlocaltrain { simulation::Trains.find_id( static_cast<std::uint16_t>( commanddata.param2 ) ) };
|
||||||
|
if( senderlocaltrain ) {
|
||||||
|
auto *currentvehicle { senderlocaltrain->Dynamic() };
|
||||||
|
auto const samevehicle { currentvehicle == targetvehicle };
|
||||||
|
|
||||||
if (!dynamic)
|
if( samevehicle ) {
|
||||||
|
// we already control desired vehicle so don't overcomplicate things
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const sameconsist{
|
||||||
|
( targetvehicle->ctOwner == currentvehicle->Mechanik )
|
||||||
|
|| ( targetvehicle->ctOwner == currentvehicle->ctOwner ) };
|
||||||
|
auto const isincharge{ currentvehicle->Mechanik->primary() };
|
||||||
|
auto const aidriveractive{ currentvehicle->Mechanik->AIControllFlag };
|
||||||
|
// TODO: support for primary mode request passed as commanddata.param1
|
||||||
|
if( !sameconsist && isincharge ) {
|
||||||
|
// oddajemy dotychczasowy AI
|
||||||
|
currentvehicle->Mechanik->TakeControl( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sameconsist && !aidriveractive ) {
|
||||||
|
// since we're consist owner we can simply move to the destination vehicle
|
||||||
|
senderlocaltrain->MoveToVehicle( targetvehicle );
|
||||||
|
senderlocaltrain->Dynamic()->Mechanik->TakeControl( false, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto *train { simulation::Trains.find( targetvehicle->name() ) };
|
||||||
|
|
||||||
TTrain *train = simulation::Trains.find(dynamic->name());
|
|
||||||
if (train)
|
if (train)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
train = new TTrain();
|
train = new TTrain();
|
||||||
if (train->Init(dynamic)) {
|
if (train->Init(targetvehicle)) {
|
||||||
simulation::Trains.insert(train);
|
simulation::Trains.insert(train);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
delete train;
|
delete train;
|
||||||
train = nullptr;
|
train = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commanddata.command == user_command::queueevent) {
|
if (commanddata.command == user_command::queueevent) {
|
||||||
@@ -268,10 +298,15 @@ void state_manager::process_commands() {
|
|||||||
|
|
||||||
if (commanddata.command == user_command::setdatetime) {
|
if (commanddata.command == user_command::setdatetime) {
|
||||||
int yearday = std::round(commanddata.param1);
|
int yearday = std::round(commanddata.param1);
|
||||||
int minute = std::round(commanddata.param2 * 60.0);
|
int minute = std::round(commanddata.param2);
|
||||||
simulation::Time.set_time(yearday, minute);
|
simulation::Time.set_time(yearday, minute);
|
||||||
|
|
||||||
|
auto const weather { Global.Weather };
|
||||||
simulation::Environment.compute_season(yearday);
|
simulation::Environment.compute_season(yearday);
|
||||||
|
if( weather != Global.Weather ) {
|
||||||
|
// HACK: force re-calculation of precipitation
|
||||||
|
Global.Overcast = clamp( Global.Overcast - 0.0001f, 0.0f, 2.0f );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commanddata.command == user_command::setweather) {
|
if (commanddata.command == user_command::setweather) {
|
||||||
@@ -394,6 +429,7 @@ void state_manager::process_commands() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (commanddata.command == user_command::quitsimulation) {
|
if (commanddata.command == user_command::quitsimulation) {
|
||||||
|
// TBD: allow clients to go into offline mode?
|
||||||
Application.queue_quit();
|
Application.queue_quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -320,6 +320,9 @@ state_serializer::deserialize_firstinit( cParser &Input, scene::scratch_data &Sc
|
|||||||
simulation::Events.InitLaunchers();
|
simulation::Events.InitLaunchers();
|
||||||
simulation::Memory.InitCells();
|
simulation::Memory.InitCells();
|
||||||
|
|
||||||
|
if (!Scratchpad.time_initialized)
|
||||||
|
init_time();
|
||||||
|
|
||||||
Scratchpad.initialized = true;
|
Scratchpad.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,20 +631,14 @@ state_serializer::deserialize_time( cParser &Input, scene::scratch_data &Scratch
|
|||||||
>> time.wHour
|
>> time.wHour
|
||||||
>> time.wMinute;
|
>> time.wMinute;
|
||||||
|
|
||||||
if( true == Global.ScenarioTimeCurrent ) {
|
|
||||||
// calculate time shift required to match scenario time with local clock
|
|
||||||
auto timenow = std::time( 0 );
|
|
||||||
auto const *localtime = std::localtime( &timenow );
|
|
||||||
Global.ScenarioTimeOffset = ( ( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
|
||||||
}
|
|
||||||
else if( false == std::isnan( Global.ScenarioTimeOverride ) ) {
|
|
||||||
// scenario time override takes precedence over scenario time offset
|
|
||||||
Global.ScenarioTimeOffset = ( ( Global.ScenarioTimeOverride * 60 ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically
|
// remaining sunrise and sunset parameters are no longer used, as they're now calculated dynamically
|
||||||
// anything else left in the section has no defined meaning
|
// anything else left in the section has no defined meaning
|
||||||
skip_until( Input, "endtime" );
|
skip_until( Input, "endtime" );
|
||||||
|
|
||||||
|
if (!Scratchpad.time_initialized)
|
||||||
|
Scratchpad.time_initialized = true;
|
||||||
|
|
||||||
|
init_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -974,6 +971,19 @@ state_serializer::deserialize_sound( cParser &Input, scene::scratch_data &Scratc
|
|||||||
return sound;
|
return sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void state_serializer::init_time() {
|
||||||
|
auto &time = simulation::Time.data();
|
||||||
|
if( true == Global.ScenarioTimeCurrent ) {
|
||||||
|
// calculate time shift required to match scenario time with local clock
|
||||||
|
auto const *localtime = std::gmtime( &Global.starting_timestamp );
|
||||||
|
Global.ScenarioTimeOffset = ( ( localtime->tm_hour * 60 + localtime->tm_min ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
||||||
|
}
|
||||||
|
else if( false == std::isnan( Global.ScenarioTimeOverride ) ) {
|
||||||
|
// scenario time override takes precedence over scenario time offset
|
||||||
|
Global.ScenarioTimeOffset = ( ( Global.ScenarioTimeOverride * 60 ) - ( time.wHour * 60 + time.wMinute ) ) / 60.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// skips content of stream until specified token
|
// skips content of stream until specified token
|
||||||
void
|
void
|
||||||
state_serializer::skip_until( cParser &Input, std::string const &Token ) {
|
state_serializer::skip_until( cParser &Input, std::string const &Token ) {
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ private:
|
|||||||
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
void init_time();
|
||||||
// skips content of stream until specified token
|
// skips content of stream until specified token
|
||||||
void skip_until( cParser &Input, std::string const &Token );
|
void skip_until( cParser &Input, std::string const &Token );
|
||||||
// transforms provided location by specifed rotation and offset
|
// transforms provided location by specifed rotation and offset
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ Copyright (C) 2007-2014 Maciej Cierniak
|
|||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
bool DebugModeFlag = false;
|
bool DebugModeFlag = false;
|
||||||
bool FreeFlyModeFlag = true;
|
bool FreeFlyModeFlag = false;
|
||||||
bool EditorModeFlag = false;
|
bool EditorModeFlag = false;
|
||||||
bool DebugCameraFlag = false;
|
bool DebugCameraFlag = false;
|
||||||
bool DebugTractionFlag = false;
|
bool DebugTractionFlag = false;
|
||||||
@@ -107,6 +109,11 @@ bool ClearFlag( int &Flag, int const Value ) {
|
|||||||
double Random(double a, double b)
|
double Random(double a, double b)
|
||||||
{
|
{
|
||||||
uint32_t val = Global.random_engine();
|
uint32_t val = Global.random_engine();
|
||||||
|
#ifdef EU07_DEBUG_NETSYNC
|
||||||
|
auto const value = interpolate( a, b, (double)val / Global.random_engine.max() );
|
||||||
|
WriteLog( "random: [" + to_string(a,0) + "-" + to_string(b,0) + "] = " + std::to_string( value ) );
|
||||||
|
return value;
|
||||||
|
#endif
|
||||||
return interpolate(a, b, (double)val / Global.random_engine.max());
|
return interpolate(a, b, (double)val / Global.random_engine.max());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user