OpenMW
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
levelledlist.hpp
Go to the documentation of this file.
1 #ifndef OPENMW_MECHANICS_LEVELLEDLIST_H
2 #define OPENMW_MECHANICS_LEVELLEDLIST_H
3 
6 
7 #include "../mwworld/ptr.hpp"
8 #include "../mwworld/esmstore.hpp"
9 #include "../mwworld/manualref.hpp"
10 #include "../mwworld/class.hpp"
11 
12 #include "../mwbase/world.hpp"
13 #include "../mwbase/environment.hpp"
14 
15 #include "creaturestats.hpp"
16 #include "actorutil.hpp"
17 
18 namespace MWMechanics
19 {
20 
22  inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, unsigned char failChance=0)
23  {
24  const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;
25 
26  const MWWorld::Ptr& player = getPlayer();
27  int playerLevel = player.getClass().getCreatureStats(player).getLevel();
28 
29  failChance += levItem->mChanceNone;
30 
31  if (Misc::Rng::roll0to99() < failChance)
32  return std::string();
33 
34  std::vector<std::string> candidates;
35  int highestLevel = 0;
36  for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
37  {
38  if (it->mLevel > highestLevel && it->mLevel <= playerLevel)
39  highestLevel = it->mLevel;
40  }
41 
42  // For levelled creatures, the flags are swapped. This file format just makes so much sense.
43  bool allLevels = (levItem->mFlags & ESM::ItemLevList::AllLevels) != 0;
44  if (creature)
45  allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
46 
47  std::pair<int, std::string> highest = std::make_pair(-1, "");
48  for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
49  {
50  if (playerLevel >= it->mLevel
51  && (allLevels || it->mLevel == highestLevel))
52  {
53  candidates.push_back(it->mId);
54  if (it->mLevel >= highest.first)
55  highest = std::make_pair(it->mLevel, it->mId);
56  }
57  }
58  if (candidates.empty())
59  return std::string();
60  std::string item = candidates[Misc::Rng::rollDice(candidates.size())];
61 
62  // Vanilla doesn't fail on nonexistent items in levelled lists
64  {
65  Log(Debug::Warning) << "Warning: ignoring nonexistent item '" << item << "' in levelled list '" << levItem->mId << "'";
66  return std::string();
67  }
68 
69  // Is this another levelled item or a real item?
70  MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1);
71  if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name()
72  && ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name())
73  {
74  return item;
75  }
76  else
77  {
78  if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name())
79  return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, failChance);
80  else
81  return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, failChance);
82  }
83  }
84 
85 }
86 
87 #endif
virtual MWMechanics::CreatureStats & getCreatureStats(const Ptr &ptr) const
Definition: class.cpp:63
World * getWorld() const
Definition: environment.cpp:107
const Class & getClass() const
Definition: ptr.hpp:40
const std::string & getTypeName() const
Definition: ptr.cpp:9
unsigned char mChanceNone
Definition: loadlevlist.hpp:24
static const Environment & get()
Return instance of this class.
Definition: environment.cpp:196
static std::string lowerCase(const std::string &in)
Returns lower case copy of input string.
Definition: stringops.hpp:177
Definition: debuglog.hpp:13
virtual const MWWorld::ESMStore & getStore() const =0
Definition: debuglog.hpp:22
MWWorld::Ptr getPlayer()
Definition: actorutil.cpp:10
const Ptr & getPtr() const
Definition: manualref.hpp:22
int getLevel() const
Definition: creaturestats.cpp:96
Manually constructed live cell ref.
Definition: manualref.hpp:11
static int rollDice(int max)
return value in range [0, max) <- note open upper range.
Definition: rng.cpp:26
MWWorld::LiveCellRef< T > * get() const
Definition: ptr.hpp:48
std::string getLevelledItem(const ESM::LevelledListBase *levItem, bool creature, unsigned char failChance=0)
Definition: levelledlist.hpp:22
Definition: loadlevlist.hpp:21
int find(const std::string &id) const
Definition: esmstore.hpp:94
int mFlags
Definition: loadlevlist.hpp:23
Definition: loadlevlist.hpp:81
static int roll0to99()
return value in range [0, 99]
Definition: rng.hpp:33
Definition: loadlevlist.hpp:46
std::vector< LevelItem > mList
Definition: loadlevlist.hpp:37
std::string mId
Definition: loadlevlist.hpp:25
Definition: loadlevlist.hpp:66
Pointer to a LiveCellRef.
Definition: ptr.hpp:19
Definition: loadlevlist.hpp:55
const char * name
Definition: crashcatcher.cpp:67