From db09ff0afcb24550a13396a56e02256eb7b3fdf4 Mon Sep 17 00:00:00 2001 From: Petr Ohlidal Date: Mon, 29 Aug 2022 01:06:04 +0200 Subject: [PATCH] Added hydro flag `j`, restored quirky `i` for backw. compat. It turns out the `i` flag has a bug: it always makes the hydro invisible, but if it comes as first/single flag, then it also makes the hydro commanded by steering input. That means: * `ri` will make the hydro respond only to airplane rudder, and invisible. * `ir` will make the hydro respond to both airplane rudder and steering input, and invisible. To resolve backward compatibility, I added a new flag `j`, which makes the hydro invisible but without the quirks of `i`. The documentation https://docs.rigsofrods.org/vehicle-creation/fileformat-truck/#hydros needs to be updated: * `` no flags given -> force `n` flag. * `n` means Normal and makes the hydro driven by steering input. and the above. --- source/main/physics/ActorSpawner.cpp | 11 ++--------- .../rig_def_fileformat/RigDef_File.h | 9 ++++++--- .../rig_def_fileformat/RigDef_Parser.cpp | 19 +++++++++++++++++-- .../rig_def_fileformat/RigDef_Serializer.cpp | 5 +++-- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/source/main/physics/ActorSpawner.cpp b/source/main/physics/ActorSpawner.cpp index a361397270..cba9b585fa 100644 --- a/source/main/physics/ActorSpawner.cpp +++ b/source/main/physics/ActorSpawner.cpp @@ -3590,12 +3590,7 @@ void ActorSpawner::ProcessHydro(RigDef::Hydro & def) bool invisible = false; unsigned int hydro_flags = 0; - if (def.options == 0) - { - invisible = false; - hydro_flags |= HYDRO_FLAG_DIR; - } - if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_i_INVISIBLE)) + if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_j_INVISIBLE)) { invisible = true; } @@ -3639,9 +3634,7 @@ void ActorSpawner::ProcessHydro(RigDef::Hydro & def) { hydro_flags |= (HYDRO_FLAG_REV_ELEVATOR | HYDRO_FLAG_RUDDER); } - - // if you use the 'INVISIBLE' flag on its own, add the direction to it - if (invisible && !hydro_flags) + if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_n_INPUT_NORMAL)) { hydro_flags |= HYDRO_FLAG_DIR; } diff --git a/source/main/resources/rig_def_fileformat/RigDef_File.h b/source/main/resources/rig_def_fileformat/RigDef_File.h index f12cd4d1da..d6cb6ed56c 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_File.h +++ b/source/main/resources/rig_def_fileformat/RigDef_File.h @@ -324,8 +324,9 @@ enum class BeamOption: char enum class HydroOption: char { - n_DUMMY = 'n', - i_INVISIBLE = 'i', + n_INPUT_NORMAL = 'n', + j_INVISIBLE = 'j', + i_INVISIBLE_INPUT_NORMAL = 'i', //!< For backwards compatibility; combines flags 'j' and 'n'. // Useful for trucks s_DISABLE_ON_HIGH_SPEED = 's', // Useful for planes: These can be used to control flight surfaces, or to create a thrust vectoring system. @@ -950,7 +951,7 @@ struct Hook struct Hydro { - static const BitMask_t OPTION_i_INVISIBLE = BITMASK(1); + static const BitMask_t OPTION_j_INVISIBLE = BITMASK(1); // Useful for trucks: static const BitMask_t OPTION_s_DISABLE_ON_HIGH_SPEED = BITMASK(2); // Useful for planes: These can be used to control flight surfaces, or to create a thrust vectoring system. @@ -963,6 +964,8 @@ struct Hydro static const BitMask_t OPTION_y_INPUT_InvAILERON_RUDDER = BITMASK(9); static const BitMask_t OPTION_g_INPUT_ELEVATOR_RUDDER = BITMASK(10); static const BitMask_t OPTION_h_INPUT_InvELEVATOR_RUDDER = BITMASK(11); + // Generic steering input + static const BitMask_t OPTION_n_INPUT_NORMAL = BITMASK(12); Node::Ref nodes[2]; float lenghtening_factor = 0.f; diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp index ac0faaa666..ad50305804 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp @@ -3111,7 +3111,7 @@ BitMask_t Parser::GetArgHydroOptions (int index) { switch (c) { - case (char)HydroOption::i_INVISIBLE : ret |= Hydro::OPTION_i_INVISIBLE ; break; + case (char)HydroOption::j_INVISIBLE : ret |= Hydro::OPTION_j_INVISIBLE ; break; case (char)HydroOption::s_DISABLE_ON_HIGH_SPEED : ret |= Hydro::OPTION_s_DISABLE_ON_HIGH_SPEED ; break; case (char)HydroOption::a_INPUT_AILERON : ret |= Hydro::OPTION_a_INPUT_AILERON ; break; case (char)HydroOption::r_INPUT_RUDDER : ret |= Hydro::OPTION_r_INPUT_RUDDER ; break; @@ -3122,14 +3122,29 @@ BitMask_t Parser::GetArgHydroOptions (int index) case (char)HydroOption::y_INPUT_InvAILERON_RUDDER : ret |= Hydro::OPTION_y_INPUT_InvAILERON_RUDDER ; break; case (char)HydroOption::g_INPUT_ELEVATOR_RUDDER : ret |= Hydro::OPTION_g_INPUT_ELEVATOR_RUDDER ; break; case (char)HydroOption::h_INPUT_InvELEVATOR_RUDDER : ret |= Hydro::OPTION_h_INPUT_InvELEVATOR_RUDDER ; break; + case (char)HydroOption::n_INPUT_NORMAL : ret |= Hydro::OPTION_n_INPUT_NORMAL ; break; - case (char)HydroOption::n_DUMMY: break; + case (char)HydroOption::i_INVISIBLE_INPUT_NORMAL: + if (ret == 0) + { + // Original intent: when using 'i' flag alone, also force 'n' (steering input). + // For backward compatibility, do it every time 'i' comes first, even if not alone. + ret |= Hydro::OPTION_n_INPUT_NORMAL; + } + ret |= Hydro::OPTION_j_INVISIBLE; + break; default: this->LogMessage(Console::CONSOLE_SYSTEM_WARNING, fmt::format("ignoring invalid option '{}'", c)); } } + + if (!ret) + { + ret |= Hydro::OPTION_n_INPUT_NORMAL; + } + return ret; } diff --git a/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp b/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp index 852fde1a4d..c7f5567dcd 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp @@ -2096,7 +2096,7 @@ void Serializer::ProcessHydro(Hydro & def) m_stream << std::setw(m_float_width) << def.lenghtening_factor << ", "; // Options - if (BITMASK_IS_1(def.options, Hydro::OPTION_i_INVISIBLE )) m_stream << (char)HydroOption::i_INVISIBLE ; + if (BITMASK_IS_1(def.options, Hydro::OPTION_j_INVISIBLE )) m_stream << (char)HydroOption::j_INVISIBLE ; if (BITMASK_IS_1(def.options, Hydro::OPTION_s_DISABLE_ON_HIGH_SPEED )) m_stream << (char)HydroOption::s_DISABLE_ON_HIGH_SPEED ; if (BITMASK_IS_1(def.options, Hydro::OPTION_a_INPUT_AILERON )) m_stream << (char)HydroOption::a_INPUT_AILERON ; if (BITMASK_IS_1(def.options, Hydro::OPTION_r_INPUT_RUDDER )) m_stream << (char)HydroOption::r_INPUT_RUDDER ; @@ -2107,7 +2107,8 @@ void Serializer::ProcessHydro(Hydro & def) if (BITMASK_IS_1(def.options, Hydro::OPTION_y_INPUT_InvAILERON_RUDDER )) m_stream << (char)HydroOption::y_INPUT_InvAILERON_RUDDER ; if (BITMASK_IS_1(def.options, Hydro::OPTION_g_INPUT_ELEVATOR_RUDDER )) m_stream << (char)HydroOption::g_INPUT_ELEVATOR_RUDDER ; if (BITMASK_IS_1(def.options, Hydro::OPTION_h_INPUT_InvELEVATOR_RUDDER )) m_stream << (char)HydroOption::h_INPUT_InvELEVATOR_RUDDER ; - if (def.options == 0) m_stream << (char)HydroOption::n_DUMMY; + if (BITMASK_IS_1(def.options, Hydro::OPTION_n_INPUT_NORMAL )) m_stream << (char)HydroOption::n_INPUT_NORMAL; + if (def.options == 0) m_stream << (char)HydroOption::n_INPUT_NORMAL; m_stream << ", "; // Inertia