mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-18 18:40:06 +00:00
Implemented levelled items
This commit is contained in:
parent
a0d34c5e8d
commit
2d2196b0d6
@ -14,6 +14,8 @@
|
|||||||
#include "../mwbase/world.hpp"
|
#include "../mwbase/world.hpp"
|
||||||
#include "../mwbase/scriptmanager.hpp"
|
#include "../mwbase/scriptmanager.hpp"
|
||||||
|
|
||||||
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
|
||||||
#include "manualref.hpp"
|
#include "manualref.hpp"
|
||||||
#include "refdata.hpp"
|
#include "refdata.hpp"
|
||||||
#include "class.hpp"
|
#include "class.hpp"
|
||||||
@ -180,21 +182,72 @@ void MWWorld::ContainerStore::fill (const ESM::InventoryList& items, const MWWor
|
|||||||
for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
|
for (std::vector<ESM::ContItem>::const_iterator iter (items.mList.begin()); iter!=items.mList.end();
|
||||||
++iter)
|
++iter)
|
||||||
{
|
{
|
||||||
ManualRef ref (store, iter->mItem.toString());
|
std::string id = iter->mItem.toString();
|
||||||
|
addInitialItem(id, iter->mCount);
|
||||||
if (ref.getPtr().getTypeName()==typeid (ESM::ItemLevList).name())
|
|
||||||
{
|
|
||||||
/// \todo implement leveled item lists
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ref.getPtr().getRefData().setCount (std::abs(iter->mCount)); /// \todo implement item restocking (indicated by negative count)
|
|
||||||
addImp (ref.getPtr());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flagAsModified();
|
flagAsModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MWWorld::ContainerStore::addInitialItem (const std::string& id, int count, unsigned char failChance, bool topLevel)
|
||||||
|
{
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
const ESM::ItemLevList* levItem = ref.getPtr().get<ESM::ItemLevList>()->mBase;
|
||||||
|
const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
|
||||||
|
|
||||||
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer();
|
||||||
|
int playerLevel = MWWorld::Class::get(player).getCreatureStats(player).getLevel();
|
||||||
|
|
||||||
|
failChance += levItem->mChanceNone;
|
||||||
|
|
||||||
|
if (topLevel && count > 1 && levItem->mFlags & ESM::ItemLevList::Each)
|
||||||
|
{
|
||||||
|
for (int i=0; i<count; ++i)
|
||||||
|
addInitialItem(id, 1, failChance, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (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, count, failChance, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ref.getPtr().getRefData().setCount (count);
|
||||||
|
addImp (ref.getPtr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MWWorld::ContainerStore::clear()
|
void MWWorld::ContainerStore::clear()
|
||||||
{
|
{
|
||||||
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
for (ContainerStoreIterator iter (begin()); iter!=end(); ++iter)
|
||||||
|
@ -53,6 +53,7 @@ namespace MWWorld
|
|||||||
mutable float mCachedWeight;
|
mutable float mCachedWeight;
|
||||||
mutable bool mWeightUpToDate;
|
mutable bool mWeightUpToDate;
|
||||||
ContainerStoreIterator addImp (const Ptr& ptr);
|
ContainerStoreIterator addImp (const Ptr& ptr);
|
||||||
|
void addInitialItem (const std::string& id, int count, unsigned char failChance=0, bool topLevel=true);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -22,17 +22,20 @@ struct LeveledListBase
|
|||||||
{
|
{
|
||||||
enum Flags
|
enum Flags
|
||||||
{
|
{
|
||||||
AllLevels = 0x01, // Calculate from all levels <= player
|
|
||||||
// level, not just the closest below
|
Each = 0x01, // Select a new item each time this
|
||||||
// player.
|
|
||||||
Each = 0x02 // Select a new item each time this
|
|
||||||
// list is instantiated, instead of
|
// list is instantiated, instead of
|
||||||
// giving several identical items
|
// giving several identical items
|
||||||
}; // (used when a container has more
|
// (used when a container has more
|
||||||
// than one instance of one leveled
|
// than one instance of one leveled
|
||||||
// list.)
|
// list.)
|
||||||
|
AllLevels = 0x02 // Calculate from all levels <= player
|
||||||
|
// level, not just the closest below
|
||||||
|
// player.
|
||||||
|
};
|
||||||
|
|
||||||
int mFlags;
|
int mFlags;
|
||||||
unsigned char mChanceNone; // Chance that none are selected (0-255?)
|
unsigned char mChanceNone; // Chance that none are selected (0-100)
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
|
||||||
// Record name used to read references. Must be set before load() is
|
// Record name used to read references. Must be set before load() is
|
||||||
|
Loading…
x
Reference in New Issue
Block a user