Removed hardcoded values from review dialog and added functionality for setting all fields in the dialog. Window manager keeps track of player values set from the outside and passes these to the review dialog.

actorid
Jan Borsodi 14 years ago
parent 1c1d33e723
commit 970a7a3498

@ -11,9 +11,12 @@
using namespace MWGui;
using namespace Widgets;
const int ReviewDialog::lineHeight = 18;
ReviewDialog::ReviewDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize)
: Layout("openmw_chargen_review_layout.xml")
, environment(environment)
, lastPos(0)
{
// Centre dialog
MyGUI::IntCoord coord = mMainWidget->getCoord();
@ -24,30 +27,24 @@ ReviewDialog::ReviewDialog(MWWorld::Environment& environment, MyGUI::IntSize gam
WindowManager *wm = environment.mWindowManager;
// Setup static stats
StaticTextPtr name, race, klass, sign;
ButtonPtr button;
getWidget(name, "NameText");
name->setCaption("Drizt");
getWidget(nameWidget, "NameText");
getWidget(button, "NameButton");
button->setCaption(wm->getGameSettingString("sName", ""));
getWidget(race, "RaceText");
race->setCaption("Dark Elf");
getWidget(raceWidget, "RaceText");
getWidget(button, "RaceButton");
button->setCaption(wm->getGameSettingString("sRace", ""));
getWidget(klass, "ClassText");
klass->setCaption("Adventurer");
getWidget(classWidget, "ClassText");
getWidget(button, "ClassButton");
button->setCaption(wm->getGameSettingString("sClass", ""));
getWidget(sign, "SignText");
sign->setCaption("The Angel");
getWidget(birthSignWidget, "SignText");
getWidget(button, "SignButton");
button->setCaption(wm->getGameSettingString("sBirthSign", ""));
// Setup dynamic stats
MWDynamicStatPtr health, magicka, fatigue;
getWidget(health, "Health");
health->setTitle(wm->getGameSettingString("sHealth", ""));
health->setValue(45, 45);
@ -61,15 +58,33 @@ ReviewDialog::ReviewDialog(MWWorld::Environment& environment, MyGUI::IntSize gam
fatigue->setValue(160, 160);
// Setup attributes
MWAttributePtr attribute;
for (int idx = 0; idx < ESM::Attribute::Length; ++idx)
{
getWidget(attribute, std::string("Attribute") + boost::lexical_cast<std::string>(idx));
attributeWidgets.insert(std::make_pair(static_cast<int>(ESM::Attribute::attributeIds[idx]), attribute));
attribute->setWindowManager(wm);
attribute->setAttributeId(ESM::Attribute::attributeIds[idx]);
attribute->setAttributeValue(MWAttribute::AttributeValue(40, 50));
attribute->setAttributeValue(MWAttribute::AttributeValue(0, 0));
}
// Setup skills
getWidget(skillAreaWidget, "Skills");
getWidget(skillClientWidget, "SkillClient");
getWidget(skillScrollerWidget, "SkillScroller");
skillScrollerWidget->eventScrollChangePosition = MyGUI::newDelegate(this, &ReviewDialog::onScrollChangePosition);
updateScroller();
for (int i = 0; i < ESM::Skill::Length; ++i)
{
skillValues.insert(std::pair<int, MWMechanics::Stat<float> >(i, MWMechanics::Stat<float>()));
skillWidgetMap.insert(std::pair<int, MyGUI::WidgetPtr>(i, nullptr));
}
static_cast<MyGUI::WindowPtr>(mMainWidget)->eventWindowChangeCoord = MyGUI::newDelegate(this, &ReviewDialog::onWindowResize);
// TODO: These buttons should be managed by a Dialog class
MyGUI::ButtonPtr backButton;
getWidget(backButton, "BackButton");
@ -80,6 +95,246 @@ ReviewDialog::ReviewDialog(MWWorld::Environment& environment, MyGUI::IntSize gam
okButton->eventMouseButtonClick = MyGUI::newDelegate(this, &ReviewDialog::onOkClicked);
}
void ReviewDialog::onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos)
{
int diff = lastPos - pos;
// Adjust position of all widget according to difference
if (diff == 0)
return;
lastPos = pos;
std::vector<MyGUI::WidgetPtr>::const_iterator end = skillWidgets.end();
for (std::vector<MyGUI::WidgetPtr>::const_iterator it = skillWidgets.begin(); it != end; ++it)
{
(*it)->setCoord((*it)->getCoord() + MyGUI::IntPoint(0, diff));
}
}
void ReviewDialog::onWindowResize(MyGUI::WidgetPtr window)
{
updateScroller();
}
void ReviewDialog::setPlayerName(const std::string &name)
{
nameWidget->setCaption(name);
}
void ReviewDialog::setRace(const std::string &raceId_)
{
raceId = raceId_;
const ESM::Race *race = environment.mWorld->getStore().races.search(raceId);
if (race)
raceWidget->setCaption(race->name);
}
void ReviewDialog::setClass(const ESM::Class& class_)
{
klass = class_;
classWidget->setCaption(klass.name);
}
void ReviewDialog::setBirthSign(const std::string& signId)
{
birthSignId = signId;
const ESM::BirthSign *sign = environment.mWorld->getStore().birthSigns.search(birthSignId);
if (sign)
birthSignWidget->setCaption(sign->name);
}
void ReviewDialog::setHealth(const MWMechanics::DynamicStat<int>& value)
{
health->setValue(value.getCurrent(), value.getModified());
}
void ReviewDialog::setMagicka(const MWMechanics::DynamicStat<int>& value)
{
magicka->setValue(value.getCurrent(), value.getModified());
}
void ReviewDialog::setFatigue(const MWMechanics::DynamicStat<int>& value)
{
fatigue->setValue(value.getCurrent(), value.getModified());
}
void ReviewDialog::setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value)
{
std::map<int, MWAttributePtr>::iterator attr = attributeWidgets.find(static_cast<int>(attributeId));
if (attr == attributeWidgets.end())
return;
attr->second->setAttributeValue(value);
}
void ReviewDialog::setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value)
{
skillValues[skillId] = value;
MyGUI::WidgetPtr widget = skillWidgetMap[skillId];
if (widget)
{
float modified = value.getModified(), base = value.getBase();
std::string text = boost::lexical_cast<std::string>(std::floor(modified));
ColorStyle style = CS_Normal;
if (modified > base)
style = CS_Super;
else if (modified < base)
style = CS_Sub;
setStyledText(widget, style, text);
}
}
void ReviewDialog::configureSkills(const std::vector<int>& major, const std::vector<int>& minor)
{
majorSkills = major;
minorSkills = minor;
// Update misc skills with the remaining skills not in major or minor
std::set<int> skillSet;
std::copy(major.begin(), major.end(), std::inserter(skillSet, skillSet.begin()));
std::copy(minor.begin(), minor.end(), std::inserter(skillSet, skillSet.begin()));
boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator end = ESM::Skill::skillIds.end();
miscSkills.clear();
for (boost::array<ESM::Skill::SkillEnum, ESM::Skill::Length>::const_iterator it = ESM::Skill::skillIds.begin(); it != end; ++it)
{
int skill = *it;
if (skillSet.find(skill) == skillSet.end())
miscSkills.push_back(skill);
}
}
void ReviewDialog::setStyledText(MyGUI::WidgetPtr widget, ColorStyle style, const std::string &value)
{
widget->setCaption(value);
if (style == CS_Super)
widget->setTextColour(MyGUI::Colour(0, 1, 0));
else if (style == CS_Sub)
widget->setTextColour(MyGUI::Colour(1, 0, 0));
else
widget->setTextColour(MyGUI::Colour(1, 1, 1));
}
void ReviewDialog::addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticImagePtr separator = skillClientWidget->createWidget<MyGUI::StaticImage>("MW_HLine", MyGUI::IntCoord(10, coord1.top, coord1.width + coord2.width - 4, 18), MyGUI::Align::Default);
skillWidgets.push_back(separator);
coord1.top += separator->getHeight();
coord2.top += separator->getHeight();
}
void ReviewDialog::addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr groupWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandBrightText", MyGUI::IntCoord(0, coord1.top, coord1.width + coord2.width, coord1.height), MyGUI::Align::Default);
groupWidget->setCaption(label);
skillWidgets.push_back(groupWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
}
MyGUI::WidgetPtr ReviewDialog::addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr skillNameWidget, skillValueWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandText", coord1, MyGUI::Align::Default);
skillNameWidget->setCaption(text);
skillValueWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandTextRight", coord2, MyGUI::Align::Default);
setStyledText(skillValueWidget, style, value);
skillWidgets.push_back(skillNameWidget);
skillWidgets.push_back(skillValueWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
return skillValueWidget;
}
void ReviewDialog::addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
MyGUI::StaticTextPtr skillNameWidget;
skillNameWidget = skillClientWidget->createWidget<MyGUI::StaticText>("SandText", coord1 + MyGUI::IntSize(coord2.width, 0), MyGUI::Align::Default);
skillNameWidget->setCaption(text);
skillWidgets.push_back(skillNameWidget);
coord1.top += lineHeight;
coord2.top += lineHeight;
}
void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2)
{
WindowManager *wm = environment.mWindowManager;
MWMechanics::MechanicsManager *mm = environment.mMechanicsManager;
ESMS::ESMStore &store = environment.mWorld->getStore();
// Add a line separator if there are items above
if (!skillWidgets.empty())
{
addSeparator(coord1, coord2);
}
addGroup(wm->getGameSettingString(titleId, titleDefault), coord1, coord2);
SkillList::const_iterator end = skills.end();
for (SkillList::const_iterator it = skills.begin(); it != end; ++it)
{
int skillId = *it;
if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes
continue;
assert(skillId >= 0 && skillId < ESM::Skill::Length);
const std::string &skillNameId = ESMS::Skill::sSkillNameIds[skillId];
const MWMechanics::Stat<float> &stat = skillValues.find(skillId)->second;
float base = stat.getBase();
float modified = stat.getModified();
ColorStyle style = CS_Normal;
if (modified > base)
style = CS_Super;
else if (modified < base)
style = CS_Sub;
MyGUI::WidgetPtr widget = addValueItem(wm->getGameSettingString(skillNameId, skillNameId), boost::lexical_cast<std::string>(static_cast<int>(modified)), style, coord1, coord2);
skillWidgetMap[skillId] = widget;
}
}
void ReviewDialog::updateSkillArea()
{
for (std::vector<MyGUI::WidgetPtr>::iterator it = skillWidgets.begin(); it != skillWidgets.end(); ++it)
{
MyGUI::Gui::getInstance().destroyWidget(*it);
}
skillWidgets.clear();
const int valueSize = 40;
MyGUI::IntCoord coord1(10, 0, skillClientWidget->getWidth() - (10 + valueSize), 18);
MyGUI::IntCoord coord2(coord1.left + coord1.width, coord1.top, valueSize, coord1.height);
if (!majorSkills.empty())
addSkills(majorSkills, "sSkillClassMajor", "Major Skills", coord1, coord2);
if (!minorSkills.empty())
addSkills(minorSkills, "sSkillClassMinor", "Minor Skills", coord1, coord2);
if (!miscSkills.empty())
addSkills(miscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2);
WindowManager *wm = environment.mWindowManager;
ESMS::ESMStore &store = environment.mWorld->getStore();
clientHeight = coord1.top;
updateScroller();
}
void ReviewDialog::updateScroller()
{
skillScrollerWidget->setScrollRange(std::max(clientHeight - skillClientWidget->getHeight(), 0));
skillScrollerWidget->setScrollPage(std::max(skillClientWidget->getHeight() - lineHeight, 0));
}
// widget controls
void ReviewDialog::onOkClicked(MyGUI::Widget* _sender)

@ -1,7 +1,10 @@
#ifndef MWGUI_REVIEW_H
#define MWGUI_REVIEW_H
#include <components/esm_store/store.hpp>
#include <openengine/gui/layout.hpp>
#include "../mwmechanics/stat.hpp"
#include "widgets.hpp"
namespace MWWorld
{
@ -20,8 +23,26 @@ namespace MWGui
class ReviewDialog : public OEngine::GUI::Layout
{
public:
typedef std::vector<int> SkillList;
ReviewDialog(MWWorld::Environment& environment, MyGUI::IntSize gameWindowSize);
void setPlayerName(const std::string &name);
void setRace(const std::string &raceId);
void setClass(const ESM::Class& class_);
void setBirthSign (const std::string &signId);
void setHealth(const MWMechanics::DynamicStat<int>& value);
void setMagicka(const MWMechanics::DynamicStat<int>& value);
void setFatigue(const MWMechanics::DynamicStat<int>& value);
void setAttribute(ESM::Attribute::AttributeID attributeId, const MWMechanics::Stat<int>& value);
void configureSkills(const SkillList& major, const SkillList& minor);
void setSkillValue(ESM::Skill::SkillEnum skillId, const MWMechanics::Stat<float>& value);
void updateSkillArea();
// Events
typedef delegates::CDelegate0 EventHandle_Void;
@ -40,7 +61,41 @@ namespace MWGui
void onBackClicked(MyGUI::Widget* _sender);
private:
enum ColorStyle
{
CS_Sub,
CS_Normal,
CS_Super
};
void setStyledText(MyGUI::WidgetPtr widget, ColorStyle style, const std::string &value);
void addSkills(const SkillList &skills, const std::string &titleId, const std::string &titleDefault, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addSeparator(MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addGroup(const std::string &label, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
MyGUI::WidgetPtr addValueItem(const std::string text, const std::string &value, ColorStyle style, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void addItem(const std::string text, MyGUI::IntCoord &coord1, MyGUI::IntCoord &coord2);
void updateScroller();
void onScrollChangePosition(MyGUI::VScrollPtr scroller, size_t pos);
void onWindowResize(MyGUI::WidgetPtr window);
static const int lineHeight;
MWWorld::Environment& environment;
MyGUI::StaticTextPtr nameWidget, raceWidget, classWidget, birthSignWidget;
MyGUI::WidgetPtr skillAreaWidget, skillClientWidget;
MyGUI::VScrollPtr skillScrollerWidget;
int lastPos, clientHeight;
Widgets::MWDynamicStatPtr health, magicka, fatigue;
std::map<int, Widgets::MWAttributePtr> attributeWidgets;
SkillList majorSkills, minorSkills, miscSkills;
std::map<int, MWMechanics::Stat<float> > skillValues;
std::map<int, MyGUI::WidgetPtr> skillWidgetMap;
std::string name, raceId, birthSignId;
ESM::Class klass;
std::vector<MyGUI::WidgetPtr> skillWidgets; //< Skills and other information
};
}
#endif

@ -56,6 +56,17 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment
// The HUD is always on
hud->setVisible(true);
// Setup player stats
for (int i = 0; i < ESM::Attribute::Length; ++i)
{
playerAttributes.insert(std::make_pair(ESM::Attribute::attributeIds[i], MWMechanics::Stat<int>()));
}
for (int i = 0; i < ESM::Skill::Length; ++i)
{
playerSkillValues.insert(std::make_pair(ESM::Skill::skillIds[i], MWMechanics::Stat<float>()));
}
// Set up visibility
updateVisible();
}
@ -193,6 +204,33 @@ void WindowManager::updateVisible()
reviewNext = false;
if (!reviewDialog)
reviewDialog = new ReviewDialog(environment, gui->getViewSize());
reviewDialog->setPlayerName(playerName);
reviewDialog->setRace(playerRaceId);
reviewDialog->setClass(playerClass);
reviewDialog->setBirthSign(playerBirthSignId);
reviewDialog->setHealth(playerHealth);
reviewDialog->setMagicka(playerMagicka);
reviewDialog->setFatigue(playerFatigue);
{
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator end = playerAttributes.end();
for (std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> >::iterator it = playerAttributes.begin(); it != end; ++it)
{
reviewDialog->setAttribute(it->first, it->second);
}
}
{
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator end = playerSkillValues.end();
for (std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> >::iterator it = playerSkillValues.begin(); it != end; ++it)
{
reviewDialog->setSkillValue(it->first, it->second);
}
reviewDialog->configureSkills(playerMajorSkills, playerMinorSkills);
}
reviewDialog->eventDone = MyGUI::newDelegate(this, &WindowManager::onReviewDialogDone);
reviewDialog->eventBack = MyGUI::newDelegate(this, &WindowManager::onReviewDialogBack);
reviewDialog->setVisible(true);
@ -225,22 +263,96 @@ void WindowManager::updateVisible()
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<int>& value)
{
stats->setValue (id, value);
static const char *ids[] =
{
"AttribVal1", "AttribVal2", "AttribVal3", "AttribVal4", "AttribVal5",
"AttribVal6", "AttribVal7", "AttribVal8"
};
static ESM::Attribute::AttributeID attributes[] =
{
ESM::Attribute::Strength,
ESM::Attribute::Intelligence,
ESM::Attribute::Willpower,
ESM::Attribute::Agility,
ESM::Attribute::Speed,
ESM::Attribute::Endurance,
ESM::Attribute::Personality,
ESM::Attribute::Luck
};
for (int i = 0; i < sizeof(ids)/sizeof(ids[0]); ++i)
{
if (id != ids[i])
continue;
playerAttributes[attributes[i]] = value;
break;
}
}
void WindowManager::setValue (const std::string& id, const MWMechanics::Stat<float>& value)
{
stats->setValue (id, value);
static struct {const char *id; ESM::Skill::SkillEnum skillId; } skillMap[] =
{
{"SkillBlock", ESM::Skill::Block},
{"SkillArmorer", ESM::Skill::Armorer},
{"SkillMediumArmor", ESM::Skill::MediumArmor},
{"SkillHeavyArmor", ESM::Skill::HeavyArmor},
{"SkillBluntWeapon", ESM::Skill::BluntWeapon},
{"SkillLongBlade", ESM::Skill::LongBlade},
{"SkillAxe", ESM::Skill::Axe},
{"SkillSpear", ESM::Skill::Spear},
{"SkillAthletics", ESM::Skill::Athletics},
{"SkillEnchant", ESM::Skill::Armorer},
{"SkillDestruction", ESM::Skill::Destruction},
{"SkillAlteration", ESM::Skill::Alteration},
{"SkillIllusion", ESM::Skill::Illusion},
{"SkillConjuration", ESM::Skill::Conjuration},
{"SkillMysticism", ESM::Skill::Mysticism},
{"SkillRestoration", ESM::Skill::Restoration},
{"SkillAlchemy", ESM::Skill::Alchemy},
{"SkillUnarmored", ESM::Skill::Unarmored},
{"SkillSecurity", ESM::Skill::Security},
{"SkillSneak", ESM::Skill::Sneak},
{"SkillAcrobatics", ESM::Skill::Acrobatics},
{"SkillLightArmor", ESM::Skill::LightArmor},
{"SkillShortBlade", ESM::Skill::ShortBlade},
{"SkillMarksman", ESM::Skill::Marksman},
{"SkillMercantile", ESM::Skill::Mercantile},
{"SkillSpeechcraft", ESM::Skill::Speechcraft},
{"SkillHandToHand", ESM::Skill::HandToHand},
};
for (int i = 0; i < sizeof(skillMap)/sizeof(skillMap[0]); ++i)
{
if (skillMap[i].id == id)
{
ESM::Skill::SkillEnum skillId = skillMap[i].skillId;
playerSkillValues[skillId] = value;
break;
}
}
}
void WindowManager::setValue (const std::string& id, const MWMechanics::DynamicStat<int>& value)
{
stats->setValue (id, value);
hud->setValue (id, value);
if (id == "HBar")
playerHealth = value;
else if (id == "MBar")
playerMagicka = value;
else if (id == "FBar")
playerFatigue = value;
}
void WindowManager::setValue (const std::string& id, const std::string& value)
{
stats->setValue (id, value);
if (id=="name")
playerName = value;
else if (id=="race")
playerRaceId = value;
}
void WindowManager::setValue (const std::string& id, int value)
@ -248,9 +360,17 @@ void WindowManager::setValue (const std::string& id, int value)
stats->setValue (id, value);
}
void WindowManager::setPlayerClass (const ESM::Class &class_)
{
playerClass = class_;
stats->setValue("class", playerClass.name);
}
void WindowManager::configureSkills (const SkillList& major, const SkillList& minor)
{
stats->configureSkills (major, minor);
playerMajorSkills = major;
playerMinorSkills = minor;
}
void WindowManager::setFactions (const FactionList& factions)

@ -14,6 +14,7 @@
#include <vector>
#include <set>
#include <components/esm_store/store.hpp>
#include "../mwmechanics/stat.hpp"
#include "mode.hpp"
@ -54,6 +55,12 @@ namespace MWGui
class WindowManager
{
public:
typedef std::pair<std::string, int> Faction;
typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList;
private:
MWWorld::Environment& environment;
HUD *hud;
MapWindow *map;
@ -87,6 +94,16 @@ namespace MWGui
unsigned generateClassStep;
std::string generateClass;
// Various stats about player as needed by window manager
std::string playerName;
ESM::Class playerClass;
std::string playerRaceId, playerBirthSignId;
std::map<ESM::Attribute::AttributeID, MWMechanics::Stat<int> > playerAttributes;
SkillList playerMajorSkills, playerMinorSkills;
std::map<ESM::Skill::SkillEnum, MWMechanics::Stat<float> > playerSkillValues;
MWMechanics::DynamicStat<int> playerHealth, playerMagicka, playerFatigue;
// Gui
MyGUI::Gui *gui;
// Current gui mode
@ -145,10 +162,6 @@ namespace MWGui
MyGUI::Gui* getGui() const { return gui; }
typedef std::pair<std::string, int> Faction;
typedef std::vector<Faction> FactionList;
typedef std::vector<int> SkillList;
void setValue (const std::string& id, const MWMechanics::Stat<int>& value);
///< Set value for the given ID.
@ -164,6 +177,9 @@ namespace MWGui
void setValue (const std::string& id, int value);
///< set value for the given ID.
void setPlayerClass (const ESM::Class &class_);
///< set current class of player
void configureSkills (const SkillList& major, const SkillList& minor);
///< configure skill groups, each set contains the skill ID for that group.

Loading…
Cancel
Save