diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index f0c71bf536..fd8eeb46b9 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -70,6 +70,22 @@ namespace MWClass } } + void Container::restock(const MWWorld::Ptr& ptr) const + { + MWWorld::LiveCellRef *ref = ptr.get(); + const ESM::InventoryList& list = ref->mBase->mInventory; + for (std::vector::const_iterator it = list.mList.begin(); it != list.mList.end(); ++it) + { + if (it->mCount < 0) + { + MWWorld::ContainerStore& store = getContainerStore(ptr); + int currentCount = store.count(it->mItem.toString()); + if (currentCount < std::abs(it->mCount)) + store.add (it->mItem.toString(), std::abs(it->mCount) - currentCount, ptr); + } + } + } + void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const { const std::string model = getModel(ptr); diff --git a/apps/openmw/mwclass/container.hpp b/apps/openmw/mwclass/container.hpp index 79a8012485..9fc013e45e 100644 --- a/apps/openmw/mwclass/container.hpp +++ b/apps/openmw/mwclass/container.hpp @@ -66,6 +66,8 @@ namespace MWClass virtual void respawn (const MWWorld::Ptr& ptr) const; + virtual void restock (const MWWorld::Ptr &ptr) const; + virtual std::string getModel(const MWWorld::Ptr &ptr) const; }; } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 4abc9ea713..db3a70a6a6 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -123,9 +123,6 @@ namespace MWClass else data->mContainerStore = new MWWorld::ContainerStore(); - // Relates to NPC gold reset delay - data->mCreatureStats.setTradeTime(MWWorld::TimeStamp(0.0, 0)); - data->mCreatureStats.setGoldPool(ref->mBase->mData.mGold); // store @@ -842,6 +839,22 @@ namespace MWClass } } + void Creature::restock(const MWWorld::Ptr& ptr) const + { + MWWorld::LiveCellRef *ref = ptr.get(); + const ESM::InventoryList& list = ref->mBase->mInventory; + for (std::vector::const_iterator it = list.mList.begin(); it != list.mList.end(); ++it) + { + if (it->mCount < 0) + { + MWWorld::ContainerStore& store = getContainerStore(ptr); + int currentCount = store.count(it->mItem.toString()); + if (currentCount < std::abs(it->mCount)) + store.add (it->mItem.toString(), std::abs(it->mCount) - currentCount, ptr); + } + } + } + const ESM::GameSetting* Creature::fMinWalkSpeedCreature; const ESM::GameSetting* Creature::fMaxWalkSpeedCreature; const ESM::GameSetting *Creature::fEncumberedMoveEffect; diff --git a/apps/openmw/mwclass/creature.hpp b/apps/openmw/mwclass/creature.hpp index d3ffb321ef..30573cd154 100644 --- a/apps/openmw/mwclass/creature.hpp +++ b/apps/openmw/mwclass/creature.hpp @@ -145,6 +145,8 @@ namespace MWClass virtual int getBaseGold(const MWWorld::Ptr& ptr) const; virtual void respawn (const MWWorld::Ptr& ptr) const; + + virtual void restock (const MWWorld::Ptr &ptr) const; }; } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 5b9e26f269..009559d192 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1330,6 +1330,22 @@ namespace MWClass } } + void Npc::restock(const MWWorld::Ptr& ptr) const + { + MWWorld::LiveCellRef *ref = ptr.get(); + const ESM::InventoryList& list = ref->mBase->mInventory; + for (std::vector::const_iterator it = list.mList.begin(); it != list.mList.end(); ++it) + { + if (it->mCount < 0) + { + MWWorld::ContainerStore& store = getContainerStore(ptr); + int currentCount = store.count(it->mItem.toString()); + if (currentCount < std::abs(it->mCount)) + store.add (it->mItem.toString(), std::abs(it->mCount) - currentCount, ptr); + } + } + } + const ESM::GameSetting *Npc::fMinWalkSpeed; const ESM::GameSetting *Npc::fMaxWalkSpeed; const ESM::GameSetting *Npc::fEncumberedMoveEffect; diff --git a/apps/openmw/mwclass/npc.hpp b/apps/openmw/mwclass/npc.hpp index 03c6e234a1..356e358b9d 100644 --- a/apps/openmw/mwclass/npc.hpp +++ b/apps/openmw/mwclass/npc.hpp @@ -180,6 +180,8 @@ namespace MWClass } virtual void respawn (const MWWorld::Ptr& ptr) const; + + virtual void restock (const MWWorld::Ptr& ptr) const; }; } diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 9cabab3e8e..65ffdb9e1e 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -84,7 +84,7 @@ namespace MWGui mCurrentBalance = 0; mCurrentMerchantOffer = 0; - checkTradeTime(); + restock(); std::vector itemSources; MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources); @@ -364,8 +364,6 @@ namespace MWGui mPtr.getClass().getCreatureStats(mPtr).getGoldPool() - mCurrentBalance ); } - updateTradeTime(); - MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse( MWBase::Environment::get().getWorld()->getStore().get().find("sBarterDialog5")->getString()); @@ -475,30 +473,26 @@ namespace MWGui return merchantGold; } - // Relates to NPC gold reset delay - void TradeWindow::checkTradeTime() + void TradeWindow::restock() { MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); - double delay = boost::lexical_cast(MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->getInt()); + float delay = MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->getFloat(); - // if time stamp longer than gold reset delay, reset gold. - if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() + delay) + if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getLastRestockTime() + delay) { sellerStats.setGoldPool(mPtr.getClass().getBaseGold(mPtr)); - } - } - void TradeWindow::updateTradeTime() - { - MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr); - MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); - double delay = boost::lexical_cast(MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->getInt()); + mPtr.getClass().restock(mPtr); - // If trade timestamp is within reset delay don't set - if ( ! (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() && - MWBase::Environment::get().getWorld()->getTimeStamp() < sellerStats.getTradeTime() + delay) ) - { - sellerStats.setTradeTime(MWBase::Environment::get().getWorld()->getTimeStamp()); + // Also restock any containers owned by this merchant, which are also available to buy in the trade window + std::vector itemSources; + MWBase::Environment::get().getWorld()->getContainersOwnedBy(mPtr, itemSources); + for (std::vector::iterator it = itemSources.begin(); it != itemSources.end(); ++it) + { + it->getClass().restock(*it); + } + + sellerStats.setLastRestockTime(MWBase::Environment::get().getWorld()->getTimeStamp()); } } } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 5c154d4259..2da58e72e1 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -101,9 +101,7 @@ namespace MWGui int getMerchantGold(); - // Relates to NPC gold reset delay - void checkTradeTime(); - void updateTradeTime(); + void restock(); }; } diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index 57618e6e93..95e25cba67 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -22,7 +22,7 @@ namespace MWMechanics mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mKnockdownOneFrame(false), mKnockdownOverOneFrame(false), mHitRecovery(false), mBlock(false), mMovementFlags(0), mDrawState (DrawState_Nothing), mAttackStrength(0.f), - mTradeTime(0,0), mGoldPool(0), mActorId(-1) + mLastRestock(0,0), mGoldPool(0), mActorId(-1) { for (int i=0; i<4; ++i) mAiSettings[i] = 0; @@ -477,7 +477,7 @@ namespace MWMechanics for (int i=0; i<3; ++i) mDynamic[i].writeState (state.mDynamic[i]); - state.mTradeTime = mTradeTime.toEsm(); + state.mTradeTime = mLastRestock.toEsm(); state.mGoldPool = mGoldPool; state.mDead = mDead; @@ -515,7 +515,7 @@ namespace MWMechanics for (int i=0; i<3; ++i) mDynamic[i].readState (state.mDynamic[i]); - mTradeTime = MWWorld::TimeStamp(state.mTradeTime); + mLastRestock = MWWorld::TimeStamp(state.mTradeTime); mGoldPool = state.mGoldPool; mFallHeight = state.mFallHeight; @@ -546,15 +546,14 @@ namespace MWMechanics mActiveSpells.readState(state.mActiveSpells); } - // Relates to NPC gold reset delay - void CreatureStats::setTradeTime(MWWorld::TimeStamp tradeTime) + void CreatureStats::setLastRestockTime(MWWorld::TimeStamp tradeTime) { - mTradeTime = tradeTime; + mLastRestock = tradeTime; } - MWWorld::TimeStamp CreatureStats::getTradeTime() const + MWWorld::TimeStamp CreatureStats::getLastRestockTime() const { - return mTradeTime; + return mLastRestock; } void CreatureStats::setGoldPool(int pool) diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 7d2dc1a62a..70a86536a0 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -56,9 +56,12 @@ namespace MWMechanics // Do we need to recalculate stats derived from attributes or other factors? bool mRecalcDynamicStats; - MWWorld::TimeStamp mTradeTime; // Relates to NPC gold reset delay + // For merchants: the last time items were restocked and gold pool refilled. + MWWorld::TimeStamp mLastRestock; + + // The pool of merchant gold (not in inventory) + int mGoldPool; - int mGoldPool; // the pool of merchant gold not in inventory int mActorId; protected: @@ -241,9 +244,8 @@ namespace MWMechanics static void writeActorIdCounter (ESM::ESMWriter& esm); static void readActorIdCounter (ESM::ESMReader& esm); - // Relates to NPC gold reset delay - void setTradeTime(MWWorld::TimeStamp tradeTime); - MWWorld::TimeStamp getTradeTime() const; + void setLastRestockTime(MWWorld::TimeStamp tradeTime); + MWWorld::TimeStamp getLastRestockTime() const; void setGoldPool(int pool); int getGoldPool() const; diff --git a/apps/openmw/mwworld/class.hpp b/apps/openmw/mwworld/class.hpp index f47b8ace32..0b1eb857c8 100644 --- a/apps/openmw/mwworld/class.hpp +++ b/apps/openmw/mwworld/class.hpp @@ -343,6 +343,8 @@ namespace MWWorld virtual void setDoorState (const MWWorld::Ptr &ptr, int state) const; virtual void respawn (const MWWorld::Ptr& ptr) const {} + + virtual void restock (const MWWorld::Ptr& ptr) const {} }; } diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index eb6760d14c..1cbaa349ca 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -376,7 +376,8 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std:: void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, const std::string& faction, int count, bool topLevel) { - count = std::abs(count); /// \todo implement item restocking (indicated by negative count) + // A negative count indicates restocking items, but this is implemented elsewhere + count = std::abs(count); ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);