|
|
|
@ -193,59 +193,68 @@ void MWWorld::ContainerStore::addInitialItem (const std::string& id, const std::
|
|
|
|
|
{
|
|
|
|
|
count = std::abs(count); /// \todo implement item restocking (indicated by negative count)
|
|
|
|
|
|
|
|
|
|
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id);
|
|
|
|
|
|
|
|
|
|
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
const ESM::ItemLevList* levItem = ref.getPtr().get<ESM::ItemLevList>()->mBase;
|
|
|
|
|
const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
|
|
|
|
|
ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), id);
|
|
|
|
|
|
|
|
|
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
|
|
|
|
int playerLevel = MWWorld::Class::get(player).getCreatureStats(player).getLevel();
|
|
|
|
|
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
|
|
|
|
|
{
|
|
|
|
|
const ESM::ItemLevList* levItem = ref.getPtr().get<ESM::ItemLevList>()->mBase;
|
|
|
|
|
const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
|
|
|
|
|
|
|
|
|
|
failChance += levItem->mChanceNone;
|
|
|
|
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
|
|
|
|
int playerLevel = MWWorld::Class::get(player).getCreatureStats(player).getLevel();
|
|
|
|
|
|
|
|
|
|
if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each)
|
|
|
|
|
{
|
|
|
|
|
for (int i=0; i<count; ++i)
|
|
|
|
|
addInitialItem(id, owner, 1, failChance, false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
failChance += levItem->mChanceNone;
|
|
|
|
|
|
|
|
|
|
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
|
|
|
|
if (random >= failChance/100.f)
|
|
|
|
|
{
|
|
|
|
|
std::vector<std::string> candidates;
|
|
|
|
|
int highestLevel = 0;
|
|
|
|
|
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
|
|
|
|
if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each)
|
|
|
|
|
{
|
|
|
|
|
if (it->mLevel > highestLevel)
|
|
|
|
|
highestLevel = it->mLevel;
|
|
|
|
|
for (int i=0; i<count; ++i)
|
|
|
|
|
addInitialItem(id, owner, 1, failChance, false);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<int, std::string> highest = std::make_pair(-1, "");
|
|
|
|
|
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
|
|
|
|
float random = static_cast<float> (std::rand()) / RAND_MAX;
|
|
|
|
|
if (random >= failChance/100.f)
|
|
|
|
|
{
|
|
|
|
|
if (playerLevel >= it->mLevel
|
|
|
|
|
&& (levItem->mFlags & ESM::ItemLevList::AllLevels || it->mLevel == highestLevel))
|
|
|
|
|
std::vector<std::string> candidates;
|
|
|
|
|
int highestLevel = 0;
|
|
|
|
|
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
candidates.push_back(it->mId);
|
|
|
|
|
if (it->mLevel >= highest.first)
|
|
|
|
|
highest = std::make_pair(it->mLevel, it->mId);
|
|
|
|
|
if (it->mLevel > highestLevel)
|
|
|
|
|
highestLevel = it->mLevel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::pair<int, std::string> highest = std::make_pair(-1, "");
|
|
|
|
|
for (std::vector<ESM::LeveledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
if (playerLevel >= it->mLevel
|
|
|
|
|
&& (levItem->mFlags & ESM::ItemLevList::AllLevels || it->mLevel == highestLevel))
|
|
|
|
|
{
|
|
|
|
|
candidates.push_back(it->mId);
|
|
|
|
|
if (it->mLevel >= highest.first)
|
|
|
|
|
highest = std::make_pair(it->mLevel, it->mId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (!candidates.size())
|
|
|
|
|
return;
|
|
|
|
|
std::string item = candidates[std::rand()%candidates.size()];
|
|
|
|
|
addInitialItem(item, owner, count, failChance, false);
|
|
|
|
|
}
|
|
|
|
|
if (!candidates.size())
|
|
|
|
|
return;
|
|
|
|
|
std::string item = candidates[std::rand()%candidates.size()];
|
|
|
|
|
addInitialItem(item, owner, count, failChance, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ref.getPtr().getRefData().setCount (count);
|
|
|
|
|
ref.getPtr().getCellRef().mOwner = owner;
|
|
|
|
|
addImp (ref.getPtr());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
catch (std::logic_error& e)
|
|
|
|
|
{
|
|
|
|
|
ref.getPtr().getRefData().setCount (count);
|
|
|
|
|
ref.getPtr().getCellRef().mOwner = owner;
|
|
|
|
|
addImp (ref.getPtr());
|
|
|
|
|
// Vanilla doesn't fail on nonexistent items in levelled lists
|
|
|
|
|
std::cerr << "Warning: ignoring nonexistent item '" << id << "'" << std::endl;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|