Skip to content

Commit

Permalink
🧹 HydroOption
Browse files Browse the repository at this point in the history
For motivation, see "CODING GUIDELINES (CLEANUP IN PROGRESS)" on top of RigDef_File.h

Spawner: fixed the "a quirk ported from v0.4.0.7 spawner (for compatibility)" glitch - testing will reveal if anything really depends on it. Likely not.
  • Loading branch information
ohlidalp authored and Petr Ohlídal committed May 28, 2022
1 parent 73a7c7a commit 9421c68
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 109 deletions.
109 changes: 49 additions & 60 deletions source/main/physics/ActorSpawner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3638,71 +3638,60 @@ void ActorSpawner::ProcessHydro(RigDef::Hydro & def)
bool invisible = false;
unsigned int hydro_flags = 0;

// Parse options
if (def.options.empty()) // Parse as if option 'n' (OPTION_n_NORMAL) was present
if (def.options == 0)
{
invisible = false;
hydro_flags |= HYDRO_FLAG_DIR;
}
else
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_i_INVISIBLE))
{
for (unsigned int i = 0; i < def.options.length(); ++i)
{
const char c = def.options[i];
switch (c)
{
case RigDef::Hydro::OPTION_i_INVISIBLE: // i
invisible = true;
break;
case RigDef::Hydro::OPTION_n_NORMAL: // n
invisible = false;
hydro_flags |= HYDRO_FLAG_DIR;
break;
case RigDef::Hydro::OPTION_s_DISABLE_ON_HIGH_SPEED: // 's': // speed changing hydro
hydro_flags |= HYDRO_FLAG_SPEED;
break;
case RigDef::Hydro::OPTION_a_INPUT_AILERON: // 'a':
hydro_flags |= HYDRO_FLAG_AILERON;
break;
case RigDef::Hydro::OPTION_r_INPUT_RUDDER: // 'r':
hydro_flags |= HYDRO_FLAG_RUDDER;
break;
case RigDef::Hydro::OPTION_e_INPUT_ELEVATOR: // 'e':
hydro_flags |= HYDRO_FLAG_ELEVATOR;
break;
case RigDef::Hydro::OPTION_u_INPUT_AILERON_ELEVATOR: // 'u':
hydro_flags |= (HYDRO_FLAG_AILERON | HYDRO_FLAG_ELEVATOR);
break;
case RigDef::Hydro::OPTION_v_INPUT_InvAILERON_ELEVATOR: // 'v':
hydro_flags |= (HYDRO_FLAG_REV_AILERON | HYDRO_FLAG_ELEVATOR);
break;
case RigDef::Hydro::OPTION_x_INPUT_AILERON_RUDDER: // 'x':
hydro_flags |= (HYDRO_FLAG_AILERON | HYDRO_FLAG_RUDDER);
break;
case RigDef::Hydro::OPTION_y_INPUT_InvAILERON_RUDDER: // 'y':
hydro_flags |= (HYDRO_FLAG_REV_AILERON | HYDRO_FLAG_RUDDER);
break;
case RigDef::Hydro::OPTION_g_INPUT_ELEVATOR_RUDDER: // 'g':
hydro_flags |= (HYDRO_FLAG_ELEVATOR | HYDRO_FLAG_RUDDER);
break;
case RigDef::Hydro::OPTION_h_INPUT_InvELEVATOR_RUDDER: // 'h':
hydro_flags |= (HYDRO_FLAG_REV_ELEVATOR | HYDRO_FLAG_RUDDER);
break;
default:
this->AddMessage(Message::TYPE_WARNING, std::string("Ignoring invalid flag:") + c);
break;
}

// NOTE: This is a quirk ported from v0.4.0.7 spawner (for compatibility)
// This code obviously belongs after the options-loop.
// However, since it's inside the loop, it only works correctly if the 'i' flag is last.
//
// ORIGINAL COMMENT: if you use the i flag on its own, add the direction to it
if (invisible && !hydro_flags)
{
hydro_flags |= HYDRO_FLAG_DIR;
}
}
invisible = true;
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_s_DISABLE_ON_HIGH_SPEED))
{
hydro_flags |= HYDRO_FLAG_SPEED;
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_a_INPUT_AILERON))
{
hydro_flags |= HYDRO_FLAG_AILERON;
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_r_INPUT_RUDDER))
{
hydro_flags |= HYDRO_FLAG_RUDDER;
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_e_INPUT_ELEVATOR))
{
hydro_flags |= HYDRO_FLAG_ELEVATOR;
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_u_INPUT_AILERON_ELEVATOR))
{
hydro_flags |= (HYDRO_FLAG_AILERON | HYDRO_FLAG_ELEVATOR);
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_v_INPUT_InvAILERON_ELEVATOR))
{
hydro_flags |= (HYDRO_FLAG_REV_AILERON | HYDRO_FLAG_ELEVATOR);
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_x_INPUT_AILERON_RUDDER))
{
hydro_flags |= (HYDRO_FLAG_AILERON | HYDRO_FLAG_RUDDER);
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_y_INPUT_InvAILERON_RUDDER))
{
hydro_flags |= (HYDRO_FLAG_REV_AILERON | HYDRO_FLAG_RUDDER);
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_g_INPUT_ELEVATOR_RUDDER))
{
hydro_flags |= (HYDRO_FLAG_ELEVATOR | HYDRO_FLAG_RUDDER);
}
if (BITMASK_IS_1(def.options, RigDef::Hydro::OPTION_h_INPUT_InvELEVATOR_RUDDER))
{
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)
{
hydro_flags |= HYDRO_FLAG_DIR;
}

node_t & node_1 = GetNode(def.nodes[0]);
Expand Down
74 changes: 34 additions & 40 deletions source/main/resources/rig_def_fileformat/RigDef_File.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,24 @@ enum class BeamOption: char
s_SUPPORT = 's',
};

enum class HydroOption: char
{
n_DUMMY = 'n',
i_INVISIBLE = 'i',
// 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.
a_INPUT_AILERON = 'a',
r_INPUT_RUDDER = 'r',
e_INPUT_ELEVATOR = 'e',
u_INPUT_AILERON_ELEVATOR = 'u',
v_INPUT_InvAILERON_ELEVATOR = 'v',
x_INPUT_AILERON_RUDDER = 'x',
y_INPUT_InvAILERON_RUDDER = 'y',
g_INPUT_ELEVATOR_RUDDER = 'g',
h_INPUT_InvELEVATOR_RUDDER = 'h',
};

/* -------------------------------------------------------------------------- */
/* Utility */
/* -------------------------------------------------------------------------- */
Expand Down Expand Up @@ -1272,51 +1290,27 @@ struct SkeletonSettings

struct Hydro
{
Hydro():
lenghtening_factor(0),
detacher_group(0)
{}

static const char OPTION_n_NORMAL = 'n';
static const char OPTION_i_INVISIBLE = 'i';

/* Useful for trucks */

static const char OPTION_s_DISABLE_ON_HIGH_SPEED = 's';

/* Useful for planes: These can be used to control flight surfaces, or to create a thrust vectoring system. */

static const char OPTION_a_INPUT_AILERON = 'a';
static const char OPTION_r_INPUT_RUDDER = 'r';
static const char OPTION_e_INPUT_ELEVATOR = 'e';
static const char OPTION_u_INPUT_AILERON_ELEVATOR = 'u';
static const char OPTION_v_INPUT_InvAILERON_ELEVATOR = 'v';
static const char OPTION_x_INPUT_AILERON_RUDDER = 'x';
static const char OPTION_y_INPUT_InvAILERON_RUDDER = 'y';
static const char OPTION_g_INPUT_ELEVATOR_RUDDER = 'g';
static const char OPTION_h_INPUT_InvELEVATOR_RUDDER = 'h';

inline bool HasFlag_a() { return options.find(RigDef::Hydro::OPTION_a_INPUT_AILERON) != std::string::npos; }
inline bool HasFlag_e() { return options.find(RigDef::Hydro::OPTION_e_INPUT_ELEVATOR) != std::string::npos; }
inline bool HasFlag_g() { return options.find(RigDef::Hydro::OPTION_g_INPUT_ELEVATOR_RUDDER) != std::string::npos; }
inline bool HasFlag_h() { return options.find(RigDef::Hydro::OPTION_h_INPUT_InvELEVATOR_RUDDER) != std::string::npos; }
inline bool HasFlag_i() { return options.find(RigDef::Hydro::OPTION_i_INVISIBLE) != std::string::npos; }
inline bool HasFlag_r() { return options.find(RigDef::Hydro::OPTION_r_INPUT_RUDDER) != std::string::npos; }
inline bool HasFlag_s() { return options.find(RigDef::Hydro::OPTION_s_DISABLE_ON_HIGH_SPEED) != std::string::npos; }
inline bool HasFlag_u() { return options.find(RigDef::Hydro::OPTION_u_INPUT_AILERON_ELEVATOR) != std::string::npos; }
inline bool HasFlag_v() { return options.find(RigDef::Hydro::OPTION_v_INPUT_InvAILERON_ELEVATOR) != std::string::npos; }
inline bool HasFlag_x() { return options.find(RigDef::Hydro::OPTION_x_INPUT_AILERON_RUDDER) != std::string::npos; }
inline bool HasFlag_y() { return options.find(RigDef::Hydro::OPTION_y_INPUT_InvAILERON_RUDDER) != std::string::npos; }

inline void AddFlag(char flag) { options += flag; }
static const BitMask_t OPTION_i_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.
static const BitMask_t OPTION_a_INPUT_AILERON = BITMASK(3);
static const BitMask_t OPTION_r_INPUT_RUDDER = BITMASK(4);
static const BitMask_t OPTION_e_INPUT_ELEVATOR = BITMASK(5);
static const BitMask_t OPTION_u_INPUT_AILERON_ELEVATOR = BITMASK(6);
static const BitMask_t OPTION_v_INPUT_InvAILERON_ELEVATOR = BITMASK(7);
static const BitMask_t OPTION_x_INPUT_AILERON_RUDDER = BITMASK(8);
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);

Node::Ref nodes[2];
float lenghtening_factor;
std::string options;
float lenghtening_factor = 0.f;
BitMask_t options = 0;
Inertia inertia;
std::shared_ptr<Inertia> inertia_defaults;
std::shared_ptr<BeamDefaults> beam_defaults;
int detacher_group;
int detacher_group = 0;
};

/* -------------------------------------------------------------------------- */
Expand Down
31 changes: 30 additions & 1 deletion source/main/resources/rig_def_fileformat/RigDef_Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2611,7 +2611,7 @@ void Parser::ParseHydros()
hydro.nodes[1] = this->GetArgNodeRef(1);
hydro.lenghtening_factor = this->GetArgFloat (2);

if (m_num_args > 3) { hydro.options = this->GetArgStr(3); }
if (m_num_args > 3) { hydro.options = this->GetArgHydroOptions(3); }

this->ParseOptionalInertia(hydro.inertia, 4);

Expand Down Expand Up @@ -3268,6 +3268,35 @@ BitMask_t Parser::GetArgBeamOptions(int index)
return ret;
}

BitMask_t Parser::GetArgHydroOptions (int index)
{
BitMask_t ret = 0;
for (char c: this->GetArgStr(index))
{
switch (c)
{
case (char)HydroOption::i_INVISIBLE : ret |= Hydro::OPTION_i_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;
case (char)HydroOption::e_INPUT_ELEVATOR : ret |= Hydro::OPTION_e_INPUT_ELEVATOR ; break;
case (char)HydroOption::u_INPUT_AILERON_ELEVATOR : ret |= Hydro::OPTION_u_INPUT_AILERON_ELEVATOR ; break;
case (char)HydroOption::v_INPUT_InvAILERON_ELEVATOR: ret |= Hydro::OPTION_v_INPUT_InvAILERON_ELEVATOR; break;
case (char)HydroOption::x_INPUT_AILERON_RUDDER : ret |= Hydro::OPTION_x_INPUT_AILERON_RUDDER ; break;
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_DUMMY: break;

default:
this->LogMessage(Console::CONSOLE_SYSTEM_WARNING,
fmt::format("ignoring invalid option '{}'", c));
}
}
return ret;
}

int Parser::TokenizeCurrentLine()
{
int cur_arg = 0;
Expand Down
1 change: 1 addition & 0 deletions source/main/resources/rig_def_fileformat/RigDef_Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ class Parser
BitMask_t GetArgCabOptions (int index);
BitMask_t GetArgTriggerOptions(int index);
BitMask_t GetArgBeamOptions (int index);
BitMask_t GetArgHydroOptions (int index);

float ParseArgFloat (const char* str);
int ParseArgInt (const char* str);
Expand Down
22 changes: 14 additions & 8 deletions source/main/resources/rig_def_fileformat/RigDef_Serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2076,14 +2076,20 @@ void Serializer::ProcessHydro(Hydro & def)
<< std::setw(m_node_id_width) << def.nodes[1].ToString() << ", ";

m_stream << std::setw(m_float_width) << def.lenghtening_factor << ", ";
if (def.options.empty())
{
m_stream << "n"; // Placeholder, does nothing
}
else
{
m_stream << def.options;
}

// 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_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 ;
if (BITMASK_IS_1(def.options, Hydro::OPTION_e_INPUT_ELEVATOR )) m_stream << (char)HydroOption::e_INPUT_ELEVATOR ;
if (BITMASK_IS_1(def.options, Hydro::OPTION_u_INPUT_AILERON_ELEVATOR )) m_stream << (char)HydroOption::u_INPUT_AILERON_ELEVATOR ;
if (BITMASK_IS_1(def.options, Hydro::OPTION_v_INPUT_InvAILERON_ELEVATOR)) m_stream << (char)HydroOption::v_INPUT_InvAILERON_ELEVATOR;
if (BITMASK_IS_1(def.options, Hydro::OPTION_x_INPUT_AILERON_RUDDER )) m_stream << (char)HydroOption::x_INPUT_AILERON_RUDDER ;
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;
m_stream << ", ";

// Inertia
Expand Down

0 comments on commit 9421c68

Please # to comment.