16
0
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:
milek7
2018-06-15 18:58:03 +02:00
54 changed files with 2310 additions and 927 deletions

291
Event.cpp
View File

@@ -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 ) {