1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-30 21:32:42 +00:00

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

668 lines
23 KiB
C++
Raw Normal View History

#include "hud.hpp"
2015-01-10 02:50:43 +01:00
#include <MyGUI_Button.h>
#include <MyGUI_ImageBox.h>
#include <MyGUI_InputManager.h>
#include <MyGUI_ProgressBar.h>
#include <MyGUI_RenderManager.h>
#include <MyGUI_ScrollView.h>
#include <components/esm3/loadgmst.hpp>
#include <components/esm3/loadmgef.hpp>
#include <components/misc/resourcehelpers.hpp>
#include <components/resource/resourcesystem.hpp>
2015-01-31 23:27:34 +01:00
#include <components/settings/settings.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
2013-05-11 18:38:27 +02:00
#include "../mwworld/class.hpp"
#include "../mwworld/esmstore.hpp"
2015-08-21 21:12:39 +12:00
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/npcstats.hpp"
2013-07-30 06:00:20 +02:00
#include "draganddrop.hpp"
#include "inventorywindow.hpp"
2013-05-11 18:38:27 +02:00
#include "itemmodel.hpp"
#include "spellicons.hpp"
#include "itemwidget.hpp"
2013-04-17 18:56:48 -04:00
namespace MWGui
{
/**
* Makes it possible to use ItemModel::moveItem to move an item from an inventory to the world.
*/
class WorldItemModel : public ItemModel
{
public:
WorldItemModel(float left, float top)
: mLeft(left)
, mTop(top)
{
}
virtual ~WorldItemModel() override {}
MWWorld::Ptr copyItem(const ItemStack& item, size_t count, bool /*allowAutoEquip*/) override
{
MWBase::World* world = MWBase::Environment::get().getWorld();
MWWorld::Ptr dropped;
if (world->canPlaceObject(mLeft, mTop))
dropped = world->placeObject(item.mBase, mLeft, mTop, count);
else
dropped = world->dropObjectOnGround(world->getPlayerPtr(), item.mBase, count);
dropped.getCellRef().setOwner("");
return dropped;
}
void removeItem(const ItemStack& item, size_t count) override
{
throw std::runtime_error("removeItem not implemented");
}
2021-08-15 19:50:28 +02:00
ModelIndex getIndex(const ItemStack& item) override { throw std::runtime_error("getIndex not implemented"); }
void update() override {}
size_t getItemCount() override { return 0; }
ItemStack getItem(ModelIndex index) override { throw std::runtime_error("getItem not implemented"); }
bool usesContainer(const MWWorld::Ptr&) override { return false; }
private:
// Where to drop the item
float mLeft;
float mTop;
};
2015-11-07 00:13:13 +01:00
HUD::HUD(CustomMarkerCollection& customMarkers, DragAndDrop* dragAndDrop, MWRender::LocalMap* localMapRender)
: WindowBase("openmw_hud.layout")
, LocalMapBase(customMarkers, localMapRender, Settings::Manager::getBool("local map hud fog of war", "Map"))
2018-10-09 10:21:12 +04:00
, mHealth(nullptr)
, mMagicka(nullptr)
, mStamina(nullptr)
, mDrowning(nullptr)
, mWeapImage(nullptr)
, mSpellImage(nullptr)
, mWeapStatus(nullptr)
, mSpellStatus(nullptr)
, mEffectBox(nullptr)
, mMinimap(nullptr)
, mCrosshair(nullptr)
, mCellNameBox(nullptr)
, mDrowningBar(nullptr)
2018-10-09 10:21:12 +04:00
, mDrowningFlash(nullptr)
2013-04-17 18:56:48 -04:00
, mHealthManaStaminaBaseLeft(0)
, mWeapBoxBaseLeft(0)
, mSpellBoxBaseLeft(0)
, mMinimapBoxBaseRight(0)
2015-04-25 13:37:42 -05:00
, mEffectBoxBaseRight(0)
2013-04-17 18:56:48 -04:00
, mDragAndDrop(dragAndDrop)
, mCellNameTimer(0.0f)
2015-04-25 13:37:42 -05:00
, mWeaponSpellTimer(0.f)
2013-04-17 18:56:48 -04:00
, mMapVisible(true)
, mWeaponVisible(true)
, mSpellVisible(true)
, mWorldMouseOver(false)
, mEnemyActorId(-1)
2015-04-25 13:37:42 -05:00
, mEnemyHealthTimer(-1)
2013-10-27 04:05:01 -04:00
, mIsDrowning(false)
, mDrowningFlashTheta(0.f)
2013-04-17 18:56:48 -04:00
{
// Energy bars
getWidget(mHealthFrame, "HealthFrame");
getWidget(mHealth, "Health");
getWidget(mMagicka, "Magicka");
getWidget(mStamina, "Stamina");
2013-07-30 06:00:20 +02:00
getWidget(mEnemyHealth, "EnemyHealth");
2013-04-17 18:56:48 -04:00
mHealthManaStaminaBaseLeft = mHealthFrame->getLeft();
2012-05-29 15:36:48 +02:00
2013-04-17 18:56:48 -04:00
MyGUI::Widget *healthFrame, *magickaFrame, *fatigueFrame;
getWidget(healthFrame, "HealthFrame");
getWidget(magickaFrame, "MagickaFrame");
getWidget(fatigueFrame, "FatigueFrame");
healthFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
magickaFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
fatigueFrame->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onHMSClicked);
// Drowning bar
getWidget(mDrowningBar, "DrowningBar");
getWidget(mDrowningFrame, "DrowningFrame");
getWidget(mDrowning, "Drowning");
2013-10-27 04:05:01 -04:00
getWidget(mDrowningFlash, "Flash");
mDrowning->setProgressRange(200);
2013-04-17 18:56:48 -04:00
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
2013-04-17 18:56:48 -04:00
// Item and spell images and status bars
getWidget(mWeapBox, "WeapBox");
getWidget(mWeapImage, "WeapImage");
getWidget(mWeapStatus, "WeapStatus");
mWeapBoxBaseLeft = mWeapBox->getLeft();
mWeapBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWeaponClicked);
2013-04-17 18:56:48 -04:00
getWidget(mSpellBox, "SpellBox");
getWidget(mSpellImage, "SpellImage");
getWidget(mSpellStatus, "SpellStatus");
mSpellBoxBaseLeft = mSpellBox->getLeft();
mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked);
getWidget(mSneakBox, "SneakBox");
mSneakBoxBaseLeft = mSneakBox->getLeft();
2013-04-17 18:56:48 -04:00
getWidget(mEffectBox, "EffectBox");
mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight();
2013-04-17 18:56:48 -04:00
getWidget(mMinimapBox, "MiniMapBox");
mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight();
getWidget(mMinimap, "MiniMap");
getWidget(mCompass, "Compass");
getWidget(mMinimapButton, "MiniMapButton");
mMinimapButton->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
2013-04-17 18:56:48 -04:00
getWidget(mCellNameBox, "CellName");
getWidget(mWeaponSpellBox, "WeaponSpellName");
2012-04-13 13:17:50 +02:00
2013-04-17 18:56:48 -04:00
getWidget(mCrosshair, "Crosshair");
2020-06-16 18:43:01 +04:00
LocalMapBase::init(mMinimap, mCompass);
2013-03-03 12:01:19 +01:00
2013-04-17 18:56:48 -04:00
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus);
2022-08-31 18:03:46 +02:00
mSpellIcons = std::make_unique<SpellIcons>();
2013-04-17 18:56:48 -04:00
}
2012-04-13 13:17:50 +02:00
2013-04-17 18:56:48 -04:00
HUD::~HUD()
2012-04-13 13:17:50 +02:00
{
2015-01-31 16:26:15 +01:00
mMainWidget->eventMouseLostFocus.clear();
mMainWidget->eventMouseMove.clear();
mMainWidget->eventMouseButtonClick.clear();
2012-04-13 13:17:50 +02:00
}
2013-04-17 18:56:48 -04:00
void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat<float>& value)
{
int current = static_cast<int>(value.getCurrent());
int modified = static_cast<int>(value.getModified());
// Fatigue can be negative
if (id != "FBar")
current = std::max(0, current);
MyGUI::Widget* w;
std::string valStr = MyGUI::utility::toString(current) + " / " + MyGUI::utility::toString(modified);
if (id == "HBar")
{
mHealth->setProgressRange(std::max(0, modified));
mHealth->setProgressPosition(std::max(0, current));
getWidget(w, "HealthFrame");
w->setUserString("Caption_HealthDescription", "#{sHealthDesc}\n" + valStr);
}
else if (id == "MBar")
{
mMagicka->setProgressRange(std::max(0, modified));
mMagicka->setProgressPosition(std::max(0, current));
getWidget(w, "MagickaFrame");
2015-11-21 02:05:27 +01:00
w->setUserString("Caption_HealthDescription", "#{sMagDesc}\n" + valStr);
}
else if (id == "FBar")
{
mStamina->setProgressRange(std::max(0, modified));
mStamina->setProgressPosition(std::max(0, current));
getWidget(w, "FatigueFrame");
w->setUserString("Caption_HealthDescription", "#{sFatDesc}\n" + valStr);
}
2013-04-17 18:56:48 -04:00
}
2012-08-13 01:26:15 +02:00
void HUD::setDrowningTimeLeft(float time, float maxTime)
{
size_t progress = static_cast<size_t>(time / maxTime * 200);
2013-10-27 04:05:01 -04:00
mDrowning->setProgressPosition(progress);
bool isDrowning = (progress == 0);
if (isDrowning && !mIsDrowning) // Just started drowning
mDrowningFlashTheta = 0.0f; // Start out on bright red every time.
mDrowningFlash->setVisible(isDrowning);
mIsDrowning = isDrowning;
}
void HUD::setDrowningBarVisible(bool visible)
{
mDrowningBar->setVisible(visible);
}
2013-04-17 18:56:48 -04:00
void HUD::onWorldClicked(MyGUI::Widget* _sender)
{
2013-04-17 18:56:48 -04:00
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
return;
MWBase::WindowManager* winMgr = MWBase::Environment::get().getWindowManager();
2013-04-17 18:56:48 -04:00
if (mDragAndDrop->mIsOnDragAndDrop)
{
// drop item into the gameworld
MWBase::Environment::get().getWorld()->breakInvisibility(MWMechanics::getPlayer());
2013-04-17 18:56:48 -04:00
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
float mouseX = cursorPosition.left / float(viewSize.width);
float mouseY = cursorPosition.top / float(viewSize.height);
2012-05-15 23:28:04 +02:00
WorldItemModel drop(mouseX, mouseY);
2018-10-09 10:21:12 +04:00
mDragAndDrop->drop(&drop, nullptr);
2012-05-14 17:41:17 +02:00
winMgr->changePointer("arrow");
2013-04-17 18:56:48 -04:00
}
else
{
GuiMode mode = winMgr->getMode();
if (!winMgr->isConsoleMode() && (mode != GM_Container) && (mode != GM_Inventory))
2013-04-17 18:56:48 -04:00
return;
2013-04-17 18:56:48 -04:00
MWWorld::Ptr object = MWBase::Environment::get().getWorld()->getFacedObject();
if (winMgr->isConsoleMode())
winMgr->setConsoleSelectedObject(object);
2019-02-17 11:42:22 +04:00
else // if ((mode == GM_Container) || (mode == GM_Inventory))
2013-04-17 18:56:48 -04:00
{
// pick up object
if (!object.isEmpty())
winMgr->getInventoryWindow()->pickUpObject(object);
2013-04-17 18:56:48 -04:00
}
}
}
2013-04-17 18:56:48 -04:00
void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
{
2013-04-17 18:56:48 -04:00
if (mDragAndDrop->mIsOnDragAndDrop)
{
mWorldMouseOver = false;
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
float mouseX = cursorPosition.left / float(viewSize.width);
float mouseY = cursorPosition.top / float(viewSize.height);
2013-04-17 18:56:48 -04:00
MWBase::World* world = MWBase::Environment::get().getWorld();
2013-04-17 18:56:48 -04:00
// if we can't drop the object at the wanted position, show the "drop on ground" cursor.
bool canDrop = world->canPlaceObject(mouseX, mouseY);
2013-04-17 18:56:48 -04:00
if (!canDrop)
MWBase::Environment::get().getWindowManager()->changePointer("drop_ground");
else
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
}
else
2013-04-17 18:56:48 -04:00
{
2013-03-07 12:46:26 +01:00
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
2013-04-17 18:56:48 -04:00
mWorldMouseOver = true;
}
}
2013-04-17 18:56:48 -04:00
void HUD::onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new)
{
2013-03-07 12:46:26 +01:00
MWBase::Environment::get().getWindowManager()->changePointer("arrow");
2013-04-17 18:56:48 -04:00
mWorldMouseOver = false;
}
2013-04-17 18:56:48 -04:00
void HUD::onHMSClicked(MyGUI::Widget* _sender)
{
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Stats);
}
2013-04-17 18:56:48 -04:00
void HUD::onMapClicked(MyGUI::Widget* _sender)
{
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Map);
}
2013-04-17 18:56:48 -04:00
void HUD::onWeaponClicked(MyGUI::Widget* _sender)
{
2015-08-21 21:12:39 +12:00
const MWWorld::Ptr& player = MWMechanics::getPlayer();
if (player.getClass().getNpcStats(player).isWerewolf())
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
return;
}
2013-04-17 18:56:48 -04:00
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Inventory);
}
2013-04-17 18:56:48 -04:00
void HUD::onMagicClicked(MyGUI::Widget* _sender)
{
2015-08-21 21:12:39 +12:00
const MWWorld::Ptr& player = MWMechanics::getPlayer();
if (player.getClass().getNpcStats(player).isWerewolf())
{
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
return;
}
2013-04-17 18:56:48 -04:00
MWBase::Environment::get().getWindowManager()->toggleVisible(GW_Magic);
}
2013-04-17 18:56:48 -04:00
void HUD::setCellName(const std::string& cellName)
{
if (mCellName != cellName)
{
mCellNameTimer = 5.0f;
mCellName = cellName;
2013-04-17 18:56:48 -04:00
mCellNameBox->setCaptionWithReplacing("#{sCell=" + mCellName + "}");
mCellNameBox->setVisible(mMapVisible);
}
}
2013-04-17 18:56:48 -04:00
void HUD::onFrame(float dt)
{
LocalMapBase::onFrame(dt);
2013-04-17 18:56:48 -04:00
mCellNameTimer -= dt;
mWeaponSpellTimer -= dt;
if (mCellNameTimer < 0)
mCellNameBox->setVisible(false);
if (mWeaponSpellTimer < 0)
mWeaponSpellBox->setVisible(false);
2013-07-30 06:00:20 +02:00
mEnemyHealthTimer -= dt;
if (mEnemyHealth->getVisible() && mEnemyHealthTimer < 0)
{
mEnemyHealth->setVisible(false);
mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() + MyGUI::IntPoint(0, 20));
}
2013-10-27 04:05:01 -04:00
2017-09-23 22:24:22 +02:00
mSpellIcons->updateWidgets(mEffectBox, true);
if (mEnemyActorId != -1 && mEnemyHealth->getVisible())
{
updateEnemyHealthBar();
}
if (mDrowningBar->getVisible())
mDrowningBar->setPosition(
mMainWidget->getWidth() / 2 - mDrowningFrame->getWidth() / 2, mMainWidget->getTop());
2017-09-23 22:24:22 +02:00
if (mIsDrowning)
{
mDrowningFlashTheta += dt * osg::PI * 2;
2017-09-23 22:24:22 +02:00
float intensity = (cos(mDrowningFlashTheta) + 2.0f) / 3.0f;
mDrowningFlash->setAlpha(intensity);
}
2013-04-17 18:56:48 -04:00
}
2013-04-17 18:56:48 -04:00
void HUD::setSelectedSpell(const std::string& spellId, int successChancePercent)
{
const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get<ESM::Spell>().find(spellId);
2022-08-28 15:06:31 +02:00
const std::string& spellName = spell->mName;
2013-04-17 18:56:48 -04:00
if (spellName != mSpellName && mSpellVisible)
{
mWeaponSpellTimer = 5.0f;
mSpellName = spellName;
mWeaponSpellBox->setCaption(mSpellName);
mWeaponSpellBox->setVisible(true);
}
2013-04-17 18:56:48 -04:00
mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(successChancePercent);
2013-04-17 18:56:48 -04:00
mSpellBox->setUserString("ToolTipType", "Spell");
mSpellBox->setUserString("Spell", spellId);
2013-04-17 18:56:48 -04:00
// use the icon of the first effect
const ESM::MagicEffect* effect = MWBase::Environment::get().getWorld()->getStore().get<ESM::MagicEffect>().find(
spell->mEffects.mList.front().mEffectID);
std::string icon = effect->mIcon;
int slashPos = icon.rfind('\\');
2013-04-17 18:56:48 -04:00
icon.insert(slashPos + 1, "b_");
icon = Misc::ResourceHelpers::correctIconPath(icon, MWBase::Environment::get().getResourceSystem()->getVFS());
mSpellImage->setSpellIcon(icon);
}
2013-04-17 18:56:48 -04:00
void HUD::setSelectedEnchantItem(const MWWorld::Ptr& item, int chargePercent)
{
2022-08-16 21:15:03 +02:00
std::string_view itemName = item.getClass().getName(item);
2013-04-17 18:56:48 -04:00
if (itemName != mSpellName && mSpellVisible)
{
mWeaponSpellTimer = 5.0f;
mSpellName = itemName;
mWeaponSpellBox->setCaption(mSpellName);
mWeaponSpellBox->setVisible(true);
}
2013-04-17 18:56:48 -04:00
mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(chargePercent);
2013-04-17 18:56:48 -04:00
mSpellBox->setUserString("ToolTipType", "ItemPtr");
mSpellBox->setUserData(MWWorld::Ptr(item));
mSpellImage->setItem(item);
}
2013-04-17 18:56:48 -04:00
void HUD::setSelectedWeapon(const MWWorld::Ptr& item, int durabilityPercent)
{
2022-08-16 21:15:03 +02:00
std::string_view itemName = item.getClass().getName(item);
2013-04-17 18:56:48 -04:00
if (itemName != mWeaponName && mWeaponVisible)
{
mWeaponSpellTimer = 5.0f;
mWeaponName = itemName;
mWeaponSpellBox->setCaption(mWeaponName);
mWeaponSpellBox->setVisible(true);
}
2014-08-25 03:15:28 +02:00
mWeapBox->clearUserStrings();
2013-04-17 18:56:48 -04:00
mWeapBox->setUserString("ToolTipType", "ItemPtr");
mWeapBox->setUserData(MWWorld::Ptr(item));
2013-04-17 18:56:48 -04:00
mWeapStatus->setProgressRange(100);
mWeapStatus->setProgressPosition(durabilityPercent);
mWeapImage->setItem(item);
}
2013-04-17 18:56:48 -04:00
void HUD::unsetSelectedSpell()
{
2022-08-28 15:06:31 +02:00
std::string_view spellName = "#{sNone}";
2013-04-17 18:56:48 -04:00
if (spellName != mSpellName && mSpellVisible)
{
mWeaponSpellTimer = 5.0f;
mSpellName = spellName;
mWeaponSpellBox->setCaptionWithReplacing(mSpellName);
mWeaponSpellBox->setVisible(true);
}
2013-04-17 18:56:48 -04:00
mSpellStatus->setProgressRange(100);
mSpellStatus->setProgressPosition(0);
mSpellImage->setItem(MWWorld::Ptr());
2013-04-17 18:56:48 -04:00
mSpellBox->clearUserStrings();
}
2013-04-17 18:56:48 -04:00
void HUD::unsetSelectedWeapon()
{
2013-04-17 18:56:48 -04:00
std::string itemName = "#{sSkillHandtohand}";
if (itemName != mWeaponName && mWeaponVisible)
{
mWeaponSpellTimer = 5.0f;
mWeaponName = itemName;
mWeaponSpellBox->setCaptionWithReplacing(mWeaponName);
mWeaponSpellBox->setVisible(true);
}
mWeapStatus->setProgressRange(100);
mWeapStatus->setProgressPosition(0);
MWBase::World* world = MWBase::Environment::get().getWorld();
MWWorld::Ptr player = world->getPlayerPtr();
mWeapImage->setItem(MWWorld::Ptr());
2014-08-25 03:15:28 +02:00
std::string icon = (player.getClass().getNpcStats(player).isWerewolf()) ? "icons\\k\\tx_werewolf_hand.dds"
: "icons\\k\\stealth_handtohand.dds";
mWeapImage->setIcon(icon);
2013-04-17 18:56:48 -04:00
mWeapBox->clearUserStrings();
2014-08-25 03:15:28 +02:00
mWeapBox->setUserString("ToolTipType", "Layout");
mWeapBox->setUserString("ToolTipLayout", "HandToHandToolTip");
mWeapBox->setUserString("Caption_HandToHandText", itemName);
mWeapBox->setUserString("ImageTexture_HandToHandImage", icon);
}
2013-04-17 18:56:48 -04:00
void HUD::setCrosshairVisible(bool visible)
{
mCrosshair->setVisible(visible);
}
2022-09-22 21:26:05 +03:00
2015-07-17 17:29:00 +02:00
void HUD::setCrosshairOwned(bool owned)
{
if (owned)
{
mCrosshair->changeWidgetSkin("HUD_Crosshair_Owned");
2015-07-17 17:29:00 +02:00
}
else
{
mCrosshair->changeWidgetSkin("HUD_Crosshair");
2015-07-17 17:29:00 +02:00
}
}
2022-09-22 21:26:05 +03:00
2013-04-17 18:56:48 -04:00
void HUD::setHmsVisible(bool visible)
{
mHealth->setVisible(visible);
mMagicka->setVisible(visible);
mStamina->setVisible(visible);
updatePositions();
}
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
void HUD::setWeapVisible(bool visible)
{
mWeapBox->setVisible(visible);
updatePositions();
}
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
void HUD::setSpellVisible(bool visible)
{
mSpellBox->setVisible(visible);
updatePositions();
}
2012-08-27 19:18:55 +02:00
void HUD::setSneakVisible(bool visible)
{
mSneakBox->setVisible(visible);
updatePositions();
}
2013-04-17 18:56:48 -04:00
void HUD::setEffectVisible(bool visible)
{
mEffectBox->setVisible(visible);
updatePositions();
}
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
void HUD::setMinimapVisible(bool visible)
{
mMinimapBox->setVisible(visible);
updatePositions();
}
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
void HUD::updatePositions()
{
int weapDx = 0, spellDx = 0, sneakDx = 0;
2013-04-17 18:56:48 -04:00
if (!mHealth->getVisible())
sneakDx = spellDx = weapDx = mWeapBoxBaseLeft - mHealthManaStaminaBaseLeft;
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
if (!mWeapBox->getVisible())
{
2013-04-17 18:56:48 -04:00
spellDx += mSpellBoxBaseLeft - mWeapBoxBaseLeft;
sneakDx = spellDx;
}
if (!mSpellBox->getVisible())
sneakDx += mSneakBoxBaseLeft - mSpellBoxBaseLeft;
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
mWeaponVisible = mWeapBox->getVisible();
mSpellVisible = mSpellBox->getVisible();
if (!mWeaponVisible && !mSpellVisible)
mWeaponSpellBox->setVisible(false);
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
mWeapBox->setPosition(mWeapBoxBaseLeft - weapDx, mWeapBox->getTop());
mSpellBox->setPosition(mSpellBoxBaseLeft - spellDx, mSpellBox->getTop());
mSneakBox->setPosition(mSneakBoxBaseLeft - sneakDx, mSneakBox->getTop());
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
const MyGUI::IntSize& viewSize = MyGUI::RenderManager::getInstance().getViewSize();
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
// effect box can have variable width -> variable left coordinate
int effectsDx = 0;
if (!mMinimapBox->getVisible())
2021-01-09 14:41:10 +04:00
effectsDx = mEffectBoxBaseRight - mMinimapBoxBaseRight;
2012-08-27 19:18:55 +02:00
2013-04-17 18:56:48 -04:00
mMapVisible = mMinimapBox->getVisible();
2014-05-20 09:45:39 +02:00
if (!mMapVisible)
mCellNameBox->setVisible(false);
2013-04-17 18:56:48 -04:00
mEffectBox->setPosition(
(viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop());
}
2012-08-27 19:18:55 +02:00
void HUD::updateEnemyHealthBar()
{
MWWorld::Ptr enemy = MWBase::Environment::get().getWorld()->searchPtrViaActorId(mEnemyActorId);
if (enemy.isEmpty())
return;
MWMechanics::CreatureStats& stats = enemy.getClass().getCreatureStats(enemy);
mEnemyHealth->setProgressRange(100);
// Health is usually cast to int before displaying. Actors die whenever they are < 1 health.
// Therefore any value < 1 should show as an empty health bar. We do the same in statswindow :)
2022-02-10 22:10:46 +01:00
mEnemyHealth->setProgressPosition(static_cast<size_t>(stats.getHealth().getRatio() * 100));
2018-08-29 18:38:12 +03:00
static const float fNPCHealthBarFade = MWBase::Environment::get()
.getWorld()
->getStore()
.get<ESM::GameSetting>()
.find("fNPCHealthBarFade")
->mValue.getFloat();
if (fNPCHealthBarFade > 0.f)
2021-11-06 07:30:28 +03:00
mEnemyHealth->setAlpha(std::clamp(mEnemyHealthTimer / fNPCHealthBarFade, 0.f, 1.f));
}
2013-07-30 06:00:20 +02:00
void HUD::setEnemy(const MWWorld::Ptr& enemy)
{
mEnemyActorId = enemy.getClass().getCreatureStats(enemy).getActorId();
2018-08-29 18:38:12 +03:00
mEnemyHealthTimer = MWBase::Environment::get()
.getWorld()
->getStore()
.get<ESM::GameSetting>()
.find("fNPCHealthBarTime")
->mValue.getFloat();
2013-07-30 06:00:20 +02:00
if (!mEnemyHealth->getVisible())
mWeaponSpellBox->setPosition(mWeaponSpellBox->getPosition() - MyGUI::IntPoint(0, 20));
mEnemyHealth->setVisible(true);
updateEnemyHealthBar();
2013-04-17 18:56:48 -04:00
}
2013-03-03 12:01:19 +01:00
2014-04-23 19:49:09 +02:00
void HUD::resetEnemy()
{
mEnemyActorId = -1;
2014-04-23 19:49:09 +02:00
mEnemyHealthTimer = -1;
}
2017-09-23 23:09:41 +02:00
void HUD::clear()
{
unsetSelectedSpell();
unsetSelectedWeapon();
resetEnemy();
}
void HUD::customMarkerCreated(MyGUI::Widget* marker)
{
marker->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
}
void HUD::doorMarkerCreated(MyGUI::Widget* marker)
{
marker->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMapClicked);
}
2013-03-03 12:01:19 +01:00
}