forked from mirror/openmw-tes3mp
Feature #1323: Implement restocking items (does not handle levelled lists yet)
This commit is contained in:
parent
ae66d28c87
commit
b4ed828e21
12 changed files with 87 additions and 40 deletions
|
@ -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
|
void Container::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const
|
||||||
{
|
{
|
||||||
const std::string model = getModel(ptr);
|
const std::string model = getModel(ptr);
|
||||||
|
|
|
@ -66,6 +66,8 @@ namespace MWClass
|
||||||
|
|
||||||
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
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;
|
virtual std::string getModel(const MWWorld::Ptr &ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,9 +123,6 @@ namespace MWClass
|
||||||
else
|
else
|
||||||
data->mContainerStore = new MWWorld::ContainerStore();
|
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);
|
data->mCreatureStats.setGoldPool(ref->mBase->mData.mGold);
|
||||||
|
|
||||||
// store
|
// 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::fMinWalkSpeedCreature;
|
||||||
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
const ESM::GameSetting* Creature::fMaxWalkSpeedCreature;
|
||||||
const ESM::GameSetting *Creature::fEncumberedMoveEffect;
|
const ESM::GameSetting *Creature::fEncumberedMoveEffect;
|
||||||
|
|
|
@ -145,6 +145,8 @@ namespace MWClass
|
||||||
virtual int getBaseGold(const MWWorld::Ptr& ptr) const;
|
virtual int getBaseGold(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual void restock (const MWWorld::Ptr &ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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::fMinWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
const ESM::GameSetting *Npc::fMaxWalkSpeed;
|
||||||
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
const ESM::GameSetting *Npc::fEncumberedMoveEffect;
|
||||||
|
|
|
@ -180,6 +180,8 @@ namespace MWClass
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
virtual void respawn (const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
|
virtual void restock (const MWWorld::Ptr& ptr) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace MWGui
|
||||||
mCurrentBalance = 0;
|
mCurrentBalance = 0;
|
||||||
mCurrentMerchantOffer = 0;
|
mCurrentMerchantOffer = 0;
|
||||||
|
|
||||||
checkTradeTime();
|
restock();
|
||||||
|
|
||||||
std::vector<MWWorld::Ptr> itemSources;
|
std::vector<MWWorld::Ptr> itemSources;
|
||||||
MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources);
|
MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources);
|
||||||
|
@ -364,8 +364,6 @@ namespace MWGui
|
||||||
mPtr.getClass().getCreatureStats(mPtr).getGoldPool() - mCurrentBalance );
|
mPtr.getClass().getCreatureStats(mPtr).getGoldPool() - mCurrentBalance );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTradeTime();
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse(
|
MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse(
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sBarterDialog5")->getString());
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("sBarterDialog5")->getString());
|
||||||
|
|
||||||
|
@ -475,30 +473,26 @@ namespace MWGui
|
||||||
return merchantGold;
|
return merchantGold;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relates to NPC gold reset delay
|
void TradeWindow::restock()
|
||||||
void TradeWindow::checkTradeTime()
|
|
||||||
{
|
{
|
||||||
MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(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());
|
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.getLastRestockTime() + delay)
|
||||||
if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() + delay)
|
|
||||||
{
|
{
|
||||||
sellerStats.setGoldPool(mPtr.getClass().getBaseGold(mPtr));
|
sellerStats.setGoldPool(mPtr.getClass().getBaseGold(mPtr));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TradeWindow::updateTradeTime()
|
mPtr.getClass().restock(mPtr);
|
||||||
{
|
|
||||||
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
|
// Also restock any containers owned by this merchant, which are also available to buy in the trade window
|
||||||
if ( ! (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() &&
|
std::vector<MWWorld::Ptr> itemSources;
|
||||||
MWBase::Environment::get().getWorld()->getTimeStamp() < sellerStats.getTradeTime() + delay) )
|
MWBase::Environment::get().getWorld()->getContainersOwnedBy(mPtr, itemSources);
|
||||||
{
|
for (std::vector<MWWorld::Ptr>::iterator it = itemSources.begin(); it != itemSources.end(); ++it)
|
||||||
sellerStats.setTradeTime(MWBase::Environment::get().getWorld()->getTimeStamp());
|
{
|
||||||
|
it->getClass().restock(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
sellerStats.setLastRestockTime(MWBase::Environment::get().getWorld()->getTimeStamp());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,9 +101,7 @@ namespace MWGui
|
||||||
|
|
||||||
int getMerchantGold();
|
int getMerchantGold();
|
||||||
|
|
||||||
// Relates to NPC gold reset delay
|
void restock();
|
||||||
void checkTradeTime();
|
|
||||||
void updateTradeTime();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace MWMechanics
|
||||||
mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mKnockdownOneFrame(false),
|
mFallHeight(0), mRecalcDynamicStats(false), mKnockdown(false), mKnockdownOneFrame(false),
|
||||||
mKnockdownOverOneFrame(false), mHitRecovery(false), mBlock(false),
|
mKnockdownOverOneFrame(false), mHitRecovery(false), mBlock(false),
|
||||||
mMovementFlags(0), mDrawState (DrawState_Nothing), mAttackStrength(0.f),
|
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)
|
for (int i=0; i<4; ++i)
|
||||||
mAiSettings[i] = 0;
|
mAiSettings[i] = 0;
|
||||||
|
@ -477,7 +477,7 @@ namespace MWMechanics
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
mDynamic[i].writeState (state.mDynamic[i]);
|
mDynamic[i].writeState (state.mDynamic[i]);
|
||||||
|
|
||||||
state.mTradeTime = mTradeTime.toEsm();
|
state.mTradeTime = mLastRestock.toEsm();
|
||||||
state.mGoldPool = mGoldPool;
|
state.mGoldPool = mGoldPool;
|
||||||
|
|
||||||
state.mDead = mDead;
|
state.mDead = mDead;
|
||||||
|
@ -515,7 +515,7 @@ namespace MWMechanics
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
mDynamic[i].readState (state.mDynamic[i]);
|
mDynamic[i].readState (state.mDynamic[i]);
|
||||||
|
|
||||||
mTradeTime = MWWorld::TimeStamp(state.mTradeTime);
|
mLastRestock = MWWorld::TimeStamp(state.mTradeTime);
|
||||||
mGoldPool = state.mGoldPool;
|
mGoldPool = state.mGoldPool;
|
||||||
mFallHeight = state.mFallHeight;
|
mFallHeight = state.mFallHeight;
|
||||||
|
|
||||||
|
@ -546,15 +546,14 @@ namespace MWMechanics
|
||||||
mActiveSpells.readState(state.mActiveSpells);
|
mActiveSpells.readState(state.mActiveSpells);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relates to NPC gold reset delay
|
void CreatureStats::setLastRestockTime(MWWorld::TimeStamp tradeTime)
|
||||||
void CreatureStats::setTradeTime(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)
|
void CreatureStats::setGoldPool(int pool)
|
||||||
|
|
|
@ -56,9 +56,12 @@ namespace MWMechanics
|
||||||
// Do we need to recalculate stats derived from attributes or other factors?
|
// Do we need to recalculate stats derived from attributes or other factors?
|
||||||
bool mRecalcDynamicStats;
|
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;
|
int mActorId;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -241,9 +244,8 @@ namespace MWMechanics
|
||||||
static void writeActorIdCounter (ESM::ESMWriter& esm);
|
static void writeActorIdCounter (ESM::ESMWriter& esm);
|
||||||
static void readActorIdCounter (ESM::ESMReader& esm);
|
static void readActorIdCounter (ESM::ESMReader& esm);
|
||||||
|
|
||||||
// Relates to NPC gold reset delay
|
void setLastRestockTime(MWWorld::TimeStamp tradeTime);
|
||||||
void setTradeTime(MWWorld::TimeStamp tradeTime);
|
MWWorld::TimeStamp getLastRestockTime() const;
|
||||||
MWWorld::TimeStamp getTradeTime() const;
|
|
||||||
|
|
||||||
void setGoldPool(int pool);
|
void setGoldPool(int pool);
|
||||||
int getGoldPool() const;
|
int getGoldPool() const;
|
||||||
|
|
|
@ -343,6 +343,8 @@ namespace MWWorld
|
||||||
virtual void setDoorState (const MWWorld::Ptr &ptr, int state) const;
|
virtual void setDoorState (const MWWorld::Ptr &ptr, int state) const;
|
||||||
|
|
||||||
virtual void respawn (const MWWorld::Ptr& ptr) const {}
|
virtual void respawn (const MWWorld::Ptr& ptr) const {}
|
||||||
|
|
||||||
|
virtual void restock (const MWWorld::Ptr& ptr) const {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner, const std::string& faction,
|
||||||
int count, bool topLevel)
|
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);
|
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue