Skip to content

Commit

Permalink
Support setting blade locators by updating the equipment.*.locator
Browse files Browse the repository at this point in the history
…attribute
  • Loading branch information
Hammie committed Jan 19, 2024
1 parent cdfd954 commit e012c73
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class BLADE : public Entity
void DrawBlade(VDX9RENDER *rs, unsigned int blendValue, MODEL *mdl, NODE *manNode);
bool LoadBladeModel(MESSAGE &message);

std::string id_;
std::string locatorName_;
std::string locatorNameActive_;

Expand Down Expand Up @@ -106,5 +107,8 @@ class BLADE : public Entity
void Realize(uint32_t Delta_Time);
uint64_t ProcessMessage(MESSAGE &message) override;

void SetEquipmentLocator(const std::string_view &equipment_id, const std::string_view &locator_name);
void SetEquipmentActiveLocator(const std::string_view &equipment_id, const std::string_view &locator_name);

void ShowEditor() override;
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#include "blade.h"
#include "storm\blade\blade.hpp"

#include "animation.h"
#include "core.h"
#include "geometry.h"
#include "shared/messages.h"
#include "string_compare.hpp"

#include <storm/editor/storm_imgui.hpp>

Expand All @@ -18,11 +19,12 @@ static const char *gunHandName = "gun_hand";
static const char *gunBeltName = "gun_belt";
static const char *gunFire = "gun_fire";

static const char *sabergunHandName = "sabergun_hand";
static const char *sabergunBeltName = "sabergun_belt";
static const char *sabergunHandName = "saberGun_hand";
static const char *sabergunBeltName = "saberGun_belt";

BLADE::BLADE_INFO::BLADE_INFO()
: parentEntityId_(0)
: id_("saber")
, parentEntityId_(0)
, vrt{}
{
locatorName_ = beltName;
Expand Down Expand Up @@ -212,8 +214,10 @@ BLADE::BLADE()

blades_[0].locatorName_ = beltName;
blades_[0].locatorNameActive_ = handName;
blades_[0].id_ = "saber";
blades_[1].locatorName_ = sabergunBeltName;
blades_[1].locatorNameActive_ = sabergunHandName;
blades_[1].id_ = "saberGun";
}

BLADE::~BLADE()
Expand Down Expand Up @@ -725,3 +729,38 @@ void BLADE::ShowEditor()
ImGui::InputText("Active locator", &gunLocatorActive_);
ImGui::PopID();
}

void BLADE::SetEquipmentLocator(const std::string_view &equipment_id, const std::string_view &locator_name)
{
if (storm::iEquals(equipment_id, "gun") )
{
gunLocator_ = locator_name;
}
else
{
for (auto &blade : blades_)
{
if (storm::iEquals(equipment_id, blade.id_) )
{
blade.locatorName_ = locator_name;
}
}
}
}
void BLADE::SetEquipmentActiveLocator(const std::string_view &equipment_id, const std::string_view &locator_name)
{
if (storm::iEquals(equipment_id, "gun") )
{
gunLocatorActive_ = locator_name;
}
else
{
for (auto &blade : blades_)
{
if (storm::iEquals(equipment_id, blade.id_) )
{
blade.locatorNameActive_ = locator_name;
}
}
}
}
61 changes: 61 additions & 0 deletions src/libs/config/testsuite/attribute_match.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "attributes.h"

#include <catch2/catch.hpp>

namespace
{

// TODO: Either move STRING_CODEC outside of Engine or make a re-usable codec for testing
class TestStringCodec : public VSTRING_CODEC
{
public:
uint32_t GetNum() override
{
return map_.size();
}

uint32_t Convert(const char *pString) override
{
std::string str(pString);
const uint32_t hash = std::hash<std::string>{}(str);
map_.emplace(hash, str);
return hash;
}

uint32_t Convert(const char *pString, int32_t iLen) override
{
std::string str(pString, iLen);
const uint32_t hash = std::hash<std::string>{}(str);
map_.emplace(hash, str);
return hash;
}

const char *Convert(uint32_t code) override
{
return map_[code].c_str();
}

void VariableChanged() override
{
}

private:
std::unordered_map<uint32_t, std::string> map_;
};

} // namespace

TEST_CASE("Match attribute path by pattern", "[config]")
{
TestStringCodec string_codec{};
ATTRIBUTES attribute(string_codec);
ATTRIBUTES *third = attribute.CreateSubAClass(&attribute, "first.second.third");
ATTRIBUTES *fourth = third->CreateAttribute("fourth", "value");

CHECK(MatchAttributePath("first.second.third.fourth", *fourth) );
CHECK_FALSE(MatchAttributePath("first.second.wrong.fourth", *fourth) );
CHECK_FALSE(MatchAttributePath("third.fourth", *fourth) );
CHECK_FALSE(MatchAttributePath("*.fourth", *fourth) );
CHECK_FALSE(MatchAttributePath("third", *fourth) );
CHECK(MatchAttributePath("first.*.third.fourth", *fourth) );
}
5 changes: 4 additions & 1 deletion src/libs/core/include/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class VSTRING_CODEC
virtual void VariableChanged() = 0;
};

class ATTRIBUTES;

bool MatchAttributePath(const std::string_view &pattern, const ATTRIBUTES &attribute);

class ATTRIBUTES final
{
// TODO: remove with another iteration of rewriting this
Expand Down Expand Up @@ -137,4 +141,3 @@ class ATTRIBUTES final
proxy_value_t proxy_value_;
};
};

19 changes: 19 additions & 0 deletions src/libs/core/src/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,22 @@ void ATTRIBUTES::Release() const noexcept
if (break_)
stringCodec_.VariableChanged();
}

// MatchAttributePath("equipment.*.locator", attribute)
bool MatchAttributePath(const std::string_view &pattern, const ATTRIBUTES &attribute)
{
const ATTRIBUTES *current_attribute = &attribute;
std::string_view remaining_pattern = pattern;
size_t last_separator = remaining_pattern.size();
while(last_separator != pattern.npos)
{
last_separator = remaining_pattern.find_last_of('.');
std::string_view section = remaining_pattern.substr( last_separator + 1);
remaining_pattern = remaining_pattern.substr(0, last_separator);
if (section != "*" && !storm::iEquals(section, current_attribute->GetThisName() ) ) {
return false;
}
current_attribute = current_attribute->GetParent();
}
return current_attribute != nullptr && current_attribute->GetParent() == nullptr;
}
2 changes: 1 addition & 1 deletion src/libs/editor/include/storm/editor/storm_imgui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ template <typename T, typename... Args>
IMGUI_API void TextFmt(T &&fmt, const Args &...args)
{
std::string str = fmt::format(std::forward<T>(fmt), args...);
ImGui::TextUnformatted(&*str.begin(), &*str.end());
ImGui::TextUnformatted(str.c_str(), str.c_str() + str.length() );
}

}
2 changes: 1 addition & 1 deletion src/libs/location/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
STORM_SETUP(
TARGET_NAME location
TYPE storm_module
DEPENDENCIES animation collide core geometry model renderer sea sound_service util
DEPENDENCIES animation blade collide core geometry model renderer sea sound_service util
)
49 changes: 49 additions & 0 deletions src/libs/location/src/character.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "character.h"
#include "characters_groups.h"
#include "lights.h"
#include "storm\blade\blade.hpp"

#include "debug-trap.h"
#include "geometry.h"
Expand Down Expand Up @@ -997,6 +998,30 @@ uint32_t Character::AttributeChanged(ATTRIBUTES *apnt)
// Updating the animation being played
UpdateAnimation();
}
else if (MatchAttributePath("equipment.*.locator", *apnt) )
{
if (isBladeSet)
{
const std::string equipment_id = apnt->GetParent()->GetThisName();
auto *blade_ptr = static_cast<BLADE *>(core.GetEntityPointer(blade));
if (blade_ptr)
{
blade_ptr->SetEquipmentLocator(equipment_id, apnt->GetValue() );
}
}
}
else if (MatchAttributePath("equipment.*.activeLocator", *apnt) )
{
if (isBladeSet)
{
const std::string equipment_id = apnt->GetParent()->GetThisName();
auto *blade_ptr = static_cast<BLADE *>(core.GetEntityPointer(blade));
if (blade_ptr)
{
blade_ptr->SetEquipmentActiveLocator(equipment_id, apnt->GetValue() );
}
}
}
return 0;
}

Expand Down Expand Up @@ -3317,6 +3342,30 @@ bool Character::zSetBlade(MESSAGE &message)
return false;
}
core.Send_Message(blade, "llisfll", MSG_BLADE_SET, nBladeIdx, mdl, name.c_str(), t, s, e);

ATTRIBUTES *equipment_attr = AttributesPointer->GetAttributeClass("equipment");
if (equipment_attr != nullptr)
{
auto *blade_ptr = static_cast<BLADE *>(core.GetEntityPointerSafe(blade));
Assert(blade_ptr);

for (size_t i = 0; i < equipment_attr->GetAttributesNum(); ++i)
{
ATTRIBUTES *equipment_entry = equipment_attr->GetAttributeClass(i);
Assert(equipment_entry != nullptr);
if (equipment_entry->HasAttribute("locator"))
{
blade_ptr->SetEquipmentLocator(equipment_entry->GetThisName(),
to_string(equipment_entry->GetAttribute("locator")));
}
if (equipment_entry->HasAttribute("activeLocator"))
{
blade_ptr->SetEquipmentActiveLocator(equipment_entry->GetThisName(),
to_string(equipment_entry->GetAttribute("active_locator")));
}
}
}

UpdateWeapons();
return true;
}
Expand Down

0 comments on commit e012c73

Please sign in to comment.