Skip to content

Commit

Permalink
🐛 Fixed #193 faulty/incomplete command list UI
Browse files Browse the repository at this point in the history
  • Loading branch information
ohlidalp committed Jun 27, 2024
1 parent cfeba57 commit 39c1549
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 18 deletions.
3 changes: 3 additions & 0 deletions source/main/ForwardDeclarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ namespace RoR
typedef int ExhaustID_t; //!< Index into `Actor::exhausts`, use `RoR::EXHAUSTID_INVALID` as empty value
static const ExhaustID_t EXHAUSTID_INVALID = -1;

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` ).
static const CommandkeyID_t COMMANDKEYID_INVALID = 0;

class Actor;
class ActorManager;
class ActorSpawner;
Expand Down
25 changes: 7 additions & 18 deletions source/main/gui/panels/GUI_VehicleDescription.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,19 @@ void VehicleDescription::Draw()
if (ImGui::CollapsingHeader(_LC("VehicleDescription", "Commands"), ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::Columns(2, /*id=*/nullptr, /*border=*/true);
for (int i = 1; i <= MAX_COMMANDS; i += 2) // BEWARE: commandkeys are indexed 1-MAX_COMMANDS!
for (const UniqueCommandKeyPair& qpair: actor->ar_unique_commandkey_pairs)
{
if (actor->ar_command_key[i].description == "hide")
continue;
if (actor->ar_command_key[i].beams.empty() && actor->ar_command_key[i].rotators.empty())
continue;

int eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", i));
Ogre::String keya = RoR::App::GetInputEngine()->getEventCommand(eventID);
eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", i + 1));
Ogre::String keyb = RoR::App::GetInputEngine()->getEventCommand(eventID);

// cut off expl
if (keya.size() > 6 && keya.substr(0, 5) == "EXPL+")
keya = keya.substr(5);
if (keyb.size() > 6 && keyb.substr(0, 5) == "EXPL+")
keyb = keyb.substr(5);
int eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", qpair.uckp_key1));
Ogre::String keya = RoR::App::GetInputEngine()->getEventCommandTrimmed(eventID);
eventID = RoR::InputEngine::resolveEventName(fmt::format("COMMANDS_{:02d}", qpair.uckp_key2));
Ogre::String keyb = RoR::App::GetInputEngine()->getEventCommandTrimmed(eventID);

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

if (!actor->ar_command_key[i].description.empty())
if (qpair.uckp_description != "")
{
ImGui::Text("%s", actor->ar_command_key[i].description.c_str());
ImGui::Text("%s", qpair.uckp_description.c_str());
}
else
{
Expand Down
2 changes: 2 additions & 0 deletions source/main/physics/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ class Actor : public RefCountingObject<Actor>
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)
std::vector<Ogre::AxisAlignedBox> ar_predicted_coll_bounding_boxes;
std::map<std::string, Ogre::MaterialPtr> ar_managed_materials;
std::vector<UniqueCommandKeyPair> ar_unique_commandkey_pairs; //!< UI helper for displaying command control keys to user (must be built at spawn).

int ar_num_contactable_nodes = 0; //!< Total number of nodes which can contact ground or cabs
int ar_num_contacters = 0; //!< Total number of nodes which can selfcontact cabs
wheel_t ar_wheels[MAX_WHEELS] = {};
Expand Down
25 changes: 25 additions & 0 deletions source/main/physics/ActorSpawner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3665,6 +3665,31 @@ void ActorSpawner::ProcessCommand(RigDef::Command2 & def)

m_actor->m_num_command_beams++;
m_actor->m_has_command_beams = true;

// Update the unique pair list
bool must_insert_qpair = true;
for (UniqueCommandKeyPair& qpair: m_actor->ar_unique_commandkey_pairs)
{
// seek match on both keys (in any order)
if ((def.contract_key == qpair.uckp_key1 && def.extend_key == qpair.uckp_key2)
|| (def.contract_key == qpair.uckp_key2 && def.extend_key == qpair.uckp_key1))
{
must_insert_qpair = false;
if (def.description != "")
{
qpair.uckp_description = def.description; // Last description always wins
}
break;
}
}
if (must_insert_qpair)
{
UniqueCommandKeyPair qpair;
qpair.uckp_key1 = def.contract_key;
qpair.uckp_key2 = def.extend_key;
qpair.uckp_description = def.description;
m_actor->ar_unique_commandkey_pairs.push_back(qpair);
}
}

void ActorSpawner::ProcessAnimator(RigDef::Animator & def)
Expand Down
9 changes: 9 additions & 0 deletions source/main/physics/SimData.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,15 @@ class CmdKeyArray
command_t m_dummykey;
};

/// UI helper for displaying command control keys to user.
/// Reconstructing such list on runtime isn't possible, we must build it on spawn.
struct UniqueCommandKeyPair
{
std::string uckp_description;
CommandkeyID_t uckp_key1 = COMMANDKEYID_INVALID;
CommandkeyID_t uckp_key2 = COMMANDKEYID_INVALID;
};

/// @}

// --------------------------------
Expand Down

0 comments on commit 39c1549

Please sign in to comment.