mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 16:19:19 +02:00
basic cargo attributes system, minor cargo enhancements and fixes
This commit is contained in:
147
DynObj.cpp
147
DynObj.cpp
@@ -1783,7 +1783,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
|||||||
asBaseDir = szDynamicPath + BaseDir + "/"; // McZapkie-310302
|
asBaseDir = szDynamicPath + BaseDir + "/"; // McZapkie-310302
|
||||||
replace_slashes( asBaseDir );
|
replace_slashes( asBaseDir );
|
||||||
asName = Name;
|
asName = Name;
|
||||||
std::string asAnimName = ""; // zmienna robocza do wyszukiwania osi i wózków
|
std::string asAnimName; // zmienna robocza do wyszukiwania osi i wózków
|
||||||
// Ra: zmieniamy znaczenie obsady na jednoliterowe, żeby dosadzić kierownika
|
// Ra: zmieniamy znaczenie obsady na jednoliterowe, żeby dosadzić kierownika
|
||||||
if (DriverType == "headdriver")
|
if (DriverType == "headdriver")
|
||||||
DriverType = "1"; // sterujący kabiną +1
|
DriverType = "1"; // sterujący kabiną +1
|
||||||
@@ -1810,7 +1810,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// utworzenie parametrów fizyki
|
// utworzenie parametrów fizyki
|
||||||
MoverParameters = new TMoverParameters(iDirection ? fVel : -fVel, Type_Name, asName, Load, LoadType, Cab);
|
MoverParameters = new TMoverParameters(iDirection ? fVel : -fVel, Type_Name, asName, Cab);
|
||||||
iLights = MoverParameters->iLights; // wskaźnik na stan własnych świateł
|
iLights = MoverParameters->iLights; // wskaźnik na stan własnych świateł
|
||||||
// McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu
|
// McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu
|
||||||
if (!MoverParameters->LoadFIZ(asBaseDir))
|
if (!MoverParameters->LoadFIZ(asBaseDir))
|
||||||
@@ -1822,6 +1822,9 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
|||||||
}
|
}
|
||||||
return 0.0; // zerowa długość to brak pojazdu
|
return 0.0; // zerowa długość to brak pojazdu
|
||||||
}
|
}
|
||||||
|
// load the cargo now that we know whether the vehicle will allow it
|
||||||
|
MoverParameters->AssignLoad( LoadType, Load );
|
||||||
|
|
||||||
bool driveractive = (fVel != 0.0); // jeśli prędkość niezerowa, to aktywujemy ruch
|
bool driveractive = (fVel != 0.0); // jeśli prędkość niezerowa, to aktywujemy ruch
|
||||||
if (!MoverParameters->CheckLocomotiveParameters(
|
if (!MoverParameters->CheckLocomotiveParameters(
|
||||||
driveractive,
|
driveractive,
|
||||||
@@ -2095,7 +2098,8 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
|||||||
iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi
|
iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi
|
||||||
*/
|
*/
|
||||||
// wczytywanie z pliku nazwatypu.mmd, w tym model
|
// wczytywanie z pliku nazwatypu.mmd, w tym model
|
||||||
LoadMMediaFile(asBaseDir, Type_Name, asReplacableSkin);
|
erase_extension( asReplacableSkin );
|
||||||
|
LoadMMediaFile(Type_Name, asReplacableSkin);
|
||||||
// McZapkie-100402: wyszukiwanie submodeli sprzegów
|
// McZapkie-100402: wyszukiwanie submodeli sprzegów
|
||||||
btCoupler1.Init( "coupler1", mdModel, false ); // false - ma być wyłączony
|
btCoupler1.Init( "coupler1", mdModel, false ); // false - ma być wyłączony
|
||||||
btCoupler2.Init( "coupler2", mdModel, false);
|
btCoupler2.Init( "coupler2", mdModel, false);
|
||||||
@@ -2612,13 +2616,13 @@ void TDynamicObject::update_exchange( double const Deltatime ) {
|
|||||||
auto const exchangesize = std::min( m_exchange.unload_count, MoverParameters->UnLoadSpeed * m_exchange.speed_factor );
|
auto const exchangesize = std::min( m_exchange.unload_count, MoverParameters->UnLoadSpeed * m_exchange.speed_factor );
|
||||||
m_exchange.unload_count -= exchangesize;
|
m_exchange.unload_count -= exchangesize;
|
||||||
MoverParameters->LoadStatus = 1;
|
MoverParameters->LoadStatus = 1;
|
||||||
MoverParameters->Load = std::max( 0.f, MoverParameters->Load - exchangesize );
|
MoverParameters->LoadAmount = std::max( 0.f, MoverParameters->LoadAmount - exchangesize );
|
||||||
update_load_visibility();
|
update_load_visibility();
|
||||||
}
|
}
|
||||||
if( m_exchange.unload_count < 0.01 ) {
|
if( m_exchange.unload_count < 0.01 ) {
|
||||||
// finish any potential unloading operation before adding new load
|
// finish any potential unloading operation before adding new load
|
||||||
// don't load more than can fit
|
// don't load more than can fit
|
||||||
m_exchange.load_count = std::min( m_exchange.load_count, MoverParameters->MaxLoad - MoverParameters->Load );
|
m_exchange.load_count = std::min( m_exchange.load_count, MoverParameters->MaxLoad - MoverParameters->LoadAmount );
|
||||||
while( ( m_exchange.load_count > 0.01 )
|
while( ( m_exchange.load_count > 0.01 )
|
||||||
&& ( m_exchange.time >= 1.0 ) ) {
|
&& ( m_exchange.time >= 1.0 ) ) {
|
||||||
|
|
||||||
@@ -2626,7 +2630,7 @@ void TDynamicObject::update_exchange( double const Deltatime ) {
|
|||||||
auto const exchangesize = std::min( m_exchange.load_count, MoverParameters->LoadSpeed * m_exchange.speed_factor );
|
auto const exchangesize = std::min( m_exchange.load_count, MoverParameters->LoadSpeed * m_exchange.speed_factor );
|
||||||
m_exchange.load_count -= exchangesize;
|
m_exchange.load_count -= exchangesize;
|
||||||
MoverParameters->LoadStatus = 2;
|
MoverParameters->LoadStatus = 2;
|
||||||
MoverParameters->Load = std::min( MoverParameters->MaxLoad, MoverParameters->Load + exchangesize ); // std::max not strictly needed but, eh
|
MoverParameters->LoadAmount = std::min( MoverParameters->MaxLoad, MoverParameters->LoadAmount + exchangesize ); // std::max not strictly needed but, eh
|
||||||
update_load_visibility();
|
update_load_visibility();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2664,34 +2668,28 @@ void TDynamicObject::LoadUpdate() {
|
|||||||
// przeładowanie modelu ładunku
|
// przeładowanie modelu ładunku
|
||||||
// Ra: nie próbujemy wczytywać modeli miliony razy podczas renderowania!!!
|
// Ra: nie próbujemy wczytywać modeli miliony razy podczas renderowania!!!
|
||||||
if( ( mdLoad == nullptr )
|
if( ( mdLoad == nullptr )
|
||||||
&& ( MoverParameters->Load > 0 ) ) {
|
&& ( MoverParameters->LoadAmount > 0 ) ) {
|
||||||
|
|
||||||
if( false == MoverParameters->LoadType.empty() ) {
|
if( false == MoverParameters->LoadType.name.empty() ) {
|
||||||
|
// bieżąca ścieżka do tekstur to dynamic/...
|
||||||
|
Global.asCurrentTexturePath = asBaseDir;
|
||||||
|
|
||||||
Global.asCurrentTexturePath = asBaseDir; // bieżąca ścieżka do tekstur to dynamic/...
|
mdLoad = LoadMMediaFile_mdload( MoverParameters->LoadType.name );
|
||||||
|
// TODO: discern from vehicle component which merely uses vehicle directory and has no animations, so it can be initialized outright
|
||||||
// try first specialized version of the load model, vehiclename_loadname
|
// and actual vehicles which get their initialization after their animations are set up
|
||||||
auto const specializedloadfilename { asBaseDir + MoverParameters->TypeName + "_" + MoverParameters->LoadType };
|
|
||||||
mdLoad = TModelsManager::GetModel( specializedloadfilename, true );
|
|
||||||
if( mdLoad == nullptr ) {
|
|
||||||
// if this fails, try generic load model
|
|
||||||
auto const genericloadfilename { asBaseDir + MoverParameters->LoadType };
|
|
||||||
mdLoad = TModelsManager::GetModel( genericloadfilename, true );
|
|
||||||
}
|
|
||||||
if( mdLoad != nullptr ) {
|
if( mdLoad != nullptr ) {
|
||||||
// TODO: discern from vehicle component which merely uses vehicle directory and has no animations, so it can be initialized outright
|
|
||||||
// and actual vehicles which get their initialization after their animations are set up
|
|
||||||
mdLoad->Init();
|
mdLoad->Init();
|
||||||
}
|
}
|
||||||
// update bindings between lowpoly sections and potential load chunks placed inside them
|
// update bindings between lowpoly sections and potential load chunks placed inside them
|
||||||
update_load_sections();
|
update_load_sections();
|
||||||
|
// z powrotem defaultowa sciezka do tekstur
|
||||||
Global.asCurrentTexturePath = std::string( szTexturePath ); // z powrotem defaultowa sciezka do tekstur
|
Global.asCurrentTexturePath = std::string( szTexturePath );
|
||||||
}
|
}
|
||||||
// Ra: w MMD można by zapisać położenie modelu ładunku (np. węgiel) w zależności od załadowania
|
// Ra: w MMD można by zapisać położenie modelu ładunku (np. węgiel) w zależności od załadowania
|
||||||
}
|
}
|
||||||
else if( MoverParameters->Load == 0 ) {
|
else if( MoverParameters->LoadAmount == 0 ) {
|
||||||
// nie ma ładunku
|
// nie ma ładunku
|
||||||
|
MoverParameters->AssignLoad( "" );
|
||||||
mdLoad = nullptr;
|
mdLoad = nullptr;
|
||||||
// erase bindings between lowpoly sections and potential load chunks placed inside them
|
// erase bindings between lowpoly sections and potential load chunks placed inside them
|
||||||
update_load_sections();
|
update_load_sections();
|
||||||
@@ -2729,7 +2727,7 @@ TDynamicObject::update_load_visibility() {
|
|||||||
auto loadpercentage { (
|
auto loadpercentage { (
|
||||||
MoverParameters->MaxLoad == 0.0 ?
|
MoverParameters->MaxLoad == 0.0 ?
|
||||||
0.0 :
|
0.0 :
|
||||||
100.0 * MoverParameters->Load / MoverParameters->MaxLoad ) };
|
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
||||||
auto const sectionloadpercentage { (
|
auto const sectionloadpercentage { (
|
||||||
SectionLoadVisibility.empty() ?
|
SectionLoadVisibility.empty() ?
|
||||||
0.0 :
|
0.0 :
|
||||||
@@ -2758,14 +2756,14 @@ TDynamicObject::update_load_visibility() {
|
|||||||
void
|
void
|
||||||
TDynamicObject::update_load_offset() {
|
TDynamicObject::update_load_offset() {
|
||||||
|
|
||||||
if( MoverParameters->LoadMinOffset == 0.f ) { return; }
|
if( MoverParameters->LoadType.offset_min == 0.f ) { return; }
|
||||||
|
|
||||||
auto const loadpercentage { (
|
auto const loadpercentage { (
|
||||||
MoverParameters->MaxLoad == 0.0 ?
|
MoverParameters->MaxLoad == 0.0 ?
|
||||||
0.0 :
|
0.0 :
|
||||||
100.0 * MoverParameters->Load / MoverParameters->MaxLoad ) };
|
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
||||||
|
|
||||||
LoadOffset = interpolate( MoverParameters->LoadMinOffset, 0.f, clamp( 0.0, 1.0, loadpercentage * 0.01 ) );
|
LoadOffset = interpolate( MoverParameters->LoadType.offset_min, 0.f, clamp( 0.0, 1.0, loadpercentage * 0.01 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -4479,20 +4477,14 @@ TDynamicObject::tracing_offset() const {
|
|||||||
|
|
||||||
// McZapkie-250202
|
// McZapkie-250202
|
||||||
// wczytywanie pliku z danymi multimedialnymi (dzwieki)
|
// wczytywanie pliku z danymi multimedialnymi (dzwieki)
|
||||||
void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName, std::string ReplacableSkin ) {
|
void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string const &ReplacableSkin ) {
|
||||||
|
|
||||||
replace_slashes( BaseDir );
|
|
||||||
Global.asCurrentDynamicPath = BaseDir;
|
|
||||||
std::string asFileName = BaseDir + TypeName + ".mmd";
|
|
||||||
std::string asLoadName;
|
|
||||||
if( false == MoverParameters->LoadType.empty() ) {
|
|
||||||
asLoadName = BaseDir + MoverParameters->LoadType;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Global.asCurrentDynamicPath = asBaseDir;
|
||||||
|
std::string asFileName = asBaseDir + TypeName + ".mmd";
|
||||||
std::string asAnimName;
|
std::string asAnimName;
|
||||||
bool Stop_InternalData = false;
|
bool Stop_InternalData = false;
|
||||||
pants = NULL; // wskaźnik pierwszego obiektu animującego dla pantografów
|
pants = NULL; // wskaźnik pierwszego obiektu animującego dla pantografów
|
||||||
cParser parser( TypeName + ".mmd", cParser::buffer_FILE, BaseDir );
|
cParser parser( TypeName + ".mmd", cParser::buffer_FILE, asBaseDir );
|
||||||
if( false == parser.ok() ) {
|
if( false == parser.ok() ) {
|
||||||
ErrorLog( "Failed to load appearance data for vehicle " + MoverParameters->Name );
|
ErrorLog( "Failed to load appearance data for vehicle " + MoverParameters->Name );
|
||||||
return;
|
return;
|
||||||
@@ -4526,8 +4518,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1
|
m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1
|
||||||
}
|
}
|
||||||
asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir
|
asModel = asBaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir
|
||||||
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
Global.asCurrentTexturePath = asBaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||||
mdModel = TModelsManager::GetModel(asModel, true);
|
mdModel = TModelsManager::GetModel(asModel, true);
|
||||||
if (ReplacableSkin != "none")
|
if (ReplacableSkin != "none")
|
||||||
{
|
{
|
||||||
@@ -4553,7 +4545,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// otherwise try the basic approach
|
// otherwise try the basic approach
|
||||||
erase_extension( ReplacableSkin );
|
|
||||||
int skinindex = 0;
|
int skinindex = 0;
|
||||||
do {
|
do {
|
||||||
material_handle material = GfxRenderer.Fetch_Material( ReplacableSkin + "," + std::to_string( skinindex + 1 ), true );
|
material_handle material = GfxRenderer.Fetch_Material( ReplacableSkin + "," + std::to_string( skinindex + 1 ), true );
|
||||||
@@ -4598,53 +4589,9 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
m_materialdata.textures_alpha |= 0x08080008;
|
m_materialdata.textures_alpha |= 0x08080008;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !MoverParameters->LoadAccepted.empty() ) {
|
if( false == MoverParameters->LoadAttributes.empty() ) {
|
||||||
|
// Ra: tu wczytywanie modelu ładunku jest w porządku
|
||||||
if( ( MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector )
|
mdLoad = LoadMMediaFile_mdload( MoverParameters->LoadType.name );
|
||||||
&& ( asLoadName == "pantstate" ) ) {
|
|
||||||
// wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
|
|
||||||
if( MoverParameters->Load == 1 ) {
|
|
||||||
MoverParameters->PantFront( true );
|
|
||||||
}
|
|
||||||
else if( MoverParameters->Load == 2 ) {
|
|
||||||
MoverParameters->PantRear( true );
|
|
||||||
}
|
|
||||||
else if( MoverParameters->Load == 3 ) {
|
|
||||||
MoverParameters->PantFront( true );
|
|
||||||
MoverParameters->PantRear( true );
|
|
||||||
}
|
|
||||||
else if( MoverParameters->Load == 4 ) {
|
|
||||||
MoverParameters->DoubleTr = -1;
|
|
||||||
}
|
|
||||||
else if( MoverParameters->Load == 5 ) {
|
|
||||||
MoverParameters->DoubleTr = -1;
|
|
||||||
MoverParameters->PantRear( true );
|
|
||||||
}
|
|
||||||
else if( MoverParameters->Load == 6 ) {
|
|
||||||
MoverParameters->DoubleTr = -1;
|
|
||||||
MoverParameters->PantFront( true );
|
|
||||||
}
|
|
||||||
else if( MoverParameters->Load == 7 ) {
|
|
||||||
MoverParameters->DoubleTr = -1;
|
|
||||||
MoverParameters->PantFront( true );
|
|
||||||
MoverParameters->PantRear( true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Ra: tu wczytywanie modelu ładunku jest w porządku
|
|
||||||
if( false == asLoadName.empty() ) {
|
|
||||||
// try first specialized version of the load model, vehiclename_loadname
|
|
||||||
auto const specializedloadfilename { BaseDir + TypeName + "_" + MoverParameters->LoadType };
|
|
||||||
if( ( true == FileExists( specializedloadfilename + ".e3d" ) )
|
|
||||||
|| ( true == FileExists( specializedloadfilename + ".t3d" ) ) ) {
|
|
||||||
mdLoad = TModelsManager::GetModel( specializedloadfilename, true );
|
|
||||||
}
|
|
||||||
if( mdLoad == nullptr ) {
|
|
||||||
// if this fails, try generic load model
|
|
||||||
mdLoad = TModelsManager::GetModel( asLoadName, true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
||||||
do {
|
do {
|
||||||
@@ -4707,8 +4654,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
// filename can potentially begin with a slash, and we don't need it
|
// filename can potentially begin with a slash, and we don't need it
|
||||||
asModel.erase( 0, 1 );
|
asModel.erase( 0, 1 );
|
||||||
}
|
}
|
||||||
asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
asModel = asBaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
||||||
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
Global.asCurrentTexturePath = asBaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||||
mdLowPolyInt = TModelsManager::GetModel(asModel, true);
|
mdLowPolyInt = TModelsManager::GetModel(asModel, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5925,6 +5872,25 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
m_couplersounds[ side::rear ].dsbBufferClamp_loud.offset( rearcoupleroffset );
|
m_couplersounds[ side::rear ].dsbBufferClamp_loud.offset( rearcoupleroffset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TModel3d *
|
||||||
|
TDynamicObject::LoadMMediaFile_mdload( std::string const &Name ) const {
|
||||||
|
|
||||||
|
if( Name.empty() ) { return nullptr; }
|
||||||
|
|
||||||
|
// try first specialized version of the load model, vehiclename_loadname
|
||||||
|
TModel3d *loadmodel { nullptr };
|
||||||
|
auto const specializedloadfilename { asBaseDir + MoverParameters->TypeName + "_" + Name };
|
||||||
|
if( ( true == FileExists( specializedloadfilename + ".e3d" ) )
|
||||||
|
|| ( true == FileExists( specializedloadfilename + ".t3d" ) ) ) {
|
||||||
|
loadmodel = TModelsManager::GetModel( specializedloadfilename, true );
|
||||||
|
}
|
||||||
|
if( loadmodel == nullptr ) {
|
||||||
|
// if this fails, try generic load model
|
||||||
|
loadmodel = TModelsManager::GetModel( asBaseDir + Name, true );
|
||||||
|
}
|
||||||
|
return loadmodel;
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void TDynamicObject::RadioStop()
|
void TDynamicObject::RadioStop()
|
||||||
{ // zatrzymanie pojazdu
|
{ // zatrzymanie pojazdu
|
||||||
@@ -7029,7 +6995,8 @@ vehicle_table::erase_disabled() {
|
|||||||
&& ( true == vehicle->MyTrack->RemoveDynamicObject( vehicle ) ) ) {
|
&& ( true == vehicle->MyTrack->RemoveDynamicObject( vehicle ) ) ) {
|
||||||
vehicle->MyTrack = nullptr;
|
vehicle->MyTrack = nullptr;
|
||||||
}
|
}
|
||||||
if( simulation::Train->Dynamic() == vehicle ) {
|
if( ( simulation::Train != nullptr )
|
||||||
|
&& ( simulation::Train->Dynamic() == vehicle ) ) {
|
||||||
// clear potential train binding
|
// clear potential train binding
|
||||||
// TBD, TODO: manually eject the driver first ?
|
// TBD, TODO: manually eject the driver first ?
|
||||||
SafeDelete( simulation::Train );
|
SafeDelete( simulation::Train );
|
||||||
|
|||||||
5
DynObj.h
5
DynObj.h
@@ -458,7 +458,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
void ABuScanObjects(int ScanDir, double ScanDist);
|
void ABuScanObjects(int ScanDir, double ScanDist);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler );
|
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler );
|
||||||
void ABuCheckMyTrack();
|
void ABuCheckMyTrack();
|
||||||
|
|
||||||
@@ -580,7 +580,8 @@ private:
|
|||||||
Axle0.GetTrack()); };
|
Axle0.GetTrack()); };
|
||||||
|
|
||||||
// McZapkie-260202
|
// McZapkie-260202
|
||||||
void LoadMMediaFile(std::string BaseDir, std::string TypeName, std::string ReplacableSkin);
|
void LoadMMediaFile(std::string const &TypeName, std::string const &ReplacableSkin);
|
||||||
|
TModel3d *LoadMMediaFile_mdload( std::string const &Name ) const;
|
||||||
|
|
||||||
inline double ABuGetDirection() const { // ABu.
|
inline double ABuGetDirection() const { // ABu.
|
||||||
return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); };
|
return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); };
|
||||||
|
|||||||
@@ -913,15 +913,15 @@ whois_event::run_() {
|
|||||||
else {
|
else {
|
||||||
// jeśli parametry ładunku
|
// jeśli parametry ładunku
|
||||||
targetcell->UpdateValues(
|
targetcell->UpdateValues(
|
||||||
m_activator->MoverParameters->LoadType, // nazwa ładunku
|
m_activator->MoverParameters->LoadType.name, // nazwa ładunku
|
||||||
m_activator->MoverParameters->Load, // aktualna ilość
|
m_activator->MoverParameters->LoadAmount, // aktualna ilość
|
||||||
m_activator->MoverParameters->MaxLoad, // maksymalna ilość
|
m_activator->MoverParameters->MaxLoad, // maksymalna ilość
|
||||||
m_input.flags & ( flags::text | flags::value_1 | flags::value_2 ) );
|
m_input.flags & ( flags::text | flags::value_1 | flags::value_2 ) );
|
||||||
|
|
||||||
WriteLog(
|
WriteLog(
|
||||||
"Type: WhoIs (" + to_string( m_input.flags ) + ") - "
|
"Type: WhoIs (" + to_string( m_input.flags ) + ") - "
|
||||||
+ "[load type: " + m_activator->MoverParameters->LoadType + "], "
|
+ "[load type: " + m_activator->MoverParameters->LoadType.name + "], "
|
||||||
+ "[current load: " + to_string( m_activator->MoverParameters->Load, 2 ) + "], "
|
+ "[current load: " + to_string( m_activator->MoverParameters->LoadAmount, 2 ) + "], "
|
||||||
+ "[max load: " + to_string( m_activator->MoverParameters->MaxLoad, 2 ) + "]" );
|
+ "[max load: " + to_string( m_activator->MoverParameters->MaxLoad, 2 ) + "]" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -944,11 +944,19 @@ public:
|
|||||||
double MED_EPVC_Time = 7; // czas korekcji sily hamowania EP, gdy nie ma dostepnego ED
|
double MED_EPVC_Time = 7; // czas korekcji sily hamowania EP, gdy nie ma dostepnego ED
|
||||||
bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku
|
bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku
|
||||||
/*-dla wagonow*/
|
/*-dla wagonow*/
|
||||||
|
struct load_attributes {
|
||||||
|
std::string name; // name of the cargo
|
||||||
|
float offset_min { 0.f }; // offset applied to cargo model when load amount is 0
|
||||||
|
|
||||||
|
load_attributes() = default;
|
||||||
|
load_attributes( std::string const &Name, float const Offsetmin ) :
|
||||||
|
name( Name ), offset_min( Offsetmin )
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
std::vector<load_attributes> LoadAttributes;
|
||||||
float MaxLoad = 0.f; /*masa w T lub ilosc w sztukach - ladownosc*/
|
float MaxLoad = 0.f; /*masa w T lub ilosc w sztukach - ladownosc*/
|
||||||
std::string LoadAccepted; std::string LoadQuantity; /*co moze byc zaladowane, jednostki miary*/
|
double OverLoadFactor = 0.0; /*ile razy moze byc przekroczona ladownosc*/
|
||||||
double OverLoadFactor = 0.0; /*ile razy moze byc przekroczona ladownosc*/
|
float LoadSpeed = 0.f; float UnLoadSpeed = 0.f;/*szybkosc na- i rozladunku jednostki/s*/
|
||||||
float LoadMinOffset { 0.f }; // offset applied to cargo model when load amount is 0
|
|
||||||
float LoadSpeed = 0.f; float UnLoadSpeed = 0.f;/*szybkosc na- i rozladunku jednostki/s*/
|
|
||||||
int DoorOpenCtrl = 0; int DoorCloseCtrl = 0; /*0: przez pasazera, 1: przez maszyniste, 2: samoczynne (zamykanie)*/
|
int DoorOpenCtrl = 0; int DoorCloseCtrl = 0; /*0: przez pasazera, 1: przez maszyniste, 2: samoczynne (zamykanie)*/
|
||||||
double DoorStayOpen = 0.0; /*jak dlugo otwarte w przypadku DoorCloseCtrl=2*/
|
double DoorStayOpen = 0.0; /*jak dlugo otwarte w przypadku DoorCloseCtrl=2*/
|
||||||
bool DoorClosureWarning = false; /*czy jest ostrzeganie przed zamknieciem*/
|
bool DoorClosureWarning = false; /*czy jest ostrzeganie przed zamknieciem*/
|
||||||
@@ -1167,9 +1175,10 @@ public:
|
|||||||
double eAngle = M_PI * 0.5;
|
double eAngle = M_PI * 0.5;
|
||||||
|
|
||||||
/*-dla wagonow*/
|
/*-dla wagonow*/
|
||||||
float Load = 0.f; /*masa w T lub ilosc w sztukach - zaladowane*/
|
float LoadAmount = 0.f; /*masa w T lub ilosc w sztukach - zaladowane*/
|
||||||
std::string LoadType; /*co jest zaladowane*/
|
load_attributes LoadType;
|
||||||
int LoadStatus = 0; //+1=trwa rozladunek,+2=trwa zaladunek,+4=zakończono,0=zaktualizowany model
|
std::string LoadQuantity; // jednostki miary
|
||||||
|
int LoadStatus = 0; //+1=trwa rozladunek,+2=trwa zaladunek,+4=zakończono,0=zaktualizowany model
|
||||||
double LastLoadChangeTime = 0.0; //raz (roz)ładowania
|
double LastLoadChangeTime = 0.0; //raz (roz)ładowania
|
||||||
|
|
||||||
bool DoorBlocked = false; //Czy jest blokada drzwi
|
bool DoorBlocked = false; //Czy jest blokada drzwi
|
||||||
@@ -1211,7 +1220,7 @@ private:
|
|||||||
double CouplerDist(int Coupler);
|
double CouplerDist(int Coupler);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int LoadInitial, std::string LoadTypeInitial, int Cab);
|
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
|
||||||
// obsługa sprzęgów
|
// obsługa sprzęgów
|
||||||
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||||
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
|
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
|
||||||
@@ -1375,7 +1384,8 @@ public:
|
|||||||
bool dizel_Update(double dt);
|
bool dizel_Update(double dt);
|
||||||
|
|
||||||
/* funckje dla wagonow*/
|
/* funckje dla wagonow*/
|
||||||
bool LoadingDone(double LSpeed, std::string LoadInit);
|
bool AssignLoad( std::string const &Name, float const Amount = 0.f );
|
||||||
|
bool LoadingDone(double LSpeed, std::string const &Loadname);
|
||||||
bool DoorLeft(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi lewych
|
bool DoorLeft(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi lewych
|
||||||
bool DoorRight(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi prawych
|
bool DoorRight(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi prawych
|
||||||
bool DoorBlockedFlag(void); //sprawdzenie blokady drzwi
|
bool DoorBlockedFlag(void); //sprawdzenie blokady drzwi
|
||||||
|
|||||||
@@ -278,21 +278,14 @@ double TMoverParameters::Current(double n, double U)
|
|||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// główny konstruktor
|
// główny konstruktor
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit,
|
TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab) :
|
||||||
std::string NameInit, int LoadInitial,
|
|
||||||
std::string LoadTypeInitial,
|
|
||||||
int Cab) ://: T_MoverParameters(VelInitial, TypeNameInit,
|
|
||||||
//NameInit, LoadInitial, LoadTypeInitial, Cab)
|
|
||||||
TypeName( TypeNameInit ),
|
TypeName( TypeNameInit ),
|
||||||
Name( NameInit ),
|
Name( NameInit ),
|
||||||
ActiveCab( Cab ),
|
ActiveCab( Cab )
|
||||||
Load( LoadInitial ),
|
|
||||||
LoadType( LoadTypeInitial )
|
|
||||||
{
|
{
|
||||||
WriteLog(
|
WriteLog(
|
||||||
"------------------------------------------------------");
|
"------------------------------------------------------");
|
||||||
WriteLog("init default physic values for " + NameInit + ", [" + TypeNameInit + "], [" +
|
WriteLog("init default physic values for " + NameInit + ", [" + TypeNameInit + "]");
|
||||||
LoadTypeInitial + "]");
|
|
||||||
Dim = TDimension();
|
Dim = TDimension();
|
||||||
|
|
||||||
// BrakeLevelSet(-2); //Pascal ustawia na 0, przestawimy na odcięcie (CHK jest jeszcze nie wczytane!)
|
// BrakeLevelSet(-2); //Pascal ustawia na 0, przestawimy na odcięcie (CHK jest jeszcze nie wczytane!)
|
||||||
@@ -354,10 +347,6 @@ LoadType( LoadTypeInitial )
|
|||||||
}
|
}
|
||||||
eimc[eimc_p_eped] = 1.5;
|
eimc[eimc_p_eped] = 1.5;
|
||||||
|
|
||||||
// inicjalizacja zmiennych}
|
|
||||||
// Loc:=LocInitial; //Ra: to i tak trzeba potem przesunąć, po ustaleniu pozycji na torze
|
|
||||||
// (potrzebna długość)
|
|
||||||
// Rot:=RotInitial;
|
|
||||||
for (int b = 0; b < 2; ++b)
|
for (int b = 0; b < 2; ++b)
|
||||||
{
|
{
|
||||||
Couplers[b].AllowedFlag = 3; // domyślnie hak i hamulec, inne trzeba włączyć jawnie w FIZ
|
Couplers[b].AllowedFlag = 3; // domyślnie hak i hamulec, inne trzeba włączyć jawnie w FIZ
|
||||||
@@ -409,20 +398,6 @@ LoadType( LoadTypeInitial )
|
|||||||
SecuritySystem.RadioStop = false; // domyślnie nie ma
|
SecuritySystem.RadioStop = false; // domyślnie nie ma
|
||||||
SecuritySystem.AwareMinSpeed = 0.1 * Vmax;
|
SecuritySystem.AwareMinSpeed = 0.1 * Vmax;
|
||||||
s_CAtestebrake = false;
|
s_CAtestebrake = false;
|
||||||
// ABu 240105:
|
|
||||||
// CouplerNr[0]:=1;
|
|
||||||
// CouplerNr[1]:=0;
|
|
||||||
|
|
||||||
// TO POTEM TU UAKTYWNIC A WYWALIC Z CHECKPARAM}
|
|
||||||
//{
|
|
||||||
// if Pos(LoadTypeInitial,LoadAccepted)>0 then
|
|
||||||
// begin
|
|
||||||
//}
|
|
||||||
|
|
||||||
//{
|
|
||||||
// end
|
|
||||||
// else Load:=0;
|
|
||||||
// }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
double TMoverParameters::Distance(const TLocation &Loc1, const TLocation &Loc2,
|
double TMoverParameters::Distance(const TLocation &Loc1, const TLocation &Loc2,
|
||||||
@@ -3758,27 +3733,25 @@ void TMoverParameters::ComputeConstans(void)
|
|||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
double TMoverParameters::ComputeMass(void)
|
double TMoverParameters::ComputeMass(void)
|
||||||
{
|
{
|
||||||
double M;
|
double M { 0.0 };
|
||||||
LoadType = ToLower(LoadType); // po co zakładać jak można mieć na pewno
|
// TODO: unit weight table, pulled from external data file
|
||||||
if (Load > 0)
|
if( LoadAmount > 0 ) {
|
||||||
{ // zakładamy, że ładunek jest pisany małymi literami
|
|
||||||
if (ToLower(LoadQuantity) == "tonns")
|
if (ToLower(LoadQuantity) == "tonns")
|
||||||
M = Load * 1000;
|
M = LoadAmount * 1000;
|
||||||
else if (LoadType == "passengers")
|
else if (LoadType.name == "passengers")
|
||||||
M = Load * 80;
|
M = LoadAmount * 80;
|
||||||
else if (LoadType == "luggage")
|
else if (LoadType.name == "luggage")
|
||||||
M = Load * 100;
|
M = LoadAmount * 100;
|
||||||
else if (LoadType == "cars")
|
else if (LoadType.name == "cars")
|
||||||
M = Load * 1200; // 800 kilo to miał maluch
|
M = LoadAmount * 1200; // 800 kilo to miał maluch
|
||||||
else if (LoadType == "containers")
|
else if (LoadType.name == "containers")
|
||||||
M = Load * 8000;
|
M = LoadAmount * 8000;
|
||||||
else if (LoadType == "transformers")
|
else if (LoadType.name == "transformers")
|
||||||
M = Load * 50000;
|
M = LoadAmount * 50000;
|
||||||
else
|
else
|
||||||
M = Load * 1000;
|
M = LoadAmount * 1000;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
M = 0;
|
|
||||||
// Ra: na razie tak, ale nie wszędzie masy wirujące się wliczają
|
// Ra: na razie tak, ale nie wszędzie masy wirujące się wliczają
|
||||||
return Mass + M + Mred;
|
return Mass + M + Mred;
|
||||||
}
|
}
|
||||||
@@ -6458,58 +6431,105 @@ void TMoverParameters::dizel_Heat( double const dt ) {
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TMoverParameters::AssignLoad( std::string const &Name, float const Amount ) {
|
||||||
|
|
||||||
|
if( Name == "pantstate" ) {
|
||||||
|
if( EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) {
|
||||||
|
// wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
|
||||||
|
auto const pantographsetup { static_cast<int>( Amount ) };
|
||||||
|
if( pantographsetup & ( 1 << 2 ) ) {
|
||||||
|
DoubleTr = -1;
|
||||||
|
}
|
||||||
|
if( pantographsetup & ( 1 << 0 ) ) {
|
||||||
|
if( DoubleTr == 1 ) { PantFront( true ); }
|
||||||
|
else { PantRear( true ); }
|
||||||
|
}
|
||||||
|
if( pantographsetup & ( 1 << 1 ) ) {
|
||||||
|
if( DoubleTr == 1 ) { PantRear( true ); }
|
||||||
|
else { PantFront( true ); }
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't mix load types, at least for the time being
|
||||||
|
if( ( LoadAmount > 0 ) && ( LoadType.name != Name ) ) { return false; }
|
||||||
|
|
||||||
|
if( Name.empty() ) {
|
||||||
|
// empty the vehicle
|
||||||
|
LoadType = load_attributes();
|
||||||
|
LoadAmount = 0.f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto const &loadattributes : LoadAttributes ) {
|
||||||
|
if( Name == loadattributes.name ) {
|
||||||
|
LoadType = loadattributes;
|
||||||
|
LoadAmount = Amount;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// didn't find matching load configuration, this type is unsupported
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
// Q: 20160713
|
// Q: 20160713
|
||||||
// Test zakończenia załadunku / rozładunku
|
// Test zakończenia załadunku / rozładunku
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
bool TMoverParameters::LoadingDone(double LSpeed, std::string LoadInit)
|
bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadname) {
|
||||||
{
|
|
||||||
// test zakończenia załadunku/rozładunku
|
|
||||||
long LoadChange = 0;
|
|
||||||
bool LD = false;
|
|
||||||
|
|
||||||
// ClearPendingExceptions; // zabezpieczenie dla Trunc()
|
if( LSpeed == 0.0 ) {
|
||||||
// LoadingDone:=false; //nie zakończone
|
// zerowa prędkość zmiany, to koniec
|
||||||
if (!LoadInit.empty()) // nazwa ładunku niepusta
|
LoadStatus = 4;
|
||||||
{
|
return true;
|
||||||
if (Load > MaxLoad)
|
|
||||||
LoadChange = abs(long(LSpeed * LastLoadChangeTime / 2.0)); // przeładowanie?
|
|
||||||
else
|
|
||||||
LoadChange = abs(long(LSpeed * LastLoadChangeTime));
|
|
||||||
if (LSpeed < 0) // gdy rozładunek
|
|
||||||
{
|
|
||||||
LoadStatus = 2; // trwa rozładunek (włączenie naliczania czasu)
|
|
||||||
if (LoadChange != 0) // jeśli coś przeładowano
|
|
||||||
{
|
|
||||||
LastLoadChangeTime = 0; // naliczony czas został zużyty
|
|
||||||
Load -= LoadChange; // zmniejszenie ilości ładunku
|
|
||||||
CommandIn.Value1 =
|
|
||||||
CommandIn.Value1 - LoadChange; // zmniejszenie ilości do rozładowania
|
|
||||||
if (Load < 0)
|
|
||||||
Load = 0; //ładunek nie może być ujemny
|
|
||||||
if ((Load == 0) || (CommandIn.Value1 < 0)) // pusto lub rozładowano żądaną ilość
|
|
||||||
LoadStatus = 4; // skończony rozładunek
|
|
||||||
if (Load == 0)
|
|
||||||
LoadType.clear(); // jak nic nie ma, to nie ma też nazwy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (LSpeed > 0) // gdy załadunek
|
|
||||||
{
|
|
||||||
LoadStatus = 1; // trwa załadunek (włączenie naliczania czasu)
|
|
||||||
if (LoadChange != 0) // jeśli coś przeładowano
|
|
||||||
{
|
|
||||||
LastLoadChangeTime = 0; // naliczony czas został zużyty
|
|
||||||
LoadType = LoadInit; // nazwa
|
|
||||||
Load += LoadChange; // zwiększenie ładunku
|
|
||||||
CommandIn.Value1 = CommandIn.Value1 - LoadChange;
|
|
||||||
if ((Load >= MaxLoad * (1.0 + OverLoadFactor)) || (CommandIn.Value1 < 0))
|
|
||||||
LoadStatus = 4; // skończony załadunek
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LoadStatus = 4; // zerowa prędkość zmiany, to koniec
|
|
||||||
}
|
}
|
||||||
return (LoadStatus >= 4);
|
|
||||||
|
if( Loadname.empty() ) { return ( LoadStatus >= 4 ); }
|
||||||
|
if( Loadname != LoadType.name ) { return ( LoadStatus >= 4 ); }
|
||||||
|
|
||||||
|
// test zakończenia załadunku/rozładunku
|
||||||
|
// load exchange speed is reduced if the wagon is overloaded
|
||||||
|
auto const loadchange { static_cast<float>( std::abs( LSpeed * LastLoadChangeTime ) * ( LoadAmount > MaxLoad ? 0.5 : 1.0 ) ) };
|
||||||
|
|
||||||
|
if( LSpeed < 0 ) {
|
||||||
|
// gdy rozładunek
|
||||||
|
LoadStatus = 2; // trwa rozładunek (włączenie naliczania czasu)
|
||||||
|
if( loadchange > 0 ) // jeśli coś przeładowano
|
||||||
|
{
|
||||||
|
LastLoadChangeTime = 0; // naliczony czas został zużyty
|
||||||
|
LoadAmount -= loadchange; // zmniejszenie ilości ładunku
|
||||||
|
CommandIn.Value1 -= loadchange; // zmniejszenie ilości do rozładowania
|
||||||
|
if( ( LoadAmount <= 0 ) || ( CommandIn.Value1 <= 0 ) ) {
|
||||||
|
// pusto lub rozładowano żądaną ilość
|
||||||
|
LoadStatus = 4; // skończony rozładunek
|
||||||
|
LoadAmount = std::max( 0.f, LoadAmount ); //ładunek nie może być ujemny
|
||||||
|
}
|
||||||
|
if( LoadAmount == 0.f ) {
|
||||||
|
AssignLoad(""); // jak nic nie ma, to nie ma też nazwy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( LSpeed > 0 ) {
|
||||||
|
// gdy załadunek
|
||||||
|
LoadStatus = 1; // trwa załadunek (włączenie naliczania czasu)
|
||||||
|
if( loadchange > 0 ) // jeśli coś przeładowano
|
||||||
|
{
|
||||||
|
LastLoadChangeTime = 0; // naliczony czas został zużyty
|
||||||
|
LoadAmount += loadchange; // zwiększenie ładunku
|
||||||
|
CommandIn.Value1 -= loadchange;
|
||||||
|
if( ( LoadAmount >= MaxLoad * ( 1.0 + OverLoadFactor ) ) || ( CommandIn.Value1 <= 0 ) ) {
|
||||||
|
LoadStatus = 4; // skończony załadunek
|
||||||
|
LoadAmount = std::min<float>( MaxLoad * ( 1.0 + OverLoadFactor ), LoadAmount );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ( LoadStatus >= 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
@@ -7593,19 +7613,30 @@ void TMoverParameters::LoadFIZ_Param( std::string const &line ) {
|
|||||||
|
|
||||||
void TMoverParameters::LoadFIZ_Load( std::string const &line ) {
|
void TMoverParameters::LoadFIZ_Load( std::string const &line ) {
|
||||||
|
|
||||||
extract_value( LoadAccepted, "LoadAccepted", line, "" );
|
auto const acceptedloads { Split( extract_value( "LoadAccepted", line ), ',' ) };
|
||||||
if( true == LoadAccepted.empty() ) {
|
|
||||||
return;
|
if( acceptedloads.empty() ) { return; }
|
||||||
|
|
||||||
|
auto const minoffsets { Split( extract_value( "LoadMinOffset", line ), ',' ) };
|
||||||
|
auto minoffset { 0.f };
|
||||||
|
auto minoffsetsiterator { std::begin( minoffsets ) };
|
||||||
|
// NOTE: last (if any) offset parameter retrieved from the list applies to the remainder of the list
|
||||||
|
// TBD, TODO: include other load parameters in this system
|
||||||
|
for( auto &load : acceptedloads ) {
|
||||||
|
if( minoffsetsiterator != std::end( minoffsets ) ) {
|
||||||
|
minoffset = std::stof( *minoffsetsiterator );
|
||||||
|
++minoffsetsiterator;
|
||||||
|
}
|
||||||
|
LoadAttributes.emplace_back(
|
||||||
|
ToLower( load ),
|
||||||
|
minoffset );
|
||||||
}
|
}
|
||||||
LoadAccepted = ToLower( LoadAccepted );
|
|
||||||
|
|
||||||
extract_value( MaxLoad, "MaxLoad", line, "" );
|
extract_value( MaxLoad, "MaxLoad", line, "" );
|
||||||
extract_value( LoadQuantity, "LoadQ", line, "" );
|
extract_value( LoadQuantity, "LoadQ", line, "" );
|
||||||
extract_value( OverLoadFactor, "OverLoadFactor", line, "" );
|
extract_value( OverLoadFactor, "OverLoadFactor", line, "" );
|
||||||
extract_value( LoadSpeed, "LoadSpeed", line, "" );
|
extract_value( LoadSpeed, "LoadSpeed", line, "" );
|
||||||
extract_value( UnLoadSpeed, "UnLoadSpeed", line, "" );
|
extract_value( UnLoadSpeed, "UnLoadSpeed", line, "" );
|
||||||
|
|
||||||
extract_value( LoadMinOffset, "LoadMinOffset", line, "" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::LoadFIZ_Dimensions( std::string const &line ) {
|
void TMoverParameters::LoadFIZ_Dimensions( std::string const &line ) {
|
||||||
@@ -8651,11 +8682,6 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
|||||||
// WriteLogSS("aa ok", BoolToYN(OK));
|
// WriteLogSS("aa ok", BoolToYN(OK));
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( LoadType.empty() == false ) && ( LoadAccepted.find( LoadType ) == std::string::npos ) ) {
|
|
||||||
// remove load if the type isn't supported
|
|
||||||
Load = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BrakeSystem == TBrakeSystem::Individual)
|
if (BrakeSystem == TBrakeSystem::Individual)
|
||||||
if (BrakeSubsystem != TBrakeSubSystem::ss_None)
|
if (BrakeSubsystem != TBrakeSubSystem::ss_None)
|
||||||
OK = false; //!
|
OK = false; //!
|
||||||
@@ -8889,16 +8915,16 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
|||||||
|
|
||||||
if( LoadFlag > 0 ) {
|
if( LoadFlag > 0 ) {
|
||||||
|
|
||||||
if( Load < MaxLoad * 0.45 ) {
|
if( LoadAmount < MaxLoad * 0.45 ) {
|
||||||
IncBrakeMult();
|
IncBrakeMult();
|
||||||
IncBrakeMult();
|
IncBrakeMult();
|
||||||
DecBrakeMult(); // TODO: przeinesiono do mover.cpp
|
DecBrakeMult(); // TODO: przeinesiono do mover.cpp
|
||||||
if( Load < MaxLoad * 0.35 )
|
if( LoadAmount < MaxLoad * 0.35 )
|
||||||
DecBrakeMult();
|
DecBrakeMult();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
IncBrakeMult(); // TODO: przeinesiono do mover.cpp
|
IncBrakeMult(); // TODO: przeinesiono do mover.cpp
|
||||||
if( Load >= MaxLoad * 0.55 )
|
if( LoadAmount >= MaxLoad * 0.55 )
|
||||||
IncBrakeMult();
|
IncBrakeMult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9479,39 +9505,44 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
OK = true; // true, gdy można usunąć komendę
|
OK = true; // true, gdy można usunąć komendę
|
||||||
}
|
}
|
||||||
/*naladunek/rozladunek*/
|
/*naladunek/rozladunek*/
|
||||||
else if ( issection( "Load=", Command ) )
|
// TODO: have these commands leverage load exchange system instead
|
||||||
|
else if ( issection( "Load=", Command ) )
|
||||||
{
|
{
|
||||||
OK = false; // będzie powtarzane aż się załaduje
|
OK = false; // będzie powtarzane aż się załaduje
|
||||||
if( ( Vel < 0.01 )
|
if( ( Vel < 0.1 ) // tolerance margin for small vehicle movements in the consist
|
||||||
&& ( MaxLoad > 0 )
|
&& ( MaxLoad > 0 )
|
||||||
&& ( Load < MaxLoad * ( 1.0 + OverLoadFactor ) ) ) {
|
&& ( LoadAmount < MaxLoad * ( 1.0 + OverLoadFactor ) )
|
||||||
// czy można ładowac?
|
&& ( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) ) { // ten peron/rampa
|
||||||
if( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) {
|
|
||||||
// ten peron/rampa
|
auto const loadname { ToLower( extract_value( "Load", Command ) ) };
|
||||||
auto const testload { ToLower( extract_value( "Load", Command ) ) };
|
if( LoadAmount == 0.f ) {
|
||||||
if( LoadAccepted.find( testload ) != std::string::npos ) // nazwa jest obecna w CHK
|
AssignLoad( loadname );
|
||||||
OK = LoadingDone( Min0R( CValue2, LoadSpeed ), testload ); // zmienia LoadStatus
|
|
||||||
}
|
}
|
||||||
|
OK = LoadingDone(
|
||||||
|
std::min<float>( CValue2, LoadSpeed ),
|
||||||
|
loadname ); // zmienia LoadStatus
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// no loading can be done if conditions aren't met
|
||||||
|
LastLoadChangeTime = 0.0;
|
||||||
}
|
}
|
||||||
// if OK then LoadStatus:=0; //nie udalo sie w ogole albo juz skonczone
|
|
||||||
}
|
}
|
||||||
else if( issection( "UnLoad=", Command ) )
|
else if( issection( "UnLoad=", Command ) )
|
||||||
{
|
{
|
||||||
OK = false; // będzie powtarzane aż się rozładuje
|
OK = false; // będzie powtarzane aż się rozładuje
|
||||||
if( ( Vel < 0.01 )
|
if( ( Vel < 0.1 ) // tolerance margin for small vehicle movements in the consist
|
||||||
&& ( Load > 0 ) ) {
|
&& ( LoadAmount > 0 ) // czy jest co rozladowac?
|
||||||
// czy jest co rozladowac?
|
&& ( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) ) { // ten peron
|
||||||
if( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) {
|
/*mozna to rozladowac*/
|
||||||
// ten peron
|
OK = LoadingDone(
|
||||||
auto const testload { ToLower( extract_value( "UnLoad", Command ) ) }; // zgodność nazwy ładunku z CHK
|
-1.f * std::min<float>( CValue2, LoadSpeed ),
|
||||||
if( LoadType == testload ) {
|
ToLower( extract_value( "UnLoad", Command ) ) );
|
||||||
/*mozna to rozladowac*/
|
|
||||||
OK = LoadingDone( -Min0R( CValue2, LoadSpeed ), testload );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// if OK then LoadStatus:=0;
|
else {
|
||||||
}
|
// no loading can be done if conditions aren't met
|
||||||
|
LastLoadChangeTime = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (Command == "SpeedCntrl")
|
else if (Command == "SpeedCntrl")
|
||||||
{
|
{
|
||||||
if ((EngineType == TEngineType::ElectricInductionMotor))
|
if ((EngineType == TEngineType::ElectricInductionMotor))
|
||||||
|
|||||||
@@ -79,12 +79,12 @@ TSubModel::SetLightLevel( float const Level, bool const Includechildren, bool co
|
|||||||
if( true == Includesiblings ) {
|
if( true == Includesiblings ) {
|
||||||
auto sibling { this };
|
auto sibling { this };
|
||||||
while( ( sibling = sibling->Next ) != nullptr ) {
|
while( ( sibling = sibling->Next ) != nullptr ) {
|
||||||
sibling->f4Emision.a = Level;
|
sibling->SetLightLevel( Level, Includechildren, false ); // no need for all siblings to duplicate the work
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( true == Includechildren )
|
if( ( true == Includechildren )
|
||||||
&& ( Child != nullptr ) ) {
|
&& ( Child != nullptr ) ) {
|
||||||
Child->SetLightLevel( Level, true, true ); // node's children include child's siblings and children
|
Child->SetLightLevel( Level, Includechildren, true ); // node's children include child's siblings and children
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -385,8 +385,8 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
|
|||||||
locale::strings[ locale::string::debug_vehicle_nameloadstatuscouplers ].c_str(),
|
locale::strings[ locale::string::debug_vehicle_nameloadstatuscouplers ].c_str(),
|
||||||
mover.Name.c_str(),
|
mover.Name.c_str(),
|
||||||
std::string( isowned ? locale::strings[ locale::string::debug_vehicle_owned ].c_str() + vehicle.ctOwner->OwnerName() : "" ).c_str(),
|
std::string( isowned ? locale::strings[ locale::string::debug_vehicle_owned ].c_str() + vehicle.ctOwner->OwnerName() : "" ).c_str(),
|
||||||
mover.Load,
|
mover.LoadAmount,
|
||||||
mover.LoadType.c_str(),
|
mover.LoadType.name.c_str(),
|
||||||
mover.EngineDescription( 0 ).c_str(),
|
mover.EngineDescription( 0 ).c_str(),
|
||||||
// TODO: put wheel flat reporting in the enginedescription()
|
// TODO: put wheel flat reporting in the enginedescription()
|
||||||
std::string( mover.WheelFlat > 0.01 ? " Flat: " + to_string( mover.WheelFlat, 1 ) + " mm" : "" ).c_str(),
|
std::string( mover.WheelFlat > 0.01 ? " Flat: " + to_string( mover.WheelFlat, 1 ) + " mm" : "" ).c_str(),
|
||||||
|
|||||||
13
station.cpp
13
station.cpp
@@ -49,20 +49,19 @@ basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Sch
|
|||||||
|
|
||||||
auto ¶meters { *vehicle->MoverParameters };
|
auto ¶meters { *vehicle->MoverParameters };
|
||||||
|
|
||||||
if( ( true == parameters.LoadType.empty() )
|
if( parameters.LoadType.name.empty() ) {
|
||||||
&& ( parameters.LoadAccepted.find( "passengers" ) != std::string::npos ) ) {
|
// (try to) set the cargo type for empty cars
|
||||||
// set the type for empty cars
|
parameters.AssignLoad( "passengers" );
|
||||||
parameters.LoadType = "passengers";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( parameters.LoadType == "passengers" ) {
|
if( parameters.LoadType.name == "passengers" ) {
|
||||||
// NOTE: for the time being we're doing simple, random load change calculation
|
// NOTE: for the time being we're doing simple, random load change calculation
|
||||||
// TODO: exchange driven by station parameters and time of the day
|
// TODO: exchange driven by station parameters and time of the day
|
||||||
auto unloadcount = static_cast<int>(
|
auto unloadcount = static_cast<int>(
|
||||||
laststop ? parameters.Load :
|
laststop ? parameters.LoadAmount :
|
||||||
firststop ? 0 :
|
firststop ? 0 :
|
||||||
std::min<float>(
|
std::min<float>(
|
||||||
parameters.Load,
|
parameters.LoadAmount,
|
||||||
Random( parameters.MaxLoad * 0.10 * stationsizemodifier ) ) );
|
Random( parameters.MaxLoad * 0.10 * stationsizemodifier ) ) );
|
||||||
auto loadcount = static_cast<int>(
|
auto loadcount = static_cast<int>(
|
||||||
laststop ?
|
laststop ?
|
||||||
|
|||||||
Reference in New Issue
Block a user