diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 611e70fe0..54cb12c59 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -29,6 +29,7 @@ namespace ESM struct Class; struct Potion; struct Spell; + struct NPC; } namespace MWRender @@ -249,6 +250,11 @@ namespace MWBase ///< Create a new recrod (of type cell) in the ESM store. /// \return ID, pointer to created record + virtual const ESM::NPC *createRecord(const ESM::NPC &record) = 0; + ///< Create a new recrod (of type npc) in the ESM store. + ///< \note special treatment for 'player' record + /// \return ID, pointer to created record + virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number = 1) = 0; ///< Run animation for a MW-reference. Calls to this function for references that are @@ -296,12 +302,6 @@ 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/levelupdialog.cpp b/apps/openmw/mwgui/levelupdialog.cpp index 099132b8b..45890b89f 100644 --- a/apps/openmw/mwgui/levelupdialog.cpp +++ b/apps/openmw/mwgui/levelupdialog.cpp @@ -108,7 +108,8 @@ namespace MWGui void LevelupDialog::open() { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer().getPlayer(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayer().getPlayer(); MWMechanics::CreatureStats& creatureStats = MWWorld::Class::get(player).getCreatureStats (player); MWMechanics::NpcStats& pcStats = MWWorld::Class::get(player).getNpcStats (player); @@ -119,9 +120,11 @@ namespace MWGui setAttributeValues(); + const ESM::NPC *playerData = player.get()->mBase; + // set class image const ESM::Class *cls = - MWBase::Environment::get().getWorld ()->getPlayer ().getClass (); + world->getStore().get().find(playerData->mClass); mClassImage->setImageTexture ("textures\\levelup\\" + cls->mId + ".dds"); diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index ae86cbf1a..a557539b7 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -252,12 +252,12 @@ void StatsWindow::onFrame () } setFactions(PCstats.getFactionRanks()); - +/* const ESM::BirthSign *sign = MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); setBirthSign((sign != 0) ? sign->mId : ""); - +*/ if (mChanged) updateSkillArea(); } @@ -429,11 +429,13 @@ void StatsWindow::updateSkillArea() if (!mMiscSkills.empty()) addSkills(mMiscSkills, "sSkillClassMisc", "Misc Skills", coord1, coord2); - const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); + MWBase::World *world = MWBase::Environment::get().getWorld(); + const MWWorld::ESMStore &store = world->getStore(); + const ESM::NPC *player = + world->getPlayer().getPlayer().get()->mBase; // race tooltip - const ESM::Race* playerRace = - MWBase::Environment::get().getWorld()->getPlayer().getRace(); + const ESM::Race* playerRace = store.get().find(player->mRace); MyGUI::Widget* raceWidget; getWidget(raceWidget, "RaceText"); @@ -445,7 +447,7 @@ void StatsWindow::updateSkillArea() MyGUI::Widget* classWidget; const ESM::Class *playerClass = - MWBase::Environment::get().getWorld()->getPlayer().getClass(); + store.get().find(player->mClass); getWidget(classWidget, "ClassText"); ToolTips::createClassToolTip(classWidget, *playerClass); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 3ca3a4ba0..be675d1bd 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -37,14 +37,17 @@ namespace MWMechanics creatureStats.getAttribute(5).setBase (player->mNpdt52.mEndurance); creatureStats.getAttribute(6).setBase (player->mNpdt52.mPersonality); creatureStats.getAttribute(7).setBase (player->mNpdt52.mLuck); + + const MWWorld::ESMStore &esmStore = + MWBase::Environment::get().getWorld()->getStore(); // race if (mRaceSelected) { const ESM::Race *race = - MWBase::Environment::get().getWorld()->getPlayer().getRace(); + esmStore.get().find(player->mRace); - bool male = MWBase::Environment::get().getWorld()->getPlayer().isMale(); + bool male = (player->mFlags & ESM::NPC::Female) == 0; for (int i=0; i<8; ++i) { @@ -87,11 +90,11 @@ namespace MWMechanics } // birthsign - const ESM::BirthSign *sign = - MWBase::Environment::get().getWorld()->getPlayer().getBirthsign(); - - if (sign != 0) + if (!mSign.empty()) { + const ESM::BirthSign *sign = + esmStore.get().find(mSign); + for (std::vector::const_iterator iter (sign->mPowers.mList.begin()); iter!=sign->mPowers.mList.end(); ++iter) { @@ -103,7 +106,7 @@ namespace MWMechanics if (mClassSelected) { const ESM::Class *class_ = - MWBase::Environment::get().getWorld()->getPlayer().getClass(); + esmStore.get().find(player->mClass); for (int i=0; i<2; ++i) { @@ -132,7 +135,7 @@ namespace MWMechanics } const MWWorld::Store &skills = - MWBase::Environment::get().getWorld()->getStore().get(); + esmStore.get(); MWWorld::Store::iterator iter = skills.begin(); for (; iter != skills.end(); ++iter) @@ -263,13 +266,19 @@ namespace MWMechanics // basic player profile; should not change anymore after the creation phase is finished. MWBase::WindowManager *winMgr = MWBase::Environment::get().getWindowManager(); - - MWWorld::Player &player = - MWBase::Environment::get().getWorld()->getPlayer(); + + MWBase::World *world = MWBase::Environment::get().getWorld(); + const ESM::NPC *player = + world->getPlayer().getPlayer().get()->mBase; - winMgr->setValue ("name", player.getName()); - winMgr->setValue ("race", player.getRace()->mName); - winMgr->setValue ("class", player.getClass()->mName); + const ESM::Race *race = + world->getStore().get().find(player->mRace); + const ESM::Class *cls = + world->getStore().get().find(player->mClass); + + winMgr->setValue ("name", player->mName); + winMgr->setValue ("race", race->mName); + winMgr->setValue ("class", cls->mName); mUpdatePlayer = false; @@ -278,8 +287,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] = cls->mData.mSkills[i][0]; + majorSkills[i] = cls->mData.mSkills[i][1]; } winMgr->configureSkills (majorSkills, minorSkills); @@ -295,14 +304,33 @@ namespace MWMechanics void MechanicsManager::setPlayerName (const std::string& name) { - MWBase::Environment::get().getWorld()->getPlayer().setName (name); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + player.mName = name; + + world->createRecord(player); + mUpdatePlayer = true; } void MechanicsManager::setPlayerRace (const std::string& race, bool male) { - MWBase::Environment::get().getWorld()->getPlayer().setGender (male); - MWBase::Environment::get().getWorld()->getPlayer().setRace (race); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + + player.mRace = race; + + player.mFlags |= ESM::NPC::Female; + if (male) { + player.mFlags ^= ESM::NPC::Female; + } + + world->createRecord(player); + mRaceSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -310,14 +338,21 @@ namespace MWMechanics void MechanicsManager::setPlayerBirthsign (const std::string& id) { - MWBase::Environment::get().getWorld()->getPlayer().setBirthsign (id); + mSign = id; buildPlayer(); mUpdatePlayer = true; } void MechanicsManager::setPlayerClass (const std::string& id) { - MWBase::Environment::get().getWorld()->getPlayer().setClass(id); + MWBase::World *world = MWBase::Environment::get().getWorld(); + + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + player.mClass = id; + + world->createRecord(player); + mClassSelected = true; buildPlayer(); mUpdatePlayer = true; @@ -329,7 +364,11 @@ namespace MWMechanics const ESM::Class *ptr = world->createRecord(cls); - world->getPlayer().setClass(ptr->mId); + ESM::NPC player = + *world->getPlayer().getPlayer().get()->mBase; + player.mClass = ptr->mId; + + world->createRecord(player); mClassSelected = true; buildPlayer(); diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 38536d3bd..cc4d8c46a 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -29,6 +29,7 @@ namespace MWMechanics bool mUpdatePlayer; bool mClassSelected; bool mRaceSelected; + std::string mSign; Actors mActors; void buildPlayer(); diff --git a/apps/openmw/mwworld/esmstore.hpp b/apps/openmw/mwworld/esmstore.hpp index dfe2ac03a..9917254ee 100644 --- a/apps/openmw/mwworld/esmstore.hpp +++ b/apps/openmw/mwworld/esmstore.hpp @@ -146,13 +146,13 @@ namespace MWWorld } template - Store &get() { - throw std::runtime_error("Storage for this type not exist (non-const)"); - } - - template - T *insert(const T &x) { + const T *insert(const T &x) { Store &store = const_cast &>(get()); + if (store.search(x.mId) != 0) { + std::ostringstream msg; + msg << "Try to override existing record '" << x.mId << "'"; + throw std::runtime_error(msg.str()); + } T record = x; std::ostringstream id; @@ -173,10 +173,30 @@ namespace MWWorld }; template <> - inline ESM::Cell *ESMStore::insert(const ESM::Cell &cell) { + inline const ESM::Cell *ESMStore::insert(const ESM::Cell &cell) { return mCells.insert(cell); } + template <> + inline const ESM::NPC *ESMStore::insert(const ESM::NPC &npc) { + if (StringUtils::ciEqual(npc.mId, "player")) { + return mNpcs.insert(npc); + } else if (mNpcs.search(npc.mId) != 0) { + std::ostringstream msg; + msg << "Try to override existing record '" << npc.mId << "'"; + throw std::runtime_error(msg.str()); + } + ESM::NPC record = npc; + + std::ostringstream id; + id << "$dynamic" << mDynamicCount++; + record.mId = id.str(); + + ESM::NPC *ptr = mNpcs.insert(record); + mIds[ptr->mId] = ESM::REC_NPC_; + return ptr; + } + template <> inline const Store &ESMStore::get() const { return mActivators; @@ -401,231 +421,6 @@ namespace MWWorld inline const Store &ESMStore::get() const { return mAttributes; } - - template <> - inline Store &ESMStore::get() { - return mActivators; - } - - template <> - inline Store &ESMStore::get() { - return mPotions; - } - - template <> - inline Store &ESMStore::get() { - return mAppas; - } - - template <> - inline Store &ESMStore::get() { - return mArmors; - } - - template <> - inline Store &ESMStore::get() { - return mBodyParts; - } - - template <> - inline Store &ESMStore::get() { - return mBooks; - } - - template <> - inline Store &ESMStore::get() { - return mBirthSigns; - } - - template <> - inline Store &ESMStore::get() { - return mClasses; - } - - template <> - inline Store &ESMStore::get() { - return mClothes; - } - - template <> - inline Store &ESMStore::get() { - return mContChange; - } - - template <> - inline Store &ESMStore::get() { - return mContainers; - } - - template <> - inline Store &ESMStore::get() { - return mCreatures; - } - - template <> - inline Store &ESMStore::get() { - return mCreaChange; - } - - template <> - inline Store &ESMStore::get() { - return mDialogs; - } - - template <> - inline Store &ESMStore::get() { - return mDoors; - } - - template <> - inline Store &ESMStore::get() { - return mEnchants; - } - - template <> - inline Store &ESMStore::get() { - return mFactions; - } - - template <> - inline Store &ESMStore::get() { - return mGlobals; - } - - template <> - inline Store &ESMStore::get() { - return mIngreds; - } - - template <> - inline Store &ESMStore::get() { - return mCreatureLists; - } - - template <> - inline Store &ESMStore::get() { - return mItemLists; - } - - template <> - inline Store &ESMStore::get() { - return mLights; - } - - template <> - inline Store &ESMStore::get() { - return mLockpicks; - } - - template <> - inline Store &ESMStore::get() { - return mMiscItems; - } - - template <> - inline Store &ESMStore::get() { - return mNpcs; - } - - template <> - inline Store &ESMStore::get() { - return mNpcChange; - } - - template <> - inline Store &ESMStore::get() { - return mProbes; - } - - template <> - inline Store &ESMStore::get() { - return mRaces; - } - - template <> - inline Store &ESMStore::get() { - return mRegions; - } - - template <> - inline Store &ESMStore::get() { - return mRepairs; - } - - template <> - inline Store &ESMStore::get() { - return mSoundGens; - } - - template <> - inline Store &ESMStore::get() { - return mSounds; - } - - template <> - inline Store &ESMStore::get() { - return mSpells; - } - - template <> - inline Store &ESMStore::get() { - return mStartScripts; - } - - template <> - inline Store &ESMStore::get() { - return mStatics; - } - - template <> - inline Store &ESMStore::get() { - return mWeapons; - } - - template <> - inline Store &ESMStore::get() { - return mGameSettings; - } - - template <> - inline Store &ESMStore::get() { - return mScripts; - } - - template <> - inline Store &ESMStore::get() { - return mCells; - } - - template <> - inline Store &ESMStore::get() { - return mLands; - } - - template <> - inline Store &ESMStore::get() { - return mLandTextures; - } - - template <> - inline Store &ESMStore::get() { - return mPathgrids; - } - - template <> - inline Store &ESMStore::get() { - return mMagicEffects; - } - - template <> - inline Store &ESMStore::get() { - return mSkills; - } - - template <> - inline Store &ESMStore::get() { - return mAttributes; - } } #endif diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 48767a1a1..3414ba448 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -15,9 +15,6 @@ namespace MWWorld { Player::Player (const ESM::NPC *player, const MWBase::World& world) : mCellStore(0), - mClass(0), - mRace(0), - mSign(0), mAutoMove(false), mForwardBackward (0) { @@ -26,9 +23,6 @@ namespace MWWorld float* playerPos = mPlayer.mData.getPosition().pos; playerPos[0] = playerPos[1] = playerPos[2] = 0; - - mClass = world.getStore().get().find (player->mClass); - mRace = world.getStore().get().find(player->mRace); } void Player::setDrawState (MWMechanics::DrawState_ state) @@ -91,36 +85,4 @@ namespace MWWorld MWWorld::Ptr ptr = getPlayer(); 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 1e6dae2c2..7c5ac0018 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -22,25 +22,10 @@ namespace MWWorld 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); @@ -55,39 +40,8 @@ namespace MWWorld return ptr; } - 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 mPlayer.mBase->mName; - } - - bool isMale() const - { - return (mPlayer.mBase->mFlags & 0x1) == 0; - } - - const ESM::Race *getRace() const - { - return mRace; - } - - const ESM::BirthSign *getBirthsign() const - { - return mSign; - } - - const ESM::Class *getClass() const - { - return mClass; - } - bool getAutoMove() const { return mAutoMove; diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index c645f6613..00f67c8ea 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -168,26 +168,6 @@ namespace MWWorld } } - T *search(const std::string &id) { - std::string key = StringUtils::lowerCase(id); - typename Dynamic::iterator dit = mDynamic.find(key); - - if (dit != mDynamic.end()) { - return &dit->second; - } - return 0; - } - - T *find(const std::string &id) { - T *ptr = search(id); - if (ptr == 0) { - std::ostringstream msg; - msg << "Object '" << id << "' not found (non-const)"; - throw std::runtime_error(msg.str()); - } - return ptr; - } - T *insert(const T &item) { std::string id = StringUtils::lowerCase(item.mId); std::pair result = @@ -523,43 +503,6 @@ namespace MWWorld } } - ESM::Cell *search(const std::string &id) { - std::string key = StringUtils::lowerCase(id); - DynamicInt::iterator it = mDynamicInt.find(key); - if (it != mDynamicInt.end()) { - return &it->second; - } - return 0; - } - - ESM::Cell *find(const std::string &id) { - ESM::Cell *ptr = search(id); - if (ptr == 0) { - std::ostringstream msg; - msg << "Interior '" << id << "' not found (non-const)"; - throw std::runtime_error(msg.str()); - } - return ptr; - } - - ESM::Cell *search(int x, int y) { - DynamicExt::iterator it = mDynamicExt.find(std::make_pair(x, y)); - if (it != mDynamicExt.end()) { - return &it->second; - } - return 0; - } - - ESM::Cell *find(int x, int y) { - ESM::Cell *ptr = search(x, y); - if (ptr == 0) { - std::ostringstream msg; - msg << "Exterior at (" << x << ", " << y << ") not found (non-const)"; - throw std::runtime_error(msg.str()); - } - return ptr; - } - ESM::Cell *insert(const ESM::Cell &cell) { if (search(cell) != 0) { std::ostringstream msg; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 26013e4ff..af5745744 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -799,6 +799,11 @@ namespace MWWorld return mStore.insert(record); } + const ESM::NPC *World::createRecord(const ESM::NPC &record) + { + return mStore.insert(record); + } + void World::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) { @@ -1055,12 +1060,12 @@ namespace MWWorld // door leads to exterior, use cell name (if any), otherwise translated region name int x,y; positionToIndex (ref.mRef.mDoorDest.pos[0], ref.mRef.mDoorDest.pos[1], x, y); - const ESM::Cell* cell = ((const ESMStore &) mStore).get().find(x,y); + const ESM::Cell* cell = mStore.get().find(x,y); if (cell->mName != "") dest = cell->mName; else { - dest = ((const ESMStore &) mStore).get().find(cell->mRegion)->mName; + dest = mStore.get().find(cell->mRegion)->mName; } } @@ -1249,51 +1254,4 @@ 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: - mStore.get().erase(player->mClass); - 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 123ad1f87..20590ff0a 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -266,6 +266,12 @@ namespace MWWorld ///< Create a new recrod (of type cell) in the ESM store. /// \return ID, pointer to created record + virtual const ESM::NPC *createRecord(const ESM::NPC &record); + ///< Create a new recrod (of type npc) in the ESM store. + ///< \note special treatment for 'player' record + /// \return ID, pointer to created record + + virtual void playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number = 1); ///< Run animation for a MW-reference. Calls to this function for references that are @@ -327,12 +333,6 @@ 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); }; }