mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 13:29:19 +02:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
291
Event.cpp
291
Event.cpp
@@ -301,9 +301,9 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
if (token.find('#') != std::string::npos)
|
||||
token.erase(token.find('#')); // obcięcie unikatowości
|
||||
win1250_to_ascii( token ); // get rid of non-ascii chars
|
||||
bEnabled = false; // nie do kolejki (dla SetVelocity też, ale jak jest do toru
|
||||
// dowiązany)
|
||||
Params[6].asCommand = cm_PassengerStopPoint;
|
||||
// nie do kolejki (dla SetVelocity też, ale jak jest do toru dowiązany)
|
||||
bEnabled = false;
|
||||
}
|
||||
else if (token == "SetVelocity")
|
||||
{
|
||||
@@ -325,11 +325,6 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
bEnabled = false;
|
||||
Params[6].asCommand = cm_ShuntVelocity;
|
||||
}
|
||||
//else if (str == "SetProximityVelocity")
|
||||
//{
|
||||
// bEnabled = false;
|
||||
// Params[6].asCommand = cm_SetProximityVelocity;
|
||||
//}
|
||||
else if (token == "OutsideStation")
|
||||
{
|
||||
bEnabled = false; // ma być skanowny, aby AI nie przekraczało W5
|
||||
@@ -388,6 +383,11 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
}
|
||||
}
|
||||
} while( token.compare( "endevent" ) != 0 );
|
||||
while( paramidx < 8 ) {
|
||||
// HACK: mark unspecified lights with magic value
|
||||
Params[ paramidx ].asdouble = -2.0;
|
||||
++paramidx;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tp_Visible: // zmiana wyświetlania obiektu
|
||||
@@ -400,7 +400,7 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
case tp_Velocity:
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
Params[0].asdouble = atof(token.c_str()) * 0.28;
|
||||
Params[0].asdouble = atof(token.c_str()) * ( 1000.0 / 3600.0 );
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
break;
|
||||
@@ -417,7 +417,6 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
*parser >> token;
|
||||
break;
|
||||
case tp_Exit:
|
||||
asNodeName = ExchangeCharInString( asNodeName, '_', ' ' );
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
break;
|
||||
@@ -534,8 +533,7 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
*parser >> token;
|
||||
break;
|
||||
case tp_Multiple: {
|
||||
int paramidx { 0 };
|
||||
bool ti { false }; // flaga dla else
|
||||
bool conditionalelse { false }; // flaga dla else
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
|
||||
@@ -546,12 +544,7 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
if( token != "else" ) {
|
||||
if( token.substr( 0, 5 ) != "none_" ) {
|
||||
// eventy rozpoczynające się od "none_" są ignorowane
|
||||
ext_params.push_back(std::make_pair(TParam(), 0));
|
||||
ext_params[ paramidx ].first.asText = new char[ token.size() + 1 ];
|
||||
strcpy( ext_params[ paramidx ].first.asText, token.c_str() );
|
||||
// oflagowanie dla eventów "else"
|
||||
ext_params[paramidx].second = (int)ti;
|
||||
++paramidx;
|
||||
m_children.emplace_back( token, nullptr, ( conditionalelse == false ) );
|
||||
}
|
||||
else {
|
||||
WriteLog( "Multi-event \"" + asName + "\" ignored link to event \"" + token + "\"" );
|
||||
@@ -559,8 +552,8 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
}
|
||||
else {
|
||||
// zmiana flagi dla słowa "else"
|
||||
ti = !ti;
|
||||
iFlags |= conditional_anyelse;
|
||||
conditionalelse = !conditionalelse;
|
||||
m_conditionalelse = true;
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
@@ -597,6 +590,185 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org)
|
||||
}
|
||||
};
|
||||
|
||||
// sends basic content of the class in legacy (text) format to provided stream
|
||||
void
|
||||
TEvent::export_as_text( std::ostream &Output ) const {
|
||||
|
||||
if( Type == tp_Unknown ) { return; }
|
||||
|
||||
// header
|
||||
Output << "event ";
|
||||
// name
|
||||
Output << asName << ' ';
|
||||
// type
|
||||
std::vector<std::string> const types {
|
||||
"unknown", "sound", "exit", "disable", "velocity", "animation", "lights",
|
||||
"updatevalues", "getvalues", "putvalues", "switch", "dynvel", "trackvel",
|
||||
"multiple", "addvalues", "copyvalues", "whois", "logvalues", "visible",
|
||||
"voltage", "message", "friction" };
|
||||
Output << types[ Type ] << ' ';
|
||||
// delay
|
||||
Output << fDelay << ' ';
|
||||
// associated node
|
||||
Output << ( asNodeName.empty() ? "none" : asNodeName ) << ' ';
|
||||
// type-specific attributes
|
||||
switch( Type ) {
|
||||
case tp_AddValues:
|
||||
case tp_UpdateValues: {
|
||||
Output
|
||||
<< ( ( iFlags & update_memstring ) == 0 ? "*" : Params[ 0 ].asText ) << ' '
|
||||
<< ( ( iFlags & update_memval1 ) == 0 ? "*" : to_string( Params[ 1 ].asdouble ) ) << ' '
|
||||
<< ( ( iFlags & update_memval2 ) == 0 ? "*" : to_string( Params[ 2 ].asdouble ) ) << ' ';
|
||||
break;
|
||||
}
|
||||
case tp_CopyValues: {
|
||||
// NOTE: there's no way to get the original parameter value if it doesn't point to existing memcell
|
||||
Output
|
||||
<< ( Params[ 9 ].asMemCell == nullptr ? "none" : Params[ 9 ].asMemCell->name() ) << ' '
|
||||
<< ( iFlags & ( update_memstring | update_memval1 | update_memval2 ) ) << ' ';
|
||||
break;
|
||||
}
|
||||
case tp_PutValues: {
|
||||
Output
|
||||
// location
|
||||
<< Params[ 3 ].asdouble << ' '
|
||||
<< Params[ 4 ].asdouble << ' '
|
||||
<< Params[ 5 ].asdouble << ' '
|
||||
// command
|
||||
<< Params[ 0 ].asText << ' '
|
||||
<< Params[ 1 ].asdouble << ' '
|
||||
<< Params[ 2 ].asdouble << ' ';
|
||||
break;
|
||||
}
|
||||
case tp_Multiple: {
|
||||
for( auto const &childevent : m_children ) {
|
||||
if( std::get<TEvent *>( childevent ) == nullptr ) { continue; }
|
||||
if( true == std::get<bool>( childevent ) ) {
|
||||
Output << std::get<std::string>( childevent ) << ' ';
|
||||
}
|
||||
}
|
||||
// optional 'else' block
|
||||
if( true == m_conditionalelse ) {
|
||||
Output << "else ";
|
||||
for( auto const &childevent : m_children ) {
|
||||
if( std::get<TEvent *>( childevent ) == nullptr ) { continue; }
|
||||
if( false == std::get<bool>( childevent ) ) {
|
||||
Output << std::get<std::string>( childevent ) << ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tp_Visible: {
|
||||
Output << Params[ 0 ].asInt << ' ';
|
||||
break;
|
||||
}
|
||||
case tp_Switch: {
|
||||
Output << Params[ 0 ].asInt << ' ';
|
||||
if( ( Params[ 1 ].asdouble != -1.0 )
|
||||
|| ( Params[ 2 ].asdouble != -1.0 ) ) {
|
||||
Output << Params[ 1 ].asdouble << ' ';
|
||||
}
|
||||
if( Params[ 2 ].asdouble != -1.0 ) {
|
||||
Output << Params[ 2 ].asdouble << ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tp_Lights: {
|
||||
auto lightidx { 0 };
|
||||
while( ( lightidx < iMaxNumLights )
|
||||
&& ( Params[ lightidx ].asdouble > -2.0 ) ) {
|
||||
Output << Params[ lightidx ].asdouble << ' ';
|
||||
++lightidx;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tp_Animation: {
|
||||
// animation type
|
||||
Output << (
|
||||
Params[ 0 ].asInt == 1 ? "rotate" :
|
||||
Params[ 0 ].asInt == 2 ? "translate" :
|
||||
// NOTE: .vmd animation doesn't preserve file name, can't be exported. TODO: fix this
|
||||
Params[ 0 ].asInt == 8 ? "digital" :
|
||||
"none" )
|
||||
<< ' ';
|
||||
// submodel
|
||||
Output << (
|
||||
Params[ 9 ].asAnimContainer != nullptr ?
|
||||
Params[ 9 ].asAnimContainer->NameGet() :
|
||||
"none" ) << ' ';
|
||||
// animation parameters
|
||||
Output
|
||||
<< Params[ 1 ].asdouble << ' '
|
||||
<< Params[ 2 ].asdouble << ' '
|
||||
<< Params[ 3 ].asdouble << ' '
|
||||
<< Params[ 4 ].asdouble << ' ';
|
||||
break;
|
||||
}
|
||||
case tp_Sound: {
|
||||
// playback mode
|
||||
Output << Params[ 0 ].asInt << ' ';
|
||||
// optional radio channel
|
||||
if( Params[ 1 ].asdouble > 0.0 ) {
|
||||
Output << Params[ 1 ].asdouble << ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tp_DynVel:
|
||||
case tp_TrackVel:
|
||||
case tp_Voltage:
|
||||
case tp_Friction: {
|
||||
Output << Params[ 0 ].asdouble << ' ';
|
||||
break;
|
||||
}
|
||||
case tp_Velocity: {
|
||||
Output << Params[ 0 ].asdouble * ( 3600.0 / 1000.0 ) << ' ';
|
||||
break;
|
||||
}
|
||||
case tp_WhoIs: {
|
||||
Output
|
||||
<< ( iFlags & ( update_memstring | update_memval1 | update_memval2 ) ) << ' ';
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// optional conditions
|
||||
// NOTE: for flexibility condition check and export is performed for all event types rather than only for these which support it currently
|
||||
auto const isconditional { ( conditional_trackoccupied | conditional_trackfree | conditional_propability | conditional_memcompare ) };
|
||||
if( ( ( iFlags & isconditional ) != 0 ) ) {
|
||||
Output << "condition ";
|
||||
if( ( iFlags & conditional_trackoccupied ) != 0 ) {
|
||||
Output << "trackoccupied ";
|
||||
}
|
||||
else if( ( iFlags & conditional_trackfree ) != 0 ) {
|
||||
Output << "trackfree ";
|
||||
}
|
||||
else if( ( iFlags & conditional_propability ) != 0 ) {
|
||||
Output
|
||||
<< "propability "
|
||||
<< Params[ 10 ].asdouble << ' ';
|
||||
}
|
||||
else if( ( iFlags & conditional_memcompare ) != 0 ) {
|
||||
Output
|
||||
<< "memcompare "
|
||||
<< ( ( iFlags & conditional_memstring ) == 0 ? "*" : Params[ 10 ].asText ) << ' '
|
||||
<< ( ( iFlags & conditional_memval1 ) == 0 ? "*" : to_string( Params[ 11 ].asdouble ) ) << ' '
|
||||
<< ( ( iFlags & conditional_memval2 ) == 0 ? "*" : to_string( Params[ 12 ].asdouble ) ) << ' ';
|
||||
}
|
||||
}
|
||||
if( fRandomDelay != 0.0 ) {
|
||||
Output
|
||||
<< "randomdelay "
|
||||
<< fRandomDelay << ' ';
|
||||
}
|
||||
// footer
|
||||
Output
|
||||
<< "endevent"
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
void TEvent::AddToQuery( TEvent *Event, TEvent *&Start ) {
|
||||
|
||||
TEvent *target( Start );
|
||||
@@ -994,6 +1166,10 @@ event_manager::CheckQuery() {
|
||||
case tp_Lights: {
|
||||
if( m_workevent->Params[ 9 ].asModel ) {
|
||||
for( i = 0; i < iMaxNumLights; ++i ) {
|
||||
if( m_workevent->Params[ i ].asdouble == -2.0 ) {
|
||||
// processed all supplied values, bail out
|
||||
break;
|
||||
}
|
||||
if( m_workevent->Params[ i ].asdouble >= 0 ) {
|
||||
// -1 zostawia bez zmiany
|
||||
m_workevent->Params[ 9 ].asModel->LightSet(
|
||||
@@ -1005,8 +1181,8 @@ event_manager::CheckQuery() {
|
||||
break;
|
||||
}
|
||||
case tp_Visible: {
|
||||
if( m_workevent->Params[ 9 ].asEditorNode )
|
||||
m_workevent->Params[ 9 ].asEditorNode->visible( m_workevent->Params[ 0 ].asInt > 0 );
|
||||
if( m_workevent->Params[ 9 ].asSceneNode )
|
||||
m_workevent->Params[ 9 ].asSceneNode->visible( m_workevent->Params[ 0 ].asInt > 0 );
|
||||
break;
|
||||
}
|
||||
case tp_Velocity: {
|
||||
@@ -1014,7 +1190,6 @@ event_manager::CheckQuery() {
|
||||
break;
|
||||
}
|
||||
case tp_Exit: {
|
||||
Global.iTextMode = -1; // wyłączenie takie samo jak sekwencja F10 -> Y
|
||||
return false;
|
||||
}
|
||||
case tp_Sound: {
|
||||
@@ -1115,29 +1290,30 @@ event_manager::CheckQuery() {
|
||||
Error("Event \"DynVel\" is obsolete");
|
||||
break;
|
||||
case tp_Multiple: {
|
||||
auto const bCondition = EventConditon(m_workevent);
|
||||
if( ( bCondition )
|
||||
|| ( m_workevent->iFlags & conditional_anyelse ) ) {
|
||||
auto const condition { EventConditon( m_workevent ) };
|
||||
if( ( true == condition )
|
||||
|| ( true == m_workevent->m_conditionalelse ) ) {
|
||||
// warunek spelniony albo było użyte else
|
||||
WriteLog("Type: Multi-event");
|
||||
for (i = 0; i < m_workevent->ext_params.size(); ++i) {
|
||||
// dodawane do kolejki w kolejności zapisania
|
||||
if( m_workevent->ext_params[ i ].first.asEvent ) {
|
||||
if( bCondition != (bool)m_workevent->ext_params[i].second ) {
|
||||
if( m_workevent->ext_params[ i ].first.asEvent != m_workevent )
|
||||
AddToQuery( m_workevent->ext_params[ i ].first.asEvent, m_workevent->Activator ); // normalnie dodać
|
||||
else {
|
||||
// jeśli ma być rekurencja to musi mieć sensowny okres powtarzania
|
||||
if( m_workevent->fDelay >= 5.0 ) {
|
||||
AddToQuery( m_workevent, m_workevent->Activator );
|
||||
}
|
||||
}
|
||||
for( auto &childevent : m_workevent->m_children ) {
|
||||
auto *childeventdata { std::get<TEvent*>( childevent ) };
|
||||
if( childeventdata == nullptr ) { continue; }
|
||||
if( std::get<bool>( childevent ) != condition ) { continue; }
|
||||
|
||||
if( childeventdata != m_workevent ) {
|
||||
// normalnie dodać
|
||||
AddToQuery( childeventdata, m_workevent->Activator );
|
||||
}
|
||||
else {
|
||||
// jeśli ma być rekurencja to musi mieć sensowny okres powtarzania
|
||||
if( m_workevent->fDelay >= 5.0 ) {
|
||||
AddToQuery( m_workevent, m_workevent->Activator );
|
||||
}
|
||||
}
|
||||
}
|
||||
if( Global.iMultiplayer ) {
|
||||
// dajemy znać do serwera o wykonaniu
|
||||
if( ( m_workevent->iFlags & conditional_anyelse ) == 0 ) {
|
||||
if( false == m_workevent->m_conditionalelse ) {
|
||||
// jednoznaczne tylko, gdy nie było else
|
||||
if( m_workevent->Activator ) {
|
||||
multiplayer::WyslijEvent( m_workevent->asName, m_workevent->Activator->name() );
|
||||
@@ -1397,7 +1573,6 @@ event_manager::InitEvents() {
|
||||
else {
|
||||
ErrorLog( "Bad event: animation event \"" + event->asName + "\" cannot find model instance \"" + event->asNodeName + "\"" );
|
||||
}
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_Lights: {
|
||||
@@ -1407,12 +1582,11 @@ event_manager::InitEvents() {
|
||||
event->Params[ 9 ].asModel = instance;
|
||||
else
|
||||
ErrorLog( "Bad event: lights event \"" + event->asName + "\" cannot find model instance \"" + event->asNodeName + "\"" );
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_Visible: {
|
||||
// ukrycie albo przywrócenie obiektu
|
||||
editor::basic_node *node = simulation::Instances.find( event->asNodeName ); // najpierw model
|
||||
scene::basic_node *node = simulation::Instances.find( event->asNodeName ); // najpierw model
|
||||
if( node == nullptr ) {
|
||||
// albo tory?
|
||||
node = simulation::Paths.find( event->asNodeName );
|
||||
@@ -1422,12 +1596,11 @@ event_manager::InitEvents() {
|
||||
node = simulation::Traction.find( event->asNodeName );
|
||||
}
|
||||
if( node != nullptr )
|
||||
event->Params[ 9 ].asEditorNode = node;
|
||||
event->Params[ 9 ].asSceneNode = node;
|
||||
else {
|
||||
event->m_ignored = true;
|
||||
ErrorLog( "Bad event: visibility event \"" + event->asName + "\" cannot find item \"" + event->asNodeName + "\"" );
|
||||
}
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_Switch: {
|
||||
@@ -1453,7 +1626,6 @@ event_manager::InitEvents() {
|
||||
else {
|
||||
ErrorLog( "Bad event: switch event \"" + event->asName + "\" cannot find track \"" + event->asNodeName + "\"" );
|
||||
}
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_Sound: {
|
||||
@@ -1463,7 +1635,6 @@ event_manager::InitEvents() {
|
||||
event->Params[ 9 ].tsTextSound = sound;
|
||||
else
|
||||
ErrorLog( "Bad event: sound event \"" + event->asName + "\" cannot find static sound \"" + event->asNodeName + "\"" );
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_TrackVel: {
|
||||
@@ -1479,7 +1650,6 @@ event_manager::InitEvents() {
|
||||
ErrorLog( "Bad event: track velocity event \"" + event->asName + "\" cannot find track \"" + event->asNodeName + "\"" );
|
||||
}
|
||||
}
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_DynVel: {
|
||||
@@ -1493,7 +1663,6 @@ event_manager::InitEvents() {
|
||||
else
|
||||
ErrorLog( "Bad event: vehicle velocity event \"" + event->asName + "\" cannot find vehicle \"" + event->asNodeName + "\"" );
|
||||
}
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_Multiple: {
|
||||
@@ -1519,15 +1688,10 @@ event_manager::InitEvents() {
|
||||
event->iFlags &= ~( conditional_memstring | conditional_memval1 | conditional_memval2 );
|
||||
}
|
||||
}
|
||||
for( int i = 0; i < event->ext_params.size(); ++i ) {
|
||||
if( event->ext_params[ i ].first.asText != nullptr ) {
|
||||
cellastext = event->ext_params[ i ].first.asText;
|
||||
SafeDeleteArray( event->ext_params[ i ].first.asText );
|
||||
event->ext_params[ i ].first.asEvent = FindEvent( cellastext );
|
||||
if( event->ext_params[ i ].first.asEvent == nullptr ) {
|
||||
// Ra: tylko w logu informacja o braku
|
||||
ErrorLog( "Bad event: multi-event \"" + event->asName + "\" cannot find event \"" + cellastext + "\"" );
|
||||
}
|
||||
for( auto &childevent : event->m_children ) {
|
||||
std::get<TEvent *>( childevent ) = FindEvent( std::get<std::string>( childevent ) );
|
||||
if( std::get<TEvent *>( childevent ) == nullptr ) {
|
||||
ErrorLog( "Bad event: multi-event \"" + event->asName + "\" cannot find event \"" + std::get<std::string>( childevent ) + "\"" );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1541,7 +1705,6 @@ event_manager::InitEvents() {
|
||||
else
|
||||
ErrorLog( "Bad event: voltage event \"" + event->asName + "\" cannot find power source \"" + event->asNodeName + "\"" );
|
||||
}
|
||||
event->asNodeName = "";
|
||||
break;
|
||||
}
|
||||
case tp_Message: {
|
||||
@@ -1590,6 +1753,20 @@ event_manager::InitLaunchers() {
|
||||
}
|
||||
}
|
||||
|
||||
// sends basic content of the class in legacy (text) format to provided stream
|
||||
void
|
||||
event_manager::export_as_text( std::ostream &Output ) const {
|
||||
|
||||
Output << "// events\n";
|
||||
for( auto const *event : m_events ) {
|
||||
event->export_as_text( Output );
|
||||
}
|
||||
Output << "// event launchers\n";
|
||||
for( auto const *launcher : m_launchers.sequence() ) {
|
||||
launcher->export_as_text( Output );
|
||||
}
|
||||
}
|
||||
|
||||
// legacy method, verifies condition for specified event
|
||||
bool
|
||||
event_manager::EventConditon( TEvent *Event ) {
|
||||
|
||||
Reference in New Issue
Block a user