Feature #1323: Implement restocking items (does not handle levelled lists yet)

This commit is contained in:
scrawl 2014-05-17 14:30:31 +02:00
parent ae66d28c87
commit b4ed828e21
12 changed files with 87 additions and 40 deletions

View file

@ -70,6 +70,22 @@ namespace MWClass
}
}
void Container::restock(const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::Container> *ref = ptr.get<ESM::Container>();
const ESM::InventoryList& list = ref->mBase->mInventory;
for (std::vector<ESM::ContItem>::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);

View file

@ -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;
};
}

View file

@ -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<ESM::Creature> *ref = ptr.get<ESM::Creature>();
const ESM::InventoryList& list = ref->mBase->mInventory;
for (std::vector<ESM::ContItem>::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;

View file

@ -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;
};
}

View file

@ -1330,6 +1330,22 @@ namespace MWClass
}
}
void Npc::restock(const MWWorld::Ptr& ptr) const
{
MWWorld::LiveCellRef<ESM::NPC> *ref = ptr.get<ESM::NPC>();
const ESM::InventoryList& list = ref->mBase->mInventory;
for (std::vector<ESM::ContItem>::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;

View file

@ -180,6 +180,8 @@ namespace MWClass
}
virtual void respawn (const MWWorld::Ptr& ptr) const;
virtual void restock (const MWWorld::Ptr& ptr) const;
};
}

View file

@ -84,7 +84,7 @@ namespace MWGui
mCurrentBalance = 0;
mCurrentMerchantOffer = 0;
checkTradeTime();
restock();
std::vector<MWWorld::Ptr> 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<ESM::GameSetting>().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<double>(MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getInt());
float delay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().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));
}
mPtr.getClass().restock(mPtr);
// Also restock any containers owned by this merchant, which are also available to buy in the trade window
std::vector<MWWorld::Ptr> itemSources;
MWBase::Environment::get().getWorld()->getContainersOwnedBy(mPtr, itemSources);
for (std::vector<MWWorld::Ptr>::iterator it = itemSources.begin(); it != itemSources.end(); ++it)
{
it->getClass().restock(*it);
}
void TradeWindow::updateTradeTime()
{
MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr);
MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr);
double delay = boost::lexical_cast<double>(MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fBarterGoldResetDelay")->getInt());
// 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());
sellerStats.setLastRestockTime(MWBase::Environment::get().getWorld()->getTimeStamp());
}
}
}

View file

@ -101,9 +101,7 @@ namespace MWGui
int getMerchantGold();
// Relates to NPC gold reset delay
void checkTradeTime();
void updateTradeTime();
void restock();
};
}

View file

@ -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)

View file

@ -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;

View file

@ -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 {}
};
}

View file

@ -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);