Skip to content

Commit 85116d2

Browse files
committed
🐛 Fixed RigsOfRods#193 faulty/incomplete command list UI
1 parent cfeba57 commit 85116d2

File tree

5 files changed

+46
-18
lines changed

5 files changed

+46
-18
lines changed

source/main/ForwardDeclarations.h

+3
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ namespace RoR
6767
typedef int ExhaustID_t; //!< Index into `Actor::exhausts`, use `RoR::EXHAUSTID_INVALID` as empty value
6868
static const ExhaustID_t EXHAUSTID_INVALID = -1;
6969

70+
typedef int CommandkeyID_t; //!< Index into `Actor::ar_commandkeys` (BEWARE: indexed 1-MAX_COMMANDKEYS, 0 is invalid value, negative subscript of any size is acceptable, see `class CmdKeyArray` ).
71+
static const CommandkeyID_t COMMANDKEYID_INVALID = 0;
72+
7073
class Actor;
7174
class ActorManager;
7275
class ActorSpawner;

source/main/gui/panels/GUI_VehicleDescription.cpp

+7-18
Original file line numberDiff line numberDiff line change
@@ -74,30 +74,19 @@ void VehicleDescription::Draw()
7474
if (ImGui::CollapsingHeader(_LC("VehicleDescription", "Commands"), ImGuiTreeNodeFlags_DefaultOpen))
7575
{
7676
ImGui::Columns(2, /*id=*/nullptr, /*border=*/true);
77-
for (int i = 1; i <= MAX_COMMANDS; i += 2) // BEWARE: commandkeys are indexed 1-MAX_COMMANDS!
77+
for (const UniqueCommandKeyPair& qpair: actor->ar_unique_commandkey_pairs)
7878
{
79-
if (actor->ar_command_key[i].description == "hide")
80-
continue;
81-
if (actor->ar_command_key[i].beams.empty() && actor->ar_command_key[i].rotators.empty())
82-
continue;
83-
84-
int eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", i));
85-
Ogre::String keya = RoR::App::GetInputEngine()->getEventCommand(eventID);
86-
eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", i + 1));
87-
Ogre::String keyb = RoR::App::GetInputEngine()->getEventCommand(eventID);
88-
89-
// cut off expl
90-
if (keya.size() > 6 && keya.substr(0, 5) == "EXPL+")
91-
keya = keya.substr(5);
92-
if (keyb.size() > 6 && keyb.substr(0, 5) == "EXPL+")
93-
keyb = keyb.substr(5);
79+
int eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", qpair.uckp_key1));
80+
Ogre::String keya = RoR::App::GetInputEngine()->getEventCommandTrimmed(eventID);
81+
eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", qpair.uckp_key2));
82+
Ogre::String keyb = RoR::App::GetInputEngine()->getEventCommandTrimmed(eventID);
9483

9584
ImGui::Text("%s/%s", keya.c_str(), keyb.c_str());
9685
ImGui::NextColumn();
9786

98-
if (!actor->ar_command_key[i].description.empty())
87+
if (qpair.uckp_description != "")
9988
{
100-
ImGui::Text("%s", actor->ar_command_key[i].description.c_str());
89+
ImGui::Text("%s", qpair.uckp_description.c_str());
10190
}
10291
else
10392
{

source/main/physics/Actor.h

+2
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,8 @@ class Actor : public RefCountingObject<Actor>
309309
std::vector<Ogre::AxisAlignedBox> ar_collision_bounding_boxes; //!< smart bounding boxes, used for determining the state of an actor (every box surrounds only a subset of nodes)
310310
std::vector<Ogre::AxisAlignedBox> ar_predicted_coll_bounding_boxes;
311311
std::map<std::string, Ogre::MaterialPtr> ar_managed_materials;
312+
std::vector<UniqueCommandKeyPair> ar_unique_commandkey_pairs; //!< UI helper for displaying command control keys to user (must be built at spawn).
313+
312314
int ar_num_contactable_nodes = 0; //!< Total number of nodes which can contact ground or cabs
313315
int ar_num_contacters = 0; //!< Total number of nodes which can selfcontact cabs
314316
wheel_t ar_wheels[MAX_WHEELS] = {};

source/main/physics/ActorSpawner.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -3665,6 +3665,31 @@ void ActorSpawner::ProcessCommand(RigDef::Command2 & def)
36653665

36663666
m_actor->m_num_command_beams++;
36673667
m_actor->m_has_command_beams = true;
3668+
3669+
// Update the unique pair list
3670+
bool must_insert_qpair = true;
3671+
for (UniqueCommandKeyPair& qpair: m_actor->ar_unique_commandkey_pairs)
3672+
{
3673+
// seek match on both keys (in any order)
3674+
if ((def.contract_key == qpair.uckp_key1 && def.extend_key == qpair.uckp_key2)
3675+
|| (def.contract_key == qpair.uckp_key2 && def.extend_key == qpair.uckp_key1))
3676+
{
3677+
must_insert_qpair = false;
3678+
if (def.description != "")
3679+
{
3680+
qpair.uckp_description = def.description; // Last description always wins
3681+
}
3682+
break;
3683+
}
3684+
}
3685+
if (must_insert_qpair)
3686+
{
3687+
UniqueCommandKeyPair qpair;
3688+
qpair.uckp_key1 = def.contract_key;
3689+
qpair.uckp_key2 = def.extend_key;
3690+
qpair.uckp_description = def.description;
3691+
m_actor->ar_unique_commandkey_pairs.push_back(qpair);
3692+
}
36683693
}
36693694

36703695
void ActorSpawner::ProcessAnimator(RigDef::Animator & def)

source/main/physics/SimData.h

+9
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,15 @@ class CmdKeyArray
701701
command_t m_dummykey;
702702
};
703703

704+
/// UI helper for displaying command control keys to user.
705+
/// Reconstructing such list on runtime isn't possible, we must build it on spawn.
706+
struct UniqueCommandKeyPair
707+
{
708+
std::string uckp_description;
709+
CommandkeyID_t uckp_key1 = COMMANDKEYID_INVALID;
710+
CommandkeyID_t uckp_key2 = COMMANDKEYID_INVALID;
711+
};
712+
704713
/// @}
705714

706715
// --------------------------------

0 commit comments

Comments
 (0)