diff --git a/mcm/scripts/LamasTinyHUD_MCM.pex b/mcm/scripts/LamasTinyHUD_MCM.pex index 877efba..f98b886 100644 Binary files a/mcm/scripts/LamasTinyHUD_MCM.pex and b/mcm/scripts/LamasTinyHUD_MCM.pex differ diff --git a/mcm/source/Scripts/LamasTinyHUD_MCM.psc b/mcm/source/Scripts/LamasTinyHUD_MCM.psc index 7d00e0d..882151d 100644 --- a/mcm/source/Scripts/LamasTinyHUD_MCM.psc +++ b/mcm/source/Scripts/LamasTinyHUD_MCM.psc @@ -38,7 +38,7 @@ Bool Property bPowerSelectedLeftLeft Auto Event OnConfigClose() native string[] function GetSelectedOptions(int a_id, bool a_both, bool a_instant) native -int function GetFormIdForSelection(int a_index) native +string function GetFormIdForSelection(int a_index) native string function GetResolutionWidth() native string function GetResolutionHeight() native diff --git a/src/equip/magic/power.cpp b/src/equip/magic/power.cpp index abb9207..e663bac 100644 --- a/src/equip/magic/power.cpp +++ b/src/equip/magic/power.cpp @@ -47,6 +47,12 @@ namespace magic { } const auto spell = a_form->As(); + + if (!a_player->HasSpell(spell)) { + logger::warn("player does not have spell {}. return."sv, spell->GetName()); + return; + } + if (a_action == handle::slot_setting::acton_type::instant) { //might not consider daily cool downs const auto actor = a_player->As(); diff --git a/src/equip/magic/shout.cpp b/src/equip/magic/shout.cpp index 219cafa..aa6398a 100644 --- a/src/equip/magic/shout.cpp +++ b/src/equip/magic/shout.cpp @@ -30,7 +30,7 @@ namespace magic { return; } } - + const auto shout = a_form->As(); RE::ActorEquipManager::GetSingleton()->EquipShout(a_player, shout); logger::trace("equipped shout {}. return."sv, a_form->GetName()); diff --git a/src/equip/magic/spell.cpp b/src/equip/magic/spell.cpp index 97e7984..1c29334 100644 --- a/src/equip/magic/spell.cpp +++ b/src/equip/magic/spell.cpp @@ -59,6 +59,10 @@ namespace magic { spell->avEffectSetting->data.dualCastScale, spell->avEffectSetting->data.baseCost);*/ + if (!a_player->HasSpell(spell)) { + logger::warn("player does not have spell {}. return."sv, spell->GetName()); + return; + } //maybe check if the spell is already equipped const auto actor = a_player->As(); diff --git a/src/handle/set_data.cpp b/src/handle/set_data.cpp index a28262e..3227065 100644 --- a/src/handle/set_data.cpp +++ b/src/handle/set_data.cpp @@ -22,6 +22,7 @@ namespace handle { logger::trace("continue with overwriting data from configuration ..."sv); + set_slot(page_setting::position::top, mcm::get_top_selected_item_form(), mcm::get_top_type(), @@ -89,17 +90,18 @@ namespace handle { } void set_data::set_slot(page_setting::position a_pos, - const uint32_t a_form, + const std::string& a_form, uint32_t a_type, uint32_t a_hand, uint32_t a_action, - const uint32_t a_form_left, + const std::string& a_form_left, uint32_t a_type_left, const uint32_t a_action_left, key_position*& a_key_pos) { - const auto form = RE::TESForm::LookupByID(a_form); - const auto form_left = RE::TESForm::LookupByID(a_form_left); - if (form == nullptr && form_left) return; + const auto form = get_form_from_mod_id_string(a_form); + const auto form_left = get_form_from_mod_id_string(a_form_left); + + if (form == nullptr && form_left == nullptr) return; auto hand = static_cast(a_hand); std::vector data; @@ -150,7 +152,8 @@ namespace handle { logger::trace("checking if we need to build a second data set, already got {}"sv, data.size()); if (const auto type_left = static_cast(a_type_left); - (type_left == util::selection_type::magic || type_left == util::selection_type::weapon || type_left == + (form_left != nullptr && type_left == util::selection_type::magic || type_left == + util::selection_type::weapon || type_left == util::selection_type::shield) && hand == slot_setting::hand_equip::single) { logger::trace("start building data pos {}, form {}, type {}, action {}, hand {}"sv, static_cast(a_pos), @@ -194,4 +197,34 @@ namespace handle { } } } + + RE::TESForm* set_data::get_form_from_mod_id_string(const std::string& a_str) { + if (!a_str.find(util::delimiter)) { + return nullptr; + } + RE::TESForm* form; + + std::istringstream string_stream{ a_str }; + std::string plugin, id; + + std::getline(string_stream, plugin, *util::delimiter); + std::getline(string_stream, id); + RE::FormID form_id; + std::istringstream(id) >> std::hex >> form_id; + + if (plugin == util::dynamic_name) { + form = RE::TESForm::LookupByID(form_id); + } else { + logger::trace("checking mod {} for form {}"sv, plugin, form_id); + + const auto data_handler = RE::TESDataHandler::GetSingleton(); + form = data_handler->LookupForm(form_id, plugin); + } + + if (form != nullptr) { + logger::trace("got form id {}, name {}", util::string_util::int_to_hex(form->GetFormID()), form->GetName()); + } + + return form; + } } diff --git a/src/handle/set_data.h b/src/handle/set_data.h index 4a65d63..34486c1 100644 --- a/src/handle/set_data.h +++ b/src/handle/set_data.h @@ -11,15 +11,17 @@ namespace handle { private: static void set_empty_slot(int a_pos, key_position*& a_key_pos); static void set_slot(page_setting::position a_pos, - uint32_t a_form, + const std::string& a_form, uint32_t a_type, uint32_t a_hand, uint32_t a_action, - uint32_t a_form_left, + const std::string& a_form_left, uint32_t a_type_left, uint32_t a_action_left, key_position*& a_key_pos); static void set_new_item_count(RE::FormID a_form_id, const char* a_name, int32_t a_count); + + static RE::TESForm* get_form_from_mod_id_string(const std::string& a_str); }; } diff --git a/src/papyrus/papyrus.cpp b/src/papyrus/papyrus.cpp index 90fb0ab..9e1c1b9 100644 --- a/src/papyrus/papyrus.cpp +++ b/src/papyrus/papyrus.cpp @@ -30,12 +30,14 @@ namespace papyrus { logger::info("Got refresh for id {}, both hands {}, instant {}"sv, a_id, a_both, a_instant_cast); std::vector empty_string_vec = { util::empty_enum_string }; const auto display_string_list = new std::vector; - clear_list(); + //clear_list(); + //let the list be valid until it is refreshed again, might be an issue with magic and weapon index_ = static_cast(a_id); auto player = RE::PlayerCharacter::GetSingleton(); if (index_ == util::selection_type::consumable) { + inventory_data_list_->clear(); //maybe add a check if it is a potion for (auto potential_items = item::inventory::get_inventory_magic_items(player); const auto& [item, inv_data] : potential_items) { @@ -50,6 +52,7 @@ namespace papyrus { } logger::trace("potion list is size {}"sv, inventory_data_list_->size()); } else if (index_ == util::selection_type::magic) { + inventory_data_list_->clear(); //add filter for casting for (const auto spell_list = magic::spell::get_spells(a_instant_cast, a_both); const auto spell : spell_list) { @@ -60,16 +63,19 @@ namespace papyrus { } } } else if (index_ == util::selection_type::shout) { + shout_data_list_->clear(); for (const auto shout_list = magic::shout::get_shouts(); const auto shout : shout_list) { display_string_list->push_back(shout->GetName()); shout_data_list_->push_back(shout); } } else if (index_ == util::selection_type::power) { + power_data_list_->clear(); for (const auto power_list = magic::power::get_powers(); const auto power : power_list) { display_string_list->push_back(power->GetName()); power_data_list_->push_back(power); } } else if (index_ == util::selection_type::weapon) { + weapon_data_list_->clear(); auto is_two_handed = false; for (auto potential_weapons = item::inventory::get_inventory_weapon_items(player); const auto& [item, inv_data] : potential_weapons) { @@ -98,6 +104,7 @@ namespace papyrus { } logger::trace("weapon list is size {}"sv, weapon_data_list_->size()); } else if (index_ == util::selection_type::shield) { + shield_data_list_->clear(); for (auto potential_items = item::inventory::get_inventory_armor_items(player); const auto& [item, inv_data] : potential_items) { //just consider favored items @@ -111,6 +118,7 @@ namespace papyrus { } logger::trace("shield list is size {}"sv, shield_data_list_->size()); } else if (index_ == util::selection_type::armor) { + item_data_list_->clear(); for (auto potential_items = item::inventory::get_inventory_armor_items(player); const auto& [item, inv_data] : potential_items) { //just consider favored items @@ -139,7 +147,7 @@ namespace papyrus { return *display_string_list; } - uint32_t hud_mcm::get_form_id_for_selection(RE::TESQuest*, uint32_t a_index) { + RE::BSFixedString hud_mcm::get_form_id_for_selection(RE::TESQuest*, uint32_t a_index) { logger::trace("Got Index {}, Search for Item for type {}"sv, a_index, static_cast(index_)); RE::FormID form_id = 0; @@ -190,8 +198,9 @@ namespace papyrus { } } + std::string form_string; if (form_id == 0) { - return 0; + return form_string; } const auto form = RE::TESForm::LookupByID(form_id); @@ -200,7 +209,29 @@ namespace papyrus { util::string_util::int_to_hex(form->GetFormID()), form->GetFormID()); - return form_id; + + if (form->IsDynamicForm()) { + form_string = fmt::format("{}{}{}", + util::dynamic_name, + util::delimiter, + util::string_util::int_to_hex(form->GetFormID())); + } else { + //it is not, search for the file it is from + auto source_file = form->sourceFiles.array->front()->fileName; + auto local_form = form->GetLocalFormID(); + + logger::info("form is from {}, local id is {}, translated {}"sv, + source_file, + local_form, + util::string_util::int_to_hex(local_form)); + + form_string = fmt::format("{}{}{}", + source_file, + util::delimiter, + util::string_util::int_to_hex(local_form)); + } + + return form_string; } diff --git a/src/papyrus/papyrus.h b/src/papyrus/papyrus.h index 5db444d..6b82806 100644 --- a/src/papyrus/papyrus.h +++ b/src/papyrus/papyrus.h @@ -9,7 +9,7 @@ namespace papyrus { uint32_t a_id, bool a_both, bool a_instant_cast); - static uint32_t get_form_id_for_selection(RE::TESQuest*, uint32_t a_index); + static RE::BSFixedString get_form_id_for_selection(RE::TESQuest*, uint32_t a_index); static RE::BSFixedString get_resolution_width(RE::TESQuest*); static RE::BSFixedString get_resolution_height(RE::TESQuest*); diff --git a/src/setting/mcm_setting.cpp b/src/setting/mcm_setting.cpp index d1d4383..0abbcf4 100644 --- a/src/setting/mcm_setting.cpp +++ b/src/setting/mcm_setting.cpp @@ -11,35 +11,35 @@ namespace config { static uint32_t left_action_key; static uint32_t top_type; - static uint32_t top_selected_item_form; + static std::string top_selected_item_form; static uint32_t top_slot_action; static uint32_t top_hand_selection; static uint32_t top_type_left; - static uint32_t top_selected_item_form_left; + static std::string top_selected_item_form_left; static uint32_t top_slot_action_left; static uint32_t right_type; - static uint32_t right_selected_item_form; + static std::string right_selected_item_form; static uint32_t right_slot_action; static uint32_t right_hand_selection; static uint32_t right_type_left; - static uint32_t right_selected_item_form_left; + static std::string right_selected_item_form_left; static uint32_t right_slot_action_left; static uint32_t bottom_type; - static uint32_t bottom_selected_item_form; + static std::string bottom_selected_item_form; static uint32_t bottom_slot_action; static uint32_t bottom_hand_selection; static uint32_t bottom_type_left; - static uint32_t bottom_selected_item_form_left; + static std::string bottom_selected_item_form_left; static uint32_t bottom_slot_action_left; static uint32_t left_type; - static uint32_t left_selected_item_form; + static std::string left_selected_item_form; static uint32_t left_slot_action; static uint32_t left_hand_selection; static uint32_t left_type_left; - static uint32_t left_selected_item_form_left; + static std::string left_selected_item_form_left; static uint32_t left_slot_action_left; static float hud_image_scale_width; @@ -73,53 +73,38 @@ namespace config { //got more settings, variables, but for now we are ok top_type = static_cast(mcm.GetLongValue("TopPage", "uType", 0)); - std::stringstream selected_top_item_form_stream(mcm.GetValue("TopPage", "sSelectedItemForm", "")); - selected_top_item_form_stream >> top_selected_item_form; + top_selected_item_form = mcm.GetValue("TopPage", "sSelectedItemForm", ""); top_slot_action = static_cast(mcm.GetLongValue("TopPage", "uSlotAction", 0)); top_hand_selection = static_cast(mcm.GetLongValue("TopPage", "uHandSelection", 1)); top_type_left = static_cast(mcm.GetLongValue("TopPage", "uTypeLeft", 0)); - std::stringstream selected_top_item_form_left_stream( - mcm.GetValue("TopPage", "sSelectedItemFormLeft", "")); - selected_top_item_form_left_stream >> top_selected_item_form_left; + top_selected_item_form_left = mcm.GetValue("TopPage", "sSelectedItemFormLeft", ""); top_slot_action_left = static_cast(mcm.GetLongValue("TopPage", "uSlotActionLeft", 0)); //got more settings, variables, but for now we are ok right_type = static_cast(mcm.GetLongValue("RightPage", "uType", 0)); - std::stringstream selected_right_item_form_stream(mcm.GetValue("RightPage", "sSelectedItemForm", "")); - selected_right_item_form_stream >> right_selected_item_form; + right_selected_item_form = mcm.GetValue("RightPage", "sSelectedItemForm", ""); right_slot_action = static_cast(mcm.GetLongValue("RightPage", "uSlotAction", 0)); right_hand_selection = static_cast(mcm.GetLongValue("RightPage", "uHandSelection", 1)); right_type_left = static_cast(mcm.GetLongValue("RightPage", "uTypeLeft", 0)); - std::stringstream selected_right_item_form_left_stream(mcm.GetValue("RightPage", - "sSelectedItemFormLeft", - "")); - selected_right_item_form_left_stream >> right_selected_item_form_left; + right_selected_item_form_left = mcm.GetValue("RightPage", "sSelectedItemFormLeft", ""); right_slot_action_left = static_cast(mcm.GetLongValue("RightPage", "uSlotActionLeft", 0)); //got more settings, variables, but for now we are ok bottom_type = static_cast(mcm.GetLongValue("BottomPage", "uType", 0)); - std::stringstream selected_bottom_item_form_stream(mcm.GetValue("BottomPage", "sSelectedItemForm", "")); - selected_bottom_item_form_stream >> bottom_selected_item_form; + bottom_selected_item_form = mcm.GetValue("BottomPage", "sSelectedItemForm", ""); bottom_slot_action = static_cast(mcm.GetLongValue("BottomPage", "uSlotAction", 0)); bottom_hand_selection = static_cast(mcm.GetLongValue("BottomPage", "uHandSelection", 1)); bottom_type_left = static_cast(mcm.GetLongValue("BottomPage", "uTypeLeft", 0)); - std::stringstream selected_bottom_item_form_left_stream(mcm.GetValue("BottomPage", - "sSelectedItemFormLeft", - "")); - selected_bottom_item_form_left_stream >> bottom_selected_item_form_left; + bottom_selected_item_form_left = mcm.GetValue("BottomPage", "sSelectedItemFormLeft", ""); bottom_slot_action_left = static_cast(mcm.GetLongValue("BottomPage", "uSlotActionLeft", 0)); //got more settings, variables, but for now we are ok left_type = static_cast(mcm.GetLongValue("LeftPage", "uType", 0)); - std::stringstream selected_left_item_form_stream(mcm.GetValue("LeftPage", "sSelectedItemForm", "")); - selected_left_item_form_stream >> left_selected_item_form; + left_selected_item_form = mcm.GetValue("LeftPage", "sSelectedItemForm", ""); left_slot_action = static_cast(mcm.GetLongValue("LeftPage", "uSlotAction", 0)); left_hand_selection = static_cast(mcm.GetLongValue("LeftPage", "uHandSelection", 1)); left_type_left = static_cast(mcm.GetLongValue("LeftPage", "uTypeLeft", 0)); - std::stringstream selected_left_item_form_left_stream(mcm.GetValue("LeftPage", - "sSelectedItemFormLeft", - "")); - selected_left_item_form_left_stream >> left_selected_item_form_left; + left_selected_item_form_left = mcm.GetValue("LeftPage", "sSelectedItemFormLeft", ""); left_slot_action_left = static_cast(mcm.GetLongValue("LeftPage", "uSlotActionLeft", 0)); hud_image_scale_width = static_cast(mcm.GetDoubleValue("HudSetting", "fHudImageScaleWidth", 0.25)); @@ -159,35 +144,35 @@ namespace config { uint32_t mcm_setting::get_left_action_key() { return left_action_key; } uint32_t mcm_setting::get_top_type() { return top_type; } - uint32_t mcm_setting::get_top_selected_item_form() { return top_selected_item_form; } + std::string mcm_setting::get_top_selected_item_form() { return top_selected_item_form; } uint32_t mcm_setting::get_top_slot_action() { return top_slot_action; } uint32_t mcm_setting::get_top_hand_selection() { return top_hand_selection; } uint32_t mcm_setting::get_top_type_left() { return top_type_left; } - uint32_t mcm_setting::get_top_selected_item_form_left() { return top_selected_item_form_left; } + std::string mcm_setting::get_top_selected_item_form_left() { return top_selected_item_form_left; } uint32_t mcm_setting::get_top_slot_action_left() { return top_slot_action_left; } uint32_t mcm_setting::get_right_type() { return right_type; } - uint32_t mcm_setting::get_right_selected_item_form() { return right_selected_item_form; } + std::string mcm_setting::get_right_selected_item_form() { return right_selected_item_form; } uint32_t mcm_setting::get_right_slot_action() { return right_slot_action; } uint32_t mcm_setting::get_right_hand_selection() { return right_hand_selection; } uint32_t mcm_setting::get_right_type_left() { return right_type_left; } - uint32_t mcm_setting::get_right_selected_item_form_left() { return right_selected_item_form_left; } + std::string mcm_setting::get_right_selected_item_form_left() { return right_selected_item_form_left; } uint32_t mcm_setting::get_right_slot_action_left() { return right_slot_action_left; } uint32_t mcm_setting::get_bottom_type() { return bottom_type; } - uint32_t mcm_setting::get_bottom_selected_item_form() { return bottom_selected_item_form; } + std::string mcm_setting::get_bottom_selected_item_form() { return bottom_selected_item_form; } uint32_t mcm_setting::get_bottom_slot_action() { return bottom_slot_action; } uint32_t mcm_setting::get_bottom_hand_selection() { return bottom_hand_selection; } uint32_t mcm_setting::get_bottom_type_left() { return bottom_type_left; } - uint32_t mcm_setting::get_bottom_selected_item_form_left() { return bottom_selected_item_form_left; } + std::string mcm_setting::get_bottom_selected_item_form_left() { return bottom_selected_item_form_left; } uint32_t mcm_setting::get_bottom_slot_action_left() { return bottom_slot_action_left; } uint32_t mcm_setting::get_left_type() { return left_type; } - uint32_t mcm_setting::get_left_selected_item_form() { return left_selected_item_form; } + std::string mcm_setting::get_left_selected_item_form() { return left_selected_item_form; } uint32_t mcm_setting::get_left_slot_action() { return left_slot_action; } uint32_t mcm_setting::get_left_hand_selection() { return left_hand_selection; } uint32_t mcm_setting::get_left_type_left() { return left_type_left; } - uint32_t mcm_setting::get_left_selected_item_form_left() { return left_selected_item_form_left; } + std::string mcm_setting::get_left_selected_item_form_left() { return left_selected_item_form_left; } uint32_t mcm_setting::get_left_slot_action_left() { return left_slot_action_left; } float mcm_setting::get_hud_image_scale_width() { return hud_image_scale_width; } diff --git a/src/setting/mcm_setting.h b/src/setting/mcm_setting.h index e4a0486..964514e 100644 --- a/src/setting/mcm_setting.h +++ b/src/setting/mcm_setting.h @@ -11,35 +11,35 @@ namespace config { static uint32_t get_left_action_key(); static uint32_t get_top_type(); - static uint32_t get_top_selected_item_form(); + static std::string get_top_selected_item_form(); static uint32_t get_top_slot_action(); static uint32_t get_top_hand_selection(); static uint32_t get_top_type_left(); - static uint32_t get_top_selected_item_form_left(); + static std::string get_top_selected_item_form_left(); static uint32_t get_top_slot_action_left(); static uint32_t get_right_type(); - static uint32_t get_right_selected_item_form(); + static std::string get_right_selected_item_form(); static uint32_t get_right_slot_action(); static uint32_t get_right_hand_selection(); static uint32_t get_right_type_left(); - static uint32_t get_right_selected_item_form_left(); + static std::string get_right_selected_item_form_left(); static uint32_t get_right_slot_action_left(); static uint32_t get_bottom_type(); - static uint32_t get_bottom_selected_item_form(); + static std::string get_bottom_selected_item_form(); static uint32_t get_bottom_slot_action(); static uint32_t get_bottom_hand_selection(); static uint32_t get_bottom_type_left(); - static uint32_t get_bottom_selected_item_form_left(); + static std::string get_bottom_selected_item_form_left(); static uint32_t get_bottom_slot_action_left(); static uint32_t get_left_type(); - static uint32_t get_left_selected_item_form(); + static std::string get_left_selected_item_form(); static uint32_t get_left_slot_action(); static uint32_t get_left_hand_selection(); static uint32_t get_left_type_left(); - static uint32_t get_left_selected_item_form_left(); + static std::string get_left_selected_item_form_left(); static uint32_t get_left_slot_action_left(); static float get_hud_image_scale_width(); diff --git a/src/ui/ui_renderer.cpp b/src/ui/ui_renderer.cpp index 163b379..4d2f15e 100644 --- a/src/ui/ui_renderer.cpp +++ b/src/ui/ui_renderer.cpp @@ -12,7 +12,6 @@ #include "imgui_internal.h" #include "key_path.h" #include "event/key_manager.h" - #include "event/sink_event.h" #include "handle/key_position.h" #include "handle/page_handle.h" diff --git a/src/util/constant.h b/src/util/constant.h index 818fba3..335eefc 100644 --- a/src/util/constant.h +++ b/src/util/constant.h @@ -16,4 +16,7 @@ namespace util { consumable = 5, armor = 6 }; + + constexpr auto dynamic_name = "dynamic"; + constexpr auto delimiter = "|"; } diff --git a/src/util/string_util.h b/src/util/string_util.h index 6420ba4..cdc2283 100644 --- a/src/util/string_util.h +++ b/src/util/string_util.h @@ -1,14 +1,29 @@ #pragma once +#include +#include +#include + namespace util { class string_util { public: template static std::string int_to_hex(T a_i) { std::stringstream stream; - stream << "0x" << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex << a_i; + stream << std::hex << a_i; + + return ltrim_copy(stream.str()); + } + + static void ltrim(std::string &s) { + s.erase(s.begin(), std::ranges::find_if(s, [](const unsigned char ch) { + return !std::isspace(ch); + })); + } - return stream.str(); + static std::string ltrim_copy(std::string s) { + ltrim(s); + return s; } }; }