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 
4 #include <iostream>
5 
7 
8 #include "../mwworld/ptr.hpp"
9 #include "../mwworld/esmstore.hpp"
10 #include "../mwworld/manualref.hpp"
11 #include "../mwworld/class.hpp"
12 
13 #include "../mwbase/world.hpp"
14 #include "../mwbase/environment.hpp"
15 
16 #include "creaturestats.hpp"
17 #include "actorutil.hpp"
18 
19 namespace MWMechanics
20 {
21 
23  inline std::string getLevelledItem (const ESM::LevelledListBase* levItem, bool creature, unsigned char failChance=0)
24  {
25  const std::vector<ESM::LevelledListBase::LevelItem>& items = levItem->mList;
26 
27  const MWWorld::Ptr& player = getPlayer();
28  int playerLevel = player.getClass().getCreatureStats(player).getLevel();
29 
30  failChance += levItem->mChanceNone;
31 
32  if (Misc::Rng::roll0to99() < failChance)
33  return std::string();
34 
35  std::vector<std::string> candidates;
36  int highestLevel = 0;
37  for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
38  {
39  if (it->mLevel > highestLevel && it->mLevel <= playerLevel)
40  highestLevel = it->mLevel;
41  }
42 
43  // For levelled creatures, the flags are swapped. This file format just makes so much sense.
44  bool allLevels = (levItem->mFlags & ESM::ItemLevList::AllLevels) != 0;
45  if (creature)
46  allLevels = levItem->mFlags & ESM::CreatureLevList::AllLevels;
47 
48  std::pair<int, std::string> highest = std::make_pair(-1, "");
49  for (std::vector<ESM::LevelledListBase::LevelItem>::const_iterator it = items.begin(); it != items.end(); ++it)
50  {
51  if (playerLevel >= it->mLevel
52  && (allLevels || it->mLevel == highestLevel))
53  {
54  candidates.push_back(it->mId);
55  if (it->mLevel >= highest.first)
56  highest = std::make_pair(it->mLevel, it->mId);
57  }
58  }
59  if (candidates.empty())
60  return std::string();
61  std::string item = candidates[Misc::Rng::rollDice(candidates.size())];
62 
63  // Vanilla doesn't fail on nonexistent items in levelled lists
65  {
66  std::cerr << "Warning: ignoring nonexistent item '" << item << "' in levelled list '" << levItem->mId << "'" << std::endl;
67  return std::string();
68  }
69 
70  // Is this another levelled item or a real item?
71  MWWorld::ManualRef ref (MWBase::Environment::get().getWorld()->getStore(), item, 1);
72  if (ref.getPtr().getTypeName() != typeid(ESM::ItemLevList).name()
73  && ref.getPtr().getTypeName() != typeid(ESM::CreatureLevList).name())
74  {
75  return item;
76  }
77  else
78  {
79  if (ref.getPtr().getTypeName() == typeid(ESM::ItemLevList).name())
80  return getLevelledItem(ref.getPtr().get<ESM::ItemLevList>()->mBase, false, failChance);
81  else
82  return getLevelledItem(ref.getPtr().get<ESM::CreatureLevList>()->mBase, true, failChance);
83  }
84  }
85 
86 }
87 
88 #endif
virtual MWMechanics::CreatureStats & getCreatureStats(const Ptr &ptr) const
Definition: class.cpp:63
World * getWorld() const
Definition: environment.cpp:82
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:171
static std::string lowerCase(const std::string &in)
Returns lower case copy of input string.
Definition: stringops.hpp:103
virtual const MWWorld::ESMStore & getStore() const =0
MWWorld::Ptr getPlayer()
Definition: actorutil.cpp:10
const Ptr & getPtr() const
Definition: manualref.hpp:22
int getLevel() const
Definition: creaturestats.cpp:95
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:23
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:23
Definition: loadlevlist.hpp:21
int find(const std::string &id) const
Definition: esmstore.hpp:91
int mFlags
Definition: loadlevlist.hpp:23
Definition: loadlevlist.hpp:81
static int roll0to99()
return value in range [0, 99]
Definition: rng.hpp:29
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:59