diff --git a/mcm/Config/LamasTinyHUD/config.json b/mcm/Config/LamasTinyHUD/config.json index 75275a8..b550cbf 100644 --- a/mcm/Config/LamasTinyHUD/config.json +++ b/mcm/Config/LamasTinyHUD/config.json @@ -1082,6 +1082,19 @@ "sourceType": "ModSettingFloat" } }, + { + "id": "fItemNameTextFontSize:GraphicSetting", + "text": "$LamasTinyHUD_GraphicSetting_ItemNameTextFontSize_OptionText", + "type": "slider", + "help": "$LamasTinyHUD_GraphicSetting_ItemNameTextFontSize_InfoText", + "valueOptions": { + "min": 10.0, + "max": 35.0, + "step": 1.0, + "formatString": "{0}", + "sourceType": "ModSettingFloat" + } + }, { "text": "$LamasTinyHUD_GraphicSetting_Color", "type": "header", @@ -1217,6 +1230,17 @@ "valueOptions": { "sourceType": "ModSettingBool" } + }, + { + "id": "bDrawPageId:GraphicSetting", + "text": "$LamasTinyHUD_GraphicSetting_DrawPageId_OptionText", + "type": "toggle", + "help": "$LamasTinyHUD_GraphicSetting_DrawPageId_InfoText", + "groupCondition": 5, + "groupBehavior": "disable", + "valueOptions": { + "sourceType": "ModSettingBool" + } } ] }, diff --git a/mcm/Config/LamasTinyHUD/settings.ini b/mcm/Config/LamasTinyHUD/settings.ini index 1f177b8..e68445d 100644 --- a/mcm/Config/LamasTinyHUD/settings.ini +++ b/mcm/Config/LamasTinyHUD/settings.ini @@ -91,6 +91,8 @@ bDrawItemNameText = 1 bDrawToggleButton = 1 bDrawCurrentShoutText = 0 fCurrentShoutFontSize = 20 +fItemNameTextFontSize = 20 +bDrawPageId = 0 [MiscSetting] bActionCheck = 0 diff --git a/mcm/Interface/Translations/LamasTinyHUD_english.txt b/mcm/Interface/Translations/LamasTinyHUD_english.txt index 8a24913..b867604 100644 Binary files a/mcm/Interface/Translations/LamasTinyHUD_english.txt and b/mcm/Interface/Translations/LamasTinyHUD_english.txt differ diff --git a/src/equip/item.cpp b/src/equip/item.cpp index 27f5877..da5392d 100644 --- a/src/equip/item.cpp +++ b/src/equip/item.cpp @@ -197,48 +197,7 @@ namespace equip { auto alchemy_item = obj->As(); if (alchemy_item->IsPoison()) { - logger::trace("try to apply poison to weapon, count left {}"sv, left); - uint32_t potion_doses = 1; - /* it works for vanilla and adamant - * vanilla does a basic set value to 3 - * adamant does 2 times a add value 2 - * ordinator we could handle it "dirty" because the Information we need needs to be RE, but if perk xy Is set - we could calculate it ourself. It is basically AV multiply base + "alchemy level" * 0.1 * 3 = dose count - * vokrii should be fine as well - * other add av multiply implementations need to be handled by getting the data from the game - * the MCM setting will be left for overwrite handling */ - if (config::mcm_setting::get_overwrite_poison_dose()) { - potion_doses = config::mcm_setting::get_apply_poison_dose(); - } else { - if (a_player->HasPerkEntries(RE::BGSEntryPoint::ENTRY_POINTS::kModPoisonDoseCount)) { - auto perk_visit = util::perk_visitor(a_player, static_cast(potion_doses)); - a_player->ForEachPerkEntry(RE::BGSEntryPoint::ENTRY_POINTS::kModPoisonDoseCount, perk_visit); - potion_doses = static_cast(perk_visit.get_result()); - } - } - logger::trace("Poison dose set value is {}"sv, potion_doses); - - //check if there is a weapon to apply it to - //check count here as well, since we need max 2 - auto equipped_object = a_player->GetEquippedEntryData(false); - if (equipped_object && equipped_object->object->IsWeapon() && !equipped_object->IsPoisoned()) { - logger::trace("try to add poison {} to right {}"sv, - alchemy_item->GetName(), - equipped_object->GetDisplayName()); - equipped_object->PoisonObject(alchemy_item, potion_doses); - a_player->RemoveItem(alchemy_item, 1, RE::ITEM_REMOVE_REASON::kRemove, nullptr, nullptr); - left--; - } - - auto equipped_object_left = a_player->GetEquippedEntryData(true); - if (equipped_object_left && equipped_object_left->object->IsWeapon() && - !equipped_object_left->IsPoisoned() && left > 0) { - logger::trace("try to add poison {} to left {}"sv, - alchemy_item->GetName(), - equipped_object_left->GetDisplayName()); - equipped_object_left->PoisonObject(alchemy_item, potion_doses); - a_player->RemoveItem(alchemy_item, 1, RE::ITEM_REMOVE_REASON::kRemove, nullptr, nullptr); - } + poison_weapon(a_player, alchemy_item, left); logger::trace("Is a poison, I am done here. return."); return; } @@ -370,4 +329,57 @@ namespace equip { logger::warn("No suitable potion found. return."); } } + + void item::poison_weapon(RE::PlayerCharacter*& a_player, RE::AlchemyItem*& a_poison, uint32_t a_count) { + logger::trace("try to apply poison to weapon, count left {}"sv, a_count); + uint32_t potion_doses = 1; + /* it works for vanilla and adamant + * vanilla does a basic set value to 3 + * adamant does 2 times add value 2 + * ordinator we could handle it "dirty" because the Information we need needs to be RE, but if perk xy Is set + we could calculate it ourselves. It is basically AV multiply base + "alchemy level" * 0.1 * 3 = dose count + * vokrii should be fine as well + * other add av multiply implementations need to be handled by getting the data from the game + * the MCM setting will be left for overwrite handling */ + if (config::mcm_setting::get_overwrite_poison_dose()) { + potion_doses = config::mcm_setting::get_apply_poison_dose(); + } else { + if (a_player->HasPerkEntries(RE::BGSEntryPoint::ENTRY_POINTS::kModPoisonDoseCount)) { + auto perk_visit = util::perk_visitor(a_player, static_cast(potion_doses)); + a_player->ForEachPerkEntry(RE::BGSEntryPoint::ENTRY_POINTS::kModPoisonDoseCount, perk_visit); + potion_doses = static_cast(perk_visit.get_result()); + } + } + logger::trace("Poison dose set value is {}"sv, potion_doses); + + RE::BGSSoundDescriptor* sound_descriptor; + if (a_poison->data.consumptionSound) { + sound_descriptor = a_poison->data.consumptionSound->soundDescriptor; + } else { + sound_descriptor = RE::TESForm::LookupByID(0x00106614)->As()->soundDescriptor; + } + + //check if there is a weapon to apply it to + //check count here as well, since we need max 2 + auto equipped_object = a_player->GetEquippedEntryData(false); + if (equipped_object && equipped_object->object->IsWeapon() && !equipped_object->IsPoisoned()) { + logger::trace("try to add poison {} to right {}"sv, a_poison->GetName(), equipped_object->GetDisplayName()); + equipped_object->PoisonObject(a_poison, potion_doses); + util::player::play_sound(sound_descriptor, a_player); + a_player->RemoveItem(a_poison, 1, RE::ITEM_REMOVE_REASON::kRemove, nullptr, nullptr); + a_count--; + } + + auto equipped_object_left = a_player->GetEquippedEntryData(true); + if (equipped_object_left && equipped_object_left->object->IsWeapon() && !equipped_object_left->IsPoisoned() && + a_count > 0) { + logger::trace("try to add poison {} to left {}"sv, + a_poison->GetName(), + equipped_object_left->GetDisplayName()); + equipped_object_left->PoisonObject(a_poison, potion_doses); + a_player->RemoveItem(a_poison, 1, RE::ITEM_REMOVE_REASON::kRemove, nullptr, nullptr); + a_count--; + } + // + } } diff --git a/src/equip/item.h b/src/equip/item.h index d6c8775..441df89 100644 --- a/src/equip/item.h +++ b/src/equip/item.h @@ -13,5 +13,8 @@ namespace equip { static void equip_ammo(const RE::TESForm* a_form, RE::PlayerCharacter*& a_player); static void un_equip_ammo(); static void find_and_consume_fitting_option(RE::ActorValue a_actor_value, RE::PlayerCharacter*& a_player); + + private: + static void poison_weapon(RE::PlayerCharacter*& a_player, RE::AlchemyItem*& a_poison, uint32_t a_count); }; } diff --git a/src/equip/magic.cpp b/src/equip/magic.cpp index 2071f87..2f7501e 100644 --- a/src/equip/magic.cpp +++ b/src/equip/magic.cpp @@ -79,7 +79,7 @@ namespace equip { //could trigger an animation here //might need to set some things //TODO make an animation to play here - //a_player->NotifyAnimationGraph("RightCastSelf"); + //a_player->NotifyAnimationGraph("IdleMagic_01"); //works auto is_self_target = spell->GetDelivery() == RE::MagicSystem::Delivery::kSelf; auto target = is_self_target ? actor : actor->GetActorRuntimeData().currentCombatTarget.get().get(); @@ -88,12 +88,10 @@ namespace equip { if (auto* effect = spell->GetCostliestEffectItem()) { magnitude = effect->GetMagnitude(); } - //auto dual_cast_scale = spell->avEffectSetting->data.dualCastScale; - logger::trace("casting spell {}, magnitude {}, effecticeness {}"sv, + logger::trace("casting spell {}, magnitude {}, effectiveness {}"sv, spell->GetName(), fmt::format(FMT_STRING("{:.2f}"), magnitude), fmt::format(FMT_STRING("{:.2f}"), effectiveness)); - caster->CastSpellImmediate(spell, false, target, diff --git a/src/handle/data/page/position_setting.h b/src/handle/data/page/position_setting.h index ae0127d..0b0ce05 100644 --- a/src/handle/data/page/position_setting.h +++ b/src/handle/data/page/position_setting.h @@ -16,7 +16,8 @@ namespace handle { uint32_t button_press_modify = ui::draw_full; uint32_t key = 0; position_draw_setting* draw_setting = nullptr; - float font_size = 0.f; + float item_name_font_size = 0.f; + float count_font_size = 0.f; bool item_name = false; bool highlight_slot = false; }; diff --git a/src/handle/data/page/slot_setting.h b/src/handle/data/page/slot_setting.h index 25d9277..c2a9634 100644 --- a/src/handle/data/page/slot_setting.h +++ b/src/handle/data/page/slot_setting.h @@ -24,6 +24,7 @@ namespace handle { mask = 12 }; + RE::TESForm* form = nullptr; slot_type type = slot_type::empty; action_type action = action_type::default_action; diff --git a/src/handle/page_handle.cpp b/src/handle/page_handle.cpp index f6ed9e2..4d0e863 100644 --- a/src/handle/page_handle.cpp +++ b/src/handle/page_handle.cpp @@ -2,6 +2,7 @@ #include "equip/equip_slot.h" #include "handle/data/data_helper.h" #include "handle/data/page/position_setting.h" +#include "handle/data/page/slot_setting.h" #include "setting/mcm_setting.h" #include "util/constant.h" #include "util/helper.h" @@ -68,6 +69,7 @@ namespace handle { if (slot->type == slot_type::consumable || slot->type == slot_type::scroll) { slot->display_item_count = true; } + slot->equip_slot = equip_slot; slots->push_back(slot); @@ -120,7 +122,7 @@ namespace handle { draw->offset_text_x = config::mcm_setting::get_slot_count_text_offset(); draw->offset_text_y = config::mcm_setting::get_slot_count_text_offset(); - if ((mcm::get_elden_demon_souls() || mcm::get_draw_item_name_text()) && + if ((elden || mcm::get_draw_item_name_text()) && (a_position == position_type::bottom || a_position == position_type::top)) { page->item_name = true; get_offset_values(a_position, @@ -156,7 +158,8 @@ namespace handle { page->draw_setting = draw; page->key = a_key_pos->get_key_for_position(a_position); - page->font_size = config::mcm_setting::get_slot_count_text_font_size(); + page->item_name_font_size = config::mcm_setting::get_item_name_font_size(); + page->count_font_size = config::mcm_setting::get_slot_count_text_font_size(); if (elden) { if (first_slot->type != slot_type::empty || slots->size() == 2 && slots->at(1)->type != slot_type::empty) { diff --git a/src/processing/set_setting_data.cpp b/src/processing/set_setting_data.cpp index e8222db..cbb33d1 100644 --- a/src/processing/set_setting_data.cpp +++ b/src/processing/set_setting_data.cpp @@ -365,7 +365,7 @@ namespace processing { return; } - clear_hands(); + //clear_hands(); logger::trace("execute first setting for left/right/top"sv); @@ -481,7 +481,9 @@ namespace processing { for (const auto& [item, inv_data] : inv) { const auto& [num_items, entry] = inv_data; const auto ammo = item->As(); - if (!ammo->GetPlayable() || ammo->GetRuntimeData().data.flags.any(RE::AMMO_DATA::Flag::kNonPlayable)) { + + if (ammo->IsBoundObject() || !ammo->GetPlayable() || + ammo->GetRuntimeData().data.flags.any(RE::AMMO_DATA::Flag::kNonPlayable)) { continue; } diff --git a/src/setting/mcm_setting.cpp b/src/setting/mcm_setting.cpp index e893f1d..de37e00 100644 --- a/src/setting/mcm_setting.cpp +++ b/src/setting/mcm_setting.cpp @@ -69,6 +69,8 @@ namespace config { static bool draw_toggle_button; static bool draw_current_shout_text; static float current_shout_font_size; + static float item_name_font_size; + static bool draw_page_id; static uint32_t alpha_slot_animation; static float duration_slot_animation; @@ -197,6 +199,8 @@ namespace config { draw_current_shout_text = mcm.GetBoolValue("GraphicSetting", "bDrawCurrentShoutText", false); current_shout_font_size = static_cast(mcm.GetDoubleValue("GraphicSetting", "fCurrentShoutFontSize", 20)); + item_name_font_size = static_cast(mcm.GetDoubleValue("GraphicSetting", "fItemNameTextFontSize", 20)); + draw_page_id = mcm.GetBoolValue("GraphicSetting", "bDrawPageId", false); alpha_slot_animation = static_cast(mcm.GetLongValue("AnimationSetting", "uAlphaSlotAnimation", 51)); @@ -315,6 +319,9 @@ namespace config { bool mcm_setting::get_draw_toggle_button() { return draw_toggle_button; } bool mcm_setting::get_draw_current_shout_text() { return draw_current_shout_text; } float mcm_setting::get_current_shout_font_size() { return current_shout_font_size; } + float mcm_setting::get_item_name_font_size() { return item_name_font_size; } + bool mcm_setting::get_draw_page_id() { return draw_page_id; } + uint32_t mcm_setting::get_alpha_slot_animation() { return alpha_slot_animation; } float mcm_setting::get_duration_slot_animation() { return duration_slot_animation; } diff --git a/src/setting/mcm_setting.h b/src/setting/mcm_setting.h index c6938a9..628d1bd 100644 --- a/src/setting/mcm_setting.h +++ b/src/setting/mcm_setting.h @@ -70,6 +70,8 @@ namespace config { static bool get_draw_item_name_text(); static bool get_draw_current_shout_text(); static float get_current_shout_font_size(); + static float get_item_name_font_size(); + static bool get_draw_page_id(); static uint32_t get_alpha_slot_animation(); static float get_duration_slot_animation(); diff --git a/src/ui/ui_renderer.cpp b/src/ui/ui_renderer.cpp index 706ec59..3db3ce5 100644 --- a/src/ui/ui_renderer.cpp +++ b/src/ui/ui_renderer.cpp @@ -347,6 +347,8 @@ namespace ui { void ui_renderer::draw_slots(const float a_x, const float a_y, const std::map& a_settings) { + auto draw_page = mcm::get_draw_page_id(); + auto elden = mcm::get_elden_demon_souls(); for (auto [position, page_setting] : a_settings) { if (!page_setting) { continue; @@ -414,7 +416,7 @@ namespace ui { draw_setting->offset_name_text_y, slot_name, color, - page_setting->font_size, + page_setting->item_name_font_size, center_text, deduct_text_x, deduct_text_y, @@ -429,45 +431,77 @@ namespace ui { mcm::get_slot_count_green(), mcm::get_slot_count_blue(), page_setting->draw_setting->text_transparency); + std::string slot_text; switch (first_type) { case slot_type::scroll: case slot_type::consumable: if (slot_settings.front()->display_item_count) { - draw_text(draw_setting->width_setting, - draw_setting->height_setting, - draw_setting->offset_slot_x, - draw_setting->offset_slot_y, - draw_setting->offset_text_x, - draw_setting->offset_text_y, - std::to_string(slot_settings.front()->item_count).c_str(), - color, - page_setting->font_size); + slot_text = std::to_string(slot_settings.front()->item_count); } break; case slot_type::shout: case slot_type::power: + slot_text = + slot_settings.front()->action == handle::slot_setting::action_type::instant ? "I" : "E"; + break; case slot_type::magic: - draw_text(draw_setting->width_setting, - draw_setting->height_setting, - draw_setting->offset_slot_x, - draw_setting->offset_slot_y, - draw_setting->offset_text_x, - draw_setting->offset_text_y, - slot_settings.front()->action == handle::slot_setting::action_type::instant ? "I" : "E", - color, - page_setting->font_size); + if ((position == position_type::top && elden) || !elden) { + slot_text = + slot_settings.front()->action == handle::slot_setting::action_type::instant ? "I" : "E"; + } else if (draw_page) { + slot_text = std::to_string(page_setting->page); + } break; case slot_type::weapon: case slot_type::shield: + case slot_type::light: + if (draw_page) { + slot_text = std::to_string(page_setting->page); + } + break; case slot_type::armor: case slot_type::empty: case slot_type::misc: - case slot_type::light: case slot_type::lantern: case slot_type::mask: //Nothing, for now break; } + + if (draw_page && elden && position == position_type::left && slot_settings.size() == 2) { + const auto second_type = slot_settings[1]->type; + switch (second_type) { + case slot_type::magic: + case slot_type::weapon: + case slot_type::shield: + case slot_type::light: + slot_text = std::to_string(page_setting->page); + break; + case slot_type::scroll: + case slot_type::consumable: + case slot_type::shout: + case slot_type::power: + case slot_type::armor: + case slot_type::empty: + case slot_type::misc: + case slot_type::lantern: + case slot_type::mask: + //Nothing, for now + break; + } + } + + if (!slot_text.empty()) { + draw_text(draw_setting->width_setting, + draw_setting->height_setting, + draw_setting->offset_slot_x, + draw_setting->offset_slot_y, + draw_setting->offset_text_x, + draw_setting->offset_text_y, + slot_text.c_str(), + color, + page_setting->count_font_size); + } } } const auto ammo_handle = handle::ammo_handle::get_singleton(); diff --git a/src/util/player/player.cpp b/src/util/player/player.cpp index 5eb6eae..4fac601 100644 --- a/src/util/player/player.cpp +++ b/src/util/player/player.cpp @@ -144,4 +144,16 @@ namespace util { REL::Relocation func{ offset::has_shout }; return func(a_actor, a_shout); } + + void player::play_sound(RE::BGSSoundDescriptor* a_sound_descriptor, RE::PlayerCharacter*& a_player) { + auto* audio_manager = RE::BSAudioManager::GetSingleton(); + if (audio_manager && a_sound_descriptor) { + RE::BSSoundHandle sound_handle; + audio_manager->BuildSoundDataFromDescriptor(sound_handle, a_sound_descriptor); + sound_handle.SetObjectToFollow(a_player->Get3D()); + sound_handle.SetVolume(1.0); + sound_handle.Play(); + logger::trace("played sound"sv); + } + } } // util diff --git a/src/util/player/player.h b/src/util/player/player.h index bd768ec..552f75f 100644 --- a/src/util/player/player.h +++ b/src/util/player/player.h @@ -11,6 +11,7 @@ namespace util { static std::vector get_hand_assignment(bool a_two_handed = false); static bool has_item_or_spell(RE::TESForm* a_form); static bool has_shout(RE::Actor* a_actor, RE::TESShout* a_shout); + static void play_sound(RE::BGSSoundDescriptor* a_sound_descriptor_form, RE::PlayerCharacter*& a_player); private: static uint32_t