Skip to content

Commit

Permalink
[feature]
Browse files Browse the repository at this point in the history
* saving the form data now with modname|formid or if it is dynamic
  dynamic|formid
* added a check if the config has an old value game does not crash
* checking before executing a power or a spell if the user has it
  • Loading branch information
mlthelama committed Jan 10, 2023
1 parent ced4404 commit 12a296d
Show file tree
Hide file tree
Showing 14 changed files with 143 additions and 65 deletions.
Binary file modified mcm/scripts/LamasTinyHUD_MCM.pex
Binary file not shown.
2 changes: 1 addition & 1 deletion mcm/source/Scripts/LamasTinyHUD_MCM.psc
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions src/equip/magic/power.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ namespace magic {
}

const auto spell = a_form->As<RE::SpellItem>();

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<RE::Actor>();
Expand Down
2 changes: 1 addition & 1 deletion src/equip/magic/shout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace magic {
return;
}
}

const auto shout = a_form->As<RE::TESShout>();
RE::ActorEquipManager::GetSingleton()->EquipShout(a_player, shout);
logger::trace("equipped shout {}. return."sv, a_form->GetName());
Expand Down
4 changes: 4 additions & 0 deletions src/equip/magic/spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<RE::Actor>();
Expand Down
45 changes: 39 additions & 6 deletions src/handle/set_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -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<slot_setting::hand_equip>(a_hand);
std::vector<data_helper*> data;
Expand Down Expand Up @@ -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<util::selection_type>(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<uint32_t>(a_pos),
Expand Down Expand Up @@ -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;
}
}
6 changes: 4 additions & 2 deletions src/handle/set_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
}
39 changes: 35 additions & 4 deletions src/papyrus/papyrus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<RE::BSFixedString> empty_string_vec = { util::empty_enum_string };
const auto display_string_list = new std::vector<RE::BSFixedString>;
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<util::selection_type>(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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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<uint32_t>(index_));

RE::FormID form_id = 0;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
}


Expand Down
2 changes: 1 addition & 1 deletion src/papyrus/papyrus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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*);

Expand Down
Loading

0 comments on commit 12a296d

Please sign in to comment.