1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-01-15 18:19:55 +00:00
openmw-tes3mp/apps/openmw/mwmechanics/levelledlist.hpp
slothlife f33559fead Fixes for MSVC warnings, less overall changes
Kept some fixes from the first round of review. Found out that several
targets weren't being built with the same basic warnings disabled.
Disabled a few warnings for external libraries specifically, rather than
applying them to all targets.
2014-05-14 20:12:52 -05:00

83 lines
3.2 KiB
C++

#ifndef OPENMW_MECHANICS_LEVELLEDLIST_H
#define OPENMW_MECHANICS_LEVELLEDLIST_H
#include "../mwworld/ptr.hpp"
#include "../mwworld/manualref.hpp"
#include "../mwworld/class.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
#include "../mwmechanics/creaturestats.hpp"
namespace MWMechanics
{
/// @return ID of resulting item, or empty if none
inline std::string getLevelledItem (const ESM::LeveledListBase* levItem, bool creature, unsigned char failChance=0)
{
const std::vector<ESM::LeveledListBase::LevelItem>& items = levItem->mList;
const MWWorld::Ptr& player = MWBase::Environment::get().getWorld()->getPlayerPtr();
int playerLevel = player.getClass().getCreatureStats(player).getLevel();
failChance += levItem->mChanceNone;
int random = std::rand()/ (static_cast<double> (RAND_MAX) + 1) * 100; // [0, 99]
if (random < failChance)
return std::string();
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 && it->mLevel <= playerLevel)
highestLevel = it->mLevel;
}
// For levelled creatures, the flags are swapped. This file format just makes so much sense.
bool allLevels = levItem->mFlags & ESM::ItemLevList::AllLevels;
if (creature)
allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
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
&& (allLevels || it->mLevel == highestLevel))
{
candidates.push_back(it->mId);
if (it->mLevel >= highest.first)
highest = std::make_pair(it->mLevel, it->mId);
}
}
if (candidates.empty())
return std::string();
std::string item = candidates[std::rand()%candidates.size()];
// Is this another levelled item or a real item?
try
{
MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1);
if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name()
&& ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name())
{
return item;
}
else
{
if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name())
return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, failChance);
else
return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, failChance);
}
}
catch (std::logic_error&)
{
// Vanilla doesn't fail on nonexistent items in levelled lists
std::cerr << "Warning: ignoring nonexistent item '" << item << "'" << std::endl;
return std::string();
}
}
}
#endif