mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Move getLevelledItem implementaiton in .cpp
This commit is contained in:
parent
6fb14841ab
commit
fbd7ae3e2d
4 changed files with 82 additions and 68 deletions
74
apps/openmw/mwmechanics/levelledlist.cpp
Normal file
74
apps/openmw/mwmechanics/levelledlist.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm3/loadlevlist.hpp>
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "actorutil.hpp"
|
||||
#include "creaturestats.hpp"
|
||||
#include "levelledlist.hpp"
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
|
||||
const ESM::RefId& getLevelledItem(const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Generator& prng)
|
||||
{
|
||||
const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;
|
||||
|
||||
const MWWorld::Ptr& player = getPlayer();
|
||||
int playerLevel = player.getClass().getCreatureStats(player).getLevel();
|
||||
|
||||
if (Misc::Rng::roll0to99(prng) < levItem->mChanceNone)
|
||||
return ESM::RefId::sEmpty;
|
||||
|
||||
std::vector<const ESM::RefId*> candidates;
|
||||
int highestLevel = 0;
|
||||
for (const auto& levelledItem : items)
|
||||
{
|
||||
if (levelledItem.mLevel > highestLevel && levelledItem.mLevel <= playerLevel)
|
||||
highestLevel = levelledItem.mLevel;
|
||||
}
|
||||
|
||||
// For levelled creatures, the flags are swapped. This file format just makes so much sense.
|
||||
bool allLevels = (levItem->mFlags & ESM::ItemLevList::AllLevels) != 0;
|
||||
if (creature)
|
||||
allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
|
||||
|
||||
for (const auto& levelledItem : items)
|
||||
{
|
||||
if (playerLevel >= levelledItem.mLevel && (allLevels || levelledItem.mLevel == highestLevel))
|
||||
candidates.push_back(&levelledItem.mId);
|
||||
}
|
||||
if (candidates.empty())
|
||||
return ESM::RefId::sEmpty;
|
||||
const ESM::RefId& item = *candidates[Misc::Rng::rollDice(candidates.size(), prng)];
|
||||
|
||||
// Vanilla doesn't fail on nonexistent items in levelled lists
|
||||
if (!MWBase::Environment::get().getWorld()->getStore().find(item))
|
||||
{
|
||||
Log(Debug::Warning) << "Warning: ignoring nonexistent item " << item << " in levelled list "
|
||||
<< levItem->mId;
|
||||
return ESM::RefId::sEmpty;
|
||||
}
|
||||
|
||||
// Is this another levelled item or a real item?
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1);
|
||||
if (ref.getPtr().getType() != ESM::ItemLevList::sRecordId
|
||||
&& ref.getPtr().getType() != ESM::CreatureLevList::sRecordId)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ref.getPtr().getType() == ESM::ItemLevList::sRecordId)
|
||||
return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, prng);
|
||||
else
|
||||
return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, prng);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,81 +1,19 @@
|
|||
#ifndef OPENMW_MECHANICS_LEVELLEDLIST_H
|
||||
#define OPENMW_MECHANICS_LEVELLEDLIST_H
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm3/loadlevlist.hpp>
|
||||
#include <components/misc/rng.hpp>
|
||||
|
||||
#include "../mwworld/class.hpp"
|
||||
#include "../mwworld/esmstore.hpp"
|
||||
#include "../mwworld/manualref.hpp"
|
||||
#include "../mwworld/ptr.hpp"
|
||||
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "actorutil.hpp"
|
||||
#include "creaturestats.hpp"
|
||||
namespace ESM
|
||||
{
|
||||
struct LevelledListBase;
|
||||
class RefId;
|
||||
}
|
||||
|
||||
namespace MWMechanics
|
||||
{
|
||||
|
||||
/// @return ID of resulting item, or empty if none
|
||||
inline const ESM::RefId& getLevelledItem(
|
||||
const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Generator& prng)
|
||||
{
|
||||
const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;
|
||||
|
||||
const MWWorld::Ptr& player = getPlayer();
|
||||
int playerLevel = player.getClass().getCreatureStats(player).getLevel();
|
||||
|
||||
if (Misc::Rng::roll0to99(prng) < levItem->mChanceNone)
|
||||
return ESM::RefId::sEmpty;
|
||||
|
||||
std::vector<const ESM::RefId*> candidates;
|
||||
int highestLevel = 0;
|
||||
for (const auto& levelledItem : items)
|
||||
{
|
||||
if (levelledItem.mLevel > highestLevel && levelledItem.mLevel <= playerLevel)
|
||||
highestLevel = levelledItem.mLevel;
|
||||
}
|
||||
|
||||
// For levelled creatures, the flags are swapped. This file format just makes so much sense.
|
||||
bool allLevels = (levItem->mFlags & ESM::ItemLevList::AllLevels) != 0;
|
||||
if (creature)
|
||||
allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
|
||||
|
||||
for (const auto& levelledItem : items)
|
||||
{
|
||||
if (playerLevel >= levelledItem.mLevel && (allLevels || levelledItem.mLevel == highestLevel))
|
||||
candidates.push_back(&levelledItem.mId);
|
||||
}
|
||||
if (candidates.empty())
|
||||
return ESM::RefId::sEmpty;
|
||||
const ESM::RefId& item = *candidates[Misc::Rng::rollDice(candidates.size(), prng)];
|
||||
|
||||
// Vanilla doesn't fail on nonexistent items in levelled lists
|
||||
if (!MWBase::Environment::get().getWorld()->getStore().find(item))
|
||||
{
|
||||
Log(Debug::Warning) << "Warning: ignoring nonexistent item " << item << " in levelled list "
|
||||
<< levItem->mId;
|
||||
return ESM::RefId::sEmpty;
|
||||
}
|
||||
|
||||
// Is this another levelled item or a real item?
|
||||
MWWorld::ManualRef ref(MWBase::Environment::get().getWorld()->getStore(), item, 1);
|
||||
if (ref.getPtr().getType() != ESM::ItemLevList::sRecordId
|
||||
&& ref.getPtr().getType() != ESM::CreatureLevList::sRecordId)
|
||||
{
|
||||
return item;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ref.getPtr().getType() == ESM::ItemLevList::sRecordId)
|
||||
return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, prng);
|
||||
else
|
||||
return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, prng);
|
||||
}
|
||||
}
|
||||
const ESM::RefId& getLevelledItem(const ESM::LevelledListBase* levItem, bool creature, Misc::Rng::Generator& prng);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm3/inventorystate.hpp>
|
||||
#include <components/esm3/loadench.hpp>
|
||||
#include <components/esm3/loadlevlist.hpp>
|
||||
#include <components/misc/strings/algorithm.hpp>
|
||||
#include <components/misc/strings/lower.hpp>
|
||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <components/esm3/loadcrea.hpp>
|
||||
#include <components/esm3/loadench.hpp>
|
||||
#include <components/esm3/loadgmst.hpp>
|
||||
#include <components/esm3/loadlevlist.hpp>
|
||||
#include <components/esm3/loadmgef.hpp>
|
||||
#include <components/esm3/loadregn.hpp>
|
||||
#include <components/esm3/loadstat.hpp>
|
||||
|
|
Loading…
Reference in a new issue