From 8f6d24bea42b92fbd57b6934520a390c23a4f869 Mon Sep 17 00:00:00 2001 From: Jan Borsodi Date: Tue, 14 Sep 2010 14:16:26 +0200 Subject: [PATCH] Race dialog now gets the list of races and skills from the ESM store. --- apps/openmw/mwgui/mw_chargen.cpp | 105 ++++++++++++++++++--------- apps/openmw/mwgui/mw_chargen.hpp | 13 +++- apps/openmw/mwgui/window_manager.cpp | 2 +- 3 files changed, 83 insertions(+), 37 deletions(-) diff --git a/apps/openmw/mwgui/mw_chargen.cpp b/apps/openmw/mwgui/mw_chargen.cpp index c7cdc6d17..fb9627aa0 100644 --- a/apps/openmw/mwgui/mw_chargen.cpp +++ b/apps/openmw/mwgui/mw_chargen.cpp @@ -1,13 +1,20 @@ #include "mw_chargen.hpp" +#include "../mwworld/environment.hpp" +#include "../mwworld/world.hpp" +#include "components/esm_store/store.hpp" #include #include #include +#include +#include + using namespace MWGui; -RaceDialog::RaceDialog() +RaceDialog::RaceDialog(MWWorld::Environment& environment) : Layout("openmw_chargen_race_layout.xml") + , environment(environment) , genderIndex(0) , faceIndex(0) , hairIndex(0) @@ -60,6 +67,24 @@ RaceDialog::RaceDialog() updateSpellPowers(); } +void RaceDialog::setRace(const std::string &race) +{ + currentRace = race; + raceList->setIndexSelected(MyGUI::ITEM_NONE); + size_t count = raceList->getItemCount(); + for (size_t i = 0; i < count; ++i) + { + if (boost::iequals(raceList->getItem(i), race)) + { + raceList->setIndexSelected(i); + break; + } + } + + updateSkills(); + updateSpellPowers(); +} + int wrap(int index, int max) { if (index < 0) @@ -109,8 +134,12 @@ void RaceDialog::onSelectNextHair(MyGUI::Widget*) void RaceDialog::onSelectRace(MyGUI::List* _sender, size_t _index) { - // TODO: Select actual race - updateSkills(); + const std::string race = raceList->getItem(_index); + if (boost::iequals(currentRace, race)) + return; + + currentRace = race; + updateSkills(); updateSpellPowers(); } @@ -119,14 +148,20 @@ void RaceDialog::onSelectRace(MyGUI::List* _sender, size_t _index) void RaceDialog::updateRaces() { raceList->removeAllItems(); - raceList->addItem("Argonian"); - raceList->addItem("Breton"); - raceList->addItem("Dark Elf"); - raceList->addItem("High Elf"); - raceList->addItem("Imperial"); - raceList->addItem("Khajiit"); - raceList->addItem("Nord"); - raceList->addItem("Orc"); + + ESMS::ESMStore &store = environment.mWorld->getStore(); + + ESMS::RecListT::MapType::const_iterator it = store.races.list.begin(); + ESMS::RecListT::MapType::const_iterator end = store.races.list.end(); + int index = 0; + for (; it != end; ++it) + { + const ESM::Race &race = it->second; + raceList->addItem(race.name); + if (boost::iequals(race.name, currentRace)) + raceList->setIndexSelected(index); + ++index; + } } void RaceDialog::updateSkills() @@ -137,35 +172,35 @@ void RaceDialog::updateSkills() } skillItems.clear(); - MyGUI::StaticTextPtr skillName, skillBonus; + if (currentRace.empty()) + return; + + MyGUI::StaticTextPtr skillNameWidget, skillBonusWidget; const int lineHeight = 18; MyGUI::IntCoord coord1(0, 0, skillList->getWidth() - (40 + 4), 18); MyGUI::IntCoord coord2(coord1.left + coord1.width, 0, 40, 18); - const char *inputList[][2] = { - {"Athletics", "5"}, - {"Destruction", "10"}, - {"Light Armor", "5"}, - {"Long Blade", "5"}, - {"Marksman", "5"}, - {"Mysticism", "5"}, - {"Short Blade", "10"}, - {0,0} - }; - - for (int i = 0; inputList[i][0]; ++i) + ESMS::ESMStore &store = environment.mWorld->getStore(); + const ESM::Race *race = store.races.find(currentRace); + int count = sizeof(race->data.bonus)/sizeof(race->data.bonus[0]); // TODO: Find a portable macro for this ARRAYSIZE? + for (int i = 0; i < count; ++i) { - std::ostringstream name; - name << std::string("SkillName") << i; - skillName = skillList->createWidget("SandText", coord1, MyGUI::Align::Default, name.str()); - skillName->setCaption(inputList[i][0]); - std::ostringstream bonus; - bonus << std::string("SkillBonus") << i; - skillBonus = skillList->createWidget("SandTextRight", coord2, MyGUI::Align::Default, bonus.str()); - skillBonus->setCaption(inputList[i][1]); - - skillItems.push_back(skillName); - skillItems.push_back(skillBonus); + int skillId = race->data.bonus[i].skill; + if (skillId < 0 || skillId > ESM::Skill::Length) // Skip unknown skill indexes + continue; + + skillNameWidget = skillList->createWidget("SandText", coord1, MyGUI::Align::Default, + std::string("SkillName") + boost::lexical_cast(i)); + assert(skillId >= 0 && skillId < ESM::Skill::Length); + skillNameWidget->setCaption(ESMS::Skill::sSkillNames[skillId]); + + skillBonusWidget = skillList->createWidget("SandTextRight", coord2, MyGUI::Align::Default, + std::string("SkillBonus") + boost::lexical_cast(i)); + int bonus = race->data.bonus[i].bonus; + skillBonusWidget->setCaption(boost::lexical_cast(bonus)); + + skillItems.push_back(skillNameWidget); + skillItems.push_back(skillBonusWidget); coord1.top += lineHeight; coord2.top += lineHeight; diff --git a/apps/openmw/mwgui/mw_chargen.hpp b/apps/openmw/mwgui/mw_chargen.hpp index fa5f83aab..4ae1b51e9 100644 --- a/apps/openmw/mwgui/mw_chargen.hpp +++ b/apps/openmw/mwgui/mw_chargen.hpp @@ -7,6 +7,11 @@ #include +namespace MWWorld +{ + class Environment; +} + /* This file contains classes corresponding to all the dialogs for the character generation, layouts are defined in resources/mygui/ *.xml. @@ -27,7 +32,9 @@ namespace MWGui class RaceDialog : public OEngine::GUI::Layout { public: - RaceDialog(); + RaceDialog(MWWorld::Environment& environment); + + void setRace(const std::string &race); protected: void onHeadRotate(MyGUI::VScroll* _sender, size_t _position); @@ -48,6 +55,8 @@ namespace MWGui void updateSkills(); void updateSpellPowers(); + MWWorld::Environment& environment; + MyGUI::CanvasPtr appearanceBox; MyGUI::ListPtr raceList; MyGUI::HScrollPtr headRotate; @@ -60,6 +69,8 @@ namespace MWGui int genderIndex, faceIndex, hairIndex; int faceCount, hairCount; + + std::string currentRace; }; } #endif diff --git a/apps/openmw/mwgui/window_manager.cpp b/apps/openmw/mwgui/window_manager.cpp index 1642c66a5..ba4a549b9 100644 --- a/apps/openmw/mwgui/window_manager.cpp +++ b/apps/openmw/mwgui/window_manager.cpp @@ -26,7 +26,7 @@ WindowManager::WindowManager(MyGUI::Gui *_gui, MWWorld::Environment& environment inventory = new InventoryWindow (); console = new Console(w,h, environment, extensions); - raceDialog = new RaceDialog (); + raceDialog = new RaceDialog (environment); // The HUD is always on hud->setVisible(true);