mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-07 03:45:33 +00:00
Fix bug 2952 with merchant and levelled items
This commit is contained in:
parent
a662a00c62
commit
aa721fe1f6
3 changed files with 53 additions and 20 deletions
|
@ -74,6 +74,7 @@ Programmers
|
||||||
Marco Melletti (mellotanica)
|
Marco Melletti (mellotanica)
|
||||||
Marco Schulze
|
Marco Schulze
|
||||||
Mateusz Kołaczek (PL_kolek)
|
Mateusz Kołaczek (PL_kolek)
|
||||||
|
Mateusz Malisz (malice)
|
||||||
megaton
|
megaton
|
||||||
Michael Hogan (Xethik)
|
Michael Hogan (Xethik)
|
||||||
Michael Mc Donnell
|
Michael Mc Donnell
|
||||||
|
|
|
@ -415,6 +415,7 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const std::
|
||||||
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner,
|
void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::string& owner,
|
||||||
int count, bool topLevel, const std::string& levItem)
|
int count, bool topLevel, const std::string& levItem)
|
||||||
{
|
{
|
||||||
|
if (count == 0) return; //Don't restock with nothing.
|
||||||
try {
|
try {
|
||||||
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);
|
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id, count);
|
||||||
|
|
||||||
|
@ -463,8 +464,8 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
|
||||||
|
|
||||||
void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner)
|
void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MWWorld::Ptr& ptr, const std::string& owner)
|
||||||
{
|
{
|
||||||
//allowedForReplace - Holds information about how many items from the list were sold;
|
//allowedForReplace - Holds information about how many items from the list were not sold;
|
||||||
// Hence, tells us how many items we need to restock.
|
// Hence, tells us how many items we don't need to restock.
|
||||||
//allowedForReplace[list] <- How many items we should generate(how many of these were sold)
|
//allowedForReplace[list] <- How many items we should generate(how many of these were sold)
|
||||||
std::map<std::string, int> allowedForReplace;
|
std::map<std::string, int> allowedForReplace;
|
||||||
|
|
||||||
|
@ -473,20 +474,42 @@ void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MW
|
||||||
{
|
{
|
||||||
int spawnedCount = it->second.first; //How many items should be in shop originally
|
int spawnedCount = it->second.first; //How many items should be in shop originally
|
||||||
int itemCount = count(it->first); //How many items are there in shop now
|
int itemCount = count(it->first); //How many items are there in shop now
|
||||||
//If anything was sold
|
//If something was not sold
|
||||||
if(itemCount < spawnedCount)
|
if(itemCount >= spawnedCount)
|
||||||
|
{
|
||||||
|
const std::string& ancestor = it->second.second;
|
||||||
|
// Security check for old saves:
|
||||||
|
//If item is imported from old save(doesn't have an ancestor) and wasn't sold
|
||||||
|
if(ancestor == "")
|
||||||
|
{
|
||||||
|
//Remove it, from shop,
|
||||||
|
remove(it->first, itemCount, ptr);//ptr is the NPC
|
||||||
|
//And remove it from map, so that when we restock, the new item will have proper ancestor.
|
||||||
|
mLevelledItemMap.erase(it);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
//Create the entry if it does not exist yet
|
||||||
|
std::map<std::string, int>::iterator listInMap = allowedForReplace.insert(
|
||||||
|
std::make_pair(it->second.second, 0)).first;
|
||||||
|
//And signal that we don't need to restock item from this list
|
||||||
|
listInMap->second += std::abs(itemCount);
|
||||||
|
}
|
||||||
|
//If every of the item was sold
|
||||||
|
else if (itemCount == 0)
|
||||||
|
{
|
||||||
|
mLevelledItemMap.erase(it);
|
||||||
|
}
|
||||||
|
//If some was sold, but some remain
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//Create entry if it does not exist yet
|
//Create entry if it does not exist yet
|
||||||
std::map<std::string, int>::iterator listInMap = allowedForReplace.insert(
|
std::map<std::string, int>::iterator listInMap = allowedForReplace.insert(
|
||||||
std::make_pair(it->second.second, 0)).first;
|
std::make_pair(it->second.second, 0)).first;
|
||||||
//And signal that we need to restock item from this list
|
//And signal that we don't need to restock all items from this list
|
||||||
listInMap->second += std::abs(spawnedCount - itemCount);
|
listInMap->second += std::abs(itemCount);
|
||||||
//Also, remove the record if item no longer figures in the shop
|
//And update itemCount so we don't mistake it next time.
|
||||||
if(!itemCount)
|
it->second.first = itemCount;
|
||||||
mLevelledItemMap.erase(it->first);
|
|
||||||
//If there's still item in the shop, change its spawnedCount to current count.
|
|
||||||
else
|
|
||||||
it->second.first -= itemCount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,8 +527,14 @@ void MWWorld::ContainerStore::restock (const ESM::InventoryList& items, const MW
|
||||||
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::ItemLevList>().search(it->mItem.toString()))
|
if (MWBase::Environment::get().getWorld()->getStore().get<ESM::ItemLevList>().search(it->mItem.toString()))
|
||||||
{
|
{
|
||||||
std::map<std::string, int>::iterator listInMap = allowedForReplace.find(itemOrList);
|
std::map<std::string, int>::iterator listInMap = allowedForReplace.find(itemOrList);
|
||||||
|
|
||||||
|
int restockNum = it-> mCount;
|
||||||
|
//If we know we must restock less, take it into account
|
||||||
if(listInMap != allowedForReplace.end())
|
if(listInMap != allowedForReplace.end())
|
||||||
addInitialItem(itemOrList, owner, listInMap->second, true);
|
restockNum += listInMap->second;//We add, because list items have negative count
|
||||||
|
//restock
|
||||||
|
addInitialItem(itemOrList, owner, restockNum, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,17 +31,20 @@ void ESM::InventoryState::load (ESMReader &esm)
|
||||||
|
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
//Next item is Levelled item
|
||||||
while (esm.isNextSub("LEVM"))
|
while (esm.isNextSub("LEVM"))
|
||||||
{
|
{
|
||||||
|
//Get its name
|
||||||
std::string id = esm.getHString();
|
std::string id = esm.getHString();
|
||||||
int count;
|
int count;
|
||||||
std::string parentList;
|
std::string parentGroup = "";
|
||||||
//TODO: How should I handle old saves?
|
//Then get its count
|
||||||
if(esm.isNextSub("LLST"))
|
|
||||||
std::string parentList = esm.getHString();
|
|
||||||
esm.getHNT (count, "COUN");
|
esm.getHNT (count, "COUN");
|
||||||
mLevelledItemMap[id] = count;
|
//Old save formats don't have information about parent group; check for that
|
||||||
|
if(esm.isNextSub("LGRP"))
|
||||||
|
//Newest saves contain parent group
|
||||||
|
parentGroup = esm.getHString();
|
||||||
|
mLevelledItemMap[id] = std::make_pair(count, parentGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (esm.isNextSub("MAGI"))
|
while (esm.isNextSub("MAGI"))
|
||||||
|
@ -87,7 +90,7 @@ void ESM::InventoryState::save (ESMWriter &esm) const
|
||||||
{
|
{
|
||||||
esm.writeHNString ("LEVM", it->first);
|
esm.writeHNString ("LEVM", it->first);
|
||||||
esm.writeHNT ("COUN", it->second.first);
|
esm.writeHNT ("COUN", it->second.first);
|
||||||
esm.writeHNString("LLST", it->second.second)
|
esm.writeHNString("LGRP", it->second.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (TEffectMagnitudes::const_iterator it = mPermanentMagicEffectMagnitudes.begin(); it != mPermanentMagicEffectMagnitudes.end(); ++it)
|
for (TEffectMagnitudes::const_iterator it = mPermanentMagicEffectMagnitudes.begin(); it != mPermanentMagicEffectMagnitudes.end(); ++it)
|
||||||
|
|
Loading…
Reference in a new issue