summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2012-12-14 22:25:07 -0800
committerBen Longbons <b.r.longbons@gmail.com>2012-12-15 19:41:53 -0800
commit4bd7eeec09629d3c0f900d42c899fe23c69e07b6 (patch)
tree4fbbfa45d9538cab7e1062f2c927297bb93ada0a /src/common
parent069f39e8a1ebee3e4a4ce8302d0099842876782b (diff)
downloadtmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.tar.gz
tmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.tar.bz2
tmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.tar.xz
tmwa-4bd7eeec09629d3c0f900d42c899fe23c69e07b6.zip
Prepare to trim skills
Diffstat (limited to 'src/common')
-rw-r--r--src/common/mmo.hpp8
-rw-r--r--src/common/utils.hpp3
-rw-r--r--src/common/utils2.hpp138
3 files changed, 146 insertions, 3 deletions
diff --git a/src/common/mmo.hpp b/src/common/mmo.hpp
index 7441a16..eb8ed1c 100644
--- a/src/common/mmo.hpp
+++ b/src/common/mmo.hpp
@@ -18,7 +18,8 @@
# define MAX_AMOUNT 30000
# define MAX_ZENY 1000000000 // 1G zeny
# define MAX_CART 100
-# define MAX_SKILL 450
+enum class SkillID : uint16_t;
+constexpr SkillID MAX_SKILL = SkillID(474); // not 450
# define GLOBAL_REG_NUM 96
# define ACCOUNT_REG_NUM 16
# define ACCOUNT_REG2_NUM 16
@@ -70,7 +71,8 @@ struct point
struct skill
{
- unsigned short id, lv, flags;
+ SkillID id;
+ unsigned short lv, flags;
};
struct global_reg
@@ -107,7 +109,7 @@ struct mmo_charstatus
struct point last_point, save_point, memo_point[10];
struct item inventory[MAX_INVENTORY], cart[MAX_CART];
- struct skill skill[MAX_SKILL];
+ earray<struct skill, SkillID, MAX_SKILL> skill;
int global_reg_num;
struct global_reg global_reg[GLOBAL_REG_NUM];
int account_reg_num;
diff --git a/src/common/utils.hpp b/src/common/utils.hpp
index fdd9d40..76ac626 100644
--- a/src/common/utils.hpp
+++ b/src/common/utils.hpp
@@ -3,6 +3,9 @@
#include "sanity.hpp"
+// unguarded!
+#include "utils2.hpp"
+
/*
Notes about memory allocation in tmwAthena:
There used to be 3 sources of allocation: these macros,
diff --git a/src/common/utils2.hpp b/src/common/utils2.hpp
new file mode 100644
index 0000000..aef6f73
--- /dev/null
+++ b/src/common/utils2.hpp
@@ -0,0 +1,138 @@
+// included by utils.hpp as a porting aid.
+// Eventually it will be promoted to one or more normal headers.
+
+#include <type_traits>
+#include <iterator>
+
+template<class T, class E, E max>
+struct earray
+{
+ // no ctor/dtor and one public member variable for easy initialization
+ T _data[size_t(max)];
+
+ T& operator[](E v)
+ {
+ return _data[size_t(v)];
+ }
+
+ const T& operator[](E v) const
+ {
+ return _data[size_t(v)];
+ }
+
+ T *begin()
+ {
+ return _data;
+ }
+
+ T *end()
+ {
+ return _data + size_t(max);
+ }
+};
+
+template<class T, class E>
+class eptr
+{
+ T *_data;
+public:
+ eptr(decltype(nullptr)=nullptr)
+ : _data(nullptr)
+ {}
+
+ template<E max>
+ eptr(earray<T, E, max>& arr)
+ : _data(arr._data)
+ {}
+
+ T& operator [](E v)
+ {
+ return _data[size_t(v)];
+ }
+
+ explicit operator bool()
+ {
+ return _data;
+ }
+
+ bool operator not()
+ {
+ return not _data;
+ }
+};
+
+template<class It>
+class IteratorPair
+{
+ It b, e;
+public:
+ IteratorPair(It b, It e)
+ : b(b), e(e)
+ {}
+
+ It begin() { return b; }
+ It end() { return e; }
+};
+
+template<class It>
+IteratorPair<It> iterator_pair(It b, It e)
+{
+ return {b, e};
+}
+
+#ifndef HAVE_STD_UNDERLYING_TYPE
+// Note: you *must* correctly define/not define this - it conflicts!
+namespace std
+{
+ template<class E>
+ struct underlying_type
+ {
+ static_assert(std::is_enum<E>::value, "Only enums have underlying type!");
+ typedef typename std::conditional<
+ std::is_signed<E>::value,
+ typename std::make_signed<E>::type,
+ typename std::make_unsigned<E>::type
+ >::type type;
+ };
+}
+#endif // HAVE_STD_UNDERLYING_TYPE
+
+template<class E>
+class EnumValueIterator
+{
+ typedef typename std::underlying_type<E>::type U;
+ E value;
+public:
+ EnumValueIterator(E v)
+ : value(v)
+ {}
+
+ E operator *()
+ {
+ return value;
+ }
+ EnumValueIterator& operator++ ()
+ {
+ value = E(U(value) + 1);
+ return *this;
+ }
+ EnumValueIterator& operator-- ()
+ {
+ value = E(U(value) - 1);
+ return *this;
+ }
+ friend bool operator == (EnumValueIterator l, EnumValueIterator r)
+ {
+ return l.value == r.value;
+ }
+ friend bool operator != (EnumValueIterator l, EnumValueIterator r)
+ {
+ return !(l == r);
+ }
+};
+
+template<class E>
+IteratorPair<EnumValueIterator<E>> erange(E b, E e)
+{
+ return {b, e};
+}