diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 3a7cb0874..f28ff0184 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -296,6 +296,12 @@ namespace MWBase /// 1 - only waiting \n /// 2 - player is underwater \n /// 3 - enemies are nearby (not implemented) + + /// Update player record part with given value + virtual void updatePlayer(int flag, const std::string &value) = 0; + + /// Update player record part with given value + virtual void updatePlayer(int flag, bool value) = 0; }; } diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index cdfa43b3b..a054f34dd 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -559,12 +559,10 @@ void CharacterCreation::onCreateClassDialogDone(WindowBase* parWindow) klass.mData.mSkills[i][1] = majorSkills[i]; klass.mData.mSkills[i][0] = minorSkills[i]; } - std::pair res = - MWBase::Environment::get().getWorld()->createRecord(klass); - MWBase::Environment::get().getMechanicsManager()->setPlayerClass(*res.second); - mPlayerClass = *res.second; - mWM->setPlayerClass(*res.second); + MWBase::Environment::get().getMechanicsManager()->setPlayerClass(klass); + mPlayerClass = klass; + mWM->setPlayerClass(klass); mWM->removeDialog(mCreateClassDialog); mCreateClassDialog = 0; diff --git a/apps/openmw/mwgui/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 399ff74a3..d8f12bcbb 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -120,7 +120,7 @@ namespace MWGui setAttributeValues(); // set class image - const ESM::Class& playerClass = MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); + const ESM::Class& playerClass = *MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); // retrieve the ID to this class std::string classId; const MWWorld::Store &classes = diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 9d6842068..ae86cbf1a 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -253,7 +253,10 @@ void StatsWindow::onFrame () setFactions(PCstats.getFactionRanks()); - setBirthSign(MWBase::Environment::get().getWorld()->getPlayer().getBirthsign()); + const ESM::BirthSign *sign = + MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); + + setBirthSign((sign != 0) ? sign->mId : ""); if (mChanged) updateSkillArea(); @@ -430,7 +433,7 @@ void StatsWindow::updateSkillArea() // race tooltip const ESM::Race* playerRace = - store.get().find (MWBase::Environment::get().getWorld()->getPlayer().getRace()); + MWBase::Environment::get().getWorld()->getPlayer().getRace(); MyGUI::Widget* raceWidget; getWidget(raceWidget, "RaceText"); @@ -440,11 +443,14 @@ void StatsWindow::updateSkillArea() // class tooltip MyGUI::Widget* classWidget; - const ESM::Class& playerClass = MWBase::Environment::get().getWorld()->getPlayer().getClass(); + + const ESM::Class *playerClass = + MWBase::Environment::get().getWorld()->getPlayer().getClass(); + getWidget(classWidget, "ClassText"); - ToolTips::createClassToolTip(classWidget, playerClass); + ToolTips::createClassToolTip(classWidget, *playerClass); getWidget(classWidget, "Class_str"); - ToolTips::createClassToolTip(classWidget, playerClass); + ToolTips::createClassToolTip(classWidget, *playerClass); if (!mFactions.empty()) { diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 94418c522..7fc7635a4 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -42,9 +42,7 @@ namespace MWMechanics if (mRaceSelected) { const ESM::Race *race = - MWBase::Environment::get().getWorld()->getStore().get().find ( - MWBase::Environment::get().getWorld()->getPlayer().getRace() - ); + MWBase::Environment::get().getWorld()->getPlayer().getRace(); bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale(); @@ -89,12 +87,11 @@ namespace MWMechanics } // birthsign - if (!MWBase::Environment::get().getWorld()->getPlayer().getBirthsign().empty()) - { - const ESM::BirthSign *sign = - MWBase::Environment::get().getWorld()->getStore().get().find ( - MWBase::Environment::get().getWorld()->getPlayer().getBirthsign()); + const ESM::BirthSign *sign = + MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); + if (sign != 0) + { for (std::vector::const_iterator iter (sign->mPowers.mList.begin()); iter!=sign->mPowers.mList.end(); ++iter) { @@ -105,11 +102,12 @@ namespace MWMechanics // class if (mClassSelected) { - const ESM::Class& class_ = MWBase::Environment::get().getWorld()->getPlayer().getClass(); + const ESM::Class *class_ = + MWBase::Environment::get().getWorld()->getPlayer().getClass(); for (int i=0; i<2; ++i) { - int attribute = class_.mData.mAttribute[i]; + int attribute = class_->mData.mAttribute[i]; if (attribute>=0 && attribute<8) { creatureStats.getAttribute(attribute).setBase ( @@ -123,7 +121,7 @@ namespace MWMechanics for (int i2=0; i2<5; ++i2) { - int index = class_.mData.mSkills[i2][i]; + int index = class_->mData.mSkills[i2][i]; if (index>=0 && index<27) { @@ -139,7 +137,7 @@ namespace MWMechanics MWWorld::Store::iterator iter = skills.begin(); for (; iter != skills.end(); ++iter) { - if (iter->mData.mSpecialization==class_.mData.mSpecialization) + if (iter->mData.mSpecialization==class_->mData.mSpecialization) { int index = iter->mIndex; @@ -266,12 +264,12 @@ namespace MWMechanics MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); - MWBase::World *world = MWBase::Environment::get().getWorld(); - MWWorld::Player &player = world->getPlayer(); + MWWorld::Player &player = + MWBase::Environment::get().getWorld()->getPlayer(); winMgr->setValue ("name", player.getName()); - winMgr->setValue ("race", world->getStore().get().find (player.getRace())->mName); - winMgr->setValue ("class", player.getClass().mName); + winMgr->setValue ("race", player.getRace()->mName); + winMgr->setValue ("class", player.getClass()->mName); mUpdatePlayer = false; @@ -280,8 +278,8 @@ namespace MWMechanics for (int i=0; i<5; ++i) { - minorSkills[i] = player.getClass().mData.mSkills[i][0]; - majorSkills[i] = player.getClass().mData.mSkills[i][1]; + minorSkills[i] = player.getClass()->mData.mSkills[i][0]; + majorSkills[i] = player.getClass()->mData.mSkills[i][1]; } winMgr->configureSkills (majorSkills, minorSkills); @@ -319,22 +317,26 @@ namespace MWMechanics void MechanicsManager::setPlayerClass (const std::string& id) { - MWBase::Environment::get().getWorld()->getPlayer().setClass ( - *MWBase::Environment::get().getWorld()->getStore().get().find (id) - ); + MWBase::Environment::get().getWorld()->getPlayer().setClass(id); mClassSelected = true; buildPlayer(); mUpdatePlayer = true; } - void MechanicsManager::setPlayerClass (const ESM::Class& class_) + void MechanicsManager::setPlayerClass (const ESM::Class &cls) { - MWBase::Environment::get().getWorld()->getPlayer().setClass (class_); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + std::pair res = + world->createRecord(cls); + + world->getPlayer().setClass(res.second->mId); + mClassSelected = true; buildPlayer(); mUpdatePlayer = true; } - + int MechanicsManager::countDeaths (const std::string& id) const { return mActors.countDeaths (id); diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 5cf1fa379..48767a1a1 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -13,25 +13,22 @@ namespace MWWorld { - Player::Player (const ESM::NPC *player, const MWBase::World& world) : - mCellStore (0), mClass (0), - mAutoMove (false), mForwardBackward (0) + Player::Player (const ESM::NPC *player, const MWBase::World& world) + : mCellStore(0), + mClass(0), + mRace(0), + mSign(0), + mAutoMove(false), + mForwardBackward (0) { mPlayer.mBase = player; mPlayer.mRef.mRefID = "player"; - mName = player->mName; - mMale = !(player->mFlags & ESM::NPC::Female); - mRace = player->mRace; float* playerPos = mPlayer.mData.getPosition().pos; playerPos[0] = playerPos[1] = playerPos[2] = 0; mClass = world.getStore().get().find (player->mClass); - } - - Player::~Player() - { - delete mClass; + mRace = world.getStore().get().find(player->mRace); } void Player::setDrawState (MWMechanics::DrawState_ state) @@ -95,4 +92,35 @@ namespace MWWorld return MWWorld::Class::get(ptr).getNpcStats(ptr).getDrawState(); } + void Player::setName(const std::string &value) + { + MWBase::Environment::get().getWorld()->updatePlayer(Data_Name, value); + } + + void Player::setGender(bool value) + { + MWBase::Environment::get().getWorld()->updatePlayer(Data_Male, value); + } + + void Player::setRace(const std::string &value) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->updatePlayer(Data_Race, value); + + mRace = world->getStore().get().find(value); + } + + void Player::setBirthsign(const std::string &value) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + mSign = world->getStore().get().find(value); + } + + void Player::setClass(const std::string &value) + { + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->updatePlayer(Data_Class, value); + + mClass = world->getStore().get().find(value); + } } diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index a7a0ec430..1e6dae2c2 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -19,21 +19,31 @@ namespace MWWorld /// \brief NPC object representing the player and additional player data class Player { - LiveCellRef mPlayer; - MWWorld::CellStore *mCellStore; - std::string mName; - bool mMale; - std::string mRace; - std::string mBirthsign; - const ESM::Class *mClass; - bool mAutoMove; - int mForwardBackward; + LiveCellRef mPlayer; + MWWorld::CellStore *mCellStore; + + // cached referenced data + const ESM::Class *mClass; + const ESM::Race *mRace; + const ESM::BirthSign *mSign; + + bool mAutoMove; + int mForwardBackward; + public: + enum { + Data_Male, + Data_Name, + Data_Race, + Data_Class, + Data_Sign, + Data_Model, + Data_Head, + Data_Hair + }; Player(const ESM::NPC *player, const MWBase::World& world); - ~Player(); - void setCell (MWWorld::CellStore *cellStore) { mCellStore = cellStore; @@ -45,55 +55,37 @@ namespace MWWorld return ptr; } - void setName (const std::string& name) - { - mName = name; - } - - void setGender (bool male) - { - mMale = male; - } - - void setRace (const std::string& race) - { - mRace = race; - } - - void setBirthsign (const std::string& birthsign) - { - mBirthsign = birthsign; - } - - void setClass (const ESM::Class& class_) { - mClass = &class_; - } + void setName (const std::string& name); + void setGender (bool male); + void setRace (const std::string& race); + void setBirthsign (const std::string& birthsign); + void setClass (const std::string &cls); void setDrawState (MWMechanics::DrawState_ state); std::string getName() const { - return mName; + return mPlayer.mBase->mName; } bool isMale() const { - return mMale; + return (mPlayer.mBase->mFlags & 0x1) == 0; } - std::string getRace() const + const ESM::Race *getRace() const { return mRace; } - std::string getBirthsign() const + const ESM::BirthSign *getBirthsign() const { - return mBirthsign; + return mSign; } - const ESM::Class& getClass() const + const ESM::Class *getClass() const { - return *mClass; + return mClass; } bool getAutoMove() const diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 395abcd83..c645f6613 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -554,7 +554,7 @@ namespace MWWorld ESM::Cell *ptr = search(x, y); if (ptr == 0) { std::ostringstream msg; - msg << "Exterior at (" << x << ", " << y << ") not found (non-const"; + msg << "Exterior at (" << x << ", " << y << ") not found (non-const)"; throw std::runtime_error(msg.str()); } return ptr; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 532d335c3..1c1a3939d 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1252,4 +1252,50 @@ namespace MWWorld return 0; } + + void World::updatePlayer(int flag, const std::string &value) + { + ESM::NPC *player = mStore.get().find("player"); + + switch (flag) { + case Player::Data_Name: + player->mName = value; + break; + + case Player::Data_Class: + player->mClass = value; + break; + + case Player::Data_Race: + player->mRace = value; + break; + + case Player::Data_Model: + player->mModel = value; + break; + + case Player::Data_Head: + player->mHead = value; + break; + + case Player::Data_Hair: + player->mHair = value; + break; + + default: + break; + } + } + + void World::updatePlayer(int flag, bool value) + { + ESM::NPC *player = mStore.get().find("player"); + + if (flag == Player::Data_Male) { + player->mFlags |= 0x1; + if (value) { + player->mFlags ^= 0x1; + } + } + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 2b2ad7821..fe9e96110 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -327,6 +327,12 @@ namespace MWWorld /// 1 - only waiting \n /// 2 - player is underwater \n /// 3 - enemies are nearby (not implemented) + + /// Update player record part with given value + virtual void updatePlayer(int flag, const std::string &value); + + /// Update player record part with given value + virtual void updatePlayer(int flag, bool value); }; }