mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-10 15:39:02 +00:00
410 lines
11 KiB
C++
410 lines
11 KiB
C++
#include "widgets.hpp"
|
|
#include "window_manager.hpp"
|
|
#include "components/esm_store/store.hpp"
|
|
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
#undef min
|
|
#undef max
|
|
|
|
using namespace MWGui;
|
|
using namespace MWGui::Widgets;
|
|
|
|
/* Helper functions */
|
|
|
|
/*
|
|
* Fixes the filename of a texture path to use the correct .dds extension.
|
|
* This is needed on some ESM entries which point to a .tga file instead.
|
|
*/
|
|
void MWGui::Widgets::fixTexturePath(std::string &path)
|
|
{
|
|
int offset = path.rfind(".");
|
|
if (offset < 0)
|
|
return;
|
|
path.replace(offset, path.length() - offset, ".dds");
|
|
}
|
|
|
|
/* MWSkill */
|
|
|
|
MWSkill::MWSkill()
|
|
: manager(nullptr)
|
|
, skillId(ESM::Skill::Length)
|
|
, skillNameWidget(nullptr)
|
|
, skillValueWidget(nullptr)
|
|
{
|
|
}
|
|
|
|
void MWSkill::setSkillId(ESM::Skill::SkillEnum skill)
|
|
{
|
|
skillId = skill;
|
|
updateWidgets();
|
|
}
|
|
|
|
void MWSkill::setSkillNumber(int skill)
|
|
{
|
|
if (skill < 0)
|
|
setSkillId(ESM::Skill::Length);
|
|
else if (skill < ESM::Skill::Length)
|
|
setSkillId(static_cast<ESM::Skill::SkillEnum>(skill));
|
|
else
|
|
throw new std::runtime_error("Skill number out of range");
|
|
}
|
|
|
|
void MWSkill::setSkillValue(const SkillValue& value_)
|
|
{
|
|
value = value_;
|
|
updateWidgets();
|
|
}
|
|
|
|
void MWSkill::updateWidgets()
|
|
{
|
|
if (skillNameWidget && manager)
|
|
{
|
|
if (skillId == ESM::Skill::Length)
|
|
{
|
|
static_cast<MyGUI::TextBox*>(skillNameWidget)->setCaption("");
|
|
}
|
|
else
|
|
{
|
|
const std::string &name = manager->getGameSettingString(ESM::Skill::sSkillNameIds[skillId], "");
|
|
static_cast<MyGUI::TextBox*>(skillNameWidget)->setCaption(name);
|
|
}
|
|
}
|
|
if (skillValueWidget)
|
|
{
|
|
SkillValue::Type modified = value.getModified(), base = value.getBase();
|
|
static_cast<MyGUI::TextBox*>(skillValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
|
|
if (modified > base)
|
|
skillValueWidget->_setWidgetState("increased");
|
|
else if (modified < base)
|
|
skillValueWidget->_setWidgetState("decreased");
|
|
else
|
|
skillValueWidget->_setWidgetState("normal");
|
|
}
|
|
}
|
|
|
|
void MWSkill::onClicked(MyGUI::Widget* _sender)
|
|
{
|
|
eventClicked(this);
|
|
}
|
|
|
|
MWSkill::~MWSkill()
|
|
{
|
|
}
|
|
|
|
void MWSkill::initialiseOverride()
|
|
{
|
|
Base::initialiseOverride();
|
|
|
|
assignWidget(skillNameWidget, "StatName");
|
|
assignWidget(skillValueWidget, "StatValue");
|
|
|
|
MyGUI::ButtonPtr button;
|
|
assignWidget(button, "StatNameButton");
|
|
if (button)
|
|
{
|
|
skillNameWidget = button;
|
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked);
|
|
}
|
|
|
|
button = 0;
|
|
assignWidget(button, "StatValueButton");
|
|
if (button)
|
|
{
|
|
skillNameWidget = button;
|
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWSkill::onClicked);
|
|
}
|
|
}
|
|
|
|
/* MWAttribute */
|
|
|
|
MWAttribute::MWAttribute()
|
|
: manager(nullptr)
|
|
, id(-1)
|
|
, attributeNameWidget(nullptr)
|
|
, attributeValueWidget(nullptr)
|
|
{
|
|
}
|
|
|
|
void MWAttribute::setAttributeId(int attributeId)
|
|
{
|
|
id = attributeId;
|
|
updateWidgets();
|
|
}
|
|
|
|
void MWAttribute::setAttributeValue(const AttributeValue& value_)
|
|
{
|
|
value = value_;
|
|
updateWidgets();
|
|
}
|
|
|
|
void MWAttribute::onClicked(MyGUI::Widget* _sender)
|
|
{
|
|
eventClicked(this);
|
|
}
|
|
|
|
void MWAttribute::updateWidgets()
|
|
{
|
|
if (attributeNameWidget && manager)
|
|
{
|
|
if (id < 0 || id >= 8)
|
|
{
|
|
static_cast<MyGUI::TextBox*>(attributeNameWidget)->setCaption("");
|
|
}
|
|
else
|
|
{
|
|
static const char *attributes[8] = {
|
|
"sAttributeStrength",
|
|
"sAttributeIntelligence",
|
|
"sAttributeWillpower",
|
|
"sAttributeAgility",
|
|
"sAttributeSpeed",
|
|
"sAttributeEndurance",
|
|
"sAttributePersonality",
|
|
"sAttributeLuck"
|
|
};
|
|
const std::string &name = manager->getGameSettingString(attributes[id], "");
|
|
static_cast<MyGUI::TextBox*>(attributeNameWidget)->setCaption(name);
|
|
}
|
|
}
|
|
if (attributeValueWidget)
|
|
{
|
|
AttributeValue::Type modified = value.getModified(), base = value.getBase();
|
|
static_cast<MyGUI::TextBox*>(attributeValueWidget)->setCaption(boost::lexical_cast<std::string>(modified));
|
|
if (modified > base)
|
|
attributeValueWidget->_setWidgetState("increased");
|
|
else if (modified < base)
|
|
attributeValueWidget->_setWidgetState("decreased");
|
|
else
|
|
attributeValueWidget->_setWidgetState("normal");
|
|
}
|
|
}
|
|
|
|
MWAttribute::~MWAttribute()
|
|
{
|
|
}
|
|
|
|
void MWAttribute::initialiseOverride()
|
|
{
|
|
Base::initialiseOverride();
|
|
|
|
assignWidget(attributeNameWidget, "StatName");
|
|
assignWidget(attributeValueWidget, "StatValue");
|
|
|
|
MyGUI::ButtonPtr button;
|
|
assignWidget(button, "StatNameButton");
|
|
if (button)
|
|
{
|
|
attributeNameWidget = button;
|
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked);
|
|
}
|
|
|
|
button = 0;
|
|
assignWidget(button, "StatValueButton");
|
|
if (button)
|
|
{
|
|
attributeValueWidget = button;
|
|
button->eventMouseButtonClick += MyGUI::newDelegate(this, &MWAttribute::onClicked);
|
|
}
|
|
}
|
|
|
|
/* MWSpell */
|
|
|
|
MWSpell::MWSpell()
|
|
: mWindowManager(nullptr)
|
|
, spellNameWidget(nullptr)
|
|
{
|
|
}
|
|
|
|
void MWSpell::setSpellId(const std::string &spellId)
|
|
{
|
|
id = spellId;
|
|
updateWidgets();
|
|
}
|
|
|
|
void MWSpell::createEffectWidgets(std::vector<MyGUI::WidgetPtr> &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord)
|
|
{
|
|
const ESMS::ESMStore &store = mWindowManager->getStore();
|
|
const ESM::Spell *spell = store.spells.search(id);
|
|
MYGUI_ASSERT(spell, "spell with id '" << id << "' not found");
|
|
|
|
MWSpellEffectPtr effect = nullptr;
|
|
std::vector<ESM::ENAMstruct>::const_iterator end = spell->effects.list.end();
|
|
for (std::vector<ESM::ENAMstruct>::const_iterator it = spell->effects.list.begin(); it != end; ++it)
|
|
{
|
|
effect = creator->createWidget<MWSpellEffect>("MW_EffectImage", coord, MyGUI::Align::Default);
|
|
effect->setWindowManager(mWindowManager);
|
|
effect->setSpellEffect(*it);
|
|
effects.push_back(effect);
|
|
coord.top += effect->getHeight();
|
|
}
|
|
}
|
|
|
|
void MWSpell::updateWidgets()
|
|
{
|
|
if (spellNameWidget && mWindowManager)
|
|
{
|
|
const ESMS::ESMStore &store = mWindowManager->getStore();
|
|
const ESM::Spell *spell = store.spells.search(id);
|
|
if (spell)
|
|
static_cast<MyGUI::TextBox*>(spellNameWidget)->setCaption(spell->name);
|
|
else
|
|
static_cast<MyGUI::TextBox*>(spellNameWidget)->setCaption("");
|
|
}
|
|
}
|
|
|
|
void MWSpell::initialiseOverride()
|
|
{
|
|
Base::initialiseOverride();
|
|
|
|
assignWidget(spellNameWidget, "StatName");
|
|
}
|
|
|
|
MWSpell::~MWSpell()
|
|
{
|
|
}
|
|
|
|
/* MWSpellEffect */
|
|
|
|
MWSpellEffect::MWSpellEffect()
|
|
: mWindowManager(nullptr)
|
|
, imageWidget(nullptr)
|
|
, textWidget(nullptr)
|
|
{
|
|
}
|
|
|
|
void MWSpellEffect::setSpellEffect(SpellEffectValue value)
|
|
{
|
|
effect = value;
|
|
updateWidgets();
|
|
}
|
|
|
|
void MWSpellEffect::updateWidgets()
|
|
{
|
|
if (!mWindowManager)
|
|
return;
|
|
|
|
const ESMS::ESMStore &store = mWindowManager->getStore();
|
|
const ESM::MagicEffect *magicEffect = store.magicEffects.search(effect.effectID);
|
|
if (textWidget)
|
|
{
|
|
if (magicEffect)
|
|
{
|
|
// TODO: Get name of effect from GMST
|
|
std::string spellLine = "";
|
|
if (effect.skill >= 0 && effect.skill < ESM::Skill::Length)
|
|
{
|
|
spellLine += " " + mWindowManager->getGameSettingString(ESM::Skill::sSkillNameIds[effect.skill], "");
|
|
}
|
|
if (effect.attribute >= 0 && effect.attribute < 8)
|
|
{
|
|
static const char *attributes[8] = {
|
|
"sAttributeStrength",
|
|
"sAttributeIntelligence",
|
|
"sAttributeWillpower",
|
|
"sAttributeAgility",
|
|
"sAttributeSpeed",
|
|
"sAttributeEndurance",
|
|
"sAttributePersonality",
|
|
"sAttributeLuck"
|
|
};
|
|
spellLine += " " + mWindowManager->getGameSettingString(attributes[effect.attribute], "");
|
|
}
|
|
if (effect.magnMin >= 0 || effect.magnMax >= 0)
|
|
{
|
|
if (effect.magnMin == effect.magnMax)
|
|
spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " pts";
|
|
else
|
|
{
|
|
spellLine += " " + boost::lexical_cast<std::string>(effect.magnMin) + " to " + boost::lexical_cast<std::string>(effect.magnMin) + " pts";
|
|
}
|
|
}
|
|
if (effect.duration >= 0)
|
|
{
|
|
spellLine += " for " + boost::lexical_cast<std::string>(effect.duration) + " secs";
|
|
}
|
|
if (effect.range == ESM::RT_Self)
|
|
spellLine += " on Self";
|
|
else if (effect.range == ESM::RT_Touch)
|
|
spellLine += " on Touch";
|
|
else if (effect.range == ESM::RT_Target)
|
|
spellLine += " on Target";
|
|
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(spellLine);
|
|
}
|
|
else
|
|
static_cast<MyGUI::TextBox*>(textWidget)->setCaption("");
|
|
}
|
|
if (imageWidget)
|
|
{
|
|
std::string path = std::string("icons\\") + magicEffect->icon;
|
|
fixTexturePath(path);
|
|
imageWidget->setImageTexture(path);
|
|
}
|
|
}
|
|
|
|
MWSpellEffect::~MWSpellEffect()
|
|
{
|
|
}
|
|
|
|
void MWSpellEffect::initialiseOverride()
|
|
{
|
|
Base::initialiseOverride();
|
|
|
|
assignWidget(textWidget, "Text");
|
|
assignWidget(imageWidget, "Image");
|
|
}
|
|
|
|
/* MWDynamicStat */
|
|
|
|
MWDynamicStat::MWDynamicStat()
|
|
: value(0)
|
|
, max(1)
|
|
, textWidget(nullptr)
|
|
, barWidget(nullptr)
|
|
, barTextWidget(nullptr)
|
|
{
|
|
}
|
|
|
|
void MWDynamicStat::setValue(int cur, int max_)
|
|
{
|
|
value = cur;
|
|
max = max_;
|
|
|
|
if (barWidget)
|
|
{
|
|
barWidget->setProgressRange(max);
|
|
barWidget->setProgressPosition(value);
|
|
}
|
|
|
|
|
|
if (barTextWidget)
|
|
{
|
|
if (value >= 0 && max > 0)
|
|
{
|
|
std::stringstream out;
|
|
out << value << "/" << max;
|
|
static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption(out.str().c_str());
|
|
}
|
|
else
|
|
static_cast<MyGUI::TextBox*>(barTextWidget)->setCaption("");
|
|
}
|
|
}
|
|
void MWDynamicStat::setTitle(const std::string text)
|
|
{
|
|
if (textWidget)
|
|
static_cast<MyGUI::TextBox*>(textWidget)->setCaption(text);
|
|
}
|
|
|
|
MWDynamicStat::~MWDynamicStat()
|
|
{
|
|
}
|
|
|
|
void MWDynamicStat::initialiseOverride()
|
|
{
|
|
Base::initialiseOverride();
|
|
|
|
assignWidget(textWidget, "Text");
|
|
assignWidget(barWidget, "Bar");
|
|
assignWidget(barTextWidget, "BarText");
|
|
}
|