mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 04:39:18 +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
|
||||
replace_slashes( asBaseDir );
|
||||
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
|
||||
if (DriverType == "headdriver")
|
||||
DriverType = "1"; // sterujący kabiną +1
|
||||
@@ -1810,7 +1810,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
}
|
||||
*/
|
||||
// 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ł
|
||||
// McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu
|
||||
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
|
||||
}
|
||||
// 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
|
||||
if (!MoverParameters->CheckLocomotiveParameters(
|
||||
driveractive,
|
||||
@@ -2095,7 +2098,8 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi
|
||||
*/
|
||||
// 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
|
||||
btCoupler1.Init( "coupler1", mdModel, false ); // false - ma być wyłączony
|
||||
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 );
|
||||
m_exchange.unload_count -= exchangesize;
|
||||
MoverParameters->LoadStatus = 1;
|
||||
MoverParameters->Load = std::max( 0.f, MoverParameters->Load - exchangesize );
|
||||
MoverParameters->LoadAmount = std::max( 0.f, MoverParameters->LoadAmount - exchangesize );
|
||||
update_load_visibility();
|
||||
}
|
||||
if( m_exchange.unload_count < 0.01 ) {
|
||||
// finish any potential unloading operation before adding new load
|
||||
// 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 )
|
||||
&& ( 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 );
|
||||
m_exchange.load_count -= exchangesize;
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -2664,34 +2668,28 @@ void TDynamicObject::LoadUpdate() {
|
||||
// przeładowanie modelu ładunku
|
||||
// Ra: nie próbujemy wczytywać modeli miliony razy podczas renderowania!!!
|
||||
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/...
|
||||
|
||||
// try first specialized version of the load model, vehiclename_loadname
|
||||
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 );
|
||||
}
|
||||
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
|
||||
// and actual vehicles which get their initialization after their animations are set up
|
||||
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();
|
||||
}
|
||||
// update bindings between lowpoly sections and potential load chunks placed inside them
|
||||
update_load_sections();
|
||||
|
||||
Global.asCurrentTexturePath = std::string( szTexturePath ); // z powrotem defaultowa sciezka do tekstur
|
||||
// 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
|
||||
}
|
||||
else if( MoverParameters->Load == 0 ) {
|
||||
else if( MoverParameters->LoadAmount == 0 ) {
|
||||
// nie ma ładunku
|
||||
MoverParameters->AssignLoad( "" );
|
||||
mdLoad = nullptr;
|
||||
// erase bindings between lowpoly sections and potential load chunks placed inside them
|
||||
update_load_sections();
|
||||
@@ -2729,7 +2727,7 @@ TDynamicObject::update_load_visibility() {
|
||||
auto loadpercentage { (
|
||||
MoverParameters->MaxLoad == 0.0 ?
|
||||
0.0 :
|
||||
100.0 * MoverParameters->Load / MoverParameters->MaxLoad ) };
|
||||
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
||||
auto const sectionloadpercentage { (
|
||||
SectionLoadVisibility.empty() ?
|
||||
0.0 :
|
||||
@@ -2758,14 +2756,14 @@ TDynamicObject::update_load_visibility() {
|
||||
void
|
||||
TDynamicObject::update_load_offset() {
|
||||
|
||||
if( MoverParameters->LoadMinOffset == 0.f ) { return; }
|
||||
if( MoverParameters->LoadType.offset_min == 0.f ) { return; }
|
||||
|
||||
auto const loadpercentage { (
|
||||
MoverParameters->MaxLoad == 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
|
||||
@@ -4479,20 +4477,14 @@ TDynamicObject::tracing_offset() const {
|
||||
|
||||
// McZapkie-250202
|
||||
// wczytywanie pliku z danymi multimedialnymi (dzwieki)
|
||||
void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName, std::string 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;
|
||||
}
|
||||
void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string const &ReplacableSkin ) {
|
||||
|
||||
Global.asCurrentDynamicPath = asBaseDir;
|
||||
std::string asFileName = asBaseDir + TypeName + ".mmd";
|
||||
std::string asAnimName;
|
||||
bool Stop_InternalData = false;
|
||||
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() ) {
|
||||
ErrorLog( "Failed to load appearance data for vehicle " + MoverParameters->Name );
|
||||
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
|
||||
}
|
||||
asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir
|
||||
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||
asModel = asBaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir
|
||||
Global.asCurrentTexturePath = asBaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||
mdModel = TModelsManager::GetModel(asModel, true);
|
||||
if (ReplacableSkin != "none")
|
||||
{
|
||||
@@ -4553,7 +4545,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
else {
|
||||
// otherwise try the basic approach
|
||||
erase_extension( ReplacableSkin );
|
||||
int skinindex = 0;
|
||||
do {
|
||||
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;
|
||||
}
|
||||
}
|
||||
if( !MoverParameters->LoadAccepted.empty() ) {
|
||||
|
||||
if( ( MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector )
|
||||
&& ( 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( false == MoverParameters->LoadAttributes.empty() ) {
|
||||
// Ra: tu wczytywanie modelu ładunku jest w porządku
|
||||
mdLoad = LoadMMediaFile_mdload( MoverParameters->LoadType.name );
|
||||
}
|
||||
Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
||||
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
|
||||
asModel.erase( 0, 1 );
|
||||
}
|
||||
asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
||||
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||
asModel = asBaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
||||
Global.asCurrentTexturePath = asBaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||
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 );
|
||||
}
|
||||
|
||||
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()
|
||||
{ // zatrzymanie pojazdu
|
||||
@@ -7029,7 +6995,8 @@ vehicle_table::erase_disabled() {
|
||||
&& ( true == vehicle->MyTrack->RemoveDynamicObject( vehicle ) ) ) {
|
||||
vehicle->MyTrack = nullptr;
|
||||
}
|
||||
if( simulation::Train->Dynamic() == vehicle ) {
|
||||
if( ( simulation::Train != nullptr )
|
||||
&& ( simulation::Train->Dynamic() == vehicle ) ) {
|
||||
// clear potential train binding
|
||||
// TBD, TODO: manually eject the driver first ?
|
||||
SafeDelete( simulation::Train );
|
||||
|
||||
5
DynObj.h
5
DynObj.h
@@ -458,7 +458,7 @@ private:
|
||||
public:
|
||||
void ABuScanObjects(int ScanDir, double ScanDist);
|
||||
|
||||
protected:
|
||||
private:
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler );
|
||||
void ABuCheckMyTrack();
|
||||
|
||||
@@ -580,7 +580,8 @@ private:
|
||||
Axle0.GetTrack()); };
|
||||
|
||||
// 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.
|
||||
return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); };
|
||||
|
||||
@@ -913,15 +913,15 @@ whois_event::run_() {
|
||||
else {
|
||||
// jeśli parametry ładunku
|
||||
targetcell->UpdateValues(
|
||||
m_activator->MoverParameters->LoadType, // nazwa ładunku
|
||||
m_activator->MoverParameters->Load, // aktualna ilość
|
||||
m_activator->MoverParameters->LoadType.name, // nazwa ładunku
|
||||
m_activator->MoverParameters->LoadAmount, // aktualna ilość
|
||||
m_activator->MoverParameters->MaxLoad, // maksymalna ilość
|
||||
m_input.flags & ( flags::text | flags::value_1 | flags::value_2 ) );
|
||||
|
||||
WriteLog(
|
||||
"Type: WhoIs (" + to_string( m_input.flags ) + ") - "
|
||||
+ "[load type: " + m_activator->MoverParameters->LoadType + "], "
|
||||
+ "[current load: " + to_string( m_activator->MoverParameters->Load, 2 ) + "], "
|
||||
+ "[load type: " + m_activator->MoverParameters->LoadType.name + "], "
|
||||
+ "[current load: " + to_string( m_activator->MoverParameters->LoadAmount, 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
|
||||
bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku
|
||||
/*-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*/
|
||||
std::string LoadAccepted; std::string LoadQuantity; /*co moze byc zaladowane, jednostki miary*/
|
||||
double OverLoadFactor = 0.0; /*ile razy moze byc przekroczona ladownosc*/
|
||||
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*/
|
||||
double OverLoadFactor = 0.0; /*ile razy moze byc przekroczona ladownosc*/
|
||||
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)*/
|
||||
double DoorStayOpen = 0.0; /*jak dlugo otwarte w przypadku DoorCloseCtrl=2*/
|
||||
bool DoorClosureWarning = false; /*czy jest ostrzeganie przed zamknieciem*/
|
||||
@@ -1167,9 +1175,10 @@ public:
|
||||
double eAngle = M_PI * 0.5;
|
||||
|
||||
/*-dla wagonow*/
|
||||
float Load = 0.f; /*masa w T lub ilosc w sztukach - zaladowane*/
|
||||
std::string LoadType; /*co jest zaladowane*/
|
||||
int LoadStatus = 0; //+1=trwa rozladunek,+2=trwa zaladunek,+4=zakończono,0=zaktualizowany model
|
||||
float LoadAmount = 0.f; /*masa w T lub ilosc w sztukach - zaladowane*/
|
||||
load_attributes LoadType;
|
||||
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
|
||||
|
||||
bool DoorBlocked = false; //Czy jest blokada drzwi
|
||||
@@ -1211,7 +1220,7 @@ private:
|
||||
double CouplerDist(int Coupler);
|
||||
|
||||
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
|
||||
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);
|
||||
@@ -1375,7 +1384,8 @@ public:
|
||||
bool dizel_Update(double dt);
|
||||
|
||||
/* 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 DoorRight(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi prawych
|
||||
bool DoorBlockedFlag(void); //sprawdzenie blokady drzwi
|
||||
|
||||
@@ -278,21 +278,14 @@ double TMoverParameters::Current(double n, double U)
|
||||
// *************************************************************************************************
|
||||
// główny konstruktor
|
||||
// *************************************************************************************************
|
||||
TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit,
|
||||
std::string NameInit, int LoadInitial,
|
||||
std::string LoadTypeInitial,
|
||||
int Cab) ://: T_MoverParameters(VelInitial, TypeNameInit,
|
||||
//NameInit, LoadInitial, LoadTypeInitial, Cab)
|
||||
TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab) :
|
||||
TypeName( TypeNameInit ),
|
||||
Name( NameInit ),
|
||||
ActiveCab( Cab ),
|
||||
Load( LoadInitial ),
|
||||
LoadType( LoadTypeInitial )
|
||||
ActiveCab( Cab )
|
||||
{
|
||||
WriteLog(
|
||||
"------------------------------------------------------");
|
||||
WriteLog("init default physic values for " + NameInit + ", [" + TypeNameInit + "], [" +
|
||||
LoadTypeInitial + "]");
|
||||
WriteLog("init default physic values for " + NameInit + ", [" + TypeNameInit + "]");
|
||||
Dim = TDimension();
|
||||
|
||||
// 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;
|
||||
|
||||
// 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)
|
||||
{
|
||||
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.AwareMinSpeed = 0.1 * Vmax;
|
||||
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,
|
||||
@@ -3758,27 +3733,25 @@ void TMoverParameters::ComputeConstans(void)
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::ComputeMass(void)
|
||||
{
|
||||
double M;
|
||||
LoadType = ToLower(LoadType); // po co zakładać jak można mieć na pewno
|
||||
if (Load > 0)
|
||||
{ // zakładamy, że ładunek jest pisany małymi literami
|
||||
double M { 0.0 };
|
||||
// TODO: unit weight table, pulled from external data file
|
||||
if( LoadAmount > 0 ) {
|
||||
|
||||
if (ToLower(LoadQuantity) == "tonns")
|
||||
M = Load * 1000;
|
||||
else if (LoadType == "passengers")
|
||||
M = Load * 80;
|
||||
else if (LoadType == "luggage")
|
||||
M = Load * 100;
|
||||
else if (LoadType == "cars")
|
||||
M = Load * 1200; // 800 kilo to miał maluch
|
||||
else if (LoadType == "containers")
|
||||
M = Load * 8000;
|
||||
else if (LoadType == "transformers")
|
||||
M = Load * 50000;
|
||||
M = LoadAmount * 1000;
|
||||
else if (LoadType.name == "passengers")
|
||||
M = LoadAmount * 80;
|
||||
else if (LoadType.name == "luggage")
|
||||
M = LoadAmount * 100;
|
||||
else if (LoadType.name == "cars")
|
||||
M = LoadAmount * 1200; // 800 kilo to miał maluch
|
||||
else if (LoadType.name == "containers")
|
||||
M = LoadAmount * 8000;
|
||||
else if (LoadType.name == "transformers")
|
||||
M = LoadAmount * 50000;
|
||||
else
|
||||
M = Load * 1000;
|
||||
M = LoadAmount * 1000;
|
||||
}
|
||||
else
|
||||
M = 0;
|
||||
// Ra: na razie tak, ale nie wszędzie masy wirujące się wliczają
|
||||
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
|
||||
// Test zakończenia załadunku / rozładunku
|
||||
// *************************************************************************************************
|
||||
bool TMoverParameters::LoadingDone(double LSpeed, std::string LoadInit)
|
||||
{
|
||||
// test zakończenia załadunku/rozładunku
|
||||
long LoadChange = 0;
|
||||
bool LD = false;
|
||||
bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadname) {
|
||||
|
||||
// ClearPendingExceptions; // zabezpieczenie dla Trunc()
|
||||
// LoadingDone:=false; //nie zakończone
|
||||
if (!LoadInit.empty()) // nazwa ładunku niepusta
|
||||
{
|
||||
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
|
||||
if( LSpeed == 0.0 ) {
|
||||
// zerowa prędkość zmiany, to koniec
|
||||
LoadStatus = 4;
|
||||
return true;
|
||||
}
|
||||
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 ) {
|
||||
|
||||
extract_value( LoadAccepted, "LoadAccepted", line, "" );
|
||||
if( true == LoadAccepted.empty() ) {
|
||||
return;
|
||||
auto const acceptedloads { Split( extract_value( "LoadAccepted", line ), ',' ) };
|
||||
|
||||
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( LoadQuantity, "LoadQ", line, "" );
|
||||
extract_value( OverLoadFactor, "OverLoadFactor", line, "" );
|
||||
extract_value( LoadSpeed, "LoadSpeed", line, "" );
|
||||
extract_value( UnLoadSpeed, "UnLoadSpeed", line, "" );
|
||||
|
||||
extract_value( LoadMinOffset, "LoadMinOffset", 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));
|
||||
}
|
||||
|
||||
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 (BrakeSubsystem != TBrakeSubSystem::ss_None)
|
||||
OK = false; //!
|
||||
@@ -8889,16 +8915,16 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
||||
|
||||
if( LoadFlag > 0 ) {
|
||||
|
||||
if( Load < MaxLoad * 0.45 ) {
|
||||
if( LoadAmount < MaxLoad * 0.45 ) {
|
||||
IncBrakeMult();
|
||||
IncBrakeMult();
|
||||
DecBrakeMult(); // TODO: przeinesiono do mover.cpp
|
||||
if( Load < MaxLoad * 0.35 )
|
||||
if( LoadAmount < MaxLoad * 0.35 )
|
||||
DecBrakeMult();
|
||||
}
|
||||
else {
|
||||
IncBrakeMult(); // TODO: przeinesiono do mover.cpp
|
||||
if( Load >= MaxLoad * 0.55 )
|
||||
if( LoadAmount >= MaxLoad * 0.55 )
|
||||
IncBrakeMult();
|
||||
}
|
||||
}
|
||||
@@ -9479,39 +9505,44 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
||||
OK = true; // true, gdy można usunąć komendę
|
||||
}
|
||||
/*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
|
||||
if( ( Vel < 0.01 )
|
||||
if( ( Vel < 0.1 ) // tolerance margin for small vehicle movements in the consist
|
||||
&& ( MaxLoad > 0 )
|
||||
&& ( Load < MaxLoad * ( 1.0 + OverLoadFactor ) ) ) {
|
||||
// czy można ładowac?
|
||||
if( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) {
|
||||
// ten peron/rampa
|
||||
auto const testload { ToLower( extract_value( "Load", Command ) ) };
|
||||
if( LoadAccepted.find( testload ) != std::string::npos ) // nazwa jest obecna w CHK
|
||||
OK = LoadingDone( Min0R( CValue2, LoadSpeed ), testload ); // zmienia LoadStatus
|
||||
&& ( LoadAmount < MaxLoad * ( 1.0 + OverLoadFactor ) )
|
||||
&& ( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) ) { // ten peron/rampa
|
||||
|
||||
auto const loadname { ToLower( extract_value( "Load", Command ) ) };
|
||||
if( LoadAmount == 0.f ) {
|
||||
AssignLoad( loadname );
|
||||
}
|
||||
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 ) )
|
||||
{
|
||||
OK = false; // będzie powtarzane aż się rozładuje
|
||||
if( ( Vel < 0.01 )
|
||||
&& ( Load > 0 ) ) {
|
||||
// czy jest co rozladowac?
|
||||
if( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) {
|
||||
// ten peron
|
||||
auto const testload { ToLower( extract_value( "UnLoad", Command ) ) }; // zgodność nazwy ładunku z CHK
|
||||
if( LoadType == testload ) {
|
||||
/*mozna to rozladowac*/
|
||||
OK = LoadingDone( -Min0R( CValue2, LoadSpeed ), testload );
|
||||
}
|
||||
}
|
||||
if( ( Vel < 0.1 ) // tolerance margin for small vehicle movements in the consist
|
||||
&& ( LoadAmount > 0 ) // czy jest co rozladowac?
|
||||
&& ( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) ) { // ten peron
|
||||
/*mozna to rozladowac*/
|
||||
OK = LoadingDone(
|
||||
-1.f * std::min<float>( CValue2, LoadSpeed ),
|
||||
ToLower( extract_value( "UnLoad", Command ) ) );
|
||||
}
|
||||
// if OK then LoadStatus:=0;
|
||||
}
|
||||
else {
|
||||
// no loading can be done if conditions aren't met
|
||||
LastLoadChangeTime = 0.0;
|
||||
}
|
||||
}
|
||||
else if (Command == "SpeedCntrl")
|
||||
{
|
||||
if ((EngineType == TEngineType::ElectricInductionMotor))
|
||||
|
||||
@@ -79,12 +79,12 @@ TSubModel::SetLightLevel( float const Level, bool const Includechildren, bool co
|
||||
if( true == Includesiblings ) {
|
||||
auto sibling { this };
|
||||
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 )
|
||||
&& ( 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(),
|
||||
mover.Name.c_str(),
|
||||
std::string( isowned ? locale::strings[ locale::string::debug_vehicle_owned ].c_str() + vehicle.ctOwner->OwnerName() : "" ).c_str(),
|
||||
mover.Load,
|
||||
mover.LoadType.c_str(),
|
||||
mover.LoadAmount,
|
||||
mover.LoadType.name.c_str(),
|
||||
mover.EngineDescription( 0 ).c_str(),
|
||||
// TODO: put wheel flat reporting in the enginedescription()
|
||||
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 };
|
||||
|
||||
if( ( true == parameters.LoadType.empty() )
|
||||
&& ( parameters.LoadAccepted.find( "passengers" ) != std::string::npos ) ) {
|
||||
// set the type for empty cars
|
||||
parameters.LoadType = "passengers";
|
||||
if( parameters.LoadType.name.empty() ) {
|
||||
// (try to) set the cargo type for empty cars
|
||||
parameters.AssignLoad( "passengers" );
|
||||
}
|
||||
|
||||
if( parameters.LoadType == "passengers" ) {
|
||||
if( parameters.LoadType.name == "passengers" ) {
|
||||
// NOTE: for the time being we're doing simple, random load change calculation
|
||||
// TODO: exchange driven by station parameters and time of the day
|
||||
auto unloadcount = static_cast<int>(
|
||||
laststop ? parameters.Load :
|
||||
laststop ? parameters.LoadAmount :
|
||||
firststop ? 0 :
|
||||
std::min<float>(
|
||||
parameters.Load,
|
||||
parameters.LoadAmount,
|
||||
Random( parameters.MaxLoad * 0.10 * stationsizemodifier ) ) );
|
||||
auto loadcount = static_cast<int>(
|
||||
laststop ?
|
||||
|
||||
Reference in New Issue
Block a user