mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 17:29:18 +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()
|
||||
{ // zwiększenie prędkości; zwraca false, jeśli dalej się nie da zwiększać
|
||||
if( true == tsGuardSignal.is_playing() ) {
|
||||
// jeśli gada, to nie jedziemy
|
||||
if( fActionTime < 0.0 ) {
|
||||
// gdy jest nakaz poczekać z jazdą, to nie ruszać
|
||||
return false;
|
||||
}
|
||||
bool OK = true;
|
||||
@@ -3093,6 +3093,7 @@ bool TController::IncSpeed()
|
||||
if (mvOccupied->SpringBrake.IsActive && mvOccupied->SpringBrake.Activate) {
|
||||
mvOccupied->SpringBrakeActivate(false);
|
||||
}
|
||||
// Doors() call can potentially adjust fActionTime
|
||||
if( fActionTime < 0.0 ) {
|
||||
// gdy jest nakaz poczekać z jazdą, to nie ruszać
|
||||
return false;
|
||||
@@ -5717,6 +5718,8 @@ TController::UpdateSituation(double dt) {
|
||||
// place virtual conductor some distance away
|
||||
tsGuardSignal.offset( { pVehicle->MoverParameters->Dim.W * -0.75f, 1.7f, std::min( -20.0, -0.2 * fLength ) } );
|
||||
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 {
|
||||
// if (iGuardRadio==iRadioChannel) //zgodność kanału
|
||||
@@ -5727,6 +5730,8 @@ TController::UpdateSituation(double dt) {
|
||||
tsGuardSignal.owner( pVehicle );
|
||||
tsGuardSignal.offset( { 0.f, 2.f, pVehicle->MoverParameters->Dim.L * 0.4f * ( pVehicle->MoverParameters->CabOccupied < 0 ? -1 : 1 ) } );
|
||||
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 )
|
||||
{ // przejęcie kontroli przez AI albo oddanie
|
||||
if (AIControllFlag == Aidriver)
|
||||
if ((AIControllFlag == Aidriver) && (!Forcevehiclecheck))
|
||||
return; // już jest jak ma być
|
||||
if (Aidriver) //żeby nie wykonywać dwa razy
|
||||
{ // teraz AI prowadzi
|
||||
@@ -7145,12 +7150,29 @@ TController::TrackBlock() const {
|
||||
|
||||
void TController::MoveTo(TDynamicObject *to)
|
||||
{ // przesunięcie AI do innego pojazdu (przy zmianie kabiny)
|
||||
// mvOccupied->CabDeactivisation(); //wyłączenie kabiny w opuszczanym
|
||||
pVehicle->Mechanik = to->Mechanik; //żeby się zamieniły, jak jest jakieś drugie
|
||||
if( ( to->Mechanik != nullptr )
|
||||
&& ( 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;
|
||||
ControllingSet(); // utworzenie połączenia do sterowanego pojazdu
|
||||
pVehicle->Mechanik = this;
|
||||
// iDirection=0; //kierunek jazdy trzeba dopiero zgadnąć
|
||||
|
||||
};
|
||||
|
||||
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( 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
|
||||
if( ( Type == "1" )
|
||||
|| ( Type == "2" ) ) {
|
||||
@@ -5539,8 +5528,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
|
||||
for( auto &bogie : m_bogiesounds ) {
|
||||
bogie.start( (
|
||||
bogieidx % 2 ?
|
||||
Random( 0.0, 30.0 ) :
|
||||
Random( 50.0, 80.0 ) )
|
||||
LocalRandom( 0.0, 30.0 ) :
|
||||
LocalRandom( 50.0, 80.0 ) )
|
||||
* 0.01 );
|
||||
++bogieidx;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ struct global_settings {
|
||||
bool ready_to_load { false };
|
||||
std::time_t starting_timestamp = 0; // starting time, in local timezone
|
||||
uint32_t random_seed = 0;
|
||||
TDynamicObject *changeDynObj{ nullptr };// info o zmianie pojazdu
|
||||
TCamera pCamera; // parametry kamery
|
||||
TCamera pDebugCamera;
|
||||
std::array<Math3D::vector3, 10> FreeCameraInit; // pozycje kamery
|
||||
|
||||
7
Names.h
7
Names.h
@@ -58,13 +58,6 @@ public:
|
||||
|
||||
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)
|
||||
{
|
||||
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||||
|
||||
48
Train.cpp
48
Train.cpp
@@ -5827,7 +5827,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
if (ff != fTachoTimer) // jesli w tej sekundzie nie zmienial
|
||||
{
|
||||
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
|
||||
fTachoVelocityJump = 0; // stoi
|
||||
fTachoTimer = ff; // juz zmienil
|
||||
@@ -6049,7 +6049,8 @@ bool TTrain::Update( double const Deltatime )
|
||||
if ((mvControlled->CompressorFlag == true) && (mvControlled->CompressorPower == 1) &&
|
||||
((mvControlled->EngineType == TEngineType::ElectricSeriesMotor) ||
|
||||
(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/)
|
||||
if (fConverterTimer < fConverterPrzekaznik)
|
||||
{
|
||||
@@ -7496,6 +7497,9 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
||||
}
|
||||
// reset view angles
|
||||
pMechViewAngle = { 0.0, 0.0 };
|
||||
|
||||
is_cab_initialized = true; // the attempt may fail, but it's the attempt that counts
|
||||
|
||||
bool parse = false;
|
||||
int cabindex = 0;
|
||||
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
|
||||
// indeed, too much hacks...
|
||||
// TODO: cleanup
|
||||
|
||||
TTrain *target_train = simulation::Trains.find(target->name());
|
||||
if (target_train) {
|
||||
// let's try to destroy this TTrain and move to already existing one
|
||||
@@ -7882,18 +7885,22 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
||||
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;
|
||||
Dynamic()->MechInside = false;
|
||||
Dynamic()->Controller = AIdriver;
|
||||
|
||||
Dynamic()->bDisplayCab = false;
|
||||
Dynamic()->ABuSetModelShake( {} );
|
||||
|
||||
Dynamic()->Mechanik->MoveTo(target);
|
||||
if( Dynamic()->Mechanik ) {
|
||||
Dynamic()->Mechanik->MoveTo( target );
|
||||
}
|
||||
|
||||
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()->Controller = Humandriver;
|
||||
target_train->Dynamic()->Controller = ( target_train->Dynamic()->Mechanik ? !target_train->Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
||||
} else {
|
||||
target_train->Dynamic()->bDisplayCab = false;
|
||||
target_train->Dynamic()->ABuSetModelShake( {} );
|
||||
@@ -7922,20 +7929,24 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
||||
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;
|
||||
Dynamic()->MechInside = false;
|
||||
Dynamic()->Controller = AIdriver;
|
||||
|
||||
Dynamic()->bDisplayCab = false;
|
||||
Dynamic()->ABuSetModelShake( {} );
|
||||
|
||||
Dynamic()->Mechanik->MoveTo(target);
|
||||
if( Dynamic()->Mechanik ) {
|
||||
Dynamic()->Mechanik->MoveTo( target );
|
||||
}
|
||||
|
||||
DynamicSet(target);
|
||||
|
||||
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()->Controller = Humandriver;
|
||||
Dynamic()->Controller = ( Dynamic()->Mechanik ? !Dynamic()->Mechanik->AIControllFlag : Humandriver );
|
||||
} else {
|
||||
Dynamic()->bDisplayCab = false;
|
||||
Dynamic()->ABuSetModelShake( {} );
|
||||
@@ -7953,6 +7964,7 @@ TTrain::MoveToVehicle(TDynamicObject *target) {
|
||||
// add it back with updated dynamic name
|
||||
simulation::Trains.insert(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 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 ) {
|
||||
ggRadioButton.PutValue( 1.f );
|
||||
}
|
||||
ggRadioChannelSelector.PutValue( RadioChannel() - 1 );
|
||||
ggRadioChannelSelector.PutValue( ( Dynamic()->Mechanik ? Dynamic()->Mechanik->iRadioChannel : 1 ) - 1 );
|
||||
// pantographs
|
||||
/*
|
||||
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
|
||||
std::array<TCab, 3> Cabine; // przedzial maszynowy, kabina 1 (A), kabina 2 (B)
|
||||
int iCabn { 0 }; // 0: mid, 1: front, 2: rear
|
||||
bool is_cab_initialized { false };
|
||||
// McZapkie: do poruszania sie po kabinie
|
||||
Math3D::vector3 pMechSittingPosition; // ABu 180404
|
||||
Math3D::vector3 MirrorPosition( bool lewe );
|
||||
@@ -773,7 +774,7 @@ private:
|
||||
float fDieselParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||
// plays provided sound from position of the radio
|
||||
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 TDynamicObject *Dynamic() { return DynamicObject; };
|
||||
inline TDynamicObject const *Dynamic() const { return DynamicObject; };
|
||||
@@ -794,6 +795,7 @@ private:
|
||||
class train_table : public basic_table<TTrain> {
|
||||
public:
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
eu07_application::run() {
|
||||
|
||||
auto frame{ 0 };
|
||||
// main application loop
|
||||
while (!glfwWindowShouldClose( m_windows.front() ) && !m_modestack.empty())
|
||||
{
|
||||
Timer::subsystem.mainloop_total.start();
|
||||
glfwPollEvents();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// multiplayer command relaying logic can seem a bit complex
|
||||
@@ -191,6 +204,9 @@ eu07_application::run() {
|
||||
int loop_remaining = MAX_NETWORK_PER_FRAME;
|
||||
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 local_commands = simulation::Commands.pop_intercept_queue();
|
||||
double slave_sync;
|
||||
@@ -272,7 +288,7 @@ eu07_application::run() {
|
||||
float awaiting = m_network->client->get_awaiting_frames();
|
||||
|
||||
// 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 {
|
||||
m_modes[m_modestack.top()]->set_progress(0.0f, 0.0f);
|
||||
}
|
||||
@@ -295,8 +311,6 @@ eu07_application::run() {
|
||||
if (!GfxRenderer->Render())
|
||||
return 0;
|
||||
|
||||
glfwPollEvents();
|
||||
|
||||
if (m_modestack.empty())
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -92,6 +92,10 @@ public:
|
||||
generate_sync();
|
||||
void
|
||||
queue_quit();
|
||||
bool
|
||||
is_server() const;
|
||||
bool
|
||||
is_client() const;
|
||||
|
||||
private:
|
||||
// types
|
||||
|
||||
@@ -386,7 +386,7 @@ command_relay::post(user_command const Command, double const Param1, double cons
|
||||
Position = Global.pCamera.Pos;
|
||||
|
||||
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)
|
||||
commanddata.payload = *Payload;
|
||||
|
||||
|
||||
@@ -324,7 +324,6 @@ struct command_data {
|
||||
double param2;
|
||||
double time_delta;
|
||||
|
||||
bool freefly;
|
||||
glm::vec3 location;
|
||||
|
||||
std::string payload;
|
||||
|
||||
237
drivermode.cpp
237
drivermode.cpp
@@ -17,6 +17,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "simulation.h"
|
||||
#include "simulationtime.h"
|
||||
#include "simulationenvironment.h"
|
||||
#include "scene.h"
|
||||
#include "lightarray.h"
|
||||
#include "particles.h"
|
||||
#include "Train.h"
|
||||
@@ -146,18 +147,19 @@ driver_mode::update() {
|
||||
|
||||
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_scripting_interface();
|
||||
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
|
||||
// m_primaryupdateaccumulator += dt; // unused for the time being
|
||||
// m_primaryupdateaccumulator += dt; // unused for the time being
|
||||
m_secondaryupdateaccumulator += deltatime;
|
||||
/*
|
||||
/*
|
||||
// NOTE: until we have no physics state interpolation during render, we need to rely on the old code,
|
||||
// as doing fixed step calculations but flexible step render results in ugly mini jitter
|
||||
// core routines (physics)
|
||||
@@ -169,20 +171,20 @@ driver_mode::update() {
|
||||
++updatecount;
|
||||
m_primaryupdateaccumulator -= m_primaryupdaterate;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
int updatecount = 1;
|
||||
if( deltatime > m_primaryupdaterate ) // normalnie 0.01s
|
||||
{
|
||||
/*
|
||||
/*
|
||||
// NOTE: experimentally disabled physics update cap
|
||||
auto const iterations = std::ceil(dt / m_primaryupdaterate);
|
||||
updatecount = std::min( 20, static_cast<int>( iterations ) );
|
||||
*/
|
||||
*/
|
||||
updatecount = std::ceil( deltatime / m_primaryupdaterate );
|
||||
/*
|
||||
/*
|
||||
// NOTE: changing dt wrecks things further down the code. re-acquire proper value later or cleanup here
|
||||
dt = dt / iterations; // Ra: fizykę lepiej by było przeliczać ze stałym krokiem
|
||||
*/
|
||||
*/
|
||||
}
|
||||
auto const stepdeltatime { deltatime / updatecount };
|
||||
// NOTE: updates are limited to 20, but dt is distributed over potentially many more iterations
|
||||
@@ -229,6 +231,7 @@ driver_mode::update() {
|
||||
if (!change_train.empty()) {
|
||||
TTrain *train = simulation::Trains.find(change_train);
|
||||
if (train) {
|
||||
Global.local_start_vehicle = change_train;
|
||||
simulation::Train = train;
|
||||
InOutKey();
|
||||
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
|
||||
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 )
|
||||
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( simulation::Train->Dynamic() );
|
||||
else
|
||||
@@ -268,6 +258,7 @@ driver_mode::update() {
|
||||
simulation::Events.update();
|
||||
simulation::Region->update_events();
|
||||
simulation::Lights.update();
|
||||
}
|
||||
|
||||
// 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
|
||||
simulation::Particles.update();
|
||||
|
||||
simulation::is_ready = true;
|
||||
|
||||
GfxRenderer->Update( deltarealtime );
|
||||
|
||||
simulation::is_ready = simulation::is_ready || ( ( simulation::Train != nullptr ) && ( simulation::Train->is_cab_initialized ) ) || ( Global.local_start_vehicle == "ghostview" );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -375,28 +366,25 @@ driver_mode::enter() {
|
||||
simulation::Vehicles.find( Global.local_start_vehicle ) :
|
||||
nullptr ) };
|
||||
|
||||
Camera.Init(Global.FreeCameraInit[0], Global.FreeCameraInitAngle[0], nPlayerTrain );
|
||||
Camera.Init(Global.FreeCameraInit[0], Global.FreeCameraInitAngle[0], nullptr );
|
||||
Global.pCamera = Camera;
|
||||
Global.pDebugCamera = DebugCamera;
|
||||
|
||||
FreeFlyModeFlag = true;
|
||||
DebugCamera = Camera;
|
||||
|
||||
if (nPlayerTrain)
|
||||
{
|
||||
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());
|
||||
m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0, nPlayerTrain->GetPosition(), &Global.local_start_vehicle );
|
||||
change_train = nPlayerTrain->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Global.local_start_vehicle != "ghostview")
|
||||
else if (Global.local_start_vehicle != "ghostview")
|
||||
{
|
||||
Global.local_start_vehicle = "ghostview";
|
||||
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
|
||||
{ // 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.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...
|
||||
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( 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;
|
||||
}
|
||||
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 )
|
||||
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 ) {
|
||||
// jeśli jakiś jest znaleziony wcześniej
|
||||
@@ -815,106 +805,32 @@ driver_mode::OnKeyDown(int cKey) {
|
||||
}
|
||||
case GLFW_KEY_F5: {
|
||||
// przesiadka do innego pojazdu
|
||||
if (!FreeFlyModeFlag)
|
||||
// only available in free fly mode
|
||||
break;
|
||||
if( !FreeFlyModeFlag ) { break; }
|
||||
|
||||
TDynamicObject *dynamic = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, false, false ) );
|
||||
if (dynamic) {
|
||||
m_relay.post(user_command::entervehicle, 0.0, 0.0, GLFW_PRESS, 0);
|
||||
auto const *targetvehicle { std::get<TDynamicObject *>( simulation::Region->find_vehicle( Camera.Pos, 50, false, false ) ) };
|
||||
|
||||
change_train = dynamic->name();
|
||||
}
|
||||
|
||||
break;
|
||||
/*
|
||||
if( false == FreeFlyModeFlag ) {
|
||||
// only available in free fly mode
|
||||
if( targetvehicle == nullptr ) { break; }
|
||||
if( ( targetvehicle->Mechanik ) &&
|
||||
( false == targetvehicle->Mechanik->AIControllFlag ) ) {
|
||||
// for the time being we don't allow more than one person per vehicle
|
||||
break;
|
||||
}
|
||||
|
||||
TDynamicObject *targetvehicle = std::get<TDynamicObject *>( simulation::Region->find_vehicle( Global.pCamera.Pos, 50, false, false ) );
|
||||
|
||||
if( targetvehicle != nullptr ) {
|
||||
|
||||
if( ( true == DebugModeFlag )
|
||||
|| ( targetvehicle->MoverParameters->Vel <= 5.0 ) ) {
|
||||
// works always in debug mode, or for stopped/slow moving vehicles otherwise
|
||||
if( simulation::Train == nullptr ) {
|
||||
simulation::Train = new TTrain(); // jeśli niczym jeszcze nie jeździlismy
|
||||
}
|
||||
if( simulation::Train->Dynamic() != nullptr ) {
|
||||
// jeśli mielismy pojazd
|
||||
if( simulation::Train->Dynamic()->Mechanik ) { // na skutek jakiegoś błędu może czasem zniknąć
|
||||
auto const *currentvehicle { simulation::Train->Dynamic() };
|
||||
auto const samevehicle { currentvehicle == targetvehicle };
|
||||
|
||||
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ć
|
||||
}
|
||||
}
|
||||
}
|
||||
m_relay.post(
|
||||
user_command::entervehicle,
|
||||
( Global.ctrlState ? GLFW_MOD_CONTROL : 0 ), // TODO: remove ctrl key mode once manual cab (de)activation is in place,
|
||||
( simulation::Train ? simulation::Train->id() : 0 ),
|
||||
GLFW_PRESS,
|
||||
0,
|
||||
targetvehicle->GetPosition(),
|
||||
&targetvehicle->name() );
|
||||
change_train = targetvehicle->name();
|
||||
}
|
||||
break;
|
||||
*/
|
||||
|
||||
}
|
||||
case GLFW_KEY_F6: {
|
||||
// przyspieszenie symulacji do testowania scenerii... uwaga na FPS!
|
||||
@@ -1176,67 +1092,6 @@ driver_mode::CabView() {
|
||||
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
|
||||
driver_mode::InOutKey()
|
||||
{ // przełączenie widoku z kabiny na zewnętrzny i odwrotnie
|
||||
|
||||
@@ -91,7 +91,6 @@ private:
|
||||
void update_camera( const double Deltatime );
|
||||
// handles vehicle change flag
|
||||
void OnKeyDown( int cKey );
|
||||
void ChangeDynamic();
|
||||
void InOutKey();
|
||||
void CabView();
|
||||
void ExternalView();
|
||||
|
||||
@@ -181,8 +181,14 @@ driver_ui::render_() {
|
||||
}
|
||||
if( ImGui::Button( locale::strings[ locale::string::driver_pause_quit ].c_str(), ImVec2( popupwidth, 0 ) ) ) {
|
||||
ImGui::CloseCurrentPopup();
|
||||
// NOTE: server shuts down entire network, client or standalone instance only shuts down self
|
||||
if( Application.is_server() ) {
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "driveruipanels.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "application.h"
|
||||
#include "translation.h"
|
||||
#include "simulation.h"
|
||||
#include "simulationtime.h"
|
||||
@@ -564,34 +565,45 @@ bool
|
||||
debug_panel::render_section_scenario() {
|
||||
|
||||
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
|
||||
{
|
||||
auto fogrange = std::log( Global.fFogEnd );
|
||||
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" ) ) {
|
||||
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
|
||||
{
|
||||
if( ImGui::SliderFloat(
|
||||
( 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 );
|
||||
simulation::Environment.compute_weather();
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
user_command::setweather,
|
||||
Global.fFogEnd,
|
||||
clamp( Global.Overcast, 0.0f, 2.0f ),
|
||||
GLFW_PRESS, 0 );
|
||||
}
|
||||
}
|
||||
// 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" ) ) {
|
||||
Global.fMoveLight = clamp( Global.fMoveLight, 0.0f, 365.0f );
|
||||
auto const weather{ Global.Weather };
|
||||
simulation::Environment.compute_season( Global.fMoveLight );
|
||||
simulation::Time.init();
|
||||
if( weather != Global.Weather ) {
|
||||
// HACK: force re-calculation of precipitation
|
||||
Global.Overcast = clamp( Global.Overcast - 0.0001f, 0.0f, 2.0f );
|
||||
}
|
||||
if( ImGui::SliderFloat(
|
||||
( to_string( Global.fMoveLight, 0, 5 ) + " (" + Global.Season + ")###movelight" ).c_str(), &Global.fMoveLight, 0.0f, 364.0f, "Day of year" ) ) {
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
user_command::setdatetime,
|
||||
clamp( Global.fMoveLight, 0.0f, 365.0f ),
|
||||
simulation::Time.data().wHour * 60 + simulation::Time.data().wMinute,
|
||||
GLFW_PRESS, 0 );
|
||||
}
|
||||
}
|
||||
// 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 ) ) ) };
|
||||
if( ImGui::SliderInt( ( timestring + " (" + Global.Period + ")###simulationtime" ).c_str(), &time, 0, 1439, "Time of day" ) ) {
|
||||
time = clamp( time, 0, 1439 );
|
||||
auto const hour{ std::floor( time / 60 ) };
|
||||
auto const minute{ time % 60 };
|
||||
simulation::Time.data().wHour = hour;
|
||||
simulation::Time.data().wMinute = minute;
|
||||
command_relay relay;
|
||||
relay.post(
|
||||
user_command::setdatetime,
|
||||
Global.fMoveLight,
|
||||
clamp( time, 0, 1439 ),
|
||||
GLFW_PRESS, 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,16 @@ void network::server_hello::serialize(std::ostream &stream) const
|
||||
{
|
||||
sn_utils::ls_uint32(stream, seed);
|
||||
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)
|
||||
{
|
||||
seed = sn_utils::ld_uint32(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
|
||||
@@ -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.time_delta);
|
||||
|
||||
sn_utils::s_bool(stream, data.freefly);
|
||||
sn_utils::s_vec3(stream, data.location);
|
||||
|
||||
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.time_delta = sn_utils::ld_float64(stream);
|
||||
|
||||
data.freefly = sn_utils::d_bool(stream);
|
||||
data.location = sn_utils::d_vec3(stream);
|
||||
|
||||
data.payload = sn_utils::d_str(stream);
|
||||
|
||||
@@ -40,6 +40,8 @@ struct server_hello : public message
|
||||
|
||||
uint32_t seed;
|
||||
int64_t timestamp;
|
||||
int64_t config;
|
||||
std::string scenario;
|
||||
|
||||
virtual void serialize(std::ostream &stream) const override;
|
||||
virtual void deserialize(std::istream &stream) override;
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#include "application.h"
|
||||
#include "Globals.h"
|
||||
|
||||
std::uint32_t const EU07_NETWORK_VERSION = 2;
|
||||
|
||||
namespace network {
|
||||
|
||||
backend_list_t& backend_list() {
|
||||
@@ -40,7 +42,7 @@ void network::connection::connected()
|
||||
|
||||
if (is_client) {
|
||||
client_hello msg;
|
||||
msg.version = 1;
|
||||
msg.version = EU07_NETWORK_VERSION;
|
||||
msg.start_packet = packet_counter;
|
||||
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) {
|
||||
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
|
||||
conn->disconnect();
|
||||
return;
|
||||
@@ -134,6 +136,8 @@ void network::server::handle_message(std::shared_ptr<connection> conn, const mes
|
||||
server_hello reply;
|
||||
reply.seed = Global.random_seed;
|
||||
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->backbuffer = backbuffer;
|
||||
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_engine.seed(Global.random_seed);
|
||||
Global.starting_timestamp = cmd.timestamp;
|
||||
// TODO: configure simulation settings according to received cmd.config
|
||||
Global.SceneryFile = cmd.scenario;
|
||||
Global.ready_to_load = true;
|
||||
} else if (Global.random_seed != cmd.seed) {
|
||||
ErrorLog("net: seed mismatch", logtype::net);
|
||||
|
||||
@@ -58,20 +58,20 @@ smoke_source::particle_emitter::deserialize( cParser &Input ) {
|
||||
void
|
||||
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 azimuthalangle { glm::radians( Random( -180, 180 ) ) }; // phi
|
||||
auto const polarangle { glm::radians( LocalRandom( inclination[ value_limit::min ], inclination[ value_limit::max ] ) ) }; // theta
|
||||
auto const azimuthalangle { glm::radians( LocalRandom( -180, 180 ) ) }; // phi
|
||||
// convert spherical coordinates to opengl coordinates
|
||||
auto const launchvector { glm::vec3(
|
||||
std::sin( polarangle ) * std::sin( azimuthalangle ) * -1,
|
||||
std::cos( polarangle ),
|
||||
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.rotation = glm::radians( Random( 0, 360 ) );
|
||||
Particle.size = Random( size[ value_limit::min ], size[ value_limit::max ] );
|
||||
Particle.opacity = Random( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity;
|
||||
Particle.rotation = glm::radians( LocalRandom( 0, 360 ) );
|
||||
Particle.size = LocalRandom( size[ value_limit::min ], size[ value_limit::max ] );
|
||||
Particle.opacity = LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity;
|
||||
Particle.age = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,6 @@ scenarioloader_mode::init() {
|
||||
// mode-specific update of simulation data. returns: false on error, true otherwise
|
||||
bool
|
||||
scenarioloader_mode::update() {
|
||||
|
||||
if (!Global.ready_to_load)
|
||||
// waiting for network connection
|
||||
return true;
|
||||
@@ -44,6 +43,7 @@ scenarioloader_mode::update() {
|
||||
if (!state) {
|
||||
WriteLog("using simulation seed: " + std::to_string(Global.random_seed), logtype::generic);
|
||||
|
||||
Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" );
|
||||
WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." );
|
||||
|
||||
timestart = std::chrono::system_clock::now();
|
||||
@@ -78,7 +78,7 @@ scenarioloader_mode::enter() {
|
||||
simulation::is_ready = false;
|
||||
|
||||
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( "Loading scenery / Wczytywanie scenerii" );
|
||||
GfxRenderer->Render();
|
||||
|
||||
1
scene.h
1
scene.h
@@ -59,6 +59,7 @@ struct scratch_data {
|
||||
|
||||
std::string name;
|
||||
bool initialized { false };
|
||||
bool time_initialized { false };
|
||||
};
|
||||
|
||||
// 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) {
|
||||
// przesiadka do innego pojazdu
|
||||
if (!commanddata.freefly)
|
||||
// only available in free fly mode
|
||||
// NOTE: because malformed scenario can have vehicle name duplicates we first try to locate vehicle in world, with name search as fallback
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
continue;
|
||||
|
||||
train = new TTrain();
|
||||
if (train->Init(dynamic)) {
|
||||
if (train->Init(targetvehicle)) {
|
||||
simulation::Trains.insert(train);
|
||||
}
|
||||
else {
|
||||
delete train;
|
||||
train = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (commanddata.command == user_command::queueevent) {
|
||||
@@ -268,10 +298,15 @@ void state_manager::process_commands() {
|
||||
|
||||
if (commanddata.command == user_command::setdatetime) {
|
||||
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);
|
||||
|
||||
auto const weather { Global.Weather };
|
||||
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) {
|
||||
@@ -394,6 +429,7 @@ void state_manager::process_commands() {
|
||||
}
|
||||
|
||||
if (commanddata.command == user_command::quitsimulation) {
|
||||
// TBD: allow clients to go into offline mode?
|
||||
Application.queue_quit();
|
||||
}
|
||||
|
||||
|
||||
@@ -320,6 +320,9 @@ state_serializer::deserialize_firstinit( cParser &Input, scene::scratch_data &Sc
|
||||
simulation::Events.InitLaunchers();
|
||||
simulation::Memory.InitCells();
|
||||
|
||||
if (!Scratchpad.time_initialized)
|
||||
init_time();
|
||||
|
||||
Scratchpad.initialized = true;
|
||||
}
|
||||
|
||||
@@ -628,20 +631,14 @@ state_serializer::deserialize_time( cParser &Input, scene::scratch_data &Scratch
|
||||
>> time.wHour
|
||||
>> 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
|
||||
// anything else left in the section has no defined meaning
|
||||
skip_until( Input, "endtime" );
|
||||
|
||||
if (!Scratchpad.time_initialized)
|
||||
Scratchpad.time_initialized = true;
|
||||
|
||||
init_time();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -974,6 +971,19 @@ state_serializer::deserialize_sound( cParser &Input, scene::scratch_data &Scratc
|
||||
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
|
||||
void
|
||||
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 );
|
||||
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 );
|
||||
void init_time();
|
||||
// skips content of stream until specified token
|
||||
void skip_until( cParser &Input, std::string const &Token );
|
||||
// transforms provided location by specifed rotation and offset
|
||||
|
||||
@@ -27,8 +27,10 @@ Copyright (C) 2007-2014 Maciej Cierniak
|
||||
#include "Globals.h"
|
||||
#include "parser.h"
|
||||
|
||||
#include "Logs.h"
|
||||
|
||||
bool DebugModeFlag = false;
|
||||
bool FreeFlyModeFlag = true;
|
||||
bool FreeFlyModeFlag = false;
|
||||
bool EditorModeFlag = false;
|
||||
bool DebugCameraFlag = false;
|
||||
bool DebugTractionFlag = false;
|
||||
@@ -107,6 +109,11 @@ bool ClearFlag( int &Flag, int const Value ) {
|
||||
double Random(double a, double b)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user