summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.cpp29
-rw-r--r--src/char/int_storage.cpp4
-rw-r--r--src/generic/array.hpp94
-rw-r--r--src/generic/array_test.cpp159
-rw-r--r--src/generic/enum.hpp60
-rw-r--r--src/generic/oops.cpp45
-rw-r--r--src/generic/oops.hpp43
-rw-r--r--src/generic/oops_test.cpp50
-rw-r--r--src/map/atcommand.cpp36
-rw-r--r--src/map/battle.cpp22
-rw-r--r--src/map/chrif.cpp12
-rw-r--r--src/map/clif.cpp154
-rw-r--r--src/map/clif.hpp20
-rw-r--r--src/map/clif.t.hpp129
-rw-r--r--src/map/magic-expr.cpp4
-rw-r--r--src/map/map.hpp6
-rw-r--r--src/map/mob.cpp4
-rw-r--r--src/map/npc.cpp8
-rw-r--r--src/map/pc.cpp143
-rw-r--r--src/map/pc.hpp18
-rw-r--r--src/map/script.cpp34
-rw-r--r--src/map/storage.cpp24
-rw-r--r--src/map/storage.hpp6
-rw-r--r--src/map/trade.cpp60
-rw-r--r--src/map/trade.hpp4
-rw-r--r--src/mmo/version.hpp58
-rw-r--r--src/proto2/include_clif_t_test.cpp2
-rw-r--r--src/proto2/map-user.hpp46
-rw-r--r--src/proto2/types.hpp40
29 files changed, 883 insertions, 431 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp
index 965693b..c26fa64 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -359,7 +359,8 @@ AString mmo_char_tostr(struct CharPair *cp)
// memos were here (no longer supported)
str_p += '\t';
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
+ {
if (p->inventory[i].nameid)
{
str_p += STRPRINTF("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d "_fmt,
@@ -376,26 +377,33 @@ AString mmo_char_tostr(struct CharPair *cp)
0 /*card[3]*/,
0 /*broken*/);
}
+ }
str_p += '\t';
// cart was here (no longer supported)
str_p += '\t';
for (SkillID i : erange(SkillID(), MAX_SKILL))
+ {
if (p->skill[i].lv)
{
str_p += STRPRINTF("%d,%d "_fmt,
i,
p->skill[i].lv | (static_cast<uint16_t>(p->skill[i].flags) << 16));
}
+ }
str_p += '\t';
assert (p->global_reg_num < GLOBAL_REG_NUM);
for (int i = 0; i < p->global_reg_num; i++)
+ {
if (p->global_reg[i].str)
+ {
str_p += STRPRINTF("%s,%d "_fmt,
p->global_reg[i].str,
p->global_reg[i].value);
+ }
+ }
str_p += '\t';
return AString(str_p);
@@ -953,10 +961,14 @@ static
ItemNameId find_equip_view(const CharPair *cp, EPOS equipmask)
{
CharData *p = cp->data.get();
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
+ {
if (p->inventory[i].nameid && p->inventory[i].amount
&& bool(p->inventory[i].equip & equipmask))
+ {
return p->inventory[i].nameid;
+ }
+ }
return ItemNameId();
}
@@ -1348,7 +1360,7 @@ void parse_tologin(Session *ls)
cd.sex = sex;
// auth_fifo[i].sex = sex;
// to avoid any problem with equipment and invalid sex, equipment is unequiped.
- for (int j = 0; j < MAX_INVENTORY; j++)
+ for (IOff0 j : IOff0::iter())
{
if (cd.inventory[j].nameid
&& bool(cd.inventory[j].equip))
@@ -1482,10 +1494,11 @@ void parse_tologin(Session *ls)
CharData *c = &cd;
Storage *s = account2storage(k->account_id);
int changes = 0;
- int j;
#define FIX(v) if (v == source_id) {v = dest_id; ++changes; }
- for (j = 0; j < MAX_INVENTORY; j++)
+ for (IOff0 j : IOff0::iter())
+ {
FIX(c->inventory[j].nameid);
+ }
// used to FIX cart, but it's no longer supported
// FIX(c->weapon);
FIX(c->shield);
@@ -1494,8 +1507,12 @@ void parse_tologin(Session *ls)
FIX(c->head_bottom);
if (s)
- for (j = 0; j < s->storage_amount; j++)
+ {
+ for (SOff0 j : SOff0::iter())
+ {
FIX(s->storage_[j].nameid);
+ }
+ }
#undef FIX
if (changes)
CHAR_LOG("itemfrob(%d -> %d): `%s'(%d, account %d): changed %d times\n"_fmt,
diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp
index 7a41f43..9527806 100644
--- a/src/char/int_storage.cpp
+++ b/src/char/int_storage.cpp
@@ -58,7 +58,8 @@ AString storage_tostr(Storage *p)
p->account_id, p->storage_amount);
int f = 0;
- for (int i = 0; i < MAX_STORAGE; i++)
+ for (SOff0 i : SOff0::iter())
+ {
if (p->storage_[i].nameid && p->storage_[i].amount)
{
str += STRPRINTF(
@@ -77,6 +78,7 @@ AString storage_tostr(Storage *p)
// shouldn't that include 'broken' also? Oh, well ...
f++;
}
+ }
str += '\t';
diff --git a/src/generic/array.hpp b/src/generic/array.hpp
index e6fefae..5e4dd67 100644
--- a/src/generic/array.hpp
+++ b/src/generic/array.hpp
@@ -24,18 +24,94 @@
# include <cassert>
# include <cstddef>
-template<class T, size_t n>
-struct Array
+# include "oops.hpp"
+
+template<class I, I be, I en>
+struct ExclusiveIndexing
+{
+ using index_type = I;
+ constexpr static size_t index_to_offset(index_type idx)
+ { return static_cast<size_t>(idx) - static_cast<size_t>(be); }
+ constexpr static index_type offset_to_index(size_t off)
+ { return static_cast<I>(off + static_cast<size_t>(be)); }
+ constexpr static size_t alloc_size = index_to_offset(en) - index_to_offset(be);
+};
+
+template<size_t n>
+using SimpleIndexing = ExclusiveIndexing<size_t, 0, n>;
+
+template<class I, I lo, I hi>
+struct InclusiveIndexing
+{
+ using index_type = I;
+ constexpr static size_t index_to_offset(index_type idx)
+ { return static_cast<size_t>(idx) - static_cast<size_t>(lo); }
+ constexpr static index_type offset_to_index(size_t off)
+ { return static_cast<I>(off + static_cast<size_t>(lo)); }
+ constexpr static size_t alloc_size = index_to_offset(hi) - index_to_offset(lo) + 1;
+};
+
+template<class E, E n=E::COUNT>
+struct EnumIndexing : ExclusiveIndexing<E, static_cast<E>(0), n>
{
- T data[n];
+};
+
+template<class I, size_t limit>
+struct InventoryIndexing
+{
+ using index_type = I;
+ constexpr static size_t index_to_offset(index_type idx)
+ { return idx.get0(); }
+ constexpr static index_type offset_to_index(size_t off)
+ { return I::from(off); }
+ constexpr static size_t alloc_size = limit;
+};
+
+template<class T, class I>
+struct GenericArray
+{
+ T data[I::alloc_size];
public:
- T& operator [](size_t i) { assert (i < n); return data[i]; }
- const T& operator [](size_t i) const { assert (i < n); return data[i]; }
+ T *begin()
+ { return data + 0; }
+ T *end()
+ { return data + I::alloc_size; }
+ const T *begin() const
+ { return data + 0; }
+ const T *end() const
+ { return data + I::alloc_size; }
+ size_t size() const
+ { return I::alloc_size; }
+
+ T& operator [](typename I::index_type i_)
+ {
+ size_t i = I::index_to_offset(i_);
+ ALLEGE ("index in bounds", i < size());
+ return data[i];
+ }
+ const T& operator [](typename I::index_type i_) const
+ {
+ size_t i = I::index_to_offset(i_);
+ ALLEGE ("index in bounds", i < size());
+ return data[i];
+ }
- T *begin() { return data + 0; }
- T *end() { return data + n; }
- const T *begin() const { return data + 0; }
- const T *end() const { return data + n; }
+ friend bool operator == (GenericArray& lhs, GenericArray& rhs)
+ {
+ for (size_t i = 0; i < I::alloc_size; ++i)
+ {
+ if (lhs.data[i] != rhs.data[i])
+ return false;
+ }
+ return true;
+ }
+ friend bool operator != (GenericArray& lhs, GenericArray& rhs)
+ {
+ return !(lhs == rhs);
+ }
};
+template<class T, size_t n>
+using Array = GenericArray<T, SimpleIndexing<n>>;
+
#endif // TMWA_GENERIC_ARRAY_HPP
diff --git a/src/generic/array_test.cpp b/src/generic/array_test.cpp
new file mode 100644
index 0000000..7b5ffca
--- /dev/null
+++ b/src/generic/array_test.cpp
@@ -0,0 +1,159 @@
+#include "array.hpp"
+// array_test.cpp - Testsuite for a simple bounds-checked array.
+//
+// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include <gtest/gtest.h>
+
+#include "../poison.hpp"
+
+
+TEST(Array, simple)
+{
+ GenericArray<int, SimpleIndexing<3>> a;
+ try
+ {
+ a[0];
+ a[1];
+ a[2];
+ SUCCEED();
+ }
+ catch (const AssertionError&)
+ {
+ FAIL();
+ }
+ try
+ {
+ a[3];
+ FAIL();
+ }
+ catch (const AssertionError&)
+ {
+ SUCCEED();
+ }
+}
+
+TEST(Array, inclusive1)
+{
+ GenericArray<int, InclusiveIndexing<int, 1, 3>> a;
+ try
+ {
+ a[0];
+ FAIL();
+ }
+ catch (const AssertionError&)
+ {
+ SUCCEED();
+ }
+ try
+ {
+ a[1];
+ a[2];
+ a[3];
+ SUCCEED();
+ }
+ catch (const AssertionError&)
+ {
+ FAIL();
+ }
+ try
+ {
+ a[4];
+ FAIL();
+ }
+ catch (const AssertionError&)
+ {
+ SUCCEED();
+ }
+}
+
+TEST(Array, negative)
+{
+ GenericArray<int, InclusiveIndexing<int, -1, 1>> a;
+ try
+ {
+ a[-2];
+ FAIL();
+ }
+ catch (const AssertionError&)
+ {
+ SUCCEED();
+ }
+ try
+ {
+ a[-1];
+ a[0];
+ a[1];
+ SUCCEED();
+ }
+ catch (const AssertionError&)
+ {
+ FAIL();
+ }
+ try
+ {
+ a[2];
+ FAIL();
+ }
+ catch (const AssertionError&)
+ {
+ SUCCEED();
+ }
+}
+
+TEST(Array, enum)
+{
+ enum class Blah
+ {
+ FOO,
+ BAR,
+ BAZ,
+ COUNT,
+ };
+
+ GenericArray<int, EnumIndexing<Blah>> a;
+ try
+ {
+ a[static_cast<Blah>(-1)];
+ FAIL();
+ }
+ catch (const AssertionError&)
+ {
+ SUCCEED();
+ }
+ try
+ {
+ a[Blah::FOO];
+ a[Blah::BAR];
+ a[Blah::BAZ];
+ SUCCEED();
+ }
+ catch (const AssertionError&)
+ {
+ FAIL();
+ }
+ try
+ {
+ a[Blah::COUNT];
+ FAIL();
+ }
+ catch (const AssertionError&)
+ {
+ SUCCEED();
+ }
+}
diff --git a/src/generic/enum.hpp b/src/generic/enum.hpp
index 5f075bc..1e83c24 100644
--- a/src/generic/enum.hpp
+++ b/src/generic/enum.hpp
@@ -29,62 +29,10 @@
# include "../compat/iter.hpp"
-template<class T, class E, E max>
-struct earray
-{
- constexpr static
- size_t size()
- {
- return static_cast<size_t>(max);
- }
-
- // no ctor/dtor and one public member variable for easy initialization
- T _data[size()];
+# include "array.hpp"
- T& operator[](E v)
- {
- auto i = static_cast<size_t>(v);
- assert (i < size());
- return _data[i];
- }
-
- const T& operator[](E v) const
- {
- auto i = static_cast<size_t>(v);
- assert (i < size());
- return _data[i];
- }
-
- T *begin()
- {
- return _data;
- }
-
- T *end()
- {
- return _data + size();
- }
-
- const T *begin() const
- {
- return _data;
- }
-
- const T *end() const
- {
- return _data + size();
- }
-
- friend bool operator == (const earray& l, const earray& r)
- {
- return std::equal(l.begin(), l.end(), r.begin());
- }
-
- friend bool operator != (const earray& l, const earray& r)
- {
- return !(l == r);
- }
-};
+template<class T, class E, E max>
+using earray = GenericArray<T, EnumIndexing<E, max>>;
template<class T, class E, E max>
class eptr
@@ -102,7 +50,7 @@ public:
{}
eptr(earray<T, E, max>& arr)
- : _data(arr._data)
+ : _data(arr.data)
{}
T& operator [](E v) const
diff --git a/src/generic/oops.cpp b/src/generic/oops.cpp
new file mode 100644
index 0000000..95fdcad
--- /dev/null
+++ b/src/generic/oops.cpp
@@ -0,0 +1,45 @@
+#include "oops.hpp"
+// oops.cpp - Stuff that shouldn't happen.
+//
+// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include <cstdlib>
+#include <cstring>
+#include <cstdio>
+
+//#include "../poison.hpp"
+
+
+static
+std::string do_asprintf(const char *desc, const char *expr,
+ const char *file, size_t line, const char *function)
+{
+ char *what = nullptr;
+ int len = asprintf(&what, "%s:%zu: error: in '%s', incorrectly alleged that '%s' (%s)",
+ file, line, function, desc, expr);
+ if (len == -1)
+ abort();
+ std::string out = what;
+ free(what);
+ return out;
+}
+
+AssertionError::AssertionError(const char *desc, const char *expr,
+ const char *file, size_t line, const char *function)
+: std::runtime_error(do_asprintf(desc, expr, file, line, function))
+{}
diff --git a/src/generic/oops.hpp b/src/generic/oops.hpp
new file mode 100644
index 0000000..231a4e4
--- /dev/null
+++ b/src/generic/oops.hpp
@@ -0,0 +1,43 @@
+#ifndef TMWA_GENERIC_OOPS_HPP
+#define TMWA_GENERIC_OOPS_HPP
+// oops.hpp - Stuff that shouldn't happen.
+//
+// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# include "fwd.hpp"
+
+# include <cstddef>
+
+# include <stdexcept>
+
+# include "oops.hpp"
+
+
+class AssertionError : public std::runtime_error
+{
+ const char *_what;
+public:
+ AssertionError(const char *desc, const char *expr,
+ const char *file, size_t line, const char *function);
+};
+
+# define ALLEGE(desc, expr) \
+ if (expr) {} \
+ else throw AssertionError(desc, #expr, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+
+#endif // TMWA_GENERIC_OOPS_HPP
diff --git a/src/generic/oops_test.cpp b/src/generic/oops_test.cpp
new file mode 100644
index 0000000..d16db04
--- /dev/null
+++ b/src/generic/oops_test.cpp
@@ -0,0 +1,50 @@
+#include "oops.hpp"
+// oops_test.cpp - Testsuite for stuff that shouldn't happen.
+//
+// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
+//
+// This file is part of The Mana World (Athena server)
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#include <gtest/gtest.h>
+
+#include "../poison.hpp"
+
+TEST(oops, okay)
+{
+ try
+ {
+ ALLEGE ("the sky is gray", true);
+ SUCCEED();
+ }
+ catch (const AssertionError& e)
+ {
+ FAIL();
+ }
+}
+
+TEST(oops, uhoh)
+{
+ try
+ {
+ ALLEGE ("the sky is falling", 1 == 0);
+ FAIL();
+ }
+ catch (const AssertionError& e)
+ {
+ ASSERT_STREQ(strstr(e.what(), "src/generic/"),
+ "src/generic/oops_test.cpp:42: error: in 'virtual void oops_uhoh_Test::TestBody()', incorrectly alleged that 'the sky is falling' (1 == 0)");
+ }
+}
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index d2f154f..f405f14 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -1371,7 +1371,7 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd,
PickupFail flag;
if ((flag = pc_additem(sd, &item_tmp, get_count))
!= PickupFail::OKAY)
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
}
clif_displaymessage(s, "Item created."_s);
}
@@ -1388,9 +1388,7 @@ static
ATCE atcommand_itemreset(Session *s, dumb_ptr<map_session_data> sd,
ZString)
{
- int i;
-
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount
&& sd->status.inventory[i].equip == EPOS::ZERO)
@@ -3118,7 +3116,6 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can reset a character only for lower or same GM level
- int i;
// Reset base level
pl_sd->status.base_level = 1;
@@ -3139,7 +3136,7 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::ZENY);
// Clear inventory
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount)
{
@@ -3678,7 +3675,7 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd,
XString item_name;
int i, number = 0;
ItemNameId item_id;
- int item_position, count;
+ int count;
struct item_data *item_data;
if (!asplit(message, &item_name, &number, &character) || number < 1)
@@ -3697,11 +3694,11 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd,
if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can kill only lower or same level
- item_position = pc_search_inventory(pl_sd, item_id);
- if (item_position >= 0)
+ IOff0 item_position = pc_search_inventory(pl_sd, item_id);
+ if (item_position.ok())
{
count = 0;
- for (i = 0; i < number && item_position >= 0; i++)
+ for (i = 0; i < number && item_position.ok(); i++)
{
pc_delitem(pl_sd, item_position, 1, 0);
count++;
@@ -3849,7 +3846,7 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
struct item_data *item_data = NULL;
- int i, count, counter;
+ int count, counter;
CharName character;
if (!asplit(message, &character))
@@ -3863,7 +3860,7 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd,
// you can look items only lower or same level
counter = 0;
count = 0;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (pl_sd->status.inventory[i].nameid
&& (item_data =
@@ -3961,7 +3958,7 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd,
{
Storage *stor;
struct item_data *item_data = NULL;
- int i, count, counter;
+ int count, counter;
CharName character;
if (!asplit(message, &character))
@@ -3977,7 +3974,7 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd,
{
counter = 0;
count = 0;
- for (i = 0; i < MAX_STORAGE; i++)
+ for (SOff0 i : SOff0::iter())
{
if (stor->storage_[i].nameid
&& (item_data =
@@ -4188,8 +4185,7 @@ static
ATCE atcommand_dropall(Session *, dumb_ptr<map_session_data> sd,
ZString)
{
- int i;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount)
{
@@ -4212,7 +4208,7 @@ ATCE atcommand_chardropall(Session *s, dumb_ptr<map_session_data>,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd == NULL)
return ATCE::EXIST;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (pl_sd->status.inventory[i].amount)
{
@@ -4232,8 +4228,6 @@ static
ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd,
ZString)
{
- int i;
-
if (!sd->state.storage_open)
{
//Open storage.
@@ -4250,7 +4244,7 @@ ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::EXIST;
}
}
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount)
{
@@ -4286,7 +4280,7 @@ ATCE atcommand_charstoreall(Session *s, dumb_ptr<map_session_data> sd,
clif_displaymessage(s, "run this command again.."_s);
return ATCE::OKAY;
}
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (pl_sd->status.inventory[i].amount)
{
diff --git a/src/map/battle.cpp b/src/map/battle.cpp
index 99252e3..a653cac 100644
--- a/src/map/battle.cpp
+++ b/src/map/battle.cpp
@@ -1327,9 +1327,9 @@ int battle_is_unarmed(dumb_ptr<block_list> bl)
{
dumb_ptr<map_session_data> sd = bl->is_player();
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- return sidx == -1 && widx == -1;
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ return !sidx.ok() && !widx.ok();
}
else
return 0;
@@ -1449,12 +1449,12 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src,
atkmin = atkmin_ = dex; //最低ATKはDEXで初期化?
sd->state.arrow_atk = 0; //arrow_atk初期化
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
- if (widx >= 0 && sd->inventory_data[widx])
+ if (widx.ok() && sd->inventory_data[widx])
atkmin = atkmin * (80 + sd->inventory_data[widx]->wlv * 20) / 100;
- if (sidx >= 0 && sd->inventory_data[sidx])
+ if (sidx.ok() && sd->inventory_data[sidx])
atkmin_ = atkmin_ * (80 + sd->inventory_data[sidx]->wlv * 20) / 100;
if (sd->status.weapon == ItemLook::BOW)
{ //武器が弓矢の場合
@@ -2010,8 +2010,8 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
// 攻撃対象となりうるので攻撃
if (sd && sd->status.weapon == ItemLook::BOW)
{
- int aidx = sd->equip_index_maybe[EQUIP::ARROW];
- if (aidx >= 0)
+ IOff0 aidx = sd->equip_index_maybe[EQUIP::ARROW];
+ if (aidx.ok())
{
if (battle_config.arrow_decrement)
pc_delitem(sd, aidx, 1, 0);
@@ -2058,9 +2058,9 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
if (src->bl_type == BL::PC)
{
- int weapon_index = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 weapon_index = sd->equip_index_maybe[EQUIP::WEAPON];
ItemNameId weapon;
- if (weapon_index >= 0 && sd->inventory_data[weapon_index]
+ if (weapon_index.ok() && sd->inventory_data[weapon_index]
&& bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON))
weapon = sd->inventory_data[weapon_index]->nameid;
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index 3a329f8..ff0adbd 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -625,7 +625,6 @@ void chrif_changedgm(Session *, const Packet_Fixed<0x2b0b>& fixed)
static
void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed)
{
- int i;
dumb_ptr<map_session_data> sd;
AccountId acc = fixed.account_id;
@@ -642,7 +641,7 @@ void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed)
else if (sd->status.sex == SEX::FEMALE)
sd->sex = sd->status.sex = SEX::MALE;
// to avoid any problem with equipment and invalid sex, equipment is unequiped.
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid
&& bool(sd->status.inventory[i].equip))
@@ -942,9 +941,8 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameI
{
dumb_ptr<map_session_data> pc = bl->is_player();
Storage *stor = account2storage2(pc->status_key.account_id);
- int j;
- for (j = 0; j < MAX_INVENTORY; j++)
+ for (IOff0 j : IOff0::iter())
IFIX(pc->status.inventory[j].nameid);
// cart is no longer supported
// IFIX(pc->status.weapon);
@@ -954,10 +952,12 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameI
IFIX(pc->status.head_bottom);
if (stor)
- for (j = 0; j < stor->storage_amount; j++)
+ {
+ for (SOff0 j : SOff0::iter())
FIX(stor->storage_[j]);
+ }
- for (j = 0; j < MAX_INVENTORY; j++)
+ for (IOff0 j : IOff0::iter())
{
struct item_data *item = pc->inventory_data[j];
if (item && item->nameid == source_id)
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 2275023..2ae9825 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -673,20 +673,20 @@ void clif_set0078_main_1d8(dumb_ptr<map_session_data> sd, Buffer& buf)
fixed_1d8.species = sd->status.species;
fixed_1d8.hair_style = sd->status.hair;
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
if (sd->attack_spell_override)
fixed_1d8.weapon = sd->attack_spell_look_override;
else
{
- if (widx >= 0 && sd->inventory_data[widx])
+ if (widx.ok() && sd->inventory_data[widx])
{
fixed_1d8.weapon = sd->status.inventory[widx].nameid;
}
else
fixed_1d8.weapon = ItemNameId();
}
- if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
{
fixed_1d8.shield = sd->status.inventory[sidx].nameid;
}
@@ -727,20 +727,20 @@ void clif_set0078_alt_1d9(dumb_ptr<map_session_data> sd, Buffer& buf)
fixed_1d8.species = sd->status.species;
fixed_1d8.hair_style = sd->status.hair;
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
if (sd->attack_spell_override)
fixed_1d8.weapon = sd->attack_spell_look_override;
else
{
- if (widx >= 0 && sd->inventory_data[widx])
+ if (widx.ok() && sd->inventory_data[widx])
{
fixed_1d8.weapon = sd->status.inventory[widx].nameid;
}
else
fixed_1d8.weapon = ItemNameId();
}
- if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
{
fixed_1d8.shield = sd->status.inventory[sidx].nameid;
}
@@ -784,15 +784,15 @@ void clif_set007b(dumb_ptr<map_session_data> sd, Buffer& buf)
fixed_1da.option = sd->status.option;
fixed_1da.species = sd->status.species;
fixed_1da.hair_style = sd->status.hair;
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
- if (widx >= 0 && sd->inventory_data[widx])
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ if (widx.ok() && sd->inventory_data[widx])
{
fixed_1da.weapon = sd->status.inventory[widx].nameid;
}
else
fixed_1da.weapon = ItemNameId();
- if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
{
fixed_1da.shield = sd->status.inventory[sidx].nameid;
}
@@ -1245,21 +1245,19 @@ int clif_buylist(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data_shop> nd)
*/
int clif_selllist(dumb_ptr<map_session_data> sd)
{
- int i, val;
-
nullpo_ret(sd);
Session *s = sd->sess;
std::vector<Packet_Repeat<0x00c7>> repeat_c7;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid && sd->inventory_data[i])
{
- val = sd->inventory_data[i]->value_sell;
+ int val = sd->inventory_data[i]->value_sell;
if (val < 0)
continue;
Packet_Repeat<0x00c7> info;
- info.ioff2 = i + 2;
+ info.ioff2 = i.shift();
info.base_price = val;
info.actual_price = val;
repeat_c7.push_back(info);
@@ -1359,7 +1357,7 @@ void clif_scriptinputstr(dumb_ptr<map_session_data> sd, BlockId npcid)
*
*------------------------------------------
*/
-int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fail)
+int clif_additem(dumb_ptr<map_session_data> sd, IOff0 n, int amount, PickupFail fail)
{
nullpo_ret(sd);
@@ -1367,18 +1365,18 @@ int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fa
Packet_Fixed<0x00a0> fixed_a0;
if (fail != PickupFail::OKAY)
{
- fixed_a0.ioff2 = n + 2;
+ fixed_a0.ioff2 = n.shift();
fixed_a0.amount = amount;
fixed_a0.name_id = ItemNameId();
fixed_a0.pickup_fail = fail;
}
else
{
- if (n < 0 || n >= MAX_INVENTORY || !sd->status.inventory[n].nameid
+ if (!n.ok() || !sd->status.inventory[n].nameid
|| sd->inventory_data[n] == NULL)
return 1;
- fixed_a0.ioff2 = n + 2;
+ fixed_a0.ioff2 = n.shift();
fixed_a0.amount = amount;
fixed_a0.name_id = sd->status.inventory[n].nameid;
fixed_a0.identify = 1;
@@ -1405,13 +1403,13 @@ int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fa
*
*------------------------------------------
*/
-void clif_delitem(dumb_ptr<map_session_data> sd, int n, int amount)
+void clif_delitem(dumb_ptr<map_session_data> sd, IOff0 n, int amount)
{
nullpo_retv(sd);
Session *s = sd->sess;
Packet_Fixed<0x00af> fixed_af;
- fixed_af.ioff2 = n + 2;
+ fixed_af.ioff2 = n.shift();
fixed_af.amount = amount;
send_fpacket<0x00af, 6>(s, fixed_af);
@@ -1425,17 +1423,17 @@ void clif_itemlist(dumb_ptr<map_session_data> sd)
{
nullpo_retv(sd);
- int arrow = -1;
+ IOff0 arrow = IOff0::from(-1);
Session *s = sd->sess;
std::vector<Packet_Repeat<0x01ee>> repeat_1ee;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (!sd->status.inventory[i].nameid
|| sd->inventory_data[i] == NULL
|| itemdb_isequip2(sd->inventory_data[i]))
continue;
Packet_Repeat<0x01ee> info;
- info.ioff2 = i + 2;
+ info.ioff2 = i.shift();
info.name_id = sd->status.inventory[i].nameid;
info.item_type = sd->inventory_data[i]->type;
info.identify = 1;
@@ -1444,7 +1442,7 @@ void clif_itemlist(dumb_ptr<map_session_data> sd)
{
info.epos = EPOS::ARROW;
if (bool(sd->status.inventory[i].equip))
- arrow = i; // ついでに矢装備チェック
+ arrow = i;
}
else
info.epos = EPOS::ZERO;
@@ -1458,7 +1456,7 @@ void clif_itemlist(dumb_ptr<map_session_data> sd)
{
send_packet_repeatonly<0x01ee, 4, 18>(s, repeat_1ee);
}
- if (arrow >= 0)
+ if (arrow.ok())
clif_arrowequip(sd, arrow);
}
@@ -1472,14 +1470,14 @@ void clif_equiplist(dumb_ptr<map_session_data> sd)
Session *s = sd->sess;
std::vector<Packet_Repeat<0x00a4>> repeat_a4;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (!sd->status.inventory[i].nameid
|| sd->inventory_data[i] == NULL
|| !itemdb_isequip2(sd->inventory_data[i]))
continue;
Packet_Repeat<0x00a4> info;
- info.ioff2 = i + 2;
+ info.ioff2 = i.shift();
info.name_id = sd->status.inventory[i].nameid;
info.item_type = (
sd->inventory_data[i]->type == ItemType::_7
@@ -1515,7 +1513,7 @@ int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor)
Session *s = sd->sess;
std::vector<Packet_Repeat<0x01f0>> repeat_1f0;
- for (int i = 0; i < MAX_STORAGE; i++)
+ for (SOff0 i : SOff0::iter())
{
if (!stor->storage_[i].nameid)
continue;
@@ -1527,7 +1525,7 @@ int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor)
continue;
Packet_Repeat<0x01f0> info;
- info.soff1 = i + 1;
+ info.soff1 = i.shift();
info.name_id = stor->storage_[i].nameid;
info.item_type = id->type;
info.identify = 0;
@@ -1557,7 +1555,7 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd, Storage *stor)
Session *s = sd->sess;
std::vector<Packet_Repeat<0x00a6>> repeat_a6;
- for (int i = 0; i < MAX_STORAGE; i++)
+ for (SOff0 i : SOff0::iter())
{
if (!stor->storage_[i].nameid)
continue;
@@ -1568,7 +1566,7 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd, Storage *stor)
if (!itemdb_isequip2(id))
continue;
Packet_Repeat<0x00a6> info;
- info.soff1 = i + 1;
+ info.soff1 = i.shift();
info.name_id = stor->storage_[i].nameid;
info.item_type = id->type;
info.identify = 0;
@@ -1837,8 +1835,8 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
EQUIP equip_point = equip_points[type];
fixed_1d7.look_type = type;
- int idx = sd->equip_index_maybe[equip_point];
- if (idx >= 0 && sd->inventory_data[idx])
+ IOff0 idx = sd->equip_index_maybe[equip_point];
+ if (idx.ok() && sd->inventory_data[idx])
{
fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->status.inventory[idx].nameid);
}
@@ -1849,20 +1847,20 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
else
{
fixed_1d7.look_type = LOOK::WEAPON;
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
if (sd->attack_spell_override)
fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->attack_spell_look_override);
else
{
- if (widx >= 0 && sd->inventory_data[widx])
+ if (widx.ok() && sd->inventory_data[widx])
{
fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->status.inventory[widx].nameid);
}
else
fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(ItemNameId());
}
- if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
{
fixed_1d7.shield = sd->status.inventory[sidx].nameid;
}
@@ -1954,7 +1952,7 @@ int clif_initialstatus(dumb_ptr<map_session_data> sd)
*矢装備
*------------------------------------------
*/
-int clif_arrowequip(dumb_ptr<map_session_data> sd, int val)
+int clif_arrowequip(dumb_ptr<map_session_data> sd, IOff0 val)
{
nullpo_ret(sd);
@@ -1962,7 +1960,7 @@ int clif_arrowequip(dumb_ptr<map_session_data> sd, int val)
Session *s = sd->sess;
Packet_Fixed<0x013c> fixed_13c;
- fixed_13c.ioff2 = val + 2;
+ fixed_13c.ioff2 = val.shift();
send_fpacket<0x013c, 4>(s, fixed_13c);
return 0;
@@ -2007,13 +2005,13 @@ int clif_statusupack(dumb_ptr<map_session_data> sd, SP type, int ok, int val)
*
*------------------------------------------
*/
-int clif_equipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok)
+int clif_equipitemack(dumb_ptr<map_session_data> sd, IOff0 n, EPOS pos, int ok)
{
nullpo_ret(sd);
Session *s = sd->sess;
Packet_Fixed<0x00aa> fixed_aa;
- fixed_aa.ioff2 = n + 2;
+ fixed_aa.ioff2 = n.shift();
fixed_aa.epos = pos;
fixed_aa.ok = ok;
send_fpacket<0x00aa, 7>(s, fixed_aa);
@@ -2025,13 +2023,13 @@ int clif_equipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok)
*
*------------------------------------------
*/
-int clif_unequipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok)
+int clif_unequipitemack(dumb_ptr<map_session_data> sd, IOff0 n, EPOS pos, int ok)
{
nullpo_ret(sd);
Session *s = sd->sess;
Packet_Fixed<0x00ac> fixed_ac;
- fixed_ac.ioff2 = n + 2;
+ fixed_ac.ioff2 = n.shift();
fixed_ac.epos = pos;
fixed_ac.ok = ok;
send_fpacket<0x00ac, 7>(s, fixed_ac);
@@ -2087,7 +2085,7 @@ int clif_changeoption(dumb_ptr<block_list> bl)
*
*------------------------------------------
*/
-int clif_useitemack(dumb_ptr<map_session_data> sd, int index, int amount,
+int clif_useitemack(dumb_ptr<map_session_data> sd, IOff0 index, int amount,
int ok)
{
nullpo_ret(sd);
@@ -2096,7 +2094,7 @@ int clif_useitemack(dumb_ptr<map_session_data> sd, int index, int amount,
{
Session *s = sd->sess;
Packet_Fixed<0x00a8> fixed_a8;
- fixed_a8.ioff2 = index + 2;
+ fixed_a8.ioff2 = index.shift();
fixed_a8.amount = amount;
fixed_a8.ok = ok;
send_fpacket<0x00a8, 7>(s, fixed_a8);
@@ -2104,7 +2102,7 @@ int clif_useitemack(dumb_ptr<map_session_data> sd, int index, int amount,
else
{
Packet_Fixed<0x01c8> fixed_1c8;
- fixed_1c8.ioff2 = index + 2;
+ fixed_1c8.ioff2 = index.shift();
fixed_1c8.name_id = sd->status.inventory[index].nameid;
fixed_1c8.block_id = sd->bl_id;
fixed_1c8.amount = amount;
@@ -2149,7 +2147,7 @@ void clif_tradestart(dumb_ptr<map_session_data> sd, int type)
*------------------------------------------
*/
void clif_tradeadditem(dumb_ptr<map_session_data> sd,
- dumb_ptr<map_session_data> tsd, int index2, int amount)
+ dumb_ptr<map_session_data> tsd, IOff2 index2, int amount)
{
nullpo_retv(sd);
nullpo_retv(tsd);
@@ -2157,7 +2155,7 @@ void clif_tradeadditem(dumb_ptr<map_session_data> sd,
Session *s = tsd->sess;
Packet_Fixed<0x00e9> fixed_e9;
fixed_e9.amount = amount;
- if (index2 == 0)
+ if (!index2.ok())
{
fixed_e9.name_id = ItemNameId();
fixed_e9.identify = 0;
@@ -2170,7 +2168,7 @@ void clif_tradeadditem(dumb_ptr<map_session_data> sd,
}
else
{
- int index0 = index2 - 2;
+ IOff0 index0 = index2.unshift();
fixed_e9.name_id = sd->status.inventory[index0].nameid;
fixed_e9.identify = 0;
fixed_e9.broken_or_attribute = 0;
@@ -2189,7 +2187,7 @@ void clif_tradeadditem(dumb_ptr<map_session_data> sd,
* アイテム追加成功/失敗
*------------------------------------------
*/
-int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index2, int amount,
+int clif_tradeitemok(dumb_ptr<map_session_data> sd, IOff2 index2, int amount,
int fail)
{
nullpo_ret(sd);
@@ -2275,14 +2273,14 @@ int clif_updatestorageamount(dumb_ptr<map_session_data> sd,
*------------------------------------------
*/
int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor,
- int index, int amount)
+ SOff0 index, int amount)
{
nullpo_ret(sd);
nullpo_ret(stor);
Session *s = sd->sess;
Packet_Fixed<0x00f4> fixed_f4;
- fixed_f4.soff1 = index + 1;
+ fixed_f4.soff1 = index.shift();
fixed_f4.amount = amount;
fixed_f4.name_id = stor->storage_[index].nameid;
fixed_f4.identify = 0;
@@ -2303,14 +2301,14 @@ int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor,
* カプラ倉庫からアイテムを取り去る
*------------------------------------------
*/
-int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index,
+int clif_storageitemremoved(dumb_ptr<map_session_data> sd, SOff0 index,
int amount)
{
nullpo_ret(sd);
Session *s = sd->sess;
Packet_Fixed<0x00f6> fixed_f6;
- fixed_f6.soff1 = index + 1;
+ fixed_f6.soff1 = index.shift();
fixed_f6.amount = amount;
send_fpacket<0x00f6, 8>(s, fixed_f6);
@@ -4110,8 +4108,6 @@ RecvResult clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd)
if (rv != RecvResult::Complete)
return rv;
- int item_index, item_amount;
-
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
@@ -4129,8 +4125,10 @@ RecvResult clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd)
return rv;
}
- item_index = fixed.ioff2 - 2;
- item_amount = fixed.amount;
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 item_index = fixed.ioff2.unshift();
+ int item_amount = fixed.amount;
pc_dropitem(sd, item_index, item_amount);
@@ -4161,7 +4159,9 @@ RecvResult clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd)
if (sd->invincible_timer)
pc_delinvincibletimer(sd);
- pc_useitem(sd, fixed.ioff2 - 2);
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ pc_useitem(sd, fixed.ioff2.unshift());
return rv;
}
@@ -4178,14 +4178,14 @@ RecvResult clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd)
if (rv != RecvResult::Complete)
return rv;
- int index;
-
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
return rv;
}
- index = fixed.ioff2 - 2;
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 index = fixed.ioff2.unshift();
if (sd->npc_id)
return rv;
@@ -4214,14 +4214,14 @@ RecvResult clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd)
if (rv != RecvResult::Complete)
return rv;
- int index;
-
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
return rv;
}
- index = fixed.ioff2 - 2;
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 index = fixed.ioff2.unshift();
if (sd->npc_id
|| sd->opt1 != Opt1::ZERO)
@@ -4366,6 +4366,8 @@ RecvResult clif_parse_TradeAddItem(Session *s, dumb_ptr<map_session_data> sd)
if (rv != RecvResult::Complete)
return rv;
+ if (fixed.zeny_or_ioff2.index != 0 && !fixed.zeny_or_ioff2.ok())
+ return RecvResult::Error;
trade_tradeadditem(sd, fixed.zeny_or_ioff2, fixed.amount);
return rv;
@@ -4577,10 +4579,10 @@ RecvResult clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd)
if (rv != RecvResult::Complete)
return rv;
- int item_index, item_amount;
-
- item_index = fixed.ioff2 - 2;
- item_amount = fixed.amount;
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 item_index = fixed.ioff2.unshift();
+ int item_amount = fixed.amount;
if ((sd->npc_id && !sd->npc_flags.storage) || sd->trade_partner
|| !sd->state.storage_open)
@@ -4604,10 +4606,10 @@ RecvResult clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd)
if (rv != RecvResult::Complete)
return rv;
- int item_index, item_amount;
-
- item_index = fixed.soff1 - 1;
- item_amount = fixed.amount;
+ if (!fixed.soff1.ok())
+ return RecvResult::Error;
+ SOff0 item_index = fixed.soff1.unshift();
+ int item_amount = fixed.amount;
if ((sd->npc_id && !sd->npc_flags.storage) || sd->trade_partner
|| !sd->state.storage_open)
diff --git a/src/map/clif.hpp b/src/map/clif.hpp
index 3bed955..0087d78 100644
--- a/src/map/clif.hpp
+++ b/src/map/clif.hpp
@@ -80,8 +80,8 @@ void clif_scriptmenu(dumb_ptr<map_session_data>, BlockId, XString); //self
void clif_scriptinput(dumb_ptr<map_session_data>, BlockId); //self
void clif_scriptinputstr(dumb_ptr<map_session_data> sd, BlockId npcid); // self
-int clif_additem(dumb_ptr<map_session_data>, int, int, PickupFail); //self
-void clif_delitem(dumb_ptr<map_session_data>, int, int); //self
+int clif_additem(dumb_ptr<map_session_data>, IOff0, int, PickupFail); //self
+void clif_delitem(dumb_ptr<map_session_data>, IOff0, int); //self
int clif_updatestatus(dumb_ptr<map_session_data>, SP); //self
int clif_damage(dumb_ptr<block_list>, dumb_ptr<block_list>,
tick_t, interval_t, interval_t,
@@ -93,14 +93,14 @@ int clif_takeitem(dumb_ptr<block_list> src, dumb_ptr<block_list> dst)
}
int clif_changelook(dumb_ptr<block_list>, LOOK, int); // area
void clif_changelook_accessories(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> dst); // area or target; list gloves, boots etc.
-int clif_arrowequip(dumb_ptr<map_session_data> sd, int val); //self
+int clif_arrowequip(dumb_ptr<map_session_data> sd, IOff0 val); //self
int clif_arrow_fail(dumb_ptr<map_session_data> sd, int type); //self
int clif_statusupack(dumb_ptr<map_session_data>, SP, int, int); // self
-int clif_equipitemack(dumb_ptr<map_session_data>, int, EPOS, int); // self
-int clif_unequipitemack(dumb_ptr<map_session_data>, int, EPOS, int); // self
+int clif_equipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self
+int clif_unequipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self
int clif_misceffect(dumb_ptr<block_list>, int); // area
int clif_changeoption(dumb_ptr<block_list>); // area
-int clif_useitemack(dumb_ptr<map_session_data>, int, int, int); // self
+int clif_useitemack(dumb_ptr<map_session_data>, IOff0, int, int); // self
void clif_emotion(dumb_ptr<block_list> bl, int type);
void clif_sitting(Session *, dumb_ptr<map_session_data> sd);
@@ -109,8 +109,8 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd);
void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name);
void clif_tradestart(dumb_ptr<map_session_data> sd, int type);
void clif_tradeadditem(dumb_ptr<map_session_data> sd,
- dumb_ptr<map_session_data> tsd, int index, int amount);
-int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount,
+ dumb_ptr<map_session_data> tsd, IOff2 index2, int amount);
+int clif_tradeitemok(dumb_ptr<map_session_data> sd, IOff2 index, int amount,
int fail);
int clif_tradedeal_lock(dumb_ptr<map_session_data> sd, int fail);
int clif_tradecancelled(dumb_ptr<map_session_data> sd);
@@ -123,8 +123,8 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd,
int clif_updatestorageamount(dumb_ptr<map_session_data> sd,
Storage *stor);
int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor,
- int index, int amount);
-int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index,
+ SOff0 index, int amount);
+int clif_storageitemremoved(dumb_ptr<map_session_data> sd, SOff0 index,
int amount);
int clif_storageclose(dumb_ptr<map_session_data> sd);
diff --git a/src/map/clif.t.hpp b/src/map/clif.t.hpp
index 5b3d32f..ba9a187 100644
--- a/src/map/clif.t.hpp
+++ b/src/map/clif.t.hpp
@@ -27,8 +27,11 @@
# include "../ints/little.hpp"
+# include "../compat/iter.hpp"
+
# include "../generic/enum.hpp"
+# include "../mmo/consts.hpp"
# include "../mmo/enums.hpp"
@@ -583,6 +586,132 @@ bool network_to_native(Position2 *native, NetPosition2 network)
return true;
}
+struct IOff2;
+struct SOff1;
+
+struct IOff0
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get0() < MAX_INVENTORY; }
+ uint16_t get0() const
+ { return index; }
+ static IOff0 from(uint16_t i)
+ { return IOff0{i}; }
+ static IteratorPair<ValueIterator<IOff0>> iter()
+ { return {IOff0::from(0), IOff0::from(MAX_INVENTORY)}; };
+ friend uint16_t convert_for_printf(IOff0 i0) { return i0.index; }
+
+ IOff0& operator ++() { ++index; return *this; }
+ friend bool operator == (IOff0 l, IOff0 r) { return l.index == r.index; }
+ friend bool operator != (IOff0 l, IOff0 r) { return !(l == r); }
+ IOff2 shift() const;
+
+ IOff0() : index(0) {}
+private:
+ explicit IOff0(uint16_t i) : index(i) {}
+};
+
+struct SOff0
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get0() < MAX_STORAGE; }
+ uint16_t get0() const
+ { return index; }
+ static SOff0 from(uint16_t i)
+ { return SOff0{i}; }
+ static IteratorPair<ValueIterator<SOff0>> iter()
+ { return {SOff0::from(0), SOff0::from(MAX_STORAGE)}; };
+ friend uint16_t convert_for_printf(SOff0 s0) { return s0.index; }
+
+ SOff0& operator ++() { ++index; return *this; }
+ friend bool operator == (SOff0 l, SOff0 r) { return l.index == r.index; }
+ friend bool operator != (SOff0 l, SOff0 r) { return !(l == r); }
+ SOff1 shift() const;
+
+ SOff0() : index(0) {}
+private:
+ explicit SOff0(uint16_t i) : index(i) {}
+};
+struct IOff2
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get2() < MAX_INVENTORY; }
+ uint16_t get2() const
+ { return index - 2; }
+ static IOff2 from(uint16_t i)
+ { return IOff2{static_cast<uint16_t>(i + 2)}; }
+ static IteratorPair<ValueIterator<IOff2>> iter()
+ { return {IOff2::from(0), IOff2::from(MAX_INVENTORY)}; };
+
+ IOff2& operator ++() { ++index; return *this; }
+ friend bool operator == (IOff2 l, IOff2 r) { return l.index == r.index; }
+ friend bool operator != (IOff2 l, IOff2 r) { return !(l == r); }
+ IOff0 unshift() const
+ { return IOff0::from(get2()); }
+
+ IOff2() : index(0) {}
+private:
+ explicit IOff2(uint16_t i) : index(i) {}
+};
+
+struct SOff1
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get1() < MAX_STORAGE; }
+ uint16_t get1() const
+ { return index - 1; }
+ static SOff1 from(uint16_t i)
+ { return SOff1{static_cast<uint16_t>(i + 1)}; }
+ static IteratorPair<ValueIterator<SOff1>> iter()
+ { return {SOff1::from(0), SOff1::from(MAX_STORAGE)}; };
+
+ SOff1& operator ++() { ++index; return *this; }
+ friend bool operator == (SOff1 l, SOff1 r) { return l.index == r.index; }
+ friend bool operator != (SOff1 l, SOff1 r) { return !(l == r); }
+ SOff0 unshift() const
+ { return SOff0::from(get1()); }
+
+ SOff1() : index(0) {}
+private:
+ explicit SOff1(uint16_t i) : index(i) {}
+};
+
+inline IOff2 IOff0::shift() const
+{ return IOff2::from(get0()); }
+inline SOff1 SOff0::shift() const
+{ return SOff1::from(get0()); }
+
+inline
+bool native_to_network(Little16 *network, IOff2 native)
+{
+ return native_to_network(network, native.index);
+}
+
+inline
+bool network_to_native(IOff2 *native, Little16 network)
+{
+ return network_to_native(&native->index, network);
+}
+
+inline
+bool native_to_network(Little16 *network, SOff1 native)
+{
+ return native_to_network(network, native.index);
+}
+
+inline
+bool network_to_native(SOff1 *native, Little16 network)
+{
+ return network_to_native(&native->index, network);
+}
#endif // TMWA_MAP_CLIF_T_HPP
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index b0e68fb..1e5c829 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -858,8 +858,8 @@ int fun_is_equipped(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
for (EQUIP i : EQUIPs)
{
- int idx = chr->equip_index_maybe[i];
- if (idx >= 0 && chr->status.inventory[idx].nameid == item.nameid)
+ IOff0 idx = chr->equip_index_maybe[i];
+ if (idx.ok() && chr->status.inventory[idx].nameid == item.nameid)
{
retval = true;
break;
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 7e61e56..8fc752b 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -183,8 +183,8 @@ struct map_session_data : block_list, SessionData
unsigned char tmw_version; // tmw client version
CharKey status_key;
CharData status;
- Array<struct item_data *, MAX_INVENTORY> inventory_data;
- earray<short, EQUIP, EQUIP::COUNT> equip_index_maybe;
+ GenericArray<struct item_data *, InventoryIndexing<IOff0, MAX_INVENTORY>> inventory_data;
+ earray<IOff0, EQUIP, EQUIP::COUNT> equip_index_maybe;
int weight, max_weight;
MapName mapname_;
Session *sess; // use this, you idiots!
@@ -284,7 +284,7 @@ struct map_session_data : block_list, SessionData
short sc_count;
AccountId trade_partner;
- Array<int, TRADE_MAX> deal_item_index;
+ Array<IOff2, TRADE_MAX> deal_item_index;
Array<int, TRADE_MAX> deal_item_amount;
int deal_zeny;
short deal_locked;
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 336dbe7..01a1029 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -2203,7 +2203,7 @@ void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem)
pc_additem(ditem.first_sd, &temp_item, ditem.amount))
!= PickupFail::OKAY)
{
- clif_additem(ditem.first_sd, 0, 0, flag);
+ clif_additem(ditem.first_sd, IOff0::from(0), 0, flag);
map_addflooritem(&temp_item, 1,
ditem.m, ditem.x, ditem.y,
ditem.first_sd, ditem.second_sd, ditem.third_sd);
@@ -2233,7 +2233,7 @@ void mob_delay_item_drop2(TimerData *, tick_t, struct delay_item_drop2 ditem)
ditem.item_data.amount))
!= PickupFail::OKAY)
{
- clif_additem(ditem.first_sd, 0, 0, flag);
+ clif_additem(ditem.first_sd, IOff0::from(0), 0, flag);
map_addflooritem(&ditem.item_data, ditem.item_data.amount,
ditem.m, ditem.x, ditem.y,
ditem.first_sd, ditem.second_sd, ditem.third_sd);
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 3232e4d..7d2b8da 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -890,11 +890,11 @@ int npc_selllist(dumb_ptr<map_session_data> sd,
return 1;
for (i = 0, z = 0; i < item_list.size(); i++)
{
- if (item_list[i].ioff2 - 2 < 0 || item_list[i].ioff2 - 2 >= MAX_INVENTORY)
+ if (!item_list[i].ioff2.ok())
return 1;
- ItemNameId nameid = sd->status.inventory[item_list[i].ioff2 - 2].nameid;
+ ItemNameId nameid = sd->status.inventory[item_list[i].ioff2.unshift()].nameid;
if (!nameid ||
- sd->status.inventory[item_list[i].ioff2 - 2].amount < item_list[i].count)
+ sd->status.inventory[item_list[i].ioff2.unshift()].amount < item_list[i].count)
return 1;
if (sd->trade_partner)
return 2; // cant sell while trading
@@ -907,7 +907,7 @@ int npc_selllist(dumb_ptr<map_session_data> sd,
pc_getzeny(sd, static_cast<int>(z));
for (i = 0; i < item_list.size(); i++)
{
- int item_id = item_list[i].ioff2 - 2;
+ IOff0 item_id = item_list[i].ioff2.unshift();
pc_delitem(sd, item_id, item_list[i].count, 0);
}
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 4d104d1..d37a7ff 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -497,7 +497,7 @@ int pc_setnewpc(dumb_ptr<map_session_data> sd, AccountId account_id, CharId char
return 0;
}
-EPOS pc_equippoint(dumb_ptr<map_session_data> sd, int n)
+EPOS pc_equippoint(dumb_ptr<map_session_data> sd, IOff0 n)
{
nullpo_retr(EPOS::ZERO, sd);
@@ -514,7 +514,7 @@ int pc_setinventorydata(dumb_ptr<map_session_data> sd)
{
nullpo_ret(sd);
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
ItemNameId id = sd->status.inventory[i].nameid;
sd->inventory_data[i] = itemdb_search(id);
@@ -571,9 +571,9 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd)
nullpo_ret(sd);
for (EQUIP i : EQUIPs)
- sd->equip_index_maybe[i] = -1;
+ sd->equip_index_maybe[i] = IOff0::from(-1);
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (!sd->status.inventory[i].nameid)
continue;
@@ -614,7 +614,7 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd)
}
static
-int pc_isequip(dumb_ptr<map_session_data> sd, int n)
+int pc_isequip(dumb_ptr<map_session_data> sd, IOff0 n)
{
struct item_data *item;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
@@ -970,7 +970,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (first & 1)
{
sd->weight = 0;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (!sd->status.inventory[i].nameid
|| sd->inventory_data[i] == NULL)
@@ -1041,8 +1041,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
for (EQUIP i : EQUIPs_noarrow)
{
- int index = sd->equip_index_maybe[i];
- if (index < 0)
+ IOff0 index = sd->equip_index_maybe[i];
+ if (!index.ok())
continue;
if (i == EQUIP::WEAPON && sd->equip_index_maybe[EQUIP::SHIELD] == index)
continue;
@@ -1077,8 +1077,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
// 装備品によるステータス変化はここで実行
for (EQUIP i : EQUIPs_noarrow)
{
- int index = sd->equip_index_maybe[i];
- if (index < 0)
+ IOff0 index = sd->equip_index_maybe[i];
+ if (!index.ok())
continue;
if (i == EQUIP::WEAPON && sd->equip_index_maybe[EQUIP::SHIELD] == index)
continue;
@@ -1153,10 +1153,10 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->watk_2 += skill_power(sd, SkillID::TMW_BRAWLING) >> 3; // +25 for 200
}
- int aidx = sd->equip_index_maybe[EQUIP::ARROW];
- if (aidx >= 0)
- { // 矢
- int index = aidx;
+ IOff0 aidx = sd->equip_index_maybe[EQUIP::ARROW];
+ if (aidx.ok())
+ {
+ IOff0 index = aidx;
if (sd->inventory_data[index])
{ //まだ属性が入っていない
argrec_t arg[2] =
@@ -1824,14 +1824,12 @@ int pc_skill(dumb_ptr<map_session_data> sd, SkillID id, int level, int flag)
*/
ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, ItemNameId nameid, int amount)
{
- int i;
-
nullpo_retr(ADDITEM::ZERO, sd);
if (itemdb_isequip(nameid))
return ADDITEM::NEW;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid == nameid)
{
@@ -1852,11 +1850,11 @@ ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, ItemNameId nameid, int am
*/
int pc_inventoryblank(dumb_ptr<map_session_data> sd)
{
- int i, b;
+ int b = 0;
nullpo_ret(sd);
- for (i = 0, b = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (!sd->status.inventory[i].nameid)
b++;
@@ -1906,30 +1904,27 @@ int pc_getzeny(dumb_ptr<map_session_data> sd, int zeny)
* アイテムを探して、インデックスを返す
*------------------------------------------
*/
-int pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id)
+IOff0 pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id)
{
- int i;
+ nullpo_retr(IOff0::from(-1), sd);
- nullpo_retr(-1, sd);
-
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid == item_id &&
(sd->status.inventory[i].amount > 0 || !item_id))
return i;
}
- return -1;
+ return IOff0::from(-1);
}
int pc_count_all_items(dumb_ptr<map_session_data> player, ItemNameId item_id)
{
- int i;
int count = 0;
nullpo_ret(player);
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (player->status.inventory[i].nameid == item_id)
count += player->status.inventory[i].amount;
@@ -1940,12 +1935,12 @@ int pc_count_all_items(dumb_ptr<map_session_data> player, ItemNameId item_id)
int pc_remove_items(dumb_ptr<map_session_data> player, ItemNameId item_id, int count)
{
- int i;
-
nullpo_ret(player);
- for (i = 0; i < MAX_INVENTORY && count; i++)
+ for (IOff0 i : IOff0::iter())
{
+ if (!count)
+ break;
if (player->status.inventory[i].nameid == item_id)
{
int to_delete = count;
@@ -1973,7 +1968,7 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, Item *item_data,
int amount)
{
struct item_data *data;
- int i, w;
+ int w;
MAP_LOG_PC(sd, "PICKUP %d %d"_fmt, item_data->nameid, amount);
@@ -1986,12 +1981,13 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, Item *item_data,
if ((w = data->weight * amount) + sd->weight > sd->max_weight)
return PickupFail::TOO_HEAVY;
- i = MAX_INVENTORY;
+ IOff0 i = IOff0::from(MAX_INVENTORY);
if (!itemdb_isequip2(data))
{
- // 装 備品ではないので、既所有品なら個数のみ変化させる
- for (i = 0; i < MAX_INVENTORY; i++)
+ // TODO see if there's any nicer way to preserve the foreach var
+ for (i = IOff0::from(0); i != IOff0::from(MAX_INVENTORY); ++i)
+ {
if (sd->status.inventory[i].nameid == item_data->nameid)
{
if (sd->status.inventory[i].amount + amount > MAX_AMOUNT)
@@ -2000,12 +1996,12 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, Item *item_data,
clif_additem(sd, i, amount, PickupFail::OKAY);
break;
}
+ }
}
- if (i >= MAX_INVENTORY)
+ if (!i.ok())
{
- // 装 備品か未所有品だったので空き欄へ追加
i = pc_search_inventory(sd, ItemNameId());
- if (i >= 0)
+ if (i.ok())
{
sd->status.inventory[i] = *item_data;
@@ -2029,7 +2025,7 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, Item *item_data,
* アイテムを減らす
*------------------------------------------
*/
-int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type)
+int pc_delitem(dumb_ptr<map_session_data> sd, IOff0 n, int amount, int type)
{
nullpo_retr(1, sd);
@@ -2062,14 +2058,14 @@ int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type)
* アイテムを落す
*------------------------------------------
*/
-int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount)
+int pc_dropitem(dumb_ptr<map_session_data> sd, IOff0 n, int amount)
{
nullpo_retr(1, sd);
if (sd->trade_partner || sd->npc_id || sd->state.storage_open)
return 0; // no dropping while trading/npc/storage
- if (n < 0 || n >= MAX_INVENTORY)
+ if (!n.ok())
return 0;
if (amount <= 0)
@@ -2172,7 +2168,7 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem)
PickupFail flag = pc_additem(sd, &fitem->item_data, fitem->item_data.amount);
if (flag != PickupFail::OKAY)
// 重量overで取得失敗
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
else
{
// 取得成功
@@ -2185,12 +2181,12 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem)
}
/* Otherwise, we can't pick up */
- clif_additem(sd, 0, 0, PickupFail::DROP_STEAL);
+ clif_additem(sd, IOff0::from(0), 0, PickupFail::DROP_STEAL);
return 0;
}
static
-int pc_isUseitem(dumb_ptr<map_session_data> sd, int n)
+int pc_isUseitem(dumb_ptr<map_session_data> sd, IOff0 n)
{
struct item_data *item;
ItemNameId nameid;
@@ -2217,13 +2213,13 @@ int pc_isUseitem(dumb_ptr<map_session_data> sd, int n)
* アイテムを使う
*------------------------------------------
*/
-int pc_useitem(dumb_ptr<map_session_data> sd, int n)
+int pc_useitem(dumb_ptr<map_session_data> sd, IOff0 n)
{
int amount;
nullpo_retr(1, sd);
- if (n >= 0 && n < MAX_INVENTORY && sd->inventory_data[n])
+ if (n.ok() && sd->inventory_data[n])
{
amount = sd->status.inventory[n].amount;
if (!sd->status.inventory[n].nameid
@@ -2716,9 +2712,9 @@ int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id)
* 装 備品のチェック
*------------------------------------------
*/
-int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos)
+IOff0 pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(IOff0::from(-1), sd);
for (EQUIP i : EQUIPs)
{
@@ -2726,7 +2722,7 @@ int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos)
return sd->equip_index_maybe[i];
}
- return -1;
+ return IOff0::from(-1);
}
/*==========================================
@@ -3314,13 +3310,13 @@ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type)
for (EQUIP i : EQUIPs)
{
// unequip items that can't be equipped by base 1 [Valaris]
- short *idx = &sd->equip_index_maybe[i];
- if (*idx >= 0)
+ IOff0 *idx = &sd->equip_index_maybe[i];
+ if ((*idx).ok())
{
if (!pc_isequip(sd, *idx))
{
pc_unequipitem(sd, *idx, CalcStatus::LATER);
- *idx = -1;
+ *idx = IOff0::from(-1);
}
}
}
@@ -4381,7 +4377,7 @@ int pc_cleareventtimer(dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, int n)
+int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, IOff0 n)
{
if (bool(sd->status.inventory[n].equip & EPOS::SHOES))
clif_changelook(sd, LOOK::SHOES, 0);
@@ -4396,7 +4392,7 @@ int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, int n)
return 0;
}
-int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
+int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS)
{
ItemNameId nameid;
struct item_data *id;
@@ -4404,9 +4400,9 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
nullpo_ret(sd);
- if (n < 0 || n >= MAX_INVENTORY)
+ if (!n.ok())
{
- clif_equipitemack(sd, 0, EPOS::ZERO, 0);
+ clif_equipitemack(sd, IOff0::from(0), EPOS::ZERO, 0);
return 0;
}
@@ -4431,11 +4427,11 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
{
// アクセサリ用例外処理
EPOS epor = EPOS::ZERO;
- int midx = sd->equip_index_maybe[EQUIP::MISC2];
- int cidx = sd->equip_index_maybe[EQUIP::CAPE];
- if (midx >= 0)
+ IOff0 midx = sd->equip_index_maybe[EQUIP::MISC2];
+ IOff0 cidx = sd->equip_index_maybe[EQUIP::CAPE];
+ if (midx.ok())
epor |= sd->status.inventory[midx].equip;
- if (cidx >= 0)
+ if (cidx.ok())
epor |= sd->status.inventory[cidx].equip;
epor &= (EPOS::MISC2 | EPOS::CAPE);
pos = (epor == EPOS::CAPE ? EPOS::MISC2 : EPOS::CAPE);
@@ -4445,8 +4441,8 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
{
if (bool(pos & equip_pos[i]))
{
- short *idx = &sd->equip_index_maybe[i];
- if (*idx >= 0) //Slot taken, remove item from there.
+ IOff0 *idx = &sd->equip_index_maybe[i];
+ if ((*idx).ok()) //Slot taken, remove item from there.
pc_unequipitem(sd, *idx, CalcStatus::LATER);
*idx = n;
}
@@ -4542,7 +4538,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
* 装 備した物を外す
*------------------------------------------
*/
-int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
+int pc_unequipitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type)
{
nullpo_ret(sd);
@@ -4557,7 +4553,7 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
for (EQUIP i : EQUIPs)
{
if (bool(sd->status.inventory[n].equip & equip_pos[i]))
- sd->equip_index_maybe[i] = -1;
+ sd->equip_index_maybe[i] = IOff0::from(-1);
}
if (bool(sd->status.inventory[n].equip & EPOS::WEAPON))
{
@@ -4605,7 +4601,7 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
return 0;
}
-int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
+int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type)
{
nullpo_retr(1, sd);
@@ -4617,7 +4613,7 @@ int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
{
//Slot taken, remove item from there.
pc_unequipitem(sd, sd->equip_index_maybe[i], type);
- sd->equip_index_maybe[i] = -1;
+ sd->equip_index_maybe[i] = IOff0::from(-1);
}
}
@@ -4631,28 +4627,29 @@ int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
*/
int pc_checkitem(dumb_ptr<map_session_data> sd)
{
- int i, j, k, calc_flag = 0;
+ int calc_flag = 0;
nullpo_ret(sd);
- // 所持品空き詰め
- for (i = j = 0; i < MAX_INVENTORY; i++)
+ IOff0 j = IOff0::from(0);
+ for (IOff0 i : IOff0::iter())
{
if (!(sd->status.inventory[i].nameid))
continue;
- if (i > j)
+ if (i != j)
{
sd->status.inventory[j] = sd->status.inventory[i];
sd->inventory_data[j] = sd->inventory_data[i];
}
- j++;
+ ++j;
}
- for (k = j; k < MAX_INVENTORY; ++k)
+ for (IOff0 k = j; k != IOff0::from(MAX_INVENTORY); ++k)
+ {
sd->status.inventory[k] = Item{};
- for (k = j; k < MAX_INVENTORY; k++)
sd->inventory_data[k] = NULL;
+ }
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (!sd->status.inventory[i].nameid)
continue;
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 87ed708..6e07070 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -84,10 +84,10 @@ int pc_setnewpc(dumb_ptr<map_session_data>, AccountId, CharId, int, uint32_t /*t
int pc_authok(AccountId, int, TimeT, short tmw_version, const CharKey *, const CharData *);
int pc_authfail(AccountId accid);
-EPOS pc_equippoint(dumb_ptr<map_session_data> sd, int n);
+EPOS pc_equippoint(dumb_ptr<map_session_data> sd, IOff0 n);
int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id);
-int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos);
+IOff0 pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos);
int pc_walktoxy(dumb_ptr<map_session_data>, int, int);
int pc_stop_walking(dumb_ptr<map_session_data>, int);
@@ -98,18 +98,18 @@ int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type);
ADDITEM pc_checkadditem(dumb_ptr<map_session_data>, ItemNameId, int);
int pc_inventoryblank(dumb_ptr<map_session_data>);
-int pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id);
+IOff0 pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id);
int pc_payzeny(dumb_ptr<map_session_data>, int);
PickupFail pc_additem(dumb_ptr<map_session_data>, Item *, int);
int pc_getzeny(dumb_ptr<map_session_data>, int);
-int pc_delitem(dumb_ptr<map_session_data>, int, int, int);
+int pc_delitem(dumb_ptr<map_session_data>, IOff0, int, int);
int pc_checkitem(dumb_ptr<map_session_data>);
int pc_count_all_items(dumb_ptr<map_session_data> player, ItemNameId item_id);
int pc_remove_items(dumb_ptr<map_session_data> player,
ItemNameId item_id, int count);
int pc_takeitem(dumb_ptr<map_session_data>, dumb_ptr<flooritem_data>);
-int pc_dropitem(dumb_ptr<map_session_data>, int, int);
+int pc_dropitem(dumb_ptr<map_session_data>, IOff0, int);
int pc_checkweighticon(dumb_ptr<map_session_data> sd);
@@ -134,10 +134,10 @@ int pc_skillup(dumb_ptr<map_session_data>, SkillID);
int pc_resetlvl(dumb_ptr<map_session_data>, int type);
int pc_resetstate(dumb_ptr<map_session_data>);
int pc_resetskill(dumb_ptr<map_session_data>);
-int pc_equipitem(dumb_ptr<map_session_data>, int, EPOS);
-int pc_unequipitem(dumb_ptr<map_session_data>, int, CalcStatus);
-int pc_unequipinvyitem(dumb_ptr<map_session_data>, int, CalcStatus);
-int pc_useitem(dumb_ptr<map_session_data>, int);
+int pc_equipitem(dumb_ptr<map_session_data>, IOff0, EPOS);
+int pc_unequipitem(dumb_ptr<map_session_data>, IOff0, CalcStatus);
+int pc_unequipinvyitem(dumb_ptr<map_session_data>, IOff0, CalcStatus);
+int pc_useitem(dumb_ptr<map_session_data>, IOff0);
int pc_damage(dumb_ptr<block_list>, dumb_ptr<map_session_data>, int);
int pc_heal(dumb_ptr<map_session_data>, int, int);
diff --git a/src/map/script.cpp b/src/map/script.cpp
index ab9f848..73ddea7 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -1926,7 +1926,7 @@ static
void builtin_countitem(ScriptState *st)
{
ItemNameId nameid;
- int count = 0, i;
+ int count = 0;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -1947,7 +1947,7 @@ void builtin_countitem(ScriptState *st)
if (nameid)
{
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid == nameid)
count += sd->status.inventory[i].amount;
@@ -2050,7 +2050,7 @@ void builtin_getitem(ScriptState *st)
PickupFail flag;
if ((flag = pc_additem(sd, &item_tmp, amount)) != PickupFail::OKAY)
{
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
map_addflooritem(&item_tmp, amount,
sd->bl_m, sd->bl_x, sd->bl_y,
NULL, NULL, NULL);
@@ -2114,7 +2114,7 @@ static
void builtin_delitem(ScriptState *st)
{
ItemNameId nameid;
- int amount, i;
+ int amount;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -2140,7 +2140,7 @@ void builtin_delitem(ScriptState *st)
return;
}
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid == nameid)
{
@@ -2290,7 +2290,7 @@ Array<EPOS, 11> equip //=
static
void builtin_getequipid(ScriptState *st)
{
- int i, num;
+ int num;
dumb_ptr<map_session_data> sd;
struct item_data *item;
@@ -2301,8 +2301,8 @@ void builtin_getequipid(ScriptState *st)
return;
}
num = conv_num(st, &AARGO2(2));
- i = pc_checkequip(sd, equip[num - 1]);
- if (i >= 0)
+ IOff0 i = pc_checkequip(sd, equip[num - 1]);
+ if (i.ok())
{
item = sd->inventory_data[i];
if (item)
@@ -2323,7 +2323,7 @@ void builtin_getequipid(ScriptState *st)
static
void builtin_getequipname(ScriptState *st)
{
- int i, num;
+ int num;
dumb_ptr<map_session_data> sd;
struct item_data *item;
@@ -2331,8 +2331,8 @@ void builtin_getequipname(ScriptState *st)
sd = script_rid2sd(st);
num = conv_num(st, &AARGO2(2));
- i = pc_checkequip(sd, equip[num - 1]);
- if (i >= 0)
+ IOff0 i = pc_checkequip(sd, equip[num - 1]);
+ if (i.ok())
{
item = sd->inventory_data[i];
if (item)
@@ -3522,10 +3522,10 @@ static
void builtin_getinventorylist(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- int i, j = 0;
+ int j = 0;
if (!sd)
return;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid
&& sd->status.inventory[i].amount > 0)
@@ -3730,8 +3730,8 @@ void builtin_nude(ScriptState *st)
for (EQUIP i : EQUIPs)
{
- int idx = sd->equip_index_maybe[i];
- if (idx >= 0)
+ IOff0 idx = sd->equip_index_maybe[i];
+ if (idx.ok())
pc_unequipitem(sd, idx, CalcStatus::LATER);
}
pc_calcstatus(sd, 0);
@@ -3754,8 +3754,8 @@ void builtin_unequipbyid(ScriptState *st)
if (slot_id >= EQUIP() && slot_id < EQUIP::COUNT)
{
- int idx = sd->equip_index_maybe[slot_id];
- if (idx >= 0)
+ IOff0 idx = sd->equip_index_maybe[slot_id];
+ if (idx.ok())
pc_unequipitem(sd, idx, CalcStatus::LATER);
}
diff --git a/src/map/storage.cpp b/src/map/storage.cpp
index e9c2cd6..88db8c4 100644
--- a/src/map/storage.cpp
+++ b/src/map/storage.cpp
@@ -105,7 +105,6 @@ int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor,
Item *item_data, int amount)
{
struct item_data *data;
- int i;
if (!item_data->nameid || amount <= 0)
return 1;
@@ -114,7 +113,7 @@ int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor,
if (!itemdb_isequip2(data))
{ //Stackable
- for (i = 0; i < MAX_STORAGE; i++)
+ for (SOff0 i : SOff0::iter())
{
if (compare_item(&stor->storage_[i], item_data))
{
@@ -128,9 +127,12 @@ int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor,
}
}
//Add item
- for (i = 0; i < MAX_STORAGE && stor->storage_[i].nameid; i++);
-
- if (i >= MAX_STORAGE)
+ SOff0 i = *std::find_if(SOff0::iter().begin(), SOff0::iter().end(),
+ [&stor](SOff0 i_)
+ {
+ return !stor->storage_[i_].nameid;
+ });
+ if (!i.ok())
return 1;
stor->storage_[i] = *item_data;
@@ -148,7 +150,7 @@ int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor,
*/
static
int storage_delitem(dumb_ptr<map_session_data> sd, Storage *stor,
- int n, int amount)
+ SOff0 n, int amount)
{
if (!stor->storage_[n].nameid || stor->storage_[n].amount < amount)
@@ -171,7 +173,7 @@ int storage_delitem(dumb_ptr<map_session_data> sd, Storage *stor,
* Add an item to the storage from the inventory.
*------------------------------------------
*/
-int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount)
+int storage_storageadd(dumb_ptr<map_session_data> sd, IOff0 index, int amount)
{
Storage *stor;
@@ -182,7 +184,7 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount)
if ((stor->storage_amount > MAX_STORAGE) || !stor->storage_status)
return 0; // storage full / storage closed
- if (index < 0 || index >= MAX_INVENTORY)
+ if (!index.ok())
return 0;
if (!sd->status.inventory[index].nameid)
@@ -206,7 +208,7 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount)
* Retrieve an item from the storage.
*------------------------------------------
*/
-int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount)
+int storage_storageget(dumb_ptr<map_session_data> sd, SOff0 index, int amount)
{
Storage *stor;
PickupFail flag;
@@ -215,7 +217,7 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount)
stor = account2storage2(sd->status_key.account_id);
nullpo_ret(stor);
- if (index < 0 || index >= MAX_STORAGE)
+ if (!index.ok())
return 0;
if (!stor->storage_[index].nameid)
@@ -227,7 +229,7 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount)
if ((flag = pc_additem(sd, &stor->storage_[index], amount)) == PickupFail::OKAY)
storage_delitem(sd, stor, index, amount);
else
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
// log_fromstorage(sd, index, 0);
return 1;
}
diff --git a/src/map/storage.hpp b/src/map/storage.hpp
index 3eab087..fe29664 100644
--- a/src/map/storage.hpp
+++ b/src/map/storage.hpp
@@ -27,9 +27,11 @@
# include "../mmo/fwd.hpp"
+# include "clif.t.hpp"
+
int storage_storageopen(dumb_ptr<map_session_data> sd);
-int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount);
-int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount);
+int storage_storageadd(dumb_ptr<map_session_data> sd, IOff0 index, int amount);
+int storage_storageget(dumb_ptr<map_session_data> sd, SOff0 index, int amount);
int storage_storageclose(dumb_ptr<map_session_data> sd);
void do_final_storage(void);
Storage *account2storage(AccountId account_id);
diff --git a/src/map/trade.cpp b/src/map/trade.cpp
index af5d1aa..7a4913a 100644
--- a/src/map/trade.cpp
+++ b/src/map/trade.cpp
@@ -123,7 +123,7 @@ void trade_tradeack(dumb_ptr<map_session_data> sd, int type)
* アイテム追加
*------------------------------------------
*/
-void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
+void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount)
{
dumb_ptr<map_session_data> target_sd;
struct item_data *id;
@@ -131,27 +131,26 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
int trade_weight = 0;
int free_ = 0;
int c;
- int i;
nullpo_retv(sd);
if (((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
&& (sd->deal_locked < 1))
{
- if (index < 2 || index >= MAX_INVENTORY + 2)
+ if (!index.ok())
{
- if (index == 0 && amount > 0 && amount <= sd->status.zeny)
+ if (index.index == 0 && amount > 0 && amount <= sd->status.zeny)
{
sd->deal_zeny = amount;
- clif_tradeadditem(sd, target_sd, 0, amount);
+ clif_tradeadditem(sd, target_sd, index, amount);
}
}
// note: amount is overridden below!
- else if (amount <= sd->status.inventory[index - 2].amount
+ else if (amount <= sd->status.inventory[index.unshift()].amount
&& amount > 0)
{
// determine free slots of receiver
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (!target_sd->status.inventory[i].nameid
&& target_sd->inventory_data[i] == NULL)
@@ -163,13 +162,13 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
{
// calculate trade weight
trade_weight +=
- sd->inventory_data[index - 2]->weight * amount;
+ sd->inventory_data[index.unshift()]->weight * amount;
// determine if item is a stackable already in receivers inventory, and up free count
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (target_sd->status.inventory[i].nameid ==
- sd->status.inventory[index - 2].nameid
+ sd->status.inventory[index.unshift()].nameid
&& target_sd->inventory_data[i] != NULL)
{
id = target_sd->inventory_data[i];
@@ -205,7 +204,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
return;
}
}
- pc_unequipinvyitem(sd, index - 2, CalcStatus::NOW);
+ pc_unequipinvyitem(sd, index.unshift(), CalcStatus::NOW);
sd->deal_item_index[trade_i] = index;
sd->deal_item_amount[trade_i] += amount;
clif_tradeitemok(sd, index, amount, 0); //success to add item
@@ -217,15 +216,15 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
{
// calculate weight for stored deal
trade_weight +=
- sd->inventory_data[sd->deal_item_index[trade_i] -
- 2]->weight *
+ sd->inventory_data[sd->deal_item_index[trade_i].unshift()
+ ]->weight *
sd->deal_item_amount[trade_i];
// count free stackables in stored deal
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (target_sd->status.inventory[i].nameid ==
sd->status.
- inventory[sd->deal_item_index[trade_i] - 2].nameid
+ inventory[sd->deal_item_index[trade_i].unshift()].nameid
&& target_sd->inventory_data[i] != NULL)
{
id = target_sd->inventory_data[i];
@@ -260,11 +259,11 @@ void trade_tradeok(dumb_ptr<map_session_data> sd)
for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
{
- int index = sd->deal_item_index[trade_i];
- if (index < 2 || index >= MAX_INVENTORY + 2)
+ IOff2 index = sd->deal_item_index[trade_i];
+ if (!index.ok())
continue;
if (sd->deal_item_amount[trade_i] >
- sd->status.inventory[index - 2].amount
+ sd->status.inventory[index.unshift()].amount
|| sd->deal_item_amount[trade_i] < 0)
{
trade_tradecancel(sd);
@@ -276,7 +275,7 @@ void trade_tradeok(dumb_ptr<map_session_data> sd)
if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
{
sd->deal_locked = 1;
- clif_tradeitemok(sd, 0, 0, 0);
+ clif_tradeitemok(sd, IOff2::from(0), 0, 0);
clif_tradedeal_lock(sd, 0);
clif_tradedeal_lock(target_sd, 1);
}
@@ -299,20 +298,22 @@ void trade_tradecancel(dumb_ptr<map_session_data> sd)
{ //give items back (only virtual)
if (sd->deal_item_amount[trade_i] != 0)
{
+ assert (sd->deal_item_index[trade_i].ok());
clif_additem(sd,
- sd->deal_item_index[trade_i] - 2,
+ sd->deal_item_index[trade_i].unshift(),
sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- sd->deal_item_index[trade_i] = 0;
+ sd->deal_item_index[trade_i] = IOff2::from(0);
sd->deal_item_amount[trade_i] = 0;
}
if (target_sd->deal_item_amount[trade_i] != 0)
{
+ assert (target_sd->deal_item_index[trade_i].ok());
clif_additem(target_sd,
- target_sd->deal_item_index[trade_i] - 2,
+ target_sd->deal_item_index[trade_i].unshift(),
target_sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- target_sd->deal_item_index[trade_i] = 0;
+ target_sd->deal_item_index[trade_i] = IOff2::from(0);
target_sd->deal_item_amount[trade_i] = 0;
}
}
@@ -379,7 +380,8 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
{
if (sd->deal_item_amount[trade_i] != 0)
{
- int n = sd->deal_item_index[trade_i] - 2;
+ assert (sd->deal_item_index[trade_i].ok());
+ IOff0 n = sd->deal_item_index[trade_i].unshift();
PickupFail flag = pc_additem(target_sd,
&sd->status.inventory[n],
sd->deal_item_amount[trade_i]);
@@ -390,12 +392,13 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
clif_additem(sd, n,
sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- sd->deal_item_index[trade_i] = 0;
+ sd->deal_item_index[trade_i] = IOff2::from(0);
sd->deal_item_amount[trade_i] = 0;
}
if (target_sd->deal_item_amount[trade_i] != 0)
{
- int n = target_sd->deal_item_index[trade_i] - 2;
+ assert (target_sd->deal_item_index[trade_i].ok());
+ IOff0 n = target_sd->deal_item_index[trade_i].unshift();
PickupFail flag = pc_additem(sd,
&target_sd->status.inventory[n],
target_sd->deal_item_amount[trade_i]);
@@ -405,10 +408,9 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
1);
else
clif_additem(target_sd, n,
-
target_sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- target_sd->deal_item_index[trade_i] = 0;
+ target_sd->deal_item_index[trade_i] = IOff2::from(0);
target_sd->deal_item_amount[trade_i] = 0;
}
}
@@ -454,7 +456,7 @@ void trade_verifyzeny(dumb_ptr<map_session_data> sd)
if (sd->deal_zeny > sd->status.zeny)
{
if (sd->deal_locked < 1)
- trade_tradeadditem(sd, 0, sd->status.zeny); // Fix money ammount
+ trade_tradeadditem(sd, IOff2::from(0), sd->status.zeny); // Fix money ammount
else
trade_tradecancel(sd); // Or cancel the trade if we can't fix it
}
diff --git a/src/map/trade.hpp b/src/map/trade.hpp
index 9d542a4..370fcdf 100644
--- a/src/map/trade.hpp
+++ b/src/map/trade.hpp
@@ -25,9 +25,11 @@
# include "../generic/fwd.hpp"
+# include "clif.t.hpp"
+
void trade_traderequest(dumb_ptr<map_session_data> sd, BlockId target_id);
void trade_tradeack(dumb_ptr<map_session_data> sd, int type);
-void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount);
+void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount);
void trade_tradeok(dumb_ptr<map_session_data> sd);
void trade_tradecancel(dumb_ptr<map_session_data> sd);
void trade_tradecommit(dumb_ptr<map_session_data> sd);
diff --git a/src/mmo/version.hpp b/src/mmo/version.hpp
index 5d28b5d..f2c146b 100644
--- a/src/mmo/version.hpp
+++ b/src/mmo/version.hpp
@@ -47,6 +47,35 @@ struct Version
uint8_t which;
uint16_t vend;
// can't add vendor name yet
+
+ constexpr friend
+ bool operator < (Version l, Version r)
+ {
+ return (l.major < r.major
+ || (l.major == r.major
+ && (l.minor < r.minor
+ || (l.minor == r.minor
+ && (l.patch < r.patch
+ || (l.patch == r.patch
+ && (l.devel < r.devel
+ || (l.devel == r.devel
+ && l.vend < r.vend))))))));
+ }
+ constexpr friend
+ bool operator > (Version l, Version r)
+ {
+ return r < l;
+ }
+ constexpr friend
+ bool operator <= (Version l, Version r)
+ {
+ return !(r < l);
+ }
+ constexpr friend
+ bool operator >= (Version l, Version r)
+ {
+ return !(l < r);
+ }
};
static_assert(sizeof(Version) == 8, "this is sent over the network, can't change");
@@ -60,33 +89,4 @@ extern LString CURRENT_VERSION_STRING;
bool extract(XString str, Version *vers);
-constexpr
-bool operator < (Version l, Version r)
-{
- return (l.major < r.major
- || (l.major == r.major
- && (l.minor < r.minor
- || (l.minor == r.minor
- && (l.patch < r.patch
- || (l.patch == r.patch
- && (l.devel < r.devel
- || (l.devel == r.devel
- && l.vend < r.vend))))))));
-}
-constexpr
-bool operator > (Version l, Version r)
-{
- return r < l;
-}
-constexpr
-bool operator <= (Version l, Version r)
-{
- return !(r < l);
-}
-constexpr
-bool operator >= (Version l, Version r)
-{
- return !(l < r);
-}
-
#endif // TMWA_MMO_VERSION_HPP
diff --git a/src/proto2/include_clif_t_test.cpp b/src/proto2/include_clif_t_test.cpp
index 93c7f90..75d36a0 100644
--- a/src/proto2/include_clif_t_test.cpp
+++ b/src/proto2/include_clif_t_test.cpp
@@ -34,3 +34,5 @@ using Test_PickupFail = PickupFail;
using Test_DamageType = DamageType;
using Test_SP = SP;
using Test_LOOK = LOOK;
+using Test_IOff2 = IOff2;
+using Test_SOff1 = SOff1;
diff --git a/src/proto2/map-user.hpp b/src/proto2/map-user.hpp
index b4ea4d8..598ef3b 100644
--- a/src/proto2/map-user.hpp
+++ b/src/proto2/map-user.hpp
@@ -510,7 +510,7 @@ struct Packet_Fixed<0x00a0>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint16_t amount = {};
ItemNameId name_id = {};
uint8_t identify = {};
@@ -542,7 +542,7 @@ struct Packet_Fixed<0x00a2>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint16_t amount = {};
};
@@ -561,7 +561,7 @@ struct Packet_Repeat<0x00a4>
{
static const uint16_t PACKET_ID = 0x00a4;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
ItemNameId name_id = {};
ItemType item_type = {};
uint8_t identify = {};
@@ -590,7 +590,7 @@ struct Packet_Repeat<0x00a6>
{
static const uint16_t PACKET_ID = 0x00a6;
- uint16_t soff1 = {};
+ SOff1 soff1 = {};
ItemNameId name_id = {};
ItemType item_type = {};
uint8_t identify = {};
@@ -611,7 +611,7 @@ struct Packet_Fixed<0x00a7>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint32_t unused_id = {};
};
@@ -622,7 +622,7 @@ struct Packet_Fixed<0x00a8>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint16_t amount = {};
uint8_t ok = {};
};
@@ -634,7 +634,7 @@ struct Packet_Fixed<0x00a9>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
EPOS epos_ignored = {};
};
@@ -645,7 +645,7 @@ struct Packet_Fixed<0x00aa>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
EPOS epos = {};
uint8_t ok = {};
};
@@ -657,7 +657,7 @@ struct Packet_Fixed<0x00ab>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
};
template<>
@@ -667,7 +667,7 @@ struct Packet_Fixed<0x00ac>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
EPOS epos = {};
uint8_t ok = {};
};
@@ -679,7 +679,7 @@ struct Packet_Fixed<0x00af>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint16_t amount = {};
};
@@ -971,7 +971,7 @@ struct Packet_Repeat<0x00c7>
{
static const uint16_t PACKET_ID = 0x00c7;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint32_t base_price = {};
uint32_t actual_price = {};
};
@@ -1010,7 +1010,7 @@ struct Packet_Repeat<0x00c9>
{
static const uint16_t PACKET_ID = 0x00c9;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint16_t count = {};
};
@@ -1091,7 +1091,7 @@ struct Packet_Fixed<0x00e8>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t zeny_or_ioff2 = {};
+ IOff2 zeny_or_ioff2 = {};
uint32_t amount = {};
};
@@ -1187,7 +1187,7 @@ struct Packet_Fixed<0x00f3>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint32_t amount = {};
};
@@ -1198,7 +1198,7 @@ struct Packet_Fixed<0x00f4>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t soff1 = {};
+ SOff1 soff1 = {};
uint32_t amount = {};
ItemNameId name_id = {};
uint8_t identify = {};
@@ -1217,7 +1217,7 @@ struct Packet_Fixed<0x00f5>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t soff1 = {};
+ SOff1 soff1 = {};
uint32_t amount = {};
};
@@ -1228,7 +1228,7 @@ struct Packet_Fixed<0x00f6>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t soff1 = {};
+ SOff1 soff1 = {};
uint32_t amount = {};
};
@@ -1582,7 +1582,7 @@ struct Packet_Fixed<0x013c>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
};
template<>
@@ -1723,7 +1723,7 @@ struct Packet_Fixed<0x01b1>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
uint16_t amount = {};
uint8_t fail = {};
};
@@ -1735,7 +1735,7 @@ struct Packet_Fixed<0x01c8>
// TODO remove this
uint16_t magic_packet_id = PACKET_ID;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
ItemNameId name_id = {};
BlockId block_id = {};
uint16_t amount = {};
@@ -1923,7 +1923,7 @@ struct Packet_Repeat<0x01ee>
{
static const uint16_t PACKET_ID = 0x01ee;
- uint16_t ioff2 = {};
+ IOff2 ioff2 = {};
ItemNameId name_id = {};
ItemType item_type = {};
uint8_t identify = {};
@@ -1950,7 +1950,7 @@ struct Packet_Repeat<0x01f0>
{
static const uint16_t PACKET_ID = 0x01f0;
- uint16_t soff1 = {};
+ SOff1 soff1 = {};
ItemNameId name_id = {};
ItemType item_type = {};
uint8_t identify = {};
diff --git a/src/proto2/types.hpp b/src/proto2/types.hpp
index f46acf3..e6730c1 100644
--- a/src/proto2/types.hpp
+++ b/src/proto2/types.hpp
@@ -58,42 +58,22 @@ struct NetArray
{
T data[N];
};
-template<class T, class U, size_t N>
-bool native_to_network(NetArray<T, N> *network, Array<U, N> native)
+template<class T, class U, class I>
+bool native_to_network(NetArray<T, I::alloc_size> *network, GenericArray<U, I> native)
{
- for (size_t i = 0; i < N; ++i)
+ for (size_t i = 0; i < I::alloc_size; ++i)
{
- if (!native_to_network(&(*network).data[i], native[i]))
+ if (!native_to_network(&(*network).data[i], native[I::offset_to_index(i)]))
return false;
}
return true;
}
-template<class T, class U, size_t N>
-bool network_to_native(Array<U, N> *native, NetArray<T, N> network)
+template<class T, class U, class I>
+bool network_to_native(GenericArray<U, I> *native, NetArray<T, I::alloc_size> network)
{
- for (size_t i = 0; i < N; ++i)
+ for (size_t i = 0; i < I::alloc_size; ++i)
{
- if (!network_to_native(&(*native)[i], network.data[i]))
- return false;
- }
- return true;
-}
-template<class T, class U, size_t N, class I>
-bool native_to_network(NetArray<T, N> *network, earray<U, I, static_cast<I>(N)> native)
-{
- for (size_t i = 0; i < N; ++i)
- {
- if (!native_to_network(&(*network).data[i], native[static_cast<I>(i)]))
- return false;
- }
- return true;
-}
-template<class T, class U, size_t N, class I>
-bool network_to_native(earray<U, I, static_cast<I>(N)> *native, NetArray<T, N> network)
-{
- for (size_t i = 0; i < N; ++i)
- {
- if (!network_to_native(&(*native)[static_cast<I>(i)], network.data[i]))
+ if (!network_to_native(&(*native)[I::offset_to_index(i)], network.data[i]))
return false;
}
return true;
@@ -1184,7 +1164,7 @@ struct CharData
uint16_t mapport = {};
Point last_point = {};
Point save_point = {};
- Array<Item, MAX_INVENTORY> inventory = {};
+ GenericArray<Item, InventoryIndexing<IOff0, MAX_INVENTORY>> inventory = {};
earray<SkillValue, SkillID, MAX_SKILL> skill = {};
uint32_t global_reg_num = {};
Array<GlobalReg, GLOBAL_REG_NUM> global_reg = {};
@@ -1403,7 +1383,7 @@ struct Storage
AccountId account_id = {};
uint16_t storage_status = {};
uint16_t storage_amount = {};
- Array<Item, MAX_STORAGE> storage_ = {};
+ GenericArray<Item, InventoryIndexing<SOff0, MAX_STORAGE>> storage_ = {};
};
struct NetStorage
{