summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in2
-rw-r--r--src/admin/fwd.hpp26
-rw-r--r--src/admin/ladmin.cpp127
-rw-r--r--src/char/char.cpp307
-rw-r--r--src/char/char.hpp4
-rw-r--r--src/char/fwd.hpp26
-rw-r--r--src/char/int_party.cpp131
-rw-r--r--src/char/int_party.hpp6
-rw-r--r--src/char/int_storage.cpp23
-rw-r--r--src/char/int_storage.hpp8
-rw-r--r--src/char/inter.cpp5
-rw-r--r--src/compat/alg.hpp2
-rw-r--r--src/compat/fwd.hpp26
-rw-r--r--src/generic/enum.hpp2
-rw-r--r--src/generic/fwd.hpp26
-rw-r--r--src/ints/cmp.hpp2
-rw-r--r--src/ints/fwd.hpp26
-rw-r--r--src/ints/udl.hpp12
-rw-r--r--src/ints/udl_test.cpp7
-rw-r--r--src/ints/wrap.cpp21
-rw-r--r--src/ints/wrap.hpp109
-rw-r--r--src/io/cxxstdio.hpp14
-rw-r--r--src/io/write.hpp2
-rw-r--r--src/login/fwd.hpp26
-rw-r--r--src/login/login.cpp294
-rw-r--r--src/map/atcommand.cpp261
-rw-r--r--src/map/atcommand.hpp4
-rw-r--r--src/map/battle.cpp48
-rw-r--r--src/map/battle.hpp6
-rw-r--r--src/map/battle.t.hpp2
-rw-r--r--src/map/chrif.cpp103
-rw-r--r--src/map/chrif.hpp10
-rw-r--r--src/map/clif.cpp332
-rw-r--r--src/map/clif.hpp28
-rw-r--r--src/map/fwd.hpp27
-rw-r--r--src/map/intif.cpp94
-rw-r--r--src/map/intif.hpp18
-rw-r--r--src/map/itemdb.cpp27
-rw-r--r--src/map/itemdb.hpp25
-rw-r--r--src/map/magic-expr.cpp16
-rw-r--r--src/map/magic-interpreter-base.cpp14
-rw-r--r--src/map/magic-interpreter.hpp14
-rw-r--r--src/map/magic-stmt.cpp70
-rw-r--r--src/map/magic-v2.cpp8
-rw-r--r--src/map/magic.hpp6
-rw-r--r--src/map/map.cpp112
-rw-r--r--src/map/map.hpp81
-rw-r--r--src/map/map.t.hpp9
-rw-r--r--src/map/mob.cpp462
-rw-r--r--src/map/mob.hpp48
-rw-r--r--src/map/npc.cpp89
-rw-r--r--src/map/npc.hpp20
-rw-r--r--src/map/party.cpp78
-rw-r--r--src/map/party.hpp30
-rw-r--r--src/map/pc.cpp215
-rw-r--r--src/map/pc.hpp24
-rw-r--r--src/map/script.cpp149
-rw-r--r--src/map/script.hpp8
-rw-r--r--src/map/skill.cpp17
-rw-r--r--src/map/skill.hpp4
-rw-r--r--src/map/storage.cpp20
-rw-r--r--src/map/storage.hpp10
-rw-r--r--src/map/tmw.cpp4
-rw-r--r--src/map/trade.cpp36
-rw-r--r--src/map/trade.hpp4
-rw-r--r--src/mmo/extract.cpp25
-rw-r--r--src/mmo/extract.hpp45
-rw-r--r--src/mmo/extract_test.cpp2
-rw-r--r--src/mmo/fwd.hpp37
-rw-r--r--src/mmo/ids.cpp21
-rw-r--r--src/mmo/ids.hpp109
-rw-r--r--src/mmo/mmo.hpp32
-rw-r--r--src/mmo/socket.cpp3
-rw-r--r--src/mmo/socket.hpp3
-rw-r--r--src/mmo/utils.hpp2
-rw-r--r--src/mmo/version.hpp2
-rw-r--r--src/range/fwd.hpp26
-rw-r--r--src/sexpr/fwd.hpp26
-rw-r--r--src/sexpr/lexer.hpp2
-rw-r--r--src/sexpr/parser.hpp2
-rw-r--r--src/strings/astring.hpp2
-rw-r--r--src/strings/literal.hpp2
82 files changed, 2340 insertions, 1768 deletions
diff --git a/Makefile.in b/Makefile.in
index a532bfe..7ac2cbb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -424,7 +424,7 @@ obj/%.hpp.formatted: src/%.hpp tools/indenter
$(MKDIR_FIRST)
apply-filter 'indenter -cpp' $<
fgrep -q Copyright $<
- fgrep -q ../sanity.hpp $<
+ if [[ $< == *fwd* ]]; then fgrep -q ../sanity.hpp $<; else fgrep -q '"fwd.hpp"' $<; fi
touch $@
obj/%.tcc.formatted: src/%.tcc tools/indenter
$(MKDIR_FIRST)
diff --git a/src/admin/fwd.hpp b/src/admin/fwd.hpp
new file mode 100644
index 0000000..f987625
--- /dev/null
+++ b/src/admin/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_ADMIN_FWD_HPP
+#define TMWA_ADMIN_FWD_HPP
+// admin/fwd.hpp - list of type names for admin client
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_ADMIN_FWD_HPP
diff --git a/src/admin/ladmin.cpp b/src/admin/ladmin.cpp
index 307e13b..a4c2464 100644
--- a/src/admin/ladmin.cpp
+++ b/src/admin/ladmin.cpp
@@ -259,7 +259,8 @@ static
TString parameters; // needs to be global since it's passed to the parse function
// really should be added to session data
static
-int list_first, list_last, list_type, list_count; // parameter to display a list of accounts
+AccountId list_first, list_last;
+int list_type, list_count; // parameter to display a list of accounts
static
int already_exit_function = 0; // sometimes, the exit function is called twice... so, don't log twice the message
@@ -1174,19 +1175,12 @@ void idaccount(ZString param)
// Sub-function: Asking to displaying information about an account (by its id)
//----------------------------------------------------------------------------
static
-void infoaccount(int account_id)
+void infoaccount(AccountId account_id)
{
- if (account_id < 0)
- {
- PRINTF("Please input a positive value for the id.\n"_fmt);
- LADMIN_LOG("Negative value was given to found the account.\n"_fmt);
- return;
- }
-
LADMIN_LOG("Request to login-server to obtain information about an account (by its id).\n"_fmt);
WFIFOW(login_session, 0) = 0x7954;
- WFIFOL(login_session, 2) = account_id;
+ WFIFOL(login_session, 2) = unwrap<AccountId>(account_id);
WFIFOSET(login_session, 6);
bytes_to_read = 1;
}
@@ -1227,8 +1221,8 @@ void listaccount(ZString param, int type)
list_type = type;
// set default values
- list_first = 0;
- list_last = 0;
+ list_first = AccountId();
+ list_last = AccountId();
if (list_type == 1)
{ // if listgm
@@ -1250,18 +1244,16 @@ void listaccount(ZString param, int type)
{
// if list (list_type == 0)
extract(param, record<' '>(&list_first, &list_last));
- if (list_first < 0)
- list_first = 0;
- if (list_last < list_first || list_last < 0)
- list_last = 0;
+ if (list_last < list_first)
+ list_last = AccountId();
}
LADMIN_LOG("Request to login-server to obtain the list of accounts from %d to %d.\n"_fmt,
list_first, list_last);
WFIFOW(login_session, 0) = 0x7920;
- WFIFOL(login_session, 2) = list_first;
- WFIFOL(login_session, 6) = list_last;
+ WFIFOL(login_session, 2) = unwrap<AccountId>(list_first);
+ WFIFOL(login_session, 6) = unwrap<AccountId>(list_last);
WFIFOSET(login_session, 10);
bytes_to_read = 1;
@@ -1277,7 +1269,7 @@ void listaccount(ZString param, int type)
static
int itemfrob(ZString param)
{
- int source_id, dest_id;
+ ItemNameId source_id, dest_id;
if (!extract(param, record<' '>(&source_id, &dest_id)))
{
@@ -1286,8 +1278,8 @@ int itemfrob(ZString param)
}
WFIFOW(login_session, 0) = 0x7924;
- WFIFOL(login_session, 2) = source_id;
- WFIFOL(login_session, 6) = dest_id;
+ WFIFOL(login_session, 2) = unwrap<ItemNameId>(source_id);
+ WFIFOL(login_session, 6) = unwrap<ItemNameId>(dest_id);
WFIFOSET(login_session, 10);
bytes_to_read = 1; // all logging is done to the three main servers
@@ -1339,19 +1331,12 @@ void changememo(ZString param)
// Sub-function: Asking to obtain an account name
//-----------------------------------------------
static
-void nameaccount(int id)
+void nameaccount(AccountId id)
{
- if (id < 0)
- {
- PRINTF("Please input a positive value for the id.\n"_fmt);
- LADMIN_LOG("Negativ id given to search an account name ('name' command).\n"_fmt);
- return;
- }
-
LADMIN_LOG("Request to login-server to know an account name.\n"_fmt);
WFIFOW(login_session, 0) = 0x7946;
- WFIFOL(login_session, 2) = id;
+ WFIFOL(login_session, 2) = unwrap<AccountId>(id);
WFIFOSET(login_session, 6);
bytes_to_read = 1;
}
@@ -1892,7 +1877,7 @@ void prompt(void)
else if (command == "id"_s)
idaccount(parameters);
else if (command == "info"_s)
- infoaccount(atoi(parameters.c_str()));
+ infoaccount(wrap<AccountId>(static_cast<uint32_t>(atoi(parameters.c_str()))));
else if (command == "kami"_s)
sendbroadcast(parameters); // flag for normal
else if (command == "itemfrob"_s)
@@ -1908,7 +1893,7 @@ void prompt(void)
else if (command == "memo"_s)
changememo(parameters);
else if (command == "name"_s)
- nameaccount(atoi(parameters.c_str()));
+ nameaccount(wrap<AccountId>(static_cast<uint32_t>(atoi(parameters.c_str()))));
else if (command == "password"_s)
changepasswd(parameters);
else if (command == "reloadgm"_s)
@@ -2031,7 +2016,8 @@ void parse_fromlogin(Session *s)
{
AccountName userid = stringish<AccountName>(RFIFO_STRING<24>(s, i + 5));
VString<23> lower_userid = userid.to_lower();
- list_first = RFIFOL(s, i) + 1;
+ // what?
+ list_first = next(wrap<AccountId>(RFIFOL(s, i)));
// here are checks...
if (list_type == 0
|| (list_type == 1 && RFIFOB(s, i + 4) > 0)
@@ -2098,8 +2084,8 @@ void parse_fromlogin(Session *s)
LADMIN_LOG("Request to login-server to obtain the list of accounts from %d to %d (complement).\n"_fmt,
list_first, list_last);
WFIFOW(login_session, 0) = 0x7920;
- WFIFOL(login_session, 2) = list_first;
- WFIFOL(login_session, 6) = list_last;
+ WFIFOL(login_session, 2) = unwrap<AccountId>(list_first);
+ WFIFOL(login_session, 6) = unwrap<AccountId>(list_last);
WFIFOSET(login_session, 10);
bytes_to_read = 1;
}
@@ -2110,9 +2096,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int accid = RFIFOL(s, 2);
+ AccountId accid = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (accid == -1)
+ if (!accid)
{
PRINTF("Account [%s] creation failed. Same account already exists.\n"_fmt,
name);
@@ -2135,9 +2121,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int accid = RFIFOL(s, 2);
+ AccountId accid = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (accid == -1)
+ if (!accid)
{
PRINTF("Account [%s] deletion failed. Account doesn't exist.\n"_fmt,
name);
@@ -2160,9 +2146,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int accid = RFIFOL(s, 2);
+ AccountId accid = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (accid == -1)
+ if (!accid)
{
PRINTF("Account [%s] password changing failed.\n"_fmt,
name);
@@ -2187,10 +2173,10 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 34)
return;
{
- int accid = RFIFOL(s, 2);
+ AccountId accid = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
int state = RFIFOL(s, 30);
- if (accid == -1)
+ if (!accid)
{
PRINTF("Account [%s] state changing failed. Account doesn't exist.\n"_fmt,
name);
@@ -2280,9 +2266,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("The account [%s] doesn't exist or the password is incorrect.\n"_fmt,
name);
@@ -2305,9 +2291,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Account [%s] sex changing failed.\n"_fmt,
name);
@@ -2332,9 +2318,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Account [%s] GM level changing failed.\n"_fmt,
name);
@@ -2360,9 +2346,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Account [%s] e-mail changing failed.\n"_fmt,
name);
@@ -2387,9 +2373,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Account [%s] memo changing failed. Account doesn't exist.\n"_fmt,
name);
@@ -2412,9 +2398,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Unable to find the account [%s] id. Account doesn't exist.\n"_fmt,
name);
@@ -2437,7 +2423,7 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 30)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
if (!name)
{
@@ -2462,7 +2448,7 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 34)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
if (RFIFOL(s, 2) == -1)
{
@@ -2501,9 +2487,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 34)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Account [%s] final date of banishment changing failed. Account doesn't exist.\n"_fmt,
name);
@@ -2540,9 +2526,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 34)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Account [%s] final date of banishment changing failed. Account doesn't exist.\n"_fmt,
name);
@@ -2597,9 +2583,9 @@ void parse_fromlogin(Session *s)
if (RFIFOREST(s) < 34)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
AccountName name = stringish<AccountName>(RFIFO_STRING<24>(s, 6));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Account [%s] validity limit changing failed. Account doesn't exist.\n"_fmt,
name);
@@ -2640,10 +2626,11 @@ void parse_fromlogin(Session *s)
|| RFIFOREST(s) < (150 + RFIFOW(s, 148)))
return;
{
- int account_id = RFIFOL(s, 2);
- uint8_t gm = RFIFOB(s, 6);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
+ // TODO fix size (there's a lot of other stuff wrong with this packet too
+ GmLevel gm = GmLevel::from(static_cast<uint32_t>(RFIFOB(s, 6)));
AccountName userid = stringish<AccountName>(RFIFO_STRING<24>(s, 7));
- uint8_t sex = RFIFOB(s, 31);
+ SEX sex = static_cast<SEX>(RFIFOB(s, 31));
int connections = RFIFOL(s, 32);
int state = RFIFOL(s, 36);
timestamp_seconds_buffer error_message = stringish<timestamp_seconds_buffer>(RFIFO_STRING<20>(s, 40));
@@ -2653,7 +2640,7 @@ void parse_fromlogin(Session *s)
TimeT connect_until_time = static_cast<time_t>(RFIFOL(s, 140));
TimeT ban_until_time = static_cast<time_t>(RFIFOL(s, 144));
AString memo = RFIFO_STRING(s, 150, RFIFOW(s, 148));
- if (account_id == -1)
+ if (!account_id)
{
PRINTF("Unabled to find the account [%s]. Account doesn't exist.\n"_fmt,
userid);
@@ -2681,11 +2668,11 @@ void parse_fromlogin(Session *s)
account_id, gm);
}
PRINTF(" Name: '%s'\n"_fmt, userid);
- if (sex == 0)
+ if (sex == SEX::FEMALE)
PRINTF(" Sex: Female\n"_fmt);
- else if (sex == 1)
+ else if (sex == SEX::MALE)
PRINTF(" Sex: Male\n"_fmt);
- else
+ else // doesn't happen anymore
PRINTF(" Sex: Server\n"_fmt);
PRINTF(" E-mail: %s\n"_fmt, email);
switch (state)
diff --git a/src/char/char.cpp b/src/char/char.cpp
index 87e48cb..f714dda 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -42,6 +42,7 @@
#include "../compat/alg.hpp"
#include "../ints/cmp.hpp"
+#include "../ints/udl.hpp"
#include "../strings/mstring.hpp"
#include "../strings/astring.hpp"
@@ -117,10 +118,14 @@ static
int char_name_option = 0; // Option to know which letters/symbols are authorised in the name of a character (0: all, 1: only those in char_name_letters, 2: all EXCEPT those in char_name_letters) by [Yor]
static
std::bitset<256> char_name_letters; // list of letters/symbols authorised (or not) in a character name. by [Yor]
+static constexpr
+GmLevel default_gm_level = GmLevel::from(0_u32);
+
struct char_session_data : SessionData
{
- int account_id, login_id1, login_id2;
+ AccountId account_id;
+ int login_id1, login_id2;
SEX sex;
unsigned short packet_tmw_version;
AccountEmail email;
@@ -134,8 +139,8 @@ void SessionDeleter::operator()(SessionData *sd)
struct AuthFifoEntry
{
- int account_id;
- int char_id;
+ AccountId account_id;
+ CharId char_id;
int login_id1, login_id2;
IP4Address ip;
int delflag;
@@ -152,7 +157,7 @@ static
int check_ip_flag = 1; // It's to check IP of a player between char-server and other servers (part of anti-hacking system)
static
-int char_id_count = 150000;
+CharId char_id_count = wrap<CharId>(150000);
static
std::vector<CharPair> char_keys;
static
@@ -177,7 +182,7 @@ int online_sorting_option = 0; // sorting option to display online players in on
static
int online_refresh_html = 20; // refresh time (in sec) of the html file in the explorer
static
-int online_gm_display_min_level = 20; // minimum GM level to display 'GM' when we want to display it
+GmLevel online_gm_display_min_level = GmLevel::from(20_u32); // minimum GM level to display 'GM' when we want to display it
static
std::vector<Session *> online_chars; // same size of char_keys, and id value of current server (or -1)
@@ -235,12 +240,12 @@ void char_log(XString line)
// and returns its level (or 0 if it isn't a GM account or if not found)
//----------------------------------------------------------------------
static
-int isGM(int account_id)
+GmLevel isGM(AccountId account_id)
{
for (GM_Account& gma : gm_accounts)
if (gma.account_id == account_id)
return gma.level;
- return 0;
+ return default_gm_level;
}
//----------------------------------------------
@@ -266,7 +271,7 @@ const CharPair *search_character(CharName character_name)
return nullptr;
}
-const CharPair *search_character_id(int char_id)
+const CharPair *search_character_id(CharId char_id)
{
for (const CharPair& cd : char_keys)
{
@@ -342,7 +347,7 @@ AString mmo_char_tostr(struct CharPair *cp)
if (p->inventory[i].nameid)
{
str_p += STRPRINTF("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d "_fmt,
- p->inventory[i].id,
+ 0 /*id*/,
p->inventory[i].nameid,
p->inventory[i].amount,
p->inventory[i].equip,
@@ -450,7 +455,7 @@ bool extract(XString str, CharPair *cp)
return false;
// TODO replace *every* lookup with a map lookup
- static std::set<int> seen_ids;
+ static std::set<CharId> seen_ids;
static std::set<CharName> seen_names;
// we don't have to worry about deleted characters,
// this is only called during startup
@@ -518,8 +523,8 @@ int mmo_char_init(void)
continue;
{
- int i, j = 0;
- if (SSCANF(line, "%d\t%%newid%%%n"_fmt, &i, &j) == 1 && j > 0)
+ CharId i;
+ if (extract(line, record<'\t'>(&i, "%newid%"_s)))
{
if (char_id_count < i)
char_id_count = i;
@@ -533,8 +538,8 @@ int mmo_char_init(void)
CHAR_LOG("Char skipped\n%s"_fmt, line);
continue;
}
- if (cd.key.char_id >= char_id_count)
- char_id_count = cd.key.char_id + 1;
+ if (char_id_count < next(cd.key.char_id))
+ char_id_count = next(cd.key.char_id);
char_keys.push_back(std::move(cd));
online_chars.push_back(nullptr);
}
@@ -740,11 +745,11 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui
CharKey& ck = cp.key;
CharData& cd = *cp.data;
- ck.char_id = char_id_count++;
+ ck.char_id = char_id_count; char_id_count = next(char_id_count);
ck.account_id = sd->account_id;
ck.char_num = slot;
ck.name = name;
- cd.species = 0;
+ cd.species = Species();
cd.base_level = 1;
cd.job_level = 1;
cd.base_exp = 0;
@@ -765,17 +770,17 @@ CharPair *make_new_char(Session *s, CharName name, const uint8_t (&stats)[6], ui
cd.option = static_cast<Option>(0x0000); // Option is only declared
cd.karma = 0;
cd.manner = 0;
- cd.party_id = 0;
+ cd.party_id = PartyId();
//cd.guild_id = 0;
cd.hair = hair_style;
cd.hair_color = hair_color;
cd.clothes_color = 0;
// removed initial armor/weapon - unused and problematic
cd.weapon = ItemLook::NONE;
- cd.shield = 0;
- cd.head_top = 0;
- cd.head_mid = 0;
- cd.head_bottom = 0;
+ cd.shield = ItemNameId();
+ cd.head_top = ItemNameId();
+ cd.head_mid = ItemNameId();
+ cd.head_bottom = ItemNameId();
cd.last_point = start_point;
cd.save_point = start_point;
char_keys.push_back(std::move(cp));
@@ -844,16 +849,16 @@ void create_online_files(void)
// displaying the character name
{
// without/with 'GM' display
- int gml = isGM(cd.key.account_id);
+ GmLevel gml = isGM(cd.key.account_id);
{
- if (gml >= online_gm_display_min_level)
+ if (gml.satisfies(online_gm_display_min_level))
FPRINTF(fp, "%-24s (GM) "_fmt, cd.key.name);
else
FPRINTF(fp, "%-24s "_fmt, cd.key.name);
}
// name of the character in the html (no < >, because that create problem in html code)
FPRINTF(fp2, " <td>"_fmt);
- if (gml >= online_gm_display_min_level)
+ if (gml.satisfies(online_gm_display_min_level))
FPRINTF(fp2, "<b>"_fmt);
for (char c : cd.key.name.to__actual())
{
@@ -873,7 +878,7 @@ void create_online_files(void)
break;
};
}
- if (gml >= online_gm_display_min_level)
+ if (gml.satisfies(online_gm_display_min_level))
FPRINTF(fp2, "</b> (GM)"_fmt);
FPRINTF(fp2, "</td>\n"_fmt);
}
@@ -927,14 +932,14 @@ int count_users(void)
// [Fate] Find inventory item based on equipment mask, return view. ID must match view ID (!).
//----------------------------------------
static
-int find_equip_view(const CharPair *cp, EPOS equipmask)
+ItemNameId find_equip_view(const CharPair *cp, EPOS equipmask)
{
CharData *p = cp->data.get();
for (int i = 0; i < MAX_INVENTORY; i++)
if (p->inventory[i].nameid && p->inventory[i].amount
&& bool(p->inventory[i].equip & equipmask))
return p->inventory[i].nameid;
- return 0;
+ return ItemNameId();
}
//----------------------------------------
@@ -969,39 +974,39 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd)
const CharKey *k = &cp->key;
const CharData *p = cp->data.get();
- WFIFOL(s, j) = k->char_id;
+ WFIFOL(s, j) = unwrap<CharId>(k->char_id);
WFIFOL(s, j + 4) = p->base_exp;
WFIFOL(s, j + 8) = p->zeny;
WFIFOL(s, j + 12) = p->job_exp;
WFIFOL(s, j + 16) = p->job_level;
- WFIFOW(s, j + 20) = find_equip_view(cp, EPOS::SHOES);
- WFIFOW(s, j + 22) = find_equip_view(cp, EPOS::GLOVES);
- WFIFOW(s, j + 24) = find_equip_view(cp, EPOS::CAPE);
- WFIFOW(s, j + 26) = find_equip_view(cp, EPOS::MISC1);
+ WFIFOW(s, j + 20) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::SHOES));
+ WFIFOW(s, j + 22) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::GLOVES));
+ WFIFOW(s, j + 24) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::CAPE));
+ WFIFOW(s, j + 26) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::MISC1));
WFIFOL(s, j + 28) = static_cast<uint16_t>(p->option);
WFIFOL(s, j + 32) = p->karma;
WFIFOL(s, j + 36) = p->manner;
WFIFOW(s, j + 40) = p->status_point;
- WFIFOW(s, j + 42) = (p->hp > 0x7fff) ? 0x7fff : p->hp;
- WFIFOW(s, j + 44) = (p->max_hp > 0x7fff) ? 0x7fff : p->max_hp;
- WFIFOW(s, j + 46) = (p->sp > 0x7fff) ? 0x7fff : p->sp;
- WFIFOW(s, j + 48) = (p->max_sp > 0x7fff) ? 0x7fff : p->max_sp;
+ WFIFOW(s, j + 42) = std::min(p->hp, 0x7fff);
+ WFIFOW(s, j + 44) = std::min(p->max_hp, 0x7fff);
+ WFIFOW(s, j + 46) = std::min(p->sp, 0x7fff);
+ WFIFOW(s, j + 48) = std::min(p->max_sp, 0x7fff);
WFIFOW(s, j + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // p->speed;
- WFIFOW(s, j + 52) = p->species;
+ WFIFOW(s, j + 52) = unwrap<Species>(p->species);
WFIFOW(s, j + 54) = p->hair;
// WFIFOW(s,j+56) = p->weapon; // dont send weapon since TMW does not support it
WFIFOW(s, j + 56) = 0;
WFIFOW(s, j + 58) = p->base_level;
WFIFOW(s, j + 60) = p->skill_point;
- WFIFOW(s, j + 62) = p->head_bottom;
- WFIFOW(s, j + 64) = p->shield;
- WFIFOW(s, j + 66) = p->head_top;
- WFIFOW(s, j + 68) = p->head_mid;
+ WFIFOW(s, j + 62) = unwrap<ItemNameId>(p->head_bottom);
+ WFIFOW(s, j + 64) = unwrap<ItemNameId>(p->shield);
+ WFIFOW(s, j + 66) = unwrap<ItemNameId>(p->head_top);
+ WFIFOW(s, j + 68) = unwrap<ItemNameId>(p->head_mid);
WFIFOW(s, j + 70) = p->hair_color;
- WFIFOW(s, j + 72) = find_equip_view(cp, EPOS::MISC2);
+ WFIFOW(s, j + 72) = unwrap<ItemNameId>(find_equip_view(cp, EPOS::MISC2));
// WFIFOW(s,j+72) = p->clothes_color;
WFIFO_STRING(s, j + 74, k->name.to__actual(), 24);
@@ -1021,7 +1026,7 @@ int mmo_char_send006b(Session *s, struct char_session_data *sd)
}
static
-int set_account_reg2(int acc, Slice<global_reg> reg)
+int set_account_reg2(AccountId acc, Slice<global_reg> reg)
{
size_t num = reg.size();
assert (num < ACCOUNT_REG2_NUM);
@@ -1053,43 +1058,44 @@ int char_divorce(CharPair *cp)
CharKey *ck = &cp->key;
CharData *cs = cp->data.get();
- if (cs->partner_id <= 0)
+ if (!cs->partner_id)
{
WBUFW(buf, 0) = 0x2b12;
- WBUFL(buf, 2) = ck->char_id;
- WBUFL(buf, 6) = 0; // partner id 0 means failure
+ WBUFL(buf, 2) = unwrap<CharId>(ck->char_id);
+ // partner id 0 means failure
+ WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id);
mapif_sendall(buf, 10);
return 0;
}
WBUFW(buf, 0) = 0x2b12;
- WBUFL(buf, 2) = ck->char_id;
+ WBUFL(buf, 2) = unwrap<CharId>(ck->char_id);
for (CharPair& cd : char_keys)
{
if (cd.key.char_id == cs->partner_id
&& cd.data->partner_id == ck->char_id)
{
- WBUFL(buf, 6) = cs->partner_id;
+ WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id);
mapif_sendall(buf, 10);
- cs->partner_id = 0;
- cd.data->partner_id = 0;
+ cs->partner_id = CharId();
+ cd.data->partner_id = CharId();
return 0;
}
// The other char doesn't have us as their partner, so just clear our partner
// Don't worry about this, as the map server should verify itself that the other doesn't have us as a partner, and so won't mess with their marriage
else if (cd.key.char_id == cs->partner_id)
{
- WBUFL(buf, 6) = cs->partner_id;
+ WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id);
mapif_sendall(buf, 10);
- cs->partner_id = 0;
+ cs->partner_id = CharId();
return 0;
}
}
// Our partner wasn't found, so just clear our marriage
- WBUFL(buf, 6) = cs->partner_id;
- cs->partner_id = 0;
+ WBUFL(buf, 6) = unwrap<CharId>(cs->partner_id);
+ cs->partner_id = CharId();
mapif_sendall(buf, 10);
return 0;
@@ -1099,25 +1105,24 @@ int char_divorce(CharPair *cp)
// Force disconnection of an online player (with account value) by [Yor]
//----------------------------------------------------------------------
static
-int disconnect_player(int accound_id)
+void disconnect_player(AccountId accound_id)
{
// disconnect player if online on char-server
for (io::FD i : iter_fds())
{
- if (!get_session(i))
+ Session *s = get_session(i);
+ if (!s)
continue;
- struct char_session_data *sd = static_cast<char_session_data *>(get_session(i)->session_data.get());
+ struct char_session_data *sd = static_cast<char_session_data *>(s->session_data.get());
if (sd)
{
if (sd->account_id == accound_id)
{
- get_session(i)->set_eof();
- return 1;
+ s->set_eof();
+ return;
}
}
}
-
- return 0;
}
// キャラ削除に伴うデータ削除
@@ -1138,7 +1143,7 @@ int char_delete(CharPair *cp)
{
unsigned char buf[6];
WBUFW(buf, 0) = 0x2afe;
- WBUFL(buf, 2) = ck->account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(ck->account_id);
mapif_sendall(buf, 6);
}
@@ -1193,11 +1198,12 @@ void parse_tologin(Session *ls)
return;
for (io::FD i : iter_fds())
{
+ AccountId acc = wrap<AccountId>(RFIFOL(ls, 2));
Session *s2 = get_session(i);
if (!s2)
continue;
sd = static_cast<char_session_data *>(s2->session_data.get());
- if (sd && sd->account_id == RFIFOL(ls, 2))
+ if (sd && sd->account_id == acc)
{
if (RFIFOB(ls, 6) != 0)
{
@@ -1234,13 +1240,14 @@ void parse_tologin(Session *ls)
return;
for (io::FD i : iter_fds())
{
+ AccountId acc = wrap<AccountId>(RFIFOL(ls, 2));
Session *s2 = get_session(i);
if (!s2)
continue;
sd = static_cast<char_session_data *>(s2->session_data.get());
if (sd)
{
- if (sd->account_id == RFIFOL(ls, 2))
+ if (sd->account_id == acc)
{
sd->email = stringish<AccountEmail>(RFIFO_STRING<40>(ls, 6));
if (!e_mail_check(sd->email))
@@ -1257,10 +1264,12 @@ void parse_tologin(Session *ls)
if (RFIFOREST(ls) < 10)
return;
{
+ AccountId acc = wrap<AccountId>(RFIFOL(ls, 2));
+ GmLevel gml = GmLevel::from(RFIFOL(ls, 2));
unsigned char buf[10];
WBUFW(buf, 0) = 0x2b0b;
- WBUFL(buf, 2) = RFIFOL(ls, 2); // account
- WBUFL(buf, 6) = RFIFOL(ls, 6); // GM level
+ WBUFL(buf, 2) = unwrap<AccountId>(acc);
+ WBUFL(buf, 6) = gml.get_all_bits();
mapif_sendall(buf, 10);
}
RFIFOSKIP(ls, 10);
@@ -1271,10 +1280,10 @@ void parse_tologin(Session *ls)
return;
{
unsigned char buf[7];
- int acc = RFIFOL(ls, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(ls, 2));
SEX sex = static_cast<SEX>(RFIFOB(ls, 6));
RFIFOSKIP(ls, 7);
- if (acc > 0)
+ if (acc)
{
for (CharPair& cp : char_keys)
{
@@ -1292,17 +1301,17 @@ void parse_tologin(Session *ls)
cd.inventory[j].equip = EPOS::ZERO;
}
cd.weapon = ItemLook::NONE;
- cd.shield = 0;
- cd.head_top = 0;
- cd.head_mid = 0;
- cd.head_bottom = 0;
+ cd.shield = ItemNameId();
+ cd.head_top = ItemNameId();
+ cd.head_mid = ItemNameId();
+ cd.head_bottom = ItemNameId();
}
}
// disconnect player if online on char-server
disconnect_player(acc);
}
WBUFW(buf, 0) = 0x2b0d;
- WBUFL(buf, 2) = acc;
+ WBUFL(buf, 2) = unwrap<AccountId>(acc);
WBUFB(buf, 6) = static_cast<uint8_t>(sex);
mapif_sendall(buf, 7);
}
@@ -1353,8 +1362,8 @@ void parse_tologin(Session *ls)
return;
{
Array<struct global_reg, ACCOUNT_REG2_NUM> reg;
- int j, p, acc;
- acc = RFIFOL(ls, 4);
+ int j, p;
+ AccountId acc = wrap<AccountId>(RFIFOL(ls, 4));
for (p = 8, j = 0;
p < RFIFOW(ls, 2) && j < ACCOUNT_REG2_NUM;
p += 36, j++)
@@ -1377,13 +1386,13 @@ void parse_tologin(Session *ls)
{ // [Fate] Itemfrob package: forwarded from login-server
if (RFIFOREST(ls) < 10)
return;
- int source_id = RFIFOL(ls, 2);
- int dest_id = RFIFOL(ls, 6);
+ ItemNameId source_id = wrap<ItemNameId>(RFIFOL(ls, 2));
+ ItemNameId dest_id = wrap<ItemNameId>(RFIFOL(ls, 6));
unsigned char buf[10];
WBUFW(buf, 0) = 0x2afa;
- WBUFL(buf, 2) = source_id;
- WBUFL(buf, 6) = dest_id;
+ WBUFL(buf, 2) = unwrap<ItemNameId>(source_id);
+ WBUFL(buf, 6) = unwrap<ItemNameId>(dest_id);
mapif_sendall(buf, 10); // forward package to map servers
for (CharPair& cp : char_keys)
@@ -1425,6 +1434,9 @@ void parse_tologin(Session *ls)
case 0x2730:
if (RFIFOREST(ls) < 6)
return;
+ {
+ AccountId aid = wrap<AccountId>(RFIFOL(ls, 2));
+
// Deletion of all characters of the account
//#warning "This comment is a lie, but it's still true."
// needs to use index because they may move during resize
@@ -1432,7 +1444,7 @@ void parse_tologin(Session *ls)
{
CharPair& cp = char_keys[idx];
CharKey& ck = cp.key;
- if (ck.account_id == RFIFOL(ls, 2))
+ if (ck.account_id == aid)
{
char_delete(&cp);
if (&cp != &char_keys.back())
@@ -1441,7 +1453,7 @@ void parse_tologin(Session *ls)
// if moved character owns to deleted account, check again it's character
// YES this is the newly swapped one
// we could avoid this by working backwards
- if (ck.account_id == RFIFOL(ls, 2))
+ if (ck.account_id == aid)
{
idx--;
// Correct moved character reference in the character's owner by [Yor]
@@ -1451,16 +1463,17 @@ void parse_tologin(Session *ls)
}
}
// Deletion of the storage
- inter_storage_delete(RFIFOL(ls, 2));
+ inter_storage_delete(aid);
// send to all map-servers to disconnect the player
{
unsigned char buf[6];
WBUFW(buf, 0) = 0x2b13;
- WBUFL(buf, 2) = RFIFOL(ls, 2);
+ WBUFL(buf, 2) = unwrap<AccountId>(aid);
mapif_sendall(buf, 6);
}
// disconnect player if online on char-server
- disconnect_player(RFIFOL(ls, 2));
+ disconnect_player(aid);
+ }
RFIFOSKIP(ls, 6);
break;
@@ -1468,17 +1481,20 @@ void parse_tologin(Session *ls)
case 0x2731:
if (RFIFOREST(ls) < 11)
return;
+ {
+ AccountId aid = wrap<AccountId>(RFIFOL(ls, 2));
// send to all map-servers to disconnect the player
{
unsigned char buf[11];
WBUFW(buf, 0) = 0x2b14;
- WBUFL(buf, 2) = RFIFOL(ls, 2);
+ WBUFL(buf, 2) = unwrap<AccountId>(aid);
WBUFB(buf, 6) = RFIFOB(ls, 6); // 0: change of statut, 1: ban
WBUFL(buf, 7) = RFIFOL(ls, 7); // status or final date of a banishment
mapif_sendall(buf, 11);
}
// disconnect player if online on char-server
- disconnect_player(RFIFOL(ls, 2));
+ disconnect_player(aid);
+ }
RFIFOSKIP(ls, 11);
break;
@@ -1493,7 +1509,7 @@ void parse_tologin(Session *ls)
gm_accounts.reserve((len - 4) / 5);
for (int i = 4; i < len; i += 5)
{
- gm_accounts.push_back({static_cast<int>(RFIFOL(ls, i)), RFIFOB(ls, i + 4)});
+ gm_accounts.push_back({wrap<AccountId>(RFIFOL(ls, i)), GmLevel::from(static_cast<uint32_t>(RFIFOB(ls, i + 4)))});
}
PRINTF("From login-server: receiving of %zu GM accounts information.\n"_fmt,
gm_accounts.size());
@@ -1512,7 +1528,7 @@ void parse_tologin(Session *ls)
if (RFIFOREST(ls) < 7)
return;
{
- int acc = RFIFOL(ls, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(ls, 2));
int status = RFIFOB(ls, 6);
for (io::FD i : iter_fds())
@@ -1668,8 +1684,8 @@ void parse_frommap(Session *ms)
if (RFIFOREST(ms) < 22)
return;
{
- int account_id = RFIFOL(ms, 2);
- int char_id = RFIFOL(ms, 6);
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 2));
+ CharId char_id = wrap<CharId>(RFIFOL(ms, 6));
int login_id1 = RFIFOL(ms, 10);
int login_id2 = RFIFOL(ms, 14);
IP4Address ip = RFIFOIP(ms, 18);
@@ -1700,7 +1716,7 @@ void parse_frommap(Session *ms)
afi.delflag = 1;
WFIFOW(ms, 0) = 0x2afd;
WFIFOW(ms, 2) = 18 + sizeof(*ck) + sizeof(*cd);
- WFIFOL(ms, 4) = account_id;
+ WFIFOL(ms, 4) = unwrap<AccountId>(account_id);
WFIFOL(ms, 8) = afi.login_id2;
WFIFOL(ms, 12) = static_cast<time_t>(afi.connect_until_time);
cd->sex = afi.sex;
@@ -1716,7 +1732,7 @@ void parse_frommap(Session *ms)
}
{
WFIFOW(ms, 0) = 0x2afe;
- WFIFOL(ms, 2) = account_id;
+ WFIFOL(ms, 2) = unwrap<AccountId>(account_id);
WFIFOSET(ms, 6);
PRINTF("auth_fifo search error! account %d not authentified.\n"_fmt,
account_id);
@@ -1743,7 +1759,7 @@ void parse_frommap(Session *ms)
// add online players in the list by [Yor]
for (int i = 0; i < server[id].users; i++)
{
- int char_id = RFIFOL(ms, 6 + i * 4);
+ CharId char_id = wrap<CharId>(RFIFOL(ms, 6 + i * 4));
for (const CharPair& cd : char_keys)
{
if (cd.key.char_id == char_id)
@@ -1768,16 +1784,20 @@ void parse_frommap(Session *ms)
case 0x2b01:
if (RFIFOREST(ms) < 4 || RFIFOREST(ms) < RFIFOW(ms, 2))
return;
+ {
+ AccountId aid = wrap<AccountId>(RFIFOL(ms, 4));
+ CharId cid = wrap<CharId>(RFIFOL(ms, 8));
for (CharPair& cd : char_keys)
{
- if (cd.key.account_id == RFIFOL(ms, 4) &&
- cd.key.char_id == RFIFOL(ms, 8))
+ if (cd.key.account_id == aid &&
+ cd.key.char_id == cid)
{
RFIFO_STRUCT(ms, 12, cd.key);
RFIFO_STRUCT(ms, 12 + sizeof(cd.key), *cd.data);
break;
}
}
+ }
RFIFOSKIP(ms, RFIFOW(ms, 2));
break;
@@ -1786,11 +1806,11 @@ void parse_frommap(Session *ms)
if (RFIFOREST(ms) < 18)
return;
{
- int account_id = RFIFOL(ms, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 2));
if (auth_fifo_iter == auth_fifo.end())
auth_fifo_iter = auth_fifo.begin();
auth_fifo_iter->account_id = account_id;
- auth_fifo_iter->char_id = 0;
+ auth_fifo_iter->char_id = CharId();
auth_fifo_iter->login_id1 = RFIFOL(ms, 6);
auth_fifo_iter->login_id2 = RFIFOL(ms, 10);
auth_fifo_iter->delflag = 2;
@@ -1798,7 +1818,7 @@ void parse_frommap(Session *ms)
auth_fifo_iter->ip = RFIFOIP(ms, 14);
auth_fifo_iter++;
WFIFOW(ms, 0) = 0x2b03;
- WFIFOL(ms, 2) = account_id;
+ WFIFOL(ms, 2) = unwrap<AccountId>(account_id);
WFIFOB(ms, 6) = 0;
WFIFOSET(ms, 7);
}
@@ -1815,8 +1835,8 @@ void parse_frommap(Session *ms)
RFIFO_WFIFO_CLONE(ms, ms, 44);
// overwrite
WFIFOW(ms, 0) = 0x2b06;
- auth_fifo_iter->account_id = RFIFOL(ms, 2);
- auth_fifo_iter->char_id = RFIFOL(ms, 14);
+ auth_fifo_iter->account_id = wrap<AccountId>(RFIFOL(ms, 2));
+ auth_fifo_iter->char_id = wrap<CharId>(RFIFOL(ms, 14));
auth_fifo_iter->login_id1 = RFIFOL(ms, 6);
auth_fifo_iter->login_id2 = RFIFOL(ms, 10);
auth_fifo_iter->delflag = 0;
@@ -1827,13 +1847,17 @@ void parse_frommap(Session *ms)
// default, if not found in the loop
WFIFOW(ms, 6) = 1;
for (const CharPair& cd : char_keys)
- if (cd.key.account_id == RFIFOL(ms, 2) &&
- cd.key.char_id == RFIFOL(ms, 14))
+ {
+ AccountId aid = wrap<AccountId>(RFIFOL(ms, 2));
+ CharId cid = wrap<CharId>(RFIFOL(ms, 14));
+ if (cd.key.account_id == aid &&
+ cd.key.char_id == cid)
{
auth_fifo_iter++;
WFIFOL(ms, 6) = 0;
break;
}
+ }
WFIFOSET(ms, 44);
RFIFOSKIP(ms, 49);
break;
@@ -1880,12 +1904,12 @@ void parse_frommap(Session *ms)
if (RFIFOREST(ms) < 44)
return;
{
- int acc = RFIFOL(ms, 2); // account_id of who ask (-1 if nobody)
+ AccountId acc = wrap<AccountId>(RFIFOL(ms, 2)); // account_id of who ask (-1 if nobody)
CharName character_name = stringish<CharName>(RFIFO_STRING<24>(ms, 6));
int operation = RFIFOW(ms, 30);
// prepare answer
WFIFOW(ms, 0) = 0x2b0f; // answer
- WFIFOL(ms, 2) = acc; // who want do operation
+ WFIFOL(ms, 2) = unwrap<AccountId>(acc); // who want do operation
WFIFOW(ms, 30) = operation; // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5-changesex
// search character
const CharPair *cd = search_character(character_name);
@@ -1897,13 +1921,13 @@ void parse_frommap(Session *ms)
switch (RFIFOW(ms, 30))
{
case 1: // block
- if (acc == -1
- || isGM(acc) >= isGM(ck->account_id))
+ if (!acc
+ || isGM(acc).overwhelms(isGM(ck->account_id)))
{
if (login_session)
{ // don't send request if no login-server
WFIFOW(login_session, 0) = 0x2724;
- WFIFOL(login_session, 2) = ck->account_id; // account value
+ WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value
WFIFOL(login_session, 6) = 5; // status of the account
WFIFOSET(login_session, 10);
}
@@ -1914,13 +1938,13 @@ void parse_frommap(Session *ms)
WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
break;
case 2: // ban
- if (acc == -1
- || isGM(acc) >= isGM(ck->account_id))
+ if (!acc
+ || isGM(acc).overwhelms(isGM(ck->account_id)))
{
if (login_session)
{ // don't send request if no login-server
WFIFOW(login_session, 0) = 0x2725;
- WFIFOL(login_session, 2) = ck->account_id; // account value
+ WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value
HumanTimeDiff ban_change;
RFIFO_STRUCT(ms, 32, ban_change);
WFIFO_STRUCT(login_session, 6, ban_change);
@@ -1933,13 +1957,13 @@ void parse_frommap(Session *ms)
WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
break;
case 3: // unblock
- if (acc == -1
- || isGM(acc) >= isGM(ck->account_id))
+ if (!acc
+ || isGM(acc).overwhelms(isGM(ck->account_id)))
{
if (login_session)
{ // don't send request if no login-server
WFIFOW(login_session, 0) = 0x2724;
- WFIFOL(login_session, 2) = ck->account_id; // account value
+ WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value
WFIFOL(login_session, 6) = 0; // status of the account
WFIFOSET(login_session, 10);
}
@@ -1950,13 +1974,13 @@ void parse_frommap(Session *ms)
WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
break;
case 4: // unban
- if (acc == -1
- || isGM(acc) >= isGM(ck->account_id))
+ if (!acc
+ || isGM(acc).overwhelms(isGM(ck->account_id)))
{
if (login_session)
{ // don't send request if no login-server
WFIFOW(login_session, 0) = 0x272a;
- WFIFOL(login_session, 2) = ck->account_id; // account value
+ WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value
WFIFOSET(login_session, 6);
}
else
@@ -1966,13 +1990,13 @@ void parse_frommap(Session *ms)
WFIFOW(ms, 32) = 2; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
break;
case 5: // changesex
- if (acc == -1
- || isGM(acc) >= isGM(ck->account_id))
+ if (!acc
+ || isGM(acc).overwhelms(isGM(ck->account_id)))
{
if (login_session)
{ // don't send request if no login-server
WFIFOW(login_session, 0) = 0x2727;
- WFIFOL(login_session, 2) = ck->account_id; // account value
+ WFIFOL(login_session, 2) = unwrap<AccountId>(ck->account_id); // account value
WFIFOSET(login_session, 6);
}
else
@@ -1990,7 +2014,7 @@ void parse_frommap(Session *ms)
WFIFOW(ms, 32) = 1; // answer: 0-login-server resquest done, 1-player not found, 2-gm level too low, 3-login-server offline
}
// send answer if a player ask, not if the server ask
- if (acc != -1)
+ if (acc)
{
WFIFOSET(ms, 34);
}
@@ -2007,7 +2031,7 @@ void parse_frommap(Session *ms)
{
Array<struct global_reg, ACCOUNT_REG2_NUM> reg;
int p, j;
- int acc = RFIFOL(ms, 4);
+ AccountId acc = wrap<AccountId>(RFIFOL(ms, 4));
for (p = 8, j = 0;
p < RFIFOW(ms, 2) && j < ACCOUNT_REG2_NUM;
p += 36, j++)
@@ -2033,8 +2057,9 @@ void parse_frommap(Session *ms)
if (RFIFOREST(ms) < 4)
return;
{
+ CharId cid = wrap<CharId>(RFIFOL(ms, 2));
for (CharPair& cd : char_keys)
- if (cd.key.char_id == RFIFOL(ms, 2))
+ if (cd.key.char_id == cid)
{
char_divorce(&cd);
break;
@@ -2144,7 +2169,7 @@ void handle_x0066(Session *s, struct char_session_data *sd, uint8_t rfifob_2, IP
}
}
WFIFOW(s, 0) = 0x71;
- WFIFOL(s, 2) = ck->char_id;
+ WFIFOL(s, 2) = unwrap<CharId>(ck->char_id);
WFIFO_STRING(s, 6, cd->last_point.map_, 16);
PRINTF("Character selection '%s' (account: %d, slot: %d) [%s]\n"_fmt,
ck->name,
@@ -2204,7 +2229,7 @@ void parse_char(Session *s)
return;
{
WFIFOW(login_session, 0) = 0x2740;
- WFIFOL(login_session, 2) = sd->account_id;
+ WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id);
AccountPass old_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 2));
WFIFO_STRING(login_session, 6, old_pass, 24);
AccountPass new_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 26));
@@ -2218,8 +2243,8 @@ void parse_char(Session *s)
if (RFIFOREST(s) < 17)
return;
{
- int account_id = RFIFOL(s, 2);
- int GM_value = isGM(account_id);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
+ GmLevel GM_value = isGM(account_id);
if (GM_value)
PRINTF("Account Logged On; Account ID: %d (GM level %d).\n"_fmt,
account_id, GM_value);
@@ -2239,7 +2264,7 @@ void parse_char(Session *s)
sd->packet_tmw_version = RFIFOW(s, 14);
sd->sex = static_cast<SEX>(RFIFOB(s, 16));
// send back account_id
- WFIFOL(s, 0) = account_id;
+ WFIFOL(s, 0) = unwrap<AccountId>(account_id);
WFIFOSET(s, 4);
// search authentification
for (AuthFifoEntry& afi : auth_fifo)
@@ -2259,7 +2284,7 @@ void parse_char(Session *s)
{ // don't send request if no login-server
// request to login-server to obtain e-mail/time limit
WFIFOW(login_session, 0) = 0x2716;
- WFIFOL(login_session, 2) = sd->account_id;
+ WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id);
WFIFOSET(login_session, 6);
}
// Record client version
@@ -2284,7 +2309,7 @@ void parse_char(Session *s)
{
// don't send request if no login-server
WFIFOW(login_session, 0) = 0x2712; // ask login-server to authentify an account
- WFIFOL(login_session, 2) = sd->account_id;
+ WFIFOL(login_session, 2) = unwrap<AccountId>(sd->account_id);
WFIFOL(login_session, 6) = sd->login_id1;
WFIFOL(login_session, 10) = sd->login_id2; // relate to the versions higher than 18
WFIFOB(login_session, 14) = static_cast<uint8_t>(sd->sex);
@@ -2336,7 +2361,7 @@ void parse_char(Session *s)
WFIFOW(s, 0) = 0x6d;
WFIFO_ZERO(s, 2, 106);
- WFIFOL(s, 2) = ck->char_id;
+ WFIFOL(s, 2) = unwrap<CharId>(ck->char_id);
WFIFOL(s, 2 + 4) = cd->base_exp;
WFIFOL(s, 2 + 8) = cd->zeny;
WFIFOL(s, 2 + 12) = cd->job_exp;
@@ -2351,15 +2376,15 @@ void parse_char(Session *s)
WFIFOW(s, 2 + 46) = saturate<int16_t>(cd->sp);
WFIFOW(s, 2 + 48) = saturate<int16_t>(cd->max_sp);
WFIFOW(s, 2 + 50) = static_cast<uint16_t>(DEFAULT_WALK_SPEED.count()); // cd->speed;
- WFIFOW(s, 2 + 52) = cd->species;
+ WFIFOW(s, 2 + 52) = unwrap<Species>(cd->species);
WFIFOW(s, 2 + 54) = cd->hair;
WFIFOW(s, 2 + 58) = cd->base_level;
WFIFOW(s, 2 + 60) = cd->skill_point;
- WFIFOW(s, 2 + 64) = cd->shield;
- WFIFOW(s, 2 + 66) = cd->head_top;
- WFIFOW(s, 2 + 68) = cd->head_mid;
+ WFIFOW(s, 2 + 64) = unwrap<ItemNameId>(cd->shield);
+ WFIFOW(s, 2 + 66) = unwrap<ItemNameId>(cd->head_top);
+ WFIFOW(s, 2 + 68) = unwrap<ItemNameId>(cd->head_mid);
WFIFOW(s, 2 + 70) = cd->hair_color;
WFIFO_STRING(s, 2 + 74, ck->name.to__actual(), 24);
@@ -2387,10 +2412,11 @@ void parse_char(Session *s)
{
{
+ CharId cid = wrap<CharId>(RFIFOL(s, 2));
CharPair *cs = nullptr;
for (CharPair& cd : char_keys)
{
- if (cd.key.char_id == RFIFOL(s, 2))
+ if (cd.key.char_id == cid)
{
cs = &cd;
break;
@@ -2467,8 +2493,8 @@ void parse_char(Session *s)
WFIFOW(s, 0) = 0x2b15;
for (const GM_Account& gma : gm_accounts)
{
- WFIFOL(s, len) = gma.account_id;
- WFIFOB(s, len + 4) = gma.level;
+ WFIFOL(s, len) = unwrap<AccountId>(gma.account_id);
+ WFIFOB(s, len + 4) = gma.level.get_all_bits();
len += 5;
}
WFIFOW(s, 2) = len;
@@ -2794,10 +2820,9 @@ bool char_config(XString w1, ZString w2)
online_sorting_option = atoi(w2.c_str());
}
else if (w1 == "online_gm_display_min_level"_s)
- { // minimum GM level to display 'GM' when we want to display it
- online_gm_display_min_level = atoi(w2.c_str());
- if (online_gm_display_min_level < 5) // send online file every 5 seconds to player is enough
- online_gm_display_min_level = 5;
+ {
+ // minimum GM level to display 'GM' when we want to display it
+ return extract(w2, &online_gm_display_min_level);
}
else if (w1 == "online_refresh_html"_s)
{
diff --git a/src/char/char.hpp b/src/char/char.hpp
index 4c11073..5b4f9b9 100644
--- a/src/char/char.hpp
+++ b/src/char/char.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/fwd.hpp"
@@ -41,7 +41,7 @@ struct mmo_map_server
};
const CharPair *search_character(CharName character_name);
-const CharPair *search_character_id(int char_id);
+const CharPair *search_character_id(CharId char_id);
Session *server_for(const CharPair *mcs);
int mapif_sendall(const uint8_t *buf, unsigned int len);
diff --git a/src/char/fwd.hpp b/src/char/fwd.hpp
new file mode 100644
index 0000000..4721cc2
--- /dev/null
+++ b/src/char/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_CHAR_FWD_HPP
+#define TMWA_CHAR_FWD_HPP
+// char/fwd.hpp - list of type names for char server
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_CHAR_FWD_HPP
diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp
index 952788c..3afa8a9 100644
--- a/src/char/int_party.cpp
+++ b/src/char/int_party.cpp
@@ -23,6 +23,8 @@
#include <cstdlib>
#include <cstring>
+#include "../ints/udl.hpp"
+
#include "../strings/mstring.hpp"
#include "../strings/astring.hpp"
#include "../strings/xstring.hpp"
@@ -45,16 +47,16 @@
AString party_txt = "save/party.txt"_s;
static
-Map<int, struct party> party_db;
+Map<PartyId, struct party> party_db;
static
-int party_newid = 100;
+PartyId party_newid = wrap<PartyId>(100_u32);
static
-void mapif_party_broken(int party_id, int flag);
+void mapif_party_broken(PartyId party_id, int flag);
static
int party_check_empty(struct party *p);
static
-void mapif_parse_PartyLeave(Session *s, int party_id, int account_id);
+void mapif_parse_PartyLeave(Session *s, PartyId party_id, AccountId account_id);
// パーティデータの文字列への変換
static
@@ -150,24 +152,24 @@ void inter_party_init(void)
if (!in.is_open())
return;
- // TODO: convert to use char_id, and change to extract()
+ // TODO: convert to use char_id
AString line;
int c = 0;
while (in.getline(line))
{
- int i, j = 0;
- if (SSCANF(line, "%d\t%%newid%%\n%n"_fmt, &i, &j) == 1 && j > 0
- && party_newid <= i)
+ PartyId i;
+ if (extract(line, record<'\t'>(&i, "%newid%"_s))
+ && party_newid < i)
{
party_newid = i;
continue;
}
struct party p {};
- if (extract(line, &p) && p.party_id > 0)
+ if (extract(line, &p) && p.party_id)
{
- if (p.party_id >= party_newid)
- party_newid = p.party_id + 1;
+ if (party_newid < next(p.party_id))
+ party_newid = next(p.party_id);
party_check_deleted_init(&p);
party_db.insert(p.party_id, p);
party_check_empty(&p);
@@ -253,7 +255,7 @@ int party_check_empty(struct party *p)
for (i = 0; i < MAX_PARTY; i++)
{
- if (p->member[i].account_id > 0)
+ if (p->member[i].account_id)
{
return 0;
}
@@ -268,7 +270,7 @@ int party_check_empty(struct party *p)
// キャラの競合がないかチェック用
static
void party_check_conflict_sub(struct party *p,
- int party_id, int account_id, CharName nick)
+ PartyId party_id, AccountId account_id, CharName nick)
{
int i;
@@ -290,7 +292,7 @@ void party_check_conflict_sub(struct party *p,
// キャラの競合がないかチェック
static
-void party_check_conflict(int party_id, int account_id, CharName nick)
+void party_check_conflict(PartyId party_id, AccountId account_id, CharName nick)
{
for (auto& pair : party_db)
party_check_conflict_sub(&pair.second,
@@ -302,14 +304,14 @@ void party_check_conflict(int party_id, int account_id, CharName nick)
// パーティ作成可否
static
-void mapif_party_created(Session *s, int account_id, struct party *p)
+void mapif_party_created(Session *s, AccountId account_id, struct party *p)
{
WFIFOW(s, 0) = 0x3820;
- WFIFOL(s, 2) = account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(account_id);
if (p != NULL)
{
WFIFOB(s, 6) = 0;
- WFIFOL(s, 7) = p->party_id;
+ WFIFOL(s, 7) = unwrap<PartyId>(p->party_id);
WFIFO_STRING(s, 11, p->name, 24);
PRINTF("int_party: created! %d %s\n"_fmt, p->party_id, p->name);
}
@@ -324,11 +326,11 @@ void mapif_party_created(Session *s, int account_id, struct party *p)
// パーティ情報見つからず
static
-void mapif_party_noinfo(Session *s, int party_id)
+void mapif_party_noinfo(Session *s, PartyId party_id)
{
WFIFOW(s, 0) = 0x3821;
WFIFOW(s, 2) = 8;
- WFIFOL(s, 4) = party_id;
+ WFIFOL(s, 4) = unwrap<PartyId>(party_id);
WFIFOSET(s, 8);
PRINTF("int_party: info not found %d\n"_fmt, party_id);
}
@@ -350,25 +352,25 @@ void mapif_party_info(Session *s, struct party *p)
// パーティメンバ追加可否
static
-void mapif_party_memberadded(Session *s, int party_id, int account_id, int flag)
+void mapif_party_memberadded(Session *s, PartyId party_id, AccountId account_id, int flag)
{
WFIFOW(s, 0) = 0x3822;
- WFIFOL(s, 2) = party_id;
- WFIFOL(s, 6) = account_id;
+ WFIFOL(s, 2) = unwrap<PartyId>(party_id);
+ WFIFOL(s, 6) = unwrap<AccountId>(account_id);
WFIFOB(s, 10) = flag;
WFIFOSET(s, 11);
}
// パーティ設定変更通知
static
-void mapif_party_optionchanged(Session *s, struct party *p, int account_id,
+void mapif_party_optionchanged(Session *s, struct party *p, AccountId account_id,
int flag)
{
unsigned char buf[15];
WBUFW(buf, 0) = 0x3823;
- WBUFL(buf, 2) = p->party_id;
- WBUFL(buf, 6) = account_id;
+ WBUFL(buf, 2) = unwrap<PartyId>(p->party_id);
+ WBUFL(buf, 6) = unwrap<AccountId>(account_id);
WBUFW(buf, 10) = p->exp;
WBUFW(buf, 12) = p->item;
WBUFB(buf, 14) = flag;
@@ -382,13 +384,13 @@ void mapif_party_optionchanged(Session *s, struct party *p, int account_id,
// パーティ脱退通知
static
-void mapif_party_leaved(int party_id, int account_id, CharName name)
+void mapif_party_leaved(PartyId party_id, AccountId account_id, CharName name)
{
unsigned char buf[34];
WBUFW(buf, 0) = 0x3824;
- WBUFL(buf, 2) = party_id;
- WBUFL(buf, 6) = account_id;
+ WBUFL(buf, 2) = unwrap<PartyId>(party_id);
+ WBUFL(buf, 6) = unwrap<AccountId>(account_id);
WBUF_STRING(buf, 10, name.to__actual(), 24);
mapif_sendall(buf, 34);
PRINTF("int_party: party leaved %d %d %s\n"_fmt, party_id, account_id, name);
@@ -402,8 +404,8 @@ void mapif_party_membermoved(struct party *p, int idx)
unsigned char buf[29];
WBUFW(buf, 0) = 0x3825;
- WBUFL(buf, 2) = p->party_id;
- WBUFL(buf, 6) = p->member[idx].account_id;
+ WBUFL(buf, 2) = unwrap<PartyId>(p->party_id);
+ WBUFL(buf, 6) = unwrap<AccountId>(p->member[idx].account_id);
WBUF_STRING(buf, 10, p->member[idx].map, 16);
WBUFB(buf, 26) = p->member[idx].online;
WBUFW(buf, 27) = p->member[idx].lv;
@@ -411,11 +413,11 @@ void mapif_party_membermoved(struct party *p, int idx)
}
// パーティ解散通知
-void mapif_party_broken(int party_id, int flag)
+void mapif_party_broken(PartyId party_id, int flag)
{
unsigned char buf[7];
WBUFW(buf, 0) = 0x3826;
- WBUFL(buf, 2) = party_id;
+ WBUFL(buf, 2) = unwrap<PartyId>(party_id);
WBUFB(buf, 6) = flag;
mapif_sendall(buf, 7);
PRINTF("int_party: broken %d\n"_fmt, party_id);
@@ -424,15 +426,15 @@ void mapif_party_broken(int party_id, int flag)
// パーティ内発言
static
-void mapif_party_message(int party_id, int account_id, XString mes)
+void mapif_party_message(PartyId party_id, AccountId account_id, XString mes)
{
size_t len = mes.size() + 1;
unsigned char buf[len + 12];
WBUFW(buf, 0) = 0x3827;
WBUFW(buf, 2) = len + 12;
- WBUFL(buf, 4) = party_id;
- WBUFL(buf, 8) = account_id;
+ WBUFL(buf, 4) = unwrap<PartyId>(party_id);
+ WBUFL(buf, 8) = unwrap<AccountId>(account_id);
WBUF_STRING(buf, 12, mes, len);
mapif_sendall(buf, len + 12);
}
@@ -442,7 +444,7 @@ void mapif_party_message(int party_id, int account_id, XString mes)
// パーティ
static
-void mapif_parse_CreateParty(Session *s, int account_id, PartyName name, CharName nick,
+void mapif_parse_CreateParty(Session *s, AccountId account_id, PartyName name, CharName nick,
MapName map, int lv)
{
{
@@ -461,7 +463,8 @@ void mapif_parse_CreateParty(Session *s, int account_id, PartyName name, CharNam
return;
}
struct party p {};
- p.party_id = party_newid++;
+ party_newid = next(party_newid);
+ p.party_id = party_newid;
p.name = name;
p.exp = 0;
p.item = 0;
@@ -480,7 +483,7 @@ void mapif_parse_CreateParty(Session *s, int account_id, PartyName name, CharNam
// パーティ情報要求
static
-void mapif_parse_PartyInfo(Session *s, int party_id)
+void mapif_parse_PartyInfo(Session *s, PartyId party_id)
{
struct party *p = party_db.search(party_id);
if (p != NULL)
@@ -491,7 +494,7 @@ void mapif_parse_PartyInfo(Session *s, int party_id)
// パーティ追加要求
static
-void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id,
+void mapif_parse_PartyAddMember(Session *s, PartyId party_id, AccountId account_id,
CharName nick, MapName map, int lv)
{
struct party *p = party_db.search(party_id);
@@ -503,7 +506,7 @@ void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id,
for (int i = 0; i < MAX_PARTY; i++)
{
- if (p->member[i].account_id == 0)
+ if (!p->member[i].account_id)
{
int flag = 0;
@@ -522,7 +525,7 @@ void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id,
flag = 0x01;
}
if (flag)
- mapif_party_optionchanged(s, p, 0, 0);
+ mapif_party_optionchanged(s, p, AccountId(), 0);
return;
}
}
@@ -531,7 +534,7 @@ void mapif_parse_PartyAddMember(Session *s, int party_id, int account_id,
// パーティー設定変更要求
static
-void mapif_parse_PartyChangeOption(Session *s, int party_id, int account_id,
+void mapif_parse_PartyChangeOption(Session *s, PartyId party_id, AccountId account_id,
int exp, int item)
{
struct party *p = party_db.search(party_id);
@@ -552,7 +555,7 @@ void mapif_parse_PartyChangeOption(Session *s, int party_id, int account_id,
}
// パーティ脱退要求
-void mapif_parse_PartyLeave(Session *, int party_id, int account_id)
+void mapif_parse_PartyLeave(Session *, PartyId party_id, AccountId account_id)
{
struct party *p = party_db.search(party_id);
if (!p)
@@ -572,7 +575,7 @@ void mapif_parse_PartyLeave(Session *, int party_id, int account_id)
// パーティマップ更新要求
static
-void mapif_parse_PartyChangeMap(Session *s, int party_id, int account_id,
+void mapif_parse_PartyChangeMap(Session *s, PartyId party_id, AccountId account_id,
MapName map, int online, int lv)
{
struct party *p = party_db.search(party_id);
@@ -596,14 +599,14 @@ void mapif_parse_PartyChangeMap(Session *s, int party_id, int account_id,
flag = 1;
}
if (flag)
- mapif_party_optionchanged(s, p, 0, 0);
+ mapif_party_optionchanged(s, p, AccountId(), 0);
return;
}
}
// パーティ解散要求
static
-void mapif_parse_BreakParty(Session *, int party_id)
+void mapif_parse_BreakParty(Session *, PartyId party_id)
{
struct party *p = party_db.search(party_id);
if (p == NULL)
@@ -615,14 +618,14 @@ void mapif_parse_BreakParty(Session *, int party_id)
// パーティメッセージ送信
static
-void mapif_parse_PartyMessage(Session *, int party_id, int account_id, XString mes)
+void mapif_parse_PartyMessage(Session *, PartyId party_id, AccountId account_id, XString mes)
{
mapif_party_message(party_id, account_id, mes);
}
// パーティチェック要求
static
-void mapif_parse_PartyCheck(Session *, int party_id, int account_id, CharName nick)
+void mapif_parse_PartyCheck(Session *, PartyId party_id, AccountId account_id, CharName nick)
{
party_check_conflict(party_id, account_id, nick);
}
@@ -638,7 +641,7 @@ int inter_party_parse_frommap(Session *ms)
{
case 0x3020:
{
- int account = RFIFOL(ms, 2);
+ AccountId account = wrap<AccountId>(RFIFOL(ms, 2));
PartyName name = stringish<PartyName>(RFIFO_STRING<24>(ms, 6));
CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 30));
MapName map = RFIFO_STRING<16>(ms, 54);
@@ -653,14 +656,14 @@ int inter_party_parse_frommap(Session *ms)
break;
case 0x3021:
{
- int party_id = RFIFOL(ms, 2);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2));
mapif_parse_PartyInfo(ms, party_id);
}
break;
case 0x3022:
{
- int party_id = RFIFOL(ms, 2);
- int account_id = RFIFOL(ms, 6);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6));
CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 10));
MapName map = RFIFO_STRING<16>(ms, 34);
uint16_t lv = RFIFOW(ms, 50);
@@ -674,8 +677,8 @@ int inter_party_parse_frommap(Session *ms)
break;
case 0x3023:
{
- int party_id = RFIFOL(ms, 2);
- int account_id = RFIFOL(ms, 6);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6));
uint16_t exp = RFIFOW(ms, 10);
uint16_t item = RFIFOW(ms, 12);
mapif_parse_PartyChangeOption(ms,
@@ -687,8 +690,8 @@ int inter_party_parse_frommap(Session *ms)
break;
case 0x3024:
{
- int party_id = RFIFOL(ms, 2);
- int account_id = RFIFOL(ms, 6);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6));
mapif_parse_PartyLeave(ms,
party_id,
account_id);
@@ -696,8 +699,8 @@ int inter_party_parse_frommap(Session *ms)
break;
case 0x3025:
{
- int party_id = RFIFOL(ms, 2);
- int account_id = RFIFOL(ms, 6);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6));
MapName map = RFIFO_STRING<16>(ms, 10);
uint8_t online = RFIFOB(ms, 26);
uint16_t lv = RFIFOW(ms, 27);
@@ -711,15 +714,15 @@ int inter_party_parse_frommap(Session *ms)
break;
case 0x3026:
{
- int party_id = RFIFOL(ms, 2);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2));
mapif_parse_BreakParty(ms, party_id);
}
break;
case 0x3027:
{
size_t len = RFIFOW(ms, 2) - 12;
- int party_id = RFIFOL(ms, 4);
- int account_id = RFIFOL(ms, 8);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 4));
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 8));
AString mes = RFIFO_STRING(ms, 12, len);
mapif_parse_PartyMessage(ms,
party_id,
@@ -729,8 +732,8 @@ int inter_party_parse_frommap(Session *ms)
break;
case 0x3028:
{
- int party_id = RFIFOL(ms, 2);
- int account_id = RFIFOL(ms, 6);
+ PartyId party_id = wrap<PartyId>(RFIFOL(ms, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(ms, 6));
CharName nick = stringish<CharName>(RFIFO_STRING<24>(ms, 10));
mapif_parse_PartyCheck(ms,
party_id,
@@ -746,7 +749,7 @@ int inter_party_parse_frommap(Session *ms)
}
// サーバーから脱退要求(キャラ削除用)
-void inter_party_leave(int party_id, int account_id)
+void inter_party_leave(PartyId party_id, AccountId account_id)
{
mapif_parse_PartyLeave(nullptr, party_id, account_id);
}
diff --git a/src/char/int_party.hpp b/src/char/int_party.hpp
index 1608c37..3c448b0 100644
--- a/src/char/int_party.hpp
+++ b/src/char/int_party.hpp
@@ -21,18 +21,18 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/fwd.hpp"
-struct Session;
+# include "../mmo/fwd.hpp"
void inter_party_init(void);
int inter_party_save(void);
int inter_party_parse_frommap(Session *ms);
-void inter_party_leave(int party_id, int account_id);
+void inter_party_leave(PartyId party_id, AccountId account_id);
extern AString party_txt;
diff --git a/src/char/int_storage.cpp b/src/char/int_storage.cpp
index 6021d54..bd87e72 100644
--- a/src/char/int_storage.cpp
+++ b/src/char/int_storage.cpp
@@ -46,7 +46,7 @@
AString storage_txt = "save/storage.txt"_s;
static
-Map<int, struct storage> storage_db;
+Map<AccountId, struct storage> storage_db;
// 倉庫データを文字列に変換
static
@@ -63,7 +63,7 @@ AString storage_tostr(struct storage *p)
{
str += STRPRINTF(
"%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d "_fmt,
- p->storage_[i].id,
+ 0 /*id*/,
p->storage_[i].nameid,
p->storage_[i].amount,
p->storage_[i].equip,
@@ -98,7 +98,7 @@ bool extract(XString str, struct storage *p)
vrec<' '>(&storage_items))))
return false;
- if (p->account_id <= 0)
+ if (!p->account_id)
return false;
if (storage_items.size() > MAX_STORAGE)
@@ -111,7 +111,7 @@ bool extract(XString str, struct storage *p)
}
// アカウントから倉庫データインデックスを得る(新規倉庫追加可能)
-struct storage *account2storage(int account_id)
+struct storage *account2storage(AccountId account_id)
{
struct storage *s = storage_db.search(account_id);
if (s == NULL)
@@ -178,7 +178,7 @@ int inter_storage_save(void)
}
// 倉庫データ削除
-void inter_storage_delete(int account_id)
+void inter_storage_delete(AccountId account_id)
{
storage_db.erase(account_id);
}
@@ -188,22 +188,22 @@ void inter_storage_delete(int account_id)
// 倉庫データの送信
static
-void mapif_load_storage(Session *ss, int account_id)
+void mapif_load_storage(Session *ss, AccountId account_id)
{
struct storage *st = account2storage(account_id);
WFIFOW(ss, 0) = 0x3810;
WFIFOW(ss, 2) = sizeof(struct storage) + 8;
- WFIFOL(ss, 4) = account_id;
+ WFIFOL(ss, 4) = unwrap<AccountId>(account_id);
WFIFO_STRUCT(ss, 8, *st);
WFIFOSET(ss, WFIFOW(ss, 2));
}
// 倉庫データ保存完了送信
static
-void mapif_save_storage_ack(Session *ss, int account_id)
+void mapif_save_storage_ack(Session *ss, AccountId account_id)
{
WFIFOW(ss, 0) = 0x3811;
- WFIFOL(ss, 2) = account_id;
+ WFIFOL(ss, 2) = unwrap<AccountId>(account_id);
WFIFOB(ss, 6) = 0;
WFIFOSET(ss, 7);
}
@@ -215,7 +215,8 @@ void mapif_save_storage_ack(Session *ss, int account_id)
static
void mapif_parse_LoadStorage(Session *ss)
{
- mapif_load_storage(ss, RFIFOL(ss, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(ss, 2));
+ mapif_load_storage(ss, account_id);
}
// 倉庫データ受信&保存
@@ -223,7 +224,7 @@ static
void mapif_parse_SaveStorage(Session *ss)
{
struct storage *st;
- int account_id = RFIFOL(ss, 4);
+ AccountId account_id = wrap<AccountId>(RFIFOL(ss, 4));
int len = RFIFOW(ss, 2);
if (sizeof(struct storage) != len - 8)
{
diff --git a/src/char/int_storage.hpp b/src/char/int_storage.hpp
index 7f6deb5..9f241e3 100644
--- a/src/char/int_storage.hpp
+++ b/src/char/int_storage.hpp
@@ -21,16 +21,16 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/fwd.hpp"
-struct Session;
+# include "../mmo/fwd.hpp"
void inter_storage_init(void);
int inter_storage_save(void);
-void inter_storage_delete(int account_id);
-struct storage *account2storage(int account_id);
+void inter_storage_delete(AccountId account_id);
+struct storage *account2storage(AccountId account_id);
int inter_storage_parse_frommap(Session *ms);
diff --git a/src/char/inter.cpp b/src/char/inter.cpp
index f7b3184..82704d1 100644
--- a/src/char/inter.cpp
+++ b/src/char/inter.cpp
@@ -240,7 +240,7 @@ void mapif_wis_message(Session *tms, CharName src, CharName dst, XString msg)
WBUFW(buf, 0) = 0x3801;
WBUFW(buf, 2) = 56 + str_size;
- WBUFL(buf, 4) = mcs->key.char_id; // formerly, whisper ID
+ WBUFL(buf, 4) = unwrap<CharId>(mcs->key.char_id); // formerly, whisper ID
WBUF_STRING(buf, 8, src.to__actual(), 24);
WBUF_STRING(buf, 32, dst.to__actual(), 24);
WBUF_STRING(buf, 56, msg, str_size);
@@ -368,7 +368,8 @@ void mapif_parse_WisRequest(Session *sms)
static
int mapif_parse_WisReply(Session *tms)
{
- int id = RFIFOL(tms, 2), flag = RFIFOB(tms, 6);
+ CharId id = wrap<CharId>(RFIFOL(tms, 2));
+ uint8_t flag = RFIFOB(tms, 6);
const CharPair *smcs = search_character_id(id);
CharName from = smcs->key.name;
diff --git a/src/compat/alg.hpp b/src/compat/alg.hpp
index f9ed8d2..2587f9e 100644
--- a/src/compat/alg.hpp
+++ b/src/compat/alg.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# if 0
# include <type_traits>
diff --git a/src/compat/fwd.hpp b/src/compat/fwd.hpp
new file mode 100644
index 0000000..46934b8
--- /dev/null
+++ b/src/compat/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_COMPAT_FWD_HPP
+#define TMWA_COMPAT_FWD_HPP
+// compat/fwd.hpp - list of type names for compat libs
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_COMPAT_FWD_HPP
diff --git a/src/generic/enum.hpp b/src/generic/enum.hpp
index 5c0fbef..bf0ac74 100644
--- a/src/generic/enum.hpp
+++ b/src/generic/enum.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cassert>
diff --git a/src/generic/fwd.hpp b/src/generic/fwd.hpp
new file mode 100644
index 0000000..df8485f
--- /dev/null
+++ b/src/generic/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_GENERIC_FWD_HPP
+#define TMWA_GENERIC_FWD_HPP
+// generic/fwd.hpp - list of type names for generic lib
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_GENERIC_FWD_HPP
diff --git a/src/ints/cmp.hpp b/src/ints/cmp.hpp
index b979c46..e0e819b 100644
--- a/src/ints/cmp.hpp
+++ b/src/ints/cmp.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <limits>
diff --git a/src/ints/fwd.hpp b/src/ints/fwd.hpp
new file mode 100644
index 0000000..7685da5
--- /dev/null
+++ b/src/ints/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_INTS_FWD_HPP
+#define TMWA_INTS_FWD_HPP
+// ints/fwd.hpp - list of type names for ints library
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_INTS_FWD_HPP
diff --git a/src/ints/udl.hpp b/src/ints/udl.hpp
index e3e5fcc..ecb5478 100644
--- a/src/ints/udl.hpp
+++ b/src/ints/udl.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cstdint>
@@ -121,14 +121,17 @@ namespace ints
ullong magnitude = V;
template<class T>
+ constexpr
operator T()
{
typedef typename std::make_unsigned<T>::type U;
-
- constexpr bool is_signed = T(-1) < T(0);
+ // boo, body of constexpr function can't use variables
+# define is_signed bool(T(-1) < T(0))
static_assert(is_signed >= (sign && magnitude), "signed");
- constexpr ullong max = ullong(U(-1) >> is_signed);
+# define max ullong(ullong(U(-1) >> is_signed))
static_assert(magnitude <= max || (sign && magnitude == max + 1), "magna");
+# undef is_signed
+# undef max
return sign ? T(ullong(-magnitude)) : T(magnitude);
}
};
@@ -162,6 +165,7 @@ namespace ints
struct nint64 { int64_t value; int64_t operator -() { return value; } };
template<char... C>
+ constexpr
SignedMagnitudeConstant<false, IntParser<C...>::value> operator "" _const()
{ return {}; }
diff --git a/src/ints/udl_test.cpp b/src/ints/udl_test.cpp
index 26ea7c3..3bcbaad 100644
--- a/src/ints/udl_test.cpp
+++ b/src/ints/udl_test.cpp
@@ -475,9 +475,10 @@ TEST(ints, smc)
TEST(ints, constant)
{
- EXPECT_EQ(0_const, (ints::SignedMagnitudeConstant<false, 0>{}));
- EXPECT_EQ(1_const, (ints::SignedMagnitudeConstant<false, 1>{}));
- EXPECT_EQ(1_const, (ints::SignedMagnitudeConstant<false, 1>{}));
+ // gtest is funny with conversions
+ assert(0_const == (ints::SignedMagnitudeConstant<false, 0>{}));
+ assert(1_const == (ints::SignedMagnitudeConstant<false, 1>{}));
+ assert(1_const == (ints::SignedMagnitudeConstant<false, 1>{}));
}
TEST(ints, udl8)
diff --git a/src/ints/wrap.cpp b/src/ints/wrap.cpp
new file mode 100644
index 0000000..a80bd9f
--- /dev/null
+++ b/src/ints/wrap.cpp
@@ -0,0 +1,21 @@
+#include "wrap.hpp"
+// wrap.cpp - basic integer wrapper classes
+//
+// 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 "../poison.hpp"
diff --git a/src/ints/wrap.hpp b/src/ints/wrap.hpp
new file mode 100644
index 0000000..b25a1ad
--- /dev/null
+++ b/src/ints/wrap.hpp
@@ -0,0 +1,109 @@
+#ifndef TMWA_INTS_WRAP_HPP
+#define TMWA_INTS_WRAP_HPP
+// wrap.hpp - basic integer wrapper classes
+//
+// 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 <cstdint>
+
+# include <type_traits>
+
+namespace ints
+{
+ namespace wrapped
+ {
+ template<class R>
+ struct Wrapped
+ {
+ typedef R wrapped_type;
+ R _value;
+ protected:
+ constexpr
+ Wrapped(uint32_t v=0)
+ : _value(v)
+ {}
+ public:
+ explicit
+ operator bool () const { return _value; }
+ bool operator !() const { return !_value; }
+ };
+
+ template<class W>
+ bool operator == (W l, W r)
+ {
+ return l._value == r._value;
+ }
+ template<class W>
+ bool operator != (W l, W r)
+ {
+ return l._value != r._value;
+ }
+ template<class W>
+ bool operator < (W l, W r)
+ {
+ return l._value < r._value;
+ }
+
+ template<class T>
+ constexpr
+ typename T::wrapped_type unwrap(typename std::enable_if<true, T>::type w)
+ {
+ return w._value;
+ }
+ template<class T>
+ constexpr
+ T wrap(typename T::wrapped_type v)
+ {
+ struct Sub : T
+ {
+ constexpr
+ Sub(typename T::wrapped_type v)
+ : T(v)
+ {}
+ };
+ return Sub(v);
+ }
+
+ template<class W>
+ constexpr
+ W next(W w)
+ {
+ return wrap<W>(unwrap<W>(w) + 1);
+ }
+ template<class W>
+ constexpr
+ W prev(W w)
+ {
+ return wrap<W>(unwrap<W>(w) - 1);
+ }
+
+ template<class R>
+ R convert_for_printf(Wrapped<R> w)
+ {
+ return w._value;
+ }
+ } // namespace wrapped
+} // namespace ints
+
+using ints::wrapped::Wrapped;
+using ints::wrapped::unwrap;
+using ints::wrapped::wrap;
+
+#endif // TMWA_INTS_WRAP_HPP
diff --git a/src/io/cxxstdio.hpp b/src/io/cxxstdio.hpp
index 8061d15..479707a 100644
--- a/src/io/cxxstdio.hpp
+++ b/src/io/cxxstdio.hpp
@@ -226,7 +226,8 @@ namespace cxxstdio
cxxstdio::PrintFormatter<format_impl>::print(out, ## __VA_ARGS__); \
})
-# define XSCANF(out, fmt, ...) \
+# if 0
+# define XSCANF(out, fmt, ...) \
({ \
struct format_impl \
{ \
@@ -235,14 +236,19 @@ namespace cxxstdio
}; \
cxxstdio::ScanFormatter<format_impl>::scan(out, ## __VA_ARGS__); \
})
+# endif
# define FPRINTF(file, fmt, ...) XPRINTF(/*no_cast<FILE *>*/(file), fmt, ## __VA_ARGS__)
-# define FSCANF(file, fmt, ...) XSCANF(no_cast<FILE *>(file), fmt, ## __VA_ARGS__)
+# if 0
+# define FSCANF(file, fmt, ...) XSCANF(no_cast<FILE *>(file), fmt, ## __VA_ARGS__)
+# endif
# define PRINTF(fmt, ...) FPRINTF(stdout, fmt, ## __VA_ARGS__)
# define SPRINTF(str, fmt, ...) XPRINTF(base_cast<AString&>(str), fmt, ## __VA_ARGS__)
# define SNPRINTF(str, n, fmt, ...) XPRINTF(base_cast<VString<n-1>&>(str), fmt, ## __VA_ARGS__)
-# define SCANF(fmt, ...) FSCANF(stdin, fmt, ## __VA_ARGS__)
-# define SSCANF(str, fmt, ...) XSCANF(maybe_cast<ZString>(str), fmt, ## __VA_ARGS__)
+# if 0
+# define SCANF(fmt, ...) FSCANF(stdin, fmt, ## __VA_ARGS__)
+# define SSCANF(str, fmt, ...) XSCANF(maybe_cast<ZString>(str), fmt, ## __VA_ARGS__)
+# endif
# define STRPRINTF(fmt, ...) \
({ \
diff --git a/src/io/write.hpp b/src/io/write.hpp
index 39d3dee..1d67494 100644
--- a/src/io/write.hpp
+++ b/src/io/write.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cstdarg>
diff --git a/src/login/fwd.hpp b/src/login/fwd.hpp
new file mode 100644
index 0000000..b2d2d24
--- /dev/null
+++ b/src/login/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_LOGIN_FWD_HPP
+#define TMWA_LOGIN_FWD_HPP
+// login/fwd.hpp - list of type names for login server
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_LOGIN_FWD_HPP
diff --git a/src/login/login.cpp b/src/login/login.cpp
index 6f3122e..e7de1ae 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -38,6 +38,8 @@
#include <set>
#include <type_traits>
+#include "../ints/udl.hpp"
+
#include "../strings/mstring.hpp"
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
@@ -67,8 +69,8 @@
constexpr int MAX_SERVERS = 30;
-constexpr int START_ACCOUNT_NUM = 2000000;
-constexpr int END_ACCOUNT_NUM = 100000000;
+constexpr AccountId START_ACCOUNT_NUM = wrap<AccountId>(2000000);
+constexpr AccountId END_ACCOUNT_NUM = wrap<AccountId>(100000000);
struct mmo_account
{
@@ -76,10 +78,10 @@ struct mmo_account
AccountPass passwd;
int passwdenc;
- long account_id;
- long login_id1;
- long login_id2;
- long char_id;
+ AccountId account_id;
+ int login_id1;
+ int login_id2;
+ AccountId char_id;
timestamp_milliseconds_buffer lastlogin;
SEX sex;
};
@@ -93,7 +95,7 @@ struct mmo_char_server
};
static
-int account_id_count = START_ACCOUNT_NUM;
+AccountId account_id_count = START_ACCOUNT_NUM;
static
int server_num;
static
@@ -163,7 +165,7 @@ std::vector<IP4Mask>
access_allow, access_deny, access_ladmin;
static
-int min_level_to_connect = 0; // minimum level of player/GM (0: player, 1-99: gm) to connect on the server
+GmLevel min_level_to_connect = GmLevel::from(0_u32); // minimum level of player/GM (0: player, 1-99: gm) to connect on the server
static
int add_to_unlimited_account = 0; // Give possibility or not to adjust (ladmin command: timeadd) the time of an unlimited account.
static
@@ -182,7 +184,8 @@ void SessionDeleter::operator()(SessionData *)
constexpr int AUTH_FIFO_SIZE = 256;
struct AuthFifo
{
- int account_id, login_id1, login_id2;
+ AccountId account_id;
+ int login_id1, login_id2;
IP4Address ip;
SEX sex;
int delflag;
@@ -194,7 +197,7 @@ int auth_fifo_pos = 0;
struct AuthData
{
- int account_id;
+ AccountId account_id;
SEX sex;
AccountName userid;
AccountCrypt pass;
@@ -223,7 +226,7 @@ static
int level_new_gm = 60;
static
-Map<int, GM_Account> gm_account_db;
+Map<AccountId, GM_Account> gm_account_db;
static
pid_t pid = 0; // For forked DB writes
@@ -289,11 +292,11 @@ void delete_admin(Session *s)
// and returns its level (or 0 if it isn't a GM account or if not found)
//----------------------------------------------------------------------
static
-uint8_t isGM(int account_id)
+GmLevel isGM(AccountId account_id)
{
GM_Account *p = gm_account_db.search(account_id);
if (p == NULL)
- return 0;
+ return GmLevel();
return p->level;
}
@@ -304,7 +307,6 @@ static
int read_gm_account(void)
{
int c = 0;
- int GM_level;
gm_account_db.clear();
@@ -332,18 +334,10 @@ int read_gm_account(void)
if (!extract(line, record<' '>(&p.account_id, &p.level)))
PRINTF("read_gm_account: file [%s], invalid 'id_acount level' format: '%s'\n"_fmt,
gm_account_filename, line);
- else if (p.level <= 0)
- PRINTF("read_gm_account: file [%s] %dth account (invalid level [0 or negative]: %d).\n"_fmt,
- gm_account_filename, c + 1, p.level);
else
{
- if (p.level > 99)
- {
- PRINTF("read_gm_account: file [%s] %dth account (invalid level, but corrected: %d->99).\n"_fmt,
- gm_account_filename, c + 1, p.level);
- p.level = 99;
- }
- if ((GM_level = isGM(p.account_id)) > 0)
+ GmLevel GM_level = isGM(p.account_id);
+ if (GM_level)
{ // if it's not a new account
if (GM_level == p.level)
PRINTF("read_gm_account: GM account %d defined twice (same level: %d).\n"_fmt,
@@ -355,7 +349,7 @@ int read_gm_account(void)
if (GM_level != p.level)
{ // if new account or new level
gm_account_db.insert(p.account_id, p);
- if (GM_level == 0)
+ if (!GM_level)
{ // if new account
c++;
if (c >= 4000)
@@ -533,10 +527,10 @@ bool extract(XString line, AuthData *ad)
ad->last_ip = IP4Address();
if (ip != "-"_s && !extract(ip, &ad->last_ip))
return false;
- if (ad->account_id > END_ACCOUNT_NUM)
+ if (!(ad->account_id < END_ACCOUNT_NUM))
return false;
// TODO replace *every* lookup with a map lookup
- static std::set<int> seen_ids;
+ static std::set<AccountId> seen_ids;
static std::set<AccountName> seen_names;
// we don't have to worry about deleted characters,
// this is only called during startup
@@ -611,10 +605,11 @@ int mmo_auth_init(void)
AuthData ad {};
if (!extract(line, &ad))
{
- int i = 0;
- if (SSCANF(line, "%d\t%%newid%%\n%n"_fmt, &ad.account_id, &i) == 1
- && i > 0 && ad.account_id > account_id_count)
- account_id_count = ad.account_id;
+ if (extract(line, record<'\t'>(&ad.account_id, "%newid%"_s)))
+ {
+ if (account_id_count < ad.account_id)
+ account_id_count = ad.account_id;
+ }
else
LOGIN_LOG("Account skipped\n%s"_fmt, line);
continue;
@@ -622,11 +617,11 @@ int mmo_auth_init(void)
auth_data.push_back(ad);
- if (isGM(ad.account_id) > 0)
+ if (isGM(ad.account_id))
gm_count++;
- if (ad.account_id >= account_id_count)
- account_id_count = ad.account_id + 1;
+ if (account_id_count < next(ad.account_id))
+ account_id_count = next(ad.account_id);
}
AString str = STRPRINTF("%s has %zu accounts (%d GMs)\n"_fmt,
@@ -673,7 +668,7 @@ void mmo_auth_sync(void)
"// ban time : 0: no ban, <other value>: banned until the date: date calculated by addition of 1/1/1970 + value (number of seconds since the 1/1/1970)\n"_fmt);
for (const AuthData& ad : auth_data)
{
- if (ad.account_id < 0)
+ if (!ad.account_id)
continue;
AString line = mmo_auth_tostr(&ad);
@@ -749,13 +744,15 @@ void send_GM_accounts(void)
len = 4;
WBUFW(buf, 0) = 0x2732;
for (const AuthData& ad : auth_data)
+ {
// send only existing accounts. We can not create a GM account when server is online.
- if (uint8_t GM_value = isGM(ad.account_id))
+ if (GmLevel GM_value = isGM(ad.account_id))
{
- WBUFL(buf, len) = ad.account_id;
- WBUFB(buf, len + 4) = GM_value;
+ WBUFL(buf, len) = unwrap<AccountId>(ad.account_id);
+ WBUFB(buf, len + 4) = static_cast<uint8_t>(GM_value.get_all_bits());
len += 5;
}
+ }
WBUFW(buf, 2) = len;
charif_sendallwos(nullptr, buf, len);
}
@@ -784,13 +781,14 @@ void check_GM_file(TimerData *, tick_t)
// Account creation (with e-mail check)
//-------------------------------------
static
-int mmo_auth_new(struct mmo_account *account, SEX sex, AccountEmail email)
+AccountId mmo_auth_new(struct mmo_account *account, SEX sex, AccountEmail email)
{
- while (isGM(account_id_count) > 0)
- account_id_count++;
+ while (isGM(account_id_count))
+ account_id_count = next(account_id_count);
struct AuthData ad {};
- ad.account_id = account_id_count++;
+ ad.account_id = account_id_count;
+ account_id_count = next(account_id_count);
ad.userid = account->userid;
ad.pass = MD5_saltcrypt(account->passwd, make_salt());
@@ -839,7 +837,7 @@ int mmo_auth(struct mmo_account *account, Session *s)
// Account creation with _M/_F
if (account->passwdenc == 0
&& (account->userid.endswith("_F"_s) || account->userid.endswith("_M"_s))
- && new_account == 1 && account_id_count <= END_ACCOUNT_NUM
+ && new_account == 1 && account_id_count < END_ACCOUNT_NUM
&& (account->userid.size() - 2) >= 4 && account->passwd.size() >= 4)
{
new_account_sex = account->userid.back();
@@ -932,7 +930,7 @@ int mmo_auth(struct mmo_account *account, Session *s)
}
else
{
- int new_id = mmo_auth_new(account, sex_from_char(new_account_sex), DEFAULT_EMAIL);
+ AccountId new_id = mmo_auth_new(account, sex_from_char(new_account_sex), DEFAULT_EMAIL);
LOGIN_LOG("Account creation and authentification accepted (account %s (id: %d), sex: %c, connection with _F/_M, ip: %s)\n"_fmt,
account->userid, new_id,
new_account_sex, ip);
@@ -1019,7 +1017,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 19)
return;
{
- int acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
int i;
for (i = 0; i < AUTH_FIFO_SIZE; i++)
{
@@ -1040,7 +1038,7 @@ void parse_fromchar(Session *s)
if (ad.account_id == acc)
{
WFIFOW(s, 0) = 0x2729; // Sending of the account_reg2
- WFIFOL(s, 4) = acc;
+ WFIFOL(s, 4) = unwrap<AccountId>(acc);
int j;
for (p = 8, j = 0;
j < ad.account_reg2_num;
@@ -1052,7 +1050,7 @@ void parse_fromchar(Session *s)
WFIFOW(s, 2) = p;
WFIFOSET(s, p);
WFIFOW(s, 0) = 0x2713;
- WFIFOL(s, 2) = acc;
+ WFIFOL(s, 2) = unwrap<AccountId>(acc);
WFIFOB(s, 6) = 0;
WFIFO_STRING(s, 7, ad.email, 40);
WFIFOL(s, 47) = static_cast<time_t>(ad.connect_until_time);
@@ -1069,7 +1067,7 @@ void parse_fromchar(Session *s)
LOGIN_LOG("Char-server '%s': authentification of the account %d REFUSED (ip: %s).\n"_fmt,
server[id].name, acc, ip);
WFIFOW(s, 0) = 0x2713;
- WFIFOL(s, 2) = acc;
+ WFIFOL(s, 2) = unwrap<AccountId>(acc);
WFIFOB(s, 6) = 1;
// It is unnecessary to send email
// It is unnecessary to send validity date of the account
@@ -1093,7 +1091,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 46)
return;
{
- int acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 6));
if (!e_mail_check(email))
LOGIN_LOG("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n"_fmt,
@@ -1124,7 +1122,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 6)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
for (const AuthData& ad : auth_data)
{
if (ad.account_id == account_id)
@@ -1132,7 +1130,7 @@ void parse_fromchar(Session *s)
LOGIN_LOG("Char-server '%s': e-mail of the account %d found (ip: %s).\n"_fmt,
server[id].name, account_id, ip);
WFIFOW(s, 0) = 0x2717;
- WFIFOL(s, 2) = account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(account_id);
WFIFO_STRING(s, 6, ad.email, 40);
WFIFOL(s, 46) = static_cast<time_t>(ad.connect_until_time);
WFIFOSET(s, 50);
@@ -1150,11 +1148,10 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 4 || RFIFOREST(s) < RFIFOW(s, 2))
return;
{
- int acc;
unsigned char buf[10];
- acc = RFIFOL(s, 4);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 4));
WBUFW(buf, 0) = 0x2721;
- WBUFL(buf, 2) = acc;
+ WBUFL(buf, 2) = unwrap<AccountId>(acc);
WBUFL(buf, 6) = 0;
size_t len = RFIFOW(s, 2) - 8;
AString pass = RFIFO_STRING(s, 8, len);
@@ -1162,10 +1159,10 @@ void parse_fromchar(Session *s)
if (pass == gm_pass)
{
// only non-GM can become GM
- if (isGM(acc) == 0)
+ if (!isGM(acc))
{
// if we autorise creation
- if (level_new_gm > 0)
+ if (level_new_gm)
{
// if we can open the file to add the new GM
io::AppendFile fp(gm_account_filename);
@@ -1231,7 +1228,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 86)
return;
{
- int acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
AccountEmail actual_email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 6).to_print());
AccountEmail new_email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 46));
if (!e_mail_check(actual_email))
@@ -1277,9 +1274,8 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 10)
return;
{
- int acc, statut;
- acc = RFIFOL(s, 2);
- statut = RFIFOL(s, 6);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
+ int statut = RFIFOL(s, 6);
for (AuthData& ad : auth_data)
{
if (ad.account_id == acc)
@@ -1293,7 +1289,7 @@ void parse_fromchar(Session *s)
{
unsigned char buf[16];
WBUFW(buf, 0) = 0x2731;
- WBUFL(buf, 2) = acc;
+ WBUFL(buf, 2) = unwrap<AccountId>(acc);
WBUFB(buf, 6) = 0; // 0: change of statut, 1: ban
WBUFL(buf, 7) = statut; // status or final date of a banishment
charif_sendallwos(nullptr, buf, 11);
@@ -1321,8 +1317,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 18)
return;
{
- int acc;
- acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
for (AuthData& ad : auth_data)
{
if (ad.account_id == acc)
@@ -1362,14 +1357,15 @@ void parse_fromchar(Session *s)
tmpstr,
ip);
WBUFW(buf, 0) = 0x2731;
- WBUFL(buf, 2) = ad.account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(ad.account_id);
WBUFB(buf, 6) = 1; // 0: change of statut, 1: ban
WBUFL(buf, 7) = static_cast<time_t>(timestamp); // status or final date of a banishment
charif_sendallwos(nullptr, buf, 11);
for (int j = 0; j < AUTH_FIFO_SIZE; j++)
- if (auth_fifo[j].account_id ==
- acc)
+ {
+ if (auth_fifo[j].account_id == acc)
auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
+ }
}
else
{
@@ -1404,8 +1400,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 6)
return;
{
- int acc;
- acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
for (AuthData& ad : auth_data)
{
if (ad.account_id == acc)
@@ -1422,11 +1417,13 @@ void parse_fromchar(Session *s)
sex_to_char(sex),
ip);
for (int j = 0; j < AUTH_FIFO_SIZE; j++)
+ {
if (auth_fifo[j].account_id == acc)
auth_fifo[j].login_id1++; // to avoid reconnection error when come back from map-server (char-server will ask again the authentification)
+ }
ad.sex = sex;
WBUFW(buf, 0) = 0x2723;
- WBUFL(buf, 2) = acc;
+ WBUFL(buf, 2) = unwrap<AccountId>(acc);
WBUFB(buf, 6) = static_cast<uint8_t>(sex);
charif_sendallwos(nullptr, buf, 7);
}
@@ -1444,8 +1441,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 4 || RFIFOREST(s) < RFIFOW(s, 2))
return;
{
- int acc, p;
- acc = RFIFOL(s, 4);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 4));
for (AuthData& ad : auth_data)
{
if (ad.account_id == acc)
@@ -1453,7 +1449,7 @@ void parse_fromchar(Session *s)
LOGIN_LOG("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n"_fmt,
server[id].name, acc, ip);
size_t len = RFIFOW(s, 2);
- int j;
+ int j, p;
for (p = 8, j = 0;
p < len && j < ACCOUNT_REG2_NUM;
p += 36, j++)
@@ -1481,7 +1477,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 6)
return;
{
- int acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
for (AuthData& ad : auth_data)
{
if (ad.account_id == acc)
@@ -1512,7 +1508,7 @@ void parse_fromchar(Session *s)
if (RFIFOREST(s) < 54)
return;
{
- int acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
AccountPass actual_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 6).to_print());
AccountPass new_pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 30).to_print());
@@ -1547,7 +1543,7 @@ void parse_fromchar(Session *s)
}
x2740_out:
WFIFOW(s, 0) = 0x2741;
- WFIFOL(s, 2) = acc;
+ WFIFOL(s, 2) = unwrap<AccountId>(acc);
WFIFOB(s, 6) = status; // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short
WFIFOSET(s, 7);
}
@@ -1649,28 +1645,25 @@ void parse_admin(Session *s)
if (RFIFOREST(s) < 10)
return;
{
- int st, ed, len;
- st = RFIFOL(s, 2);
- ed = RFIFOL(s, 6);
+ AccountId st = wrap<AccountId>(RFIFOL(s, 2));
+ AccountId ed = wrap<AccountId>(RFIFOL(s, 6));
RFIFOSKIP(s, 10);
WFIFOW(s, 0) = 0x7921;
- if (st < 0)
- st = 0;
- if (ed > END_ACCOUNT_NUM || ed < st || ed <= 0)
+ if (!(ed < END_ACCOUNT_NUM) || ed < st)
ed = END_ACCOUNT_NUM;
LOGIN_LOG("'ladmin': Sending an accounts list (ask: from %d to %d, ip: %s)\n"_fmt,
st, ed, ip);
// Sending accounts information
- len = 4;
+ int len = 4;
for (const AuthData& ad : auth_data)
{
if (len >= 30000)
break;
- int account_id = ad.account_id;
- if (account_id >= st && account_id <= ed)
+ AccountId account_id = ad.account_id;
+ if (!(account_id < st) && !(ed < account_id))
{
- WFIFOL(s, len) = account_id;
- WFIFOB(s, len + 4) = isGM(account_id);
+ WFIFOL(s, len) = unwrap<AccountId>(account_id);
+ WFIFOB(s, len + 4) = static_cast<uint8_t>(isGM(account_id).get_all_bits());
WFIFO_STRING(s, len + 5, ad.userid, 24);
WFIFOB(s, len + 29) = static_cast<uint8_t>(ad.sex);
WFIFOL(s, len + 30) = ad.logincount;
@@ -1722,7 +1715,7 @@ void parse_admin(Session *s)
LOGIN_LOG("'ladmin': Attempt to create an invalid account (account: %s, invalid sex, ip: %s)\n"_fmt,
ma.userid, ip);
}
- else if (account_id_count > END_ACCOUNT_NUM)
+ else if (!(account_id_count < END_ACCOUNT_NUM))
{
LOGIN_LOG("'ladmin': Attempt to create an account, but there is no more available id number (account: %s, sex: %c, ip: %s)\n"_fmt,
ma.userid, ma.sex, ip);
@@ -1740,11 +1733,11 @@ void parse_admin(Session *s)
}
{
AccountEmail email = stringish<AccountEmail>(RFIFO_STRING<40>(s, 51));
- int new_id = mmo_auth_new(&ma, ma.sex, email);
+ AccountId new_id = mmo_auth_new(&ma, ma.sex, email);
LOGIN_LOG("'ladmin': Account creation (account: %s (id: %d), sex: %c, email: %s, ip: %s)\n"_fmt,
ma.userid, new_id,
ma.sex, auth_data.back().email, ip);
- WFIFOL(s, 2) = new_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(new_id);
}
}
x7930_out:
@@ -1766,11 +1759,11 @@ void parse_admin(Session *s)
// Char-server is notified of deletion (for characters deletion).
uint8_t buf[6];
WBUFW(buf, 0) = 0x2730;
- WBUFL(buf, 2) = ad->account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(ad->account_id);
charif_sendallwos(nullptr, buf, 6);
// send answer
WFIFO_STRING(s, 6, ad->userid, 24);
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
// save deleted account in log file
LOGIN_LOG("'ladmin': Account deletion (account: %s, id: %d, ip: %s) - saved in next line:\n"_fmt,
ad->userid, ad->account_id,
@@ -1781,7 +1774,7 @@ void parse_admin(Session *s)
}
// delete account
ad->userid = AccountName();
- ad->account_id = -1;
+ ad->account_id = AccountId();
}
else
{
@@ -1807,7 +1800,7 @@ void parse_admin(Session *s)
WFIFO_STRING(s, 6, ad->userid, 24);
AccountPass plain = stringish<AccountPass>(RFIFO_STRING<24>(s, 26));
ad->pass = MD5_saltcrypt(plain, make_salt());
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
LOGIN_LOG("'ladmin': Modification of a password (account: %s, new password: %s, ip: %s)\n"_fmt,
ad->userid, ad->pass, ip);
}
@@ -1840,7 +1833,7 @@ void parse_admin(Session *s)
if (ad)
{
WFIFO_STRING(s, 6, ad->userid, 24);
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
if (ad->state == statut
&& ad->error_message == error_message)
LOGIN_LOG("'ladmin': Modification of a state, but the state of the account is already the good state (account: %s, received state: %d, ip: %s)\n"_fmt,
@@ -1858,7 +1851,7 @@ void parse_admin(Session *s)
{
unsigned char buf[16];
WBUFW(buf, 0) = 0x2731;
- WBUFL(buf, 2) = ad->account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(ad->account_id);
WBUFB(buf, 6) = 0; // 0: change of statut, 1: ban
WBUFL(buf, 7) = statut; // status or final date of a banishment
charif_sendallwos(nullptr, buf, 11);
@@ -1919,7 +1912,7 @@ void parse_admin(Session *s)
AccountPass pass = stringish<AccountPass>(RFIFO_STRING<24>(s, 26));
if (pass_ok(pass, ad->pass))
{
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
LOGIN_LOG("'ladmin': Check of password OK (account: %s, password: %s, ip: %s)\n"_fmt,
ad->userid, ad->pass,
ip);
@@ -1965,7 +1958,7 @@ void parse_admin(Session *s)
if (ad->sex != sex)
{
unsigned char buf[16];
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
for (int j = 0; j < AUTH_FIFO_SIZE; j++)
if (auth_fifo[j].account_id ==
ad->account_id)
@@ -1975,7 +1968,7 @@ void parse_admin(Session *s)
ad->userid, sex_to_char(sex), ip);
// send to all char-server the change
WBUFW(buf, 0) = 0x2723;
- WBUFL(buf, 2) = ad->account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(ad->account_id);
WBUFB(buf, 6) = static_cast<uint8_t>(ad->sex);
charif_sendallwos(nullptr, buf, 7);
}
@@ -2007,24 +2000,18 @@ void parse_admin(Session *s)
WFIFO_STRING(s, 6, account_name, 24);
bool reread = false;
{
- char new_gm_level;
- new_gm_level = RFIFOB(s, 26);
- if (new_gm_level < 0 || new_gm_level > 99)
- {
- LOGIN_LOG("'ladmin': Attempt to give an invalid GM level (account: %s, received GM level: %d, ip: %s)\n"_fmt,
- account_name, new_gm_level, ip);
- }
- else
+ GmLevel new_gm_level = GmLevel::from(static_cast<uint32_t>(RFIFOB(s, 26)));
{
const AuthData *ad = search_account(account_name);
if (ad)
{
- int acc = ad->account_id;
+ AccountId acc = ad->account_id;
WFIFO_STRING(s, 6, ad->userid, 24);
if (isGM(acc) != new_gm_level)
{
// modification of the file
- int GM_account, GM_level;
+ AccountId GM_account;
+ GmLevel GM_level;
int modify_flag;
io::WriteLock fp2(gm_account_filename);
if (fp2.is_open())
@@ -2047,7 +2034,7 @@ void parse_admin(Session *s)
fp2.put_line(line);
else if (GM_account != acc)
fp2.put_line(line);
- else if (new_gm_level == 0)
+ else if (!new_gm_level)
{
FPRINTF(fp2,
"// %s: 'ladmin' GM level removed on account %d '%s' (previous level: %d)\n//%d %d\n"_fmt,
@@ -2084,7 +2071,7 @@ void parse_admin(Session *s)
ad->userid, acc,
new_gm_level, ip);
}
- WFIFOL(s, 2) = acc;
+ WFIFOL(s, 2) = unwrap<AccountId>(acc);
LOGIN_LOG("'ladmin': Modification of a GM level (account: %s (%d), new GM level: %d, ip: %s)\n"_fmt,
ad->userid, acc,
new_gm_level, ip);
@@ -2145,7 +2132,7 @@ void parse_admin(Session *s)
{
WFIFO_STRING(s, 6, ad->userid, 24);
ad->email = email;
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
LOGIN_LOG("'ladmin': Modification of an email (account: %s, new e-mail: %s, ip: %s)\n"_fmt,
ad->userid, email, ip);
}
@@ -2185,7 +2172,7 @@ void parse_admin(Session *s)
ad->memo = RFIFO_STRING(s, 28, len);
}
ad->memo = ad->memo.to_print();
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
LOGIN_LOG("'ladmin': Modification of a memo field (account: %s, new memo: %s, ip: %s)\n"_fmt,
ad->userid, ad->memo, ip);
}
@@ -2211,7 +2198,7 @@ void parse_admin(Session *s)
if (ad)
{
WFIFO_STRING(s, 6, ad->userid, 24);
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
LOGIN_LOG("'ladmin': Request (by the name) of an account id (account: %s, id: %d, ip: %s)\n"_fmt,
ad->userid, ad->account_id,
ip);
@@ -2231,9 +2218,9 @@ void parse_admin(Session *s)
if (RFIFOREST(s) < 6)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
WFIFOW(s, 0) = 0x7947;
- WFIFOL(s, 2) = account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(account_id);
WFIFO_ZERO(s, 6, 24);
for (const AuthData& ad : auth_data)
{
@@ -2275,7 +2262,7 @@ void parse_admin(Session *s)
tmpstr,
ip);
ad->connect_until_time = timestamp;
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
}
else
{
@@ -2309,7 +2296,7 @@ void parse_admin(Session *s)
if (ad)
{
WFIFO_STRING(s, 6, ad->userid, 24);
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
LOGIN_LOG("'ladmin': Change of the final date of a banishment (account: %s, new final date of banishment: %lld (%s), ip: %s)\n"_fmt,
ad->userid, timestamp,
tmpstr,
@@ -2320,7 +2307,7 @@ void parse_admin(Session *s)
{
unsigned char buf[16];
WBUFW(buf, 0) = 0x2731;
- WBUFL(buf, 2) = ad->account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(ad->account_id);
WBUFB(buf, 6) = 1; // 0: change of statut, 1: ban
WBUFL(buf, 7) = static_cast<time_t>(timestamp); // status or final date of a banishment
charif_sendallwos(nullptr, buf, 11);
@@ -2356,7 +2343,7 @@ void parse_admin(Session *s)
AuthData *ad = search_account(account_name);
if (ad)
{
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
WFIFO_STRING(s, 6, ad->userid, 24);
TimeT timestamp;
TimeT now = TimeT::now();
@@ -2396,7 +2383,7 @@ void parse_admin(Session *s)
{
unsigned char buf[16];
WBUFW(buf, 0) = 0x2731;
- WBUFL(buf, 2) = ad->account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(ad->account_id);
WBUFB(buf, 6) = 1; // 0: change of statut, 1: ban
WBUFL(buf, 7) = static_cast<time_t>(timestamp); // status or final date of a banishment
charif_sendallwos(nullptr, buf, 11);
@@ -2487,7 +2474,7 @@ void parse_admin(Session *s)
AuthData *ad = search_account(account_name);
if (ad)
{
- WFIFOL(s, 2) = ad->account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
WFIFO_STRING(s, 6, ad->userid, 24);
if (add_to_unlimited_account == 0 && !ad->connect_until_time)
{
@@ -2577,8 +2564,9 @@ void parse_admin(Session *s)
const AuthData *ad = search_account(account_name);
if (ad)
{
- WFIFOL(s, 2) = ad->account_id;
- WFIFOB(s, 6) = isGM(ad->account_id);
+ WFIFOL(s, 2) = unwrap<AccountId>(ad->account_id);
+ // TODO fix size (there's a lot of other stuff wrong with this packet too)
+ WFIFOB(s, 6) = static_cast<uint8_t>(isGM(ad->account_id).get_all_bits());
WFIFO_STRING(s, 7, ad->userid, 24);
WFIFOB(s, 31) = static_cast<uint8_t>(ad->sex);
WFIFOL(s, 32) = ad->logincount;
@@ -2613,9 +2601,9 @@ void parse_admin(Session *s)
if (RFIFOREST(s) < 6)
return;
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
WFIFOW(s, 0) = 0x7953;
- WFIFOL(s, 2) = account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(account_id);
WFIFO_ZERO(s, 7, 24);
for (const AuthData& ad : auth_data)
{
@@ -2623,7 +2611,7 @@ void parse_admin(Session *s)
{
LOGIN_LOG("'ladmin': Sending information of an account (request by the id; account: %s, id: %d, ip: %s)\n"_fmt,
ad.userid, RFIFOL(s, 2), ip);
- WFIFOB(s, 6) = isGM(ad.account_id);
+ WFIFOB(s, 6) = static_cast<uint8_t>(isGM(ad.account_id).get_all_bits());
WFIFO_STRING(s, 7, ad.userid, 24);
WFIFOB(s, 31) = static_cast<uint8_t>(ad.sex);
WFIFOL(s, 32) = ad.logincount;
@@ -2822,8 +2810,8 @@ void parse_login(Session *s)
}
if (result == -1)
{
- int gm_level = isGM(account.account_id);
- if (min_level_to_connect > gm_level)
+ GmLevel gm_level = isGM(account.account_id);
+ if (!(gm_level.satisfies(min_level_to_connect)))
{
LOGIN_LOG("Connection refused: the minimum GM level for connection is %d (account: %s, GM level: %d, ip: %s).\n"_fmt,
min_level_to_connect, account.userid,
@@ -2891,7 +2879,7 @@ void parse_login(Session *s)
WFIFOW(s, 0) = 0x69;
WFIFOW(s, 2) = 47 + 32 * server_num;
WFIFOL(s, 4) = account.login_id1;
- WFIFOL(s, 8) = account.account_id;
+ WFIFOL(s, 8) = unwrap<AccountId>(account.account_id);
WFIFOL(s, 12) = account.login_id2;
WFIFOL(s, 16) = 0; // in old version, that was for ip (not more used)
WFIFO_STRING(s, 20, account.lastlogin, 24); // in old version, that was for name (not more used)
@@ -2955,6 +2943,7 @@ void parse_login(Session *s)
if (RFIFOREST(s) < 86)
return;
{
+ // TODO: this is exceptionally silly. Fix it.
int len;
account.userid = stringish<AccountName>(RFIFO_STRING<24>(s, 2).to_print());
account.passwd = stringish<AccountPass>(RFIFO_STRING<24>(s, 26).to_print());
@@ -2968,7 +2957,7 @@ void parse_login(Session *s)
if (!server_session[0]
&& server_name == main_server)
{
- account.account_id = 0;
+ account.account_id = wrap<AccountId>(0_u32);
goto x2710_okay;
}
else
@@ -2978,7 +2967,7 @@ void parse_login(Session *s)
{
if (!server_session[i])
{
- account.account_id = i;
+ account.account_id = wrap<AccountId>(i);
goto x2710_okay;
}
}
@@ -2993,16 +2982,16 @@ void parse_login(Session *s)
account.passwd, ip);
PRINTF("Connection of the char-server '%s' accepted.\n"_fmt,
server_name);
- server[account.account_id] = mmo_char_server{};
- server[account.account_id].ip = RFIFOIP(s, 54);
- server[account.account_id].port = RFIFOW(s, 58);
- server[account.account_id].name = server_name;
- server[account.account_id].users = 0;
+ server[unwrap<AccountId>(account.account_id)] = mmo_char_server{};
+ server[unwrap<AccountId>(account.account_id)].ip = RFIFOIP(s, 54);
+ server[unwrap<AccountId>(account.account_id)].port = RFIFOW(s, 58);
+ server[unwrap<AccountId>(account.account_id)].name = server_name;
+ server[unwrap<AccountId>(account.account_id)].users = 0;
//maintenance = RFIFOW(fd, 82);
//is_new = RFIFOW(fd, 84);
- server_session[account.account_id] = s;
+ server_session[unwrap<AccountId>(account.account_id)] = s;
if (anti_freeze_enable)
- server_freezeflag[account.account_id] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
+ server_freezeflag[unwrap<AccountId>(account.account_id)] = 5; // Char-server anti-freeze system. Counter. 5 ok, 4...0 freezed
WFIFOW(s, 0) = 0x2711;
WFIFOB(s, 2) = 0;
WFIFOSET(s, 3);
@@ -3013,10 +3002,10 @@ void parse_login(Session *s)
WFIFOW(s, 0) = 0x2732;
for (const AuthData& ad : auth_data)
// send only existing accounts. We can not create a GM account when server is online.
- if (uint8_t GM_value = isGM(ad.account_id))
+ if (GmLevel GM_value = isGM(ad.account_id))
{
- WFIFOL(s, len) = ad.account_id;
- WFIFOB(s, len + 4) = GM_value;
+ WFIFOL(s, len) = unwrap<AccountId>(ad.account_id);
+ WFIFOB(s, len + 4) = static_cast<uint8_t>(GM_value.get_all_bits());
len += 5;
}
WFIFOW(s, 2) = len;
@@ -3333,7 +3322,7 @@ bool login_config(XString w1, ZString w2)
}
else if (w1 == "min_level_to_connect"_s)
{
- min_level_to_connect = atoi(w2.c_str());
+ min_level_to_connect = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str())));
}
else if (w1 == "add_to_unlimited_account"_s)
{
@@ -3563,23 +3552,6 @@ bool display_conf_warnings(void)
rv = false;
}
- if (min_level_to_connect < 0)
- { // 0: all players, 1-99 at least gm level x
- PRINTF("***WARNING: Invalid value for min_level_to_connect (%d) parameter\n"_fmt,
- min_level_to_connect);
- PRINTF(" -> set to 0 (any player).\n"_fmt);
- min_level_to_connect = 0;
- rv = false;
- }
- else if (min_level_to_connect > 99)
- { // 0: all players, 1-99 at least gm level x
- PRINTF("***WARNING: Invalid value for min_level_to_connect (%d) parameter\n"_fmt,
- min_level_to_connect);
- PRINTF(" -> set to 99 (only GM level 99).\n"_fmt);
- min_level_to_connect = 99;
- rv = false;
- }
-
if (add_to_unlimited_account != 0 && add_to_unlimited_account != 1)
{ // 0: no, 1: yes
PRINTF("***WARNING: Invalid value for add_to_unlimited_account parameter\n"_fmt);
@@ -3726,10 +3698,8 @@ void save_config_in_log(void)
else
LOGIN_LOG("- to NOT display char-server parse packets on console.\n"_fmt);
- if (min_level_to_connect == 0) // 0: all players, 1-99 at least gm level x
+ if (!min_level_to_connect) // 0: all players, 1-99 at least gm level x
LOGIN_LOG("- with no minimum level for connection.\n"_fmt);
- else if (min_level_to_connect == 99)
- LOGIN_LOG("- to accept only GM with level 99.\n"_fmt);
else
LOGIN_LOG("- to accept only GM with level %d or more.\n"_fmt,
min_level_to_connect);
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index c76c34c..3cfeb42 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -81,12 +81,12 @@ enum class ATCE
struct AtCommandInfo
{
ZString args;
- int level;
+ GmLevel level;
ATCE (*proc)(Session *s, dumb_ptr<map_session_data> sd, ZString message);
ZString help;
- AtCommandInfo(ZString a, int l, ATCE (*p)(Session *s, dumb_ptr<map_session_data>, ZString), ZString h)
- : args(a), level(l), proc(p), help(h)
+ AtCommandInfo(ZString a, uint32_t l, ATCE (*p)(Session *s, dumb_ptr<map_session_data>, ZString), ZString h)
+ : args(a), level(GmLevel::from(l)), proc(p), help(h)
{}
};
@@ -242,7 +242,7 @@ io::AppendFile *get_gm_log()
}
bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd,
- ZString message, int gmlvl)
+ ZString message, GmLevel gmlvl)
{
nullpo_retr(false, sd);
@@ -272,7 +272,7 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd,
return true;
// don't show in chat
}
- if (info->level > gmlvl)
+ if (!(gmlvl.satisfies(info->level)))
{
AString output = STRPRINTF("GM command is level %d, but you are level %d: %s"_fmt,
info->level, gmlvl,
@@ -368,11 +368,7 @@ bool atcommand_config_read(ZString cfgName)
AtCommandInfo *p = get_atcommandinfo_byname(w1);
if (p != NULL)
{
- p->level = atoi(w2.c_str());
- if (p->level > 100)
- p->level = 100;
- else if (p->level < 0)
- p->level = 0;
+ p->level = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str())));
}
else if (w1 == "import"_s)
rv &= atcommand_config_read(w2);
@@ -391,12 +387,14 @@ bool atcommand_config_read(ZString cfgName)
static
void atc_do_help(Session *s, ZString cmd, const AtCommandInfo& info)
{
+ // TODO convert to hex or something
+ uint32_t level = info.level.get_all_bits();
auto msg = STRPRINTF("\u2007\u2007%d: @%s %s"_fmt, info.level, cmd, info.args);
// manually padding because *space*
size_t ll = 1;
- if (info.level >= 10)
+ if (level >= 10)
++ll;
- if (info.level >= 100)
+ if (level >= 100)
++ll;
clif_displaymessage(s, msg.xslice_t((ll - 1) * 3));
}
@@ -436,20 +434,34 @@ ATCE atcommand_help(Session *s, dumb_ptr<map_session_data>,
return ATCE::OKAY;
}
- int low = 0, high;
+ // previous logic is silly
+ //
+ // @help N: list all commands available at level N
+ // @help M-N: list all commands available at level N that were not at level M
+ GmLevel low, high;
+ bool pass;
if (extract(message, &high))
- ++high;
- else if (!extract(message, record<'-'>(&low, &high)))
+ {
+ pass = true;
+ }
+ else if (extract(message, record<'-'>(&low, &high)))
+ {
+ pass = false;
+ }
+ else
return ATCE::USAGE;
- if (low < 0 || high > 100 || low >= high)
+ if (low.obsoletes(high))
return ATCE::RANGE;
- clif_displaymessage(s, STRPRINTF("Synopses of GM commands in level [%d, %d):"_fmt, low, high));
+ if (pass)
+ clif_displaymessage(s, STRPRINTF("Synopses of GM commands available at level %u:"_fmt, high));
+ else
+ clif_displaymessage(s, STRPRINTF("Synopses of GM commands available at level %u, but not at level %u:"_fmt, high, low));
for (const auto& pair : atcommand_info)
{
auto cmd = ZString(strings::really_construct_from_a_pointer, &*pair.first.begin(), nullptr);
const AtCommandInfo& info = pair.second;
- if (low <= info.level && info.level < high)
+ if ((!low.satisfies(info.level) || pass) && high.satisfies(info.level))
atc_do_help(s, cmd, info);
}
return ATCE::OKAY;
@@ -510,21 +522,21 @@ ATCE atcommand_charwarp(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can rura+ only lower or same GM level
if (x > 0 && x < 800 && y > 0 && y < 800)
{
map_local *m = map_mapname2mapid(map_name);
if (m != nullptr && m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))
{
clif_displaymessage(s,
"You are not authorised to warp someone to this map."_s);
return ATCE::PERM;
}
if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp this player from its actual map."_s);
@@ -586,14 +598,14 @@ ATCE atcommand_warp(Session *s, dumb_ptr<map_session_data> sd,
{
map_local *m = map_mapname2mapid(map_name);
if (m != nullptr && m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you to this map."_s);
return ATCE::PERM;
}
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you from your actual map."_s);
@@ -627,7 +639,7 @@ ATCE atcommand_where(Session *s, dumb_ptr<map_session_data> sd,
if (pl_sd != NULL &&
!((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
- && (pc_isGM(pl_sd) > pc_isGM(sd))))
+ && !(pc_isGM(sd).detects(pc_isGM(pl_sd)))))
{
// you can look only lower or same level
AString output = STRPRINTF("%s: %s (%d,%d)"_fmt,
@@ -661,14 +673,14 @@ ATCE atcommand_goto(Session *s, dumb_ptr<map_session_data> sd,
if (pl_sd != NULL)
{
if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you to the map of this player."_s);
return ATCE::PERM;
}
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you from your actual map."_s);
@@ -702,14 +714,14 @@ ATCE atcommand_jump(Session *s, dumb_ptr<map_session_data> sd,
if (x > 0 && x < 800 && y > 0 && y < 800)
{
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you to your actual map."_s);
return ATCE::PERM;
}
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you from your actual map."_s);
@@ -733,12 +745,11 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
int count;
- int pl_GM_level, GM_level;
VString<23> match_text = message;
match_text = match_text.to_lower();
count = 0;
- GM_level = pc_isGM(sd);
+ GmLevel gm_level = pc_isGM(sd);
for (io::FD i : iter_fds())
{
Session *s2 = get_session(i);
@@ -747,11 +758,11 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd && pl_sd->state.auth)
{
- pl_GM_level = pc_isGM(pl_sd);
+ GmLevel pl_gm_level = pc_isGM(pl_sd);
if (!
((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
- && (pl_GM_level > GM_level)))
+ && !(gm_level.detects(pl_gm_level))))
{
// you can look only lower or same level
VString<23> player_name = pl_sd->status_key.name.to__lower();
@@ -759,10 +770,10 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd,
{
// search with no case sensitive
AString output;
- if (pl_GM_level > 0)
+ if (pl_gm_level)
output = STRPRINTF(
- "Name: %s (GM:%d) | Location: %s %d %d"_fmt,
- pl_sd->status_key.name, pl_GM_level,
+ "Name: %s (GM:%u) | Location: %s %d %d"_fmt,
+ pl_sd->status_key.name, pl_gm_level,
pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y);
else
output = STRPRINTF(
@@ -794,14 +805,13 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
int count;
- int pl_GM_level, GM_level;
struct party *p;
VString<23> match_text = message;
match_text = match_text.to_lower();
count = 0;
- GM_level = pc_isGM(sd);
+ GmLevel gm_level = pc_isGM(sd);
for (io::FD i : iter_fds())
{
Session *s2 = get_session(i);
@@ -810,11 +820,11 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd && pl_sd->state.auth)
{
- pl_GM_level = pc_isGM(pl_sd);
+ GmLevel pl_gm_level = pc_isGM(pl_sd);
if (!
((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
- && (pl_GM_level > GM_level)))
+ && (!(gm_level.detects(pl_gm_level)))))
{
// you can look only lower or same level
VString<23> player_name = pl_sd->status_key.name.to__lower();
@@ -824,10 +834,10 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd,
p = party_search(pl_sd->status.party_id);
PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s);
AString output;
- if (pl_GM_level > 0)
+ if (pl_gm_level)
output = STRPRINTF(
"Name: %s (GM:%d) | Party: '%s'"_fmt,
- pl_sd->status_key.name, pl_GM_level, temp0);
+ pl_sd->status_key.name, pl_gm_level, temp0);
clif_displaymessage(s, output);
count++;
}
@@ -853,7 +863,6 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
int count;
- int pl_GM_level, GM_level;
map_local *map_id;
{
@@ -865,7 +874,7 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd,
}
count = 0;
- GM_level = pc_isGM(sd);
+ GmLevel gm_level = pc_isGM(sd);
for (io::FD i : iter_fds())
{
Session *s2 = get_session(i);
@@ -874,20 +883,20 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd && pl_sd->state.auth)
{
- pl_GM_level = pc_isGM(pl_sd);
+ GmLevel pl_gm_level = pc_isGM(pl_sd);
if (!
((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
- && (pl_GM_level > GM_level)))
+ && (!(gm_level.detects(pl_gm_level)))))
{
// you can look only lower or same level
if (pl_sd->bl_m == map_id)
{
AString output;
- if (pl_GM_level > 0)
+ if (pl_gm_level)
output = STRPRINTF(
"Name: %s (GM:%d) | Location: %s %d %d"_fmt,
- pl_sd->status_key.name, pl_GM_level,
+ pl_sd->status_key.name, pl_gm_level,
pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y);
else
output = STRPRINTF(
@@ -913,7 +922,6 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
int count;
- int pl_GM_level, GM_level;
struct party *p;
map_local *map_id;
@@ -926,7 +934,7 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd,
}
count = 0;
- GM_level = pc_isGM(sd);
+ GmLevel gm_level = pc_isGM(sd);
for (io::FD i : iter_fds())
{
Session *s2 = get_session(i);
@@ -935,11 +943,11 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd && pl_sd->state.auth)
{
- pl_GM_level = pc_isGM(pl_sd);
+ GmLevel pl_gm_level = pc_isGM(pl_sd);
if (!
((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
- && (pl_GM_level > GM_level)))
+ && (!(gm_level.detects(pl_gm_level)))))
{
// you can look only lower or same level
if (pl_sd->bl_m == map_id)
@@ -947,9 +955,9 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd,
p = party_search(pl_sd->status.party_id);
PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s);
AString output;
- if (pl_GM_level > 0)
+ if (pl_gm_level)
output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'"_fmt,
- pl_sd->status_key.name, pl_GM_level, temp0);
+ pl_sd->status_key.name, pl_gm_level, temp0);
else
output = STRPRINTF("Name: %s | Party: '%s'"_fmt,
pl_sd->status_key.name, temp0);
@@ -979,14 +987,13 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
int count;
- int pl_GM_level, GM_level;
struct party *p;
VString<23> match_text = message;
match_text = match_text.to_lower();
count = 0;
- GM_level = pc_isGM(sd);
+ GmLevel gm_level = pc_isGM(sd);
for (io::FD i : iter_fds())
{
Session *s2 = get_session(i);
@@ -995,13 +1002,13 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd && pl_sd->state.auth)
{
- pl_GM_level = pc_isGM(pl_sd);
- if (pl_GM_level > 0)
+ GmLevel pl_gm_level = pc_isGM(pl_sd);
+ if (pl_gm_level)
{
if (!
((battle_config.hide_GM_session
|| bool(pl_sd->status.option & Option::HIDE))
- && (pl_GM_level > GM_level)))
+ && (!(gm_level.detects(pl_gm_level)))))
{
// you can look only lower or same level
VString<23> player_name = pl_sd->status_key.name.to__lower();
@@ -1011,7 +1018,7 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd,
AString output;
output = STRPRINTF(
"Name: %s (GM:%d) | Location: %s %d %d"_fmt,
- pl_sd->status_key.name, pl_GM_level,
+ pl_sd->status_key.name, pl_gm_level,
pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y);
clif_displaymessage(s, output);
output = STRPRINTF(
@@ -1064,14 +1071,14 @@ ATCE atcommand_load(Session *s, dumb_ptr<map_session_data> sd,
{
map_local *m = map_mapname2mapid(sd->status.save_point.map_);
if (m != nullptr && m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you to your save map."_s);
return ATCE::PERM;
}
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you from your actual map."_s);
@@ -1217,7 +1224,7 @@ ATCE atcommand_kill(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can kill only lower or same level
pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
@@ -1322,7 +1329,8 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
XString item_name;
- int number = 0, item_id;
+ int number = 0;
+ ItemNameId item_id;
struct item_data *item_data = NULL;
int get_count, i;
@@ -1336,15 +1344,12 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd,
if (number <= 0)
number = 1;
- item_id = 0;
if ((item_data = itemdb_searchname(item_name)) != NULL)
item_id = item_data->nameid;
else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != NULL)
item_id = item_data->nameid;
- else
- item_id = 0;
- if (item_id >= 500)
+ if (item_id)
{
get_count = number;
if (item_data->type == ItemType::WEAPON
@@ -1722,22 +1727,21 @@ ATCE atcommand_spawn(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
MobName monster;
- int mob_id;
+ Species mob_id;
int number = 0;
int x = 0, y = 0;
int count;
- int i, j, k;
int mx, my, range;
if (!extract(message, record<' ', 1>(&monster, &number, &x, &y)))
return ATCE::USAGE;
// If monster identifier/name argument is a name
- if ((mob_id = mobdb_searchname(monster)) == 0)
+ if ((mob_id = mobdb_searchname(monster)) == Species())
// check name first (to avoid possible name begining by a number)
- mob_id = mobdb_checkid(atoi(monster.c_str()));
+ mob_id = mobdb_checkid(wrap<Species>(atoi(monster.c_str())));
- if (mob_id == 0)
+ if (mob_id == Species())
return ATCE::EXIST;
if (number <= 0)
@@ -1756,11 +1760,11 @@ ATCE atcommand_spawn(Session *s, dumb_ptr<map_session_data> sd,
range = sqrt(number) / 2;
range = range * 2 + 5;
// calculation of an odd number (+ 4 area around)
- for (i = 0; i < number; i++)
+ for (int i = 0; i < number; i++)
{
- j = 0;
- k = 0;
- while (j++ < 8 && k == 0)
+ int j = 0;
+ BlockId k;
+ while (j++ < 8 && !k)
{
// try 8 times to spawn the monster (needed for close area)
if (x <= 0)
@@ -1773,7 +1777,7 @@ ATCE atcommand_spawn(Session *s, dumb_ptr<map_session_data> sd,
my = y;
k = mob_once_spawn(sd, MOB_THIS_MAP, mx, my, MobName(), mob_id, 1, NpcEvent());
}
- count += (k != 0) ? 1 : 0;
+ count += k ? 1 : 0;
}
if (count != 0)
@@ -2066,18 +2070,18 @@ ATCE atcommand_recall(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can recall only lower or same level
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp somenone to your actual map."_s);
return ATCE::PERM;
}
if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp this player from its actual map."_s);
@@ -2199,8 +2203,8 @@ ATCE atcommand_character_stats_all(Session *s, dumb_ptr<map_session_data>,
if (pl_sd && pl_sd->state.auth)
{
AString gmlevel;
- if (pc_isGM(pl_sd) > 0)
- gmlevel = STRPRINTF("| GM Lvl: %d"_fmt, pc_isGM(pl_sd));
+ if (GmLevel pl_gm_level = pc_isGM(pl_sd))
+ gmlevel = STRPRINTF("| GM Lvl: %d"_fmt, pl_gm_level);
else
gmlevel = " "_s;
@@ -2254,7 +2258,7 @@ ATCE atcommand_character_option(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can change option only to lower or same level
pl_sd->opt1 = opt1;
@@ -2389,7 +2393,7 @@ ATCE atcommand_character_save(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can change save point only to lower or same gm level
map_local *m = map_mapname2mapid(map_name);
@@ -2401,7 +2405,7 @@ ATCE atcommand_character_save(Session *s, dumb_ptr<map_session_data> sd,
else
{
if (m != nullptr && m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to set this map as a save map."_s);
@@ -2438,7 +2442,7 @@ ATCE atcommand_doom(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd
&& pl_sd->state.auth && s2 != s
- && pc_isGM(sd) >= pc_isGM(pl_sd))
+ && pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can doom only lower or same gm level
pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
@@ -2462,7 +2466,7 @@ ATCE atcommand_doommap(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd
&& pl_sd->state.auth && s2 != s && sd->bl_m == pl_sd->bl_m
- && pc_isGM(sd) >= pc_isGM(pl_sd))
+ && pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can doom only lower or same gm level
pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
@@ -2539,7 +2543,7 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can change base level only lower or same gm level
if (level > 0)
@@ -2626,7 +2630,7 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can change job level only lower or same gm level
max_level -= 40;
@@ -2700,7 +2704,7 @@ ATCE atcommand_kick(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
// you can kick only lower or same gm level
clif_GM_kick(sd, pl_sd, 1);
else
@@ -2729,7 +2733,7 @@ ATCE atcommand_kickall(Session *s, dumb_ptr<map_session_data> sd,
continue;
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd
- && pl_sd->state.auth && pc_isGM(sd) >= pc_isGM(pl_sd))
+ && pl_sd->state.auth && pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can kick only lower or same gm level
if (sd->status_key.account_id != pl_sd->status_key.account_id)
@@ -2964,7 +2968,7 @@ ATCE atcommand_idsearch(Session *s, dumb_ptr<map_session_data>,
ZString message)
{
ItemName item_name;
- int i, match;
+ int match;
struct item_data *item;
if (!extract(message, &item_name) || !item_name)
@@ -2973,7 +2977,7 @@ ATCE atcommand_idsearch(Session *s, dumb_ptr<map_session_data>,
AString output = STRPRINTF("The reference result of '%s' (name: id):"_fmt, item_name);
clif_displaymessage(s, output);
match = 0;
- for (i = 0; i < 20000; i++)
+ for (ItemNameId i = wrap<ItemNameId>(0); i < wrap<ItemNameId>(-1); i = next(i))
{
if ((item = itemdb_exists(i)) != NULL
&& item->jname.contains_seq(item_name))
@@ -3001,7 +3005,7 @@ ATCE atcommand_charskreset(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can reset skill points only lower or same gm level
pc_resetskill(pl_sd);
@@ -3036,7 +3040,7 @@ ATCE atcommand_charstreset(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can reset stats points only lower or same gm level
pc_resetstate(pl_sd);
@@ -3072,7 +3076,7 @@ ATCE atcommand_charreset(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can reset a character only for lower or same GM level
pc_resetstate(pl_sd);
@@ -3112,7 +3116,7 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can reset a character only for lower or same GM level
int i;
@@ -3148,9 +3152,9 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
// Give knife and shirt
struct item item;
- item.nameid = 1201;
+ item.nameid = wrap<ItemNameId>(1201);
pc_additem(pl_sd, &item, 1);
- item.nameid = 1202;
+ item.nameid = wrap<ItemNameId>(1202);
pc_additem(pl_sd, &item, 1);
// Reset stats and skills
@@ -3341,7 +3345,7 @@ ATCE atcommand_recallall(Session *s, dumb_ptr<map_session_data> sd,
int count;
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp somenone to your actual map."_s);
@@ -3358,11 +3362,11 @@ ATCE atcommand_recallall(Session *s, dumb_ptr<map_session_data> sd,
if (pl_sd
&& pl_sd->state.auth
&& sd->status_key.account_id != pl_sd->status_key.account_id
- && pc_isGM(sd) >= pc_isGM(pl_sd))
+ && pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can recall only lower or same level
if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
count++;
else
pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT);
@@ -3393,7 +3397,7 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp somenone to your actual map."_s);
@@ -3402,7 +3406,7 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd,
if ((p = party_searchname(party_name)) != NULL ||
// name first to avoid error when name begin with a number
- (p = party_search(atoi(message.c_str()))) != NULL)
+ (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str()))))) != NULL)
{
count = 0;
for (io::FD i : iter_fds())
@@ -3416,7 +3420,7 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd,
&& pl_sd->status.party_id == p->party_id)
{
if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
count++;
else
pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT);
@@ -3585,11 +3589,11 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr<map_session_data> sd,
struct party *p;
if ((p = party_searchname(party_name)) != NULL ||
// name first to avoid error when name begin with a number
- (p = party_search(atoi(message.c_str()))) != NULL)
+ (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str()))))) != NULL)
{
if (sd->partyspy == p->party_id)
{
- sd->partyspy = 0;
+ sd->partyspy = PartyId();
AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name);
clif_displaymessage(s, output);
}
@@ -3673,26 +3677,25 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd,
{
CharName character;
XString item_name;
- int i, number = 0, item_id, item_position, count;
+ int i, number = 0;
+ ItemNameId item_id;
+ int item_position, count;
struct item_data *item_data;
if (!asplit(message, &item_name, &number, &character) || number < 1)
return ATCE::USAGE;
- item_id = 0;
if ((item_data = itemdb_searchname(item_name)) != NULL)
item_id = item_data->nameid;
else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != NULL)
item_id = item_data->nameid;
- else
- item_id = 0;
- if (item_id > 500)
+ if (item_id)
{
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_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);
@@ -3856,14 +3859,14 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can look items only lower or same level
counter = 0;
count = 0;
for (i = 0; i < MAX_INVENTORY; i++)
{
- if (pl_sd->status.inventory[i].nameid > 0
+ if (pl_sd->status.inventory[i].nameid
&& (item_data =
itemdb_search(pl_sd->status.inventory[i].nameid)) !=
NULL)
@@ -3968,7 +3971,7 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
if (pl_sd != NULL)
{
- if (pc_isGM(sd) >= pc_isGM(pl_sd))
+ if (pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can look items only lower or same level
if ((stor = account2storage2(pl_sd->status_key.account_id)) != NULL)
@@ -3977,7 +3980,7 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd,
count = 0;
for (i = 0; i < MAX_STORAGE; i++)
{
- if (stor->storage_[i].nameid > 0
+ if (stor->storage_[i].nameid
&& (item_data =
itemdb_search(stor->storage_[i].nameid)) != NULL)
{
@@ -4382,30 +4385,29 @@ ATCE atcommand_summon(Session *, dumb_ptr<map_session_data> sd,
ZString message)
{
MobName name;
- int mob_id = 0;
+ Species mob_id;
int x = 0;
int y = 0;
- int id = 0;
tick_t tick = gettick();
if (!extract(message, &name) || !name)
return ATCE::USAGE;
- if ((mob_id = atoi(name.c_str())) == 0)
+ if ((mob_id = wrap<Species>(static_cast<uint16_t>(atoi(name.c_str())))) == Species())
mob_id = mobdb_searchname(name);
- if (mob_id == 0)
+ if (mob_id == Species())
return ATCE::EXIST;
x = sd->bl_x + random_::in(-5, 4);
y = sd->bl_y + random_::in(-5, 4);
- id = mob_once_spawn(sd, MOB_THIS_MAP, x, y, JAPANESE_NAME, mob_id, 1, NpcEvent());
+ BlockId id = mob_once_spawn(sd, MOB_THIS_MAP, x, y, JAPANESE_NAME, mob_id, 1, NpcEvent());
dumb_ptr<mob_data> md = map_id_is_mob(id);
if (md)
{
md->master_id = sd->bl_id;
md->state.special_mob_ai = 1;
- md->mode = mob_db[md->mob_class].mode | MobMode::AGGRESSIVE;
+ md->mode = get_mob_db(md->mob_class).mode | MobMode::AGGRESSIVE;
md->deletetimer = Timer(tick + std::chrono::minutes(1),
std::bind(mob_timer_delete, ph::_1, ph::_2,
id));
@@ -4419,7 +4421,7 @@ static
ATCE atcommand_adjcmdlvl(Session *s, dumb_ptr<map_session_data>,
ZString message)
{
- int newlev;
+ GmLevel newlev;
XString cmd;
if (!extract(message, record<' '>(&newlev, &cmd)))
@@ -4446,11 +4448,10 @@ static
ATCE atcommand_adjgmlvl(Session *s, dumb_ptr<map_session_data>,
ZString message)
{
- int newlev;
+ GmLevel newlev;
CharName user;
- if (!asplit(message, &newlev, &user)
- || newlev < 0 || newlev > 99)
+ if (!asplit(message, &newlev, &user))
{
clif_displaymessage(s, "usage: @adjgmlvl <lvl> <user>."_s);
return ATCE::USAGE;
@@ -4660,14 +4661,14 @@ ATCE atcommand_jump_iterate(Session *s, dumb_ptr<map_session_data> sd,
}
if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARPTO)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you to the map of this player."_s);
return ATCE::PERM;
}
if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARP)
- && battle_config.any_warp_GM_min_level > pc_isGM(sd))
+ && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))))
{
clif_displaymessage(s,
"You are not authorised to warp you from your actual map."_s);
@@ -4897,7 +4898,7 @@ ATCE atcommand_doomspot(Session *s, dumb_ptr<map_session_data> sd,
if (pl_sd
&& pl_sd->state.auth && s2 != s && sd->bl_m == pl_sd->bl_m
&& sd->bl_x == pl_sd->bl_x && sd->bl_y == pl_sd->bl_y
- && pc_isGM(sd) >= pc_isGM(pl_sd))
+ && pc_isGM(sd).overwhelms(pc_isGM(pl_sd)))
{
// you can doom only lower or same gm level
pc_damage(NULL, pl_sd, pl_sd->status.hp + 1);
diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp
index 95e3814..df3448b 100644
--- a/src/map/atcommand.hpp
+++ b/src/map/atcommand.hpp
@@ -21,14 +21,14 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/fwd.hpp"
# include "map.hpp"
bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd,
- ZString message, int gmlvl);
+ ZString message, GmLevel gmlvl);
bool atcommand_config_read(ZString cfgName);
diff --git a/src/map/battle.cpp b/src/map/battle.cpp
index c19d310..09910c6 100644
--- a/src/map/battle.cpp
+++ b/src/map/battle.cpp
@@ -77,15 +77,15 @@ int battle_counttargeted(dumb_ptr<block_list> bl, dumb_ptr<block_list> src,
* 戻りは整数で0以上
*------------------------------------------
*/
-int battle_get_class(dumb_ptr<block_list> bl)
+Species battle_get_class(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retr(Species(), bl);
if (bl->bl_type == BL::MOB)
return bl->is_mob()->mob_class;
else if (bl->bl_type == BL::PC)
- return 0;
+ return bl->is_player()->status.species;
else
- return 0;
+ return Species();
}
/*==========================================
@@ -129,7 +129,7 @@ int battle_get_range(dumb_ptr<block_list> bl)
{
nullpo_ret(bl);
if (bl->bl_type == BL::MOB)
- return mob_db[bl->is_mob()->mob_class].range;
+ return get_mob_db(bl->is_mob()->mob_class).range;
else if (bl->bl_type == BL::PC)
return bl->is_player()->attackrange;
else
@@ -768,7 +768,7 @@ interval_t battle_get_amotion(dumb_ptr<block_list> bl)
interval_t amotion = std::chrono::seconds(2);
int aspd_rate = 100;
if (bl->bl_type == BL::MOB)
- amotion = static_cast<interval_t>(mob_db[bl->is_mob()->mob_class].amotion);
+ amotion = static_cast<interval_t>(get_mob_db(bl->is_mob()->mob_class).amotion);
if (sc_data)
{
@@ -789,7 +789,7 @@ interval_t battle_get_dmotion(dumb_ptr<block_list> bl)
nullpo_retr(interval_t::zero(), bl);
if (bl->bl_type == BL::MOB)
{
- return static_cast<interval_t>(mob_db[bl->is_mob()->mob_class].dmotion);
+ return static_cast<interval_t>(get_mob_db(bl->is_mob()->mob_class).dmotion);
}
else if (bl->bl_type == BL::PC)
{
@@ -810,26 +810,26 @@ LevelElement battle_get_element(dumb_ptr<block_list> bl)
return ret;
}
-int battle_get_party_id(dumb_ptr<block_list> bl)
+PartyId battle_get_party_id(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retr(PartyId(), bl);
if (bl->bl_type == BL::PC)
return bl->is_player()->status.party_id;
else if (bl->bl_type == BL::MOB)
{
dumb_ptr<mob_data> md = bl->is_mob();
- if (md->master_id > 0)
- return -md->master_id;
- return -md->bl_id;
+ if (md->master_id)
+ return wrap<PartyId>(-unwrap<BlockId>(md->master_id));
+ return wrap<PartyId>(-unwrap<BlockId>(md->bl_id));
}
- return 0;
+ return PartyId();
}
Race battle_get_race(dumb_ptr<block_list> bl)
{
nullpo_retr(Race::formless, bl);
if (bl->bl_type == BL::MOB)
- return mob_db[bl->is_mob()->mob_class].race;
+ return get_mob_db(bl->is_mob()->mob_class).race;
else if (bl->bl_type == BL::PC)
return Race::demihuman;
else
@@ -840,7 +840,7 @@ MobMode battle_get_mode(dumb_ptr<block_list> bl)
{
nullpo_retr(MobMode::CAN_MOVE, bl);
if (bl->bl_type == BL::MOB)
- return mob_db[bl->is_mob()->mob_class].mode;
+ return get_mob_db(bl->is_mob()->mob_class).mode;
// とりあえず動くということで1
return MobMode::CAN_MOVE;
}
@@ -1143,7 +1143,7 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src,
atkmin = battle_get_atk(src);
atkmax = battle_get_atk2(src);
}
- if (mob_db[md->mob_class].range > 3)
+ if (get_mob_db(md->mob_class).range > 3)
flag = (flag & ~BF::RANGEMASK) | BF::LONG;
if (atkmin > atkmax)
@@ -2059,7 +2059,7 @@ 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];
- int weapon = 0;
+ ItemNameId weapon;
if (weapon_index >= 0 && sd->inventory_data[weapon_index]
&& bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON))
weapon = sd->inventory_data[weapon_index]->nameid;
@@ -2068,8 +2068,8 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
sd->status_key.char_id, src->bl_m->name_, src->bl_x, src->bl_y,
(target->bl_type == BL::PC) ? "PC"_s : "MOB"_s,
(target->bl_type == BL::PC)
- ? target->is_player()-> status_key.char_id
- : target->bl_id,
+ ? unwrap<CharId>(target->is_player()->status_key.char_id)
+ : unwrap<BlockId>(target->bl_id),
battle_get_class(target),
wd.damage + wd.damage2, weapon);
}
@@ -2081,8 +2081,8 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
sd2->status_key.char_id, target->bl_m->name_, target->bl_x, target->bl_y,
(src->bl_type == BL::PC) ? "PC"_s : "MOB"_s,
(src->bl_type == BL::PC)
- ? src->is_player()->status_key.char_id
- : src->bl_id,
+ ? unwrap<CharId>(src->is_player()->status_key.char_id)
+ : unwrap<BlockId>(src->bl_id),
battle_get_class(src),
wd.damage + wd.damage2);
}
@@ -2161,7 +2161,7 @@ bool battle_check_undead(Race race, Element element)
int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
BCT flag)
{
- int s_p, t_p;
+ PartyId s_p, t_p;
dumb_ptr<block_list> ss = src;
nullpo_ret(src);
@@ -2191,7 +2191,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
if (src->bl_type == BL::MOB)
{
dumb_ptr<mob_data> md = src->is_mob();
- if (md && md->master_id > 0)
+ if (md && md->master_id)
{
if (md->master_id == target->bl_id) // 主なら肯定
return 1;
@@ -2253,7 +2253,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
{ // [MouseJstr]
if (battle_config.pk_mode)
return 1; // prevent novice engagement in pk_mode [Valaris]
- else if (ss->bl_m->flag.get(MapFlag::PVP_NOPARTY) && s_p > 0 && t_p > 0
+ else if (ss->bl_m->flag.get(MapFlag::PVP_NOPARTY) && s_p && t_p
&& s_p == t_p)
return 1;
return 0;
diff --git a/src/map/battle.hpp b/src/map/battle.hpp
index b8060a9..94d0b45 100644
--- a/src/map/battle.hpp
+++ b/src/map/battle.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "battle.t.hpp"
@@ -69,7 +69,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> bl, dumb_ptr<block_list> target,
tick_t tick);
int battle_is_unarmed(dumb_ptr<block_list> bl);
-int battle_get_class(dumb_ptr<block_list> bl);
+Species battle_get_class(dumb_ptr<block_list> bl);
DIR battle_get_dir(dumb_ptr<block_list> bl);
int battle_get_lv(dumb_ptr<block_list> bl);
int battle_get_range(dumb_ptr<block_list> bl);
@@ -95,7 +95,7 @@ Element battle_get_elem_type(dumb_ptr<block_list> bl)
{
return battle_get_element(bl).element;
}
-int battle_get_party_id(dumb_ptr<block_list> bl);
+PartyId battle_get_party_id(dumb_ptr<block_list> bl);
Race battle_get_race(dumb_ptr<block_list> bl);
MobMode battle_get_mode(dumb_ptr<block_list> bl);
int battle_get_stat(SP stat_id, dumb_ptr<block_list> bl);
diff --git a/src/map/battle.t.hpp b/src/map/battle.t.hpp
index d3a7a9c..45d75b8 100644
--- a/src/map/battle.t.hpp
+++ b/src/map/battle.t.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../generic/enum.hpp"
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index 64fd547..88fb039 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -134,8 +134,8 @@ int chrif_save(dumb_ptr<map_session_data> sd)
WFIFOW(char_session, 0) = 0x2b01;
WFIFOW(char_session, 2) = sizeof(sd->status_key) + sizeof(sd->status) + 12;
- WFIFOL(char_session, 4) = sd->bl_id;
- WFIFOL(char_session, 8) = sd->char_id;
+ WFIFOL(char_session, 4) = unwrap<BlockId>(sd->bl_id);
+ WFIFOL(char_session, 8) = unwrap<CharId>(sd->char_id_);
WFIFO_STRUCT(char_session, 12, sd->status_key);
WFIFO_STRUCT(char_session, 12 + sizeof(sd->status_key), sd->status);
WFIFOSET(char_session, WFIFOW(char_session, 2));
@@ -239,10 +239,10 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd,
}
WFIFOW(char_session, 0) = 0x2b05;
- WFIFOL(char_session, 2) = sd->bl_id;
+ WFIFOL(char_session, 2) = unwrap<BlockId>(sd->bl_id);
WFIFOL(char_session, 6) = sd->login_id1;
WFIFOL(char_session, 10) = sd->login_id2;
- WFIFOL(char_session, 14) = sd->status_key.char_id;
+ WFIFOL(char_session, 14) = unwrap<CharId>(sd->status_key.char_id);
WFIFO_STRING(char_session, 18, name, 16);
WFIFOW(char_session, 34) = x;
WFIFOW(char_session, 36) = y;
@@ -262,9 +262,9 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd,
static
int chrif_changemapserverack(Session *s)
{
- dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 2));
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(wrap<AccountId>(RFIFOL(s, 2))));
- if (sd == NULL || sd->status_key.char_id != RFIFOL(s, 14))
+ if (sd == NULL || sd->status_key.char_id != wrap<CharId>(RFIFOL(s, 14)))
return -1;
if (RFIFOL(s, 6) == 1)
@@ -350,8 +350,8 @@ int chrif_authreq(dumb_ptr<map_session_data> sd)
{
assert (s == sd->sess);
WFIFOW(char_session, 0) = 0x2afc;
- WFIFOL(char_session, 2) = sd->bl_id;
- WFIFOL(char_session, 6) = sd->char_id;
+ WFIFOL(char_session, 2) = unwrap<BlockId>(sd->bl_id);
+ WFIFOL(char_session, 6) = unwrap<CharId>(sd->char_id_);
WFIFOL(char_session, 10) = sd->login_id1;
WFIFOL(char_session, 14) = sd->login_id2;
WFIFOIP(char_session, 18) = s->client_ip;
@@ -389,7 +389,7 @@ int chrif_charselectreq(dumb_ptr<map_session_data> sd)
}
WFIFOW(char_session, 0) = 0x2b02;
- WFIFOL(char_session, 2) = sd->bl_id;
+ WFIFOL(char_session, 2) = unwrap<BlockId>(sd->bl_id);
WFIFOL(char_session, 6) = sd->login_id1;
WFIFOL(char_session, 10) = sd->login_id2;
WFIFOIP(char_session, 14) = s_ip;
@@ -402,7 +402,7 @@ int chrif_charselectreq(dumb_ptr<map_session_data> sd)
* GMに変化要求
*------------------------------------------
*/
-void chrif_changegm(int id, ZString pass)
+void chrif_changegm(AccountId id, ZString pass)
{
if (battle_config.etc_log)
PRINTF("chrif_changegm: account: %d, password: '%s'.\n"_fmt, id, pass);
@@ -410,7 +410,7 @@ void chrif_changegm(int id, ZString pass)
size_t len = pass.size() + 1;
WFIFOW(char_session, 0) = 0x2b0a;
WFIFOW(char_session, 2) = len + 8;
- WFIFOL(char_session, 4) = id;
+ WFIFOL(char_session, 4) = unwrap<AccountId>(id);
WFIFO_STRING(char_session, 8, pass, len);
WFIFOSET(char_session, len + 8);
}
@@ -419,7 +419,7 @@ void chrif_changegm(int id, ZString pass)
* Change Email
*------------------------------------------
*/
-void chrif_changeemail(int id, AccountEmail actual_email,
+void chrif_changeemail(AccountId id, AccountEmail actual_email,
AccountEmail new_email)
{
if (battle_config.etc_log)
@@ -427,7 +427,7 @@ void chrif_changeemail(int id, AccountEmail actual_email,
id, actual_email, new_email);
WFIFOW(char_session, 0) = 0x2b0c;
- WFIFOL(char_session, 2) = id;
+ WFIFOL(char_session, 2) = unwrap<AccountId>(id);
WFIFO_STRING(char_session, 6, actual_email, 40);
WFIFO_STRING(char_session, 46, new_email, 40);
WFIFOSET(char_session, 86);
@@ -444,11 +444,11 @@ void chrif_changeemail(int id, AccountEmail actual_email,
* 5: changesex
*------------------------------------------
*/
-void chrif_char_ask_name(int id, CharName character_name, short operation_type,
+void chrif_char_ask_name(AccountId id, CharName character_name, short operation_type,
HumanTimeDiff modif)
{
WFIFOW(char_session, 0) = 0x2b0e;
- WFIFOL(char_session, 2) = id; // account_id of who ask (for answer) -1 if nobody
+ WFIFOL(char_session, 2) = unwrap<AccountId>(id); // account_id of who ask (for answer) -1 if nobody
WFIFO_STRING(char_session, 6, character_name.to__actual(), 24);
WFIFOW(char_session, 30) = operation_type; // type of operation
if (operation_type == 2)
@@ -476,11 +476,11 @@ void chrif_char_ask_name(int id, CharName character_name, short operation_type,
static
int chrif_char_ask_name_answer(Session *s)
{
- int acc = RFIFOL(s, 2); // account_id of who has asked (-1 if nobody)
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2)); // account_id of who has asked (-1 if nobody)
CharName player_name = stringish<CharName>(RFIFO_STRING<24>(s, 6));
- dumb_ptr<map_session_data> sd = map_id2sd(acc);
- if (acc >= 0 && sd != NULL)
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(acc));
+ if (acc && sd != NULL)
{
AString output;
if (RFIFOW(s, 32) == 1) // player not found
@@ -613,20 +613,17 @@ int chrif_char_ask_name_answer(Session *s)
static
void chrif_changedgm(Session *s)
{
- int acc, level;
- dumb_ptr<map_session_data> sd = NULL;
-
- acc = RFIFOL(s, 2);
- level = RFIFOL(s, 6);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
+ GmLevel level = GmLevel::from(RFIFOL(s, 6));
- sd = map_id2sd(acc);
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(acc));
if (battle_config.etc_log)
PRINTF("chrif_changedgm: account: %d, GM level 0 -> %d.\n"_fmt, acc,
level);
if (sd != NULL)
{
- if (level > 0)
+ if (level)
clif_displaymessage(sd->sess, "GM modification success."_s);
else
clif_displaymessage(sd->sess, "Failure of GM modification."_s);
@@ -640,15 +637,15 @@ void chrif_changedgm(Session *s)
static
void chrif_changedsex(Session *s)
{
- int acc, i;
+ int i;
dumb_ptr<map_session_data> sd;
- acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
SEX sex = static_cast<SEX>(RFIFOB(s, 6));
if (battle_config.etc_log)
PRINTF("chrif_changedsex %d.\n"_fmt, acc);
- sd = map_id2sd(acc);
- if (acc > 0)
+ sd = map_id2sd(account_to_block(acc));
+ if (acc)
{
if (sd != NULL && sd->status.sex != sex)
{
@@ -703,7 +700,7 @@ int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd)
}
WFIFOW(char_session, 0) = 0x2b10;
WFIFOW(char_session, 2) = p;
- WFIFOL(char_session, 4) = sd->bl_id;
+ WFIFOL(char_session, 4) = unwrap<BlockId>(sd->bl_id);
WFIFOSET(char_session, p);
return 0;
@@ -717,7 +714,7 @@ static
int chrif_accountreg2(Session *s)
{
int j, p;
- dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 4));
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(wrap<AccountId>(RFIFOL(s, 4))));
if (sd == NULL)
return 1;
@@ -739,7 +736,7 @@ int chrif_accountreg2(Session *s)
*------------------------------------------
*/
static
-int chrif_divorce(int char_id, int partner_id)
+int chrif_divorce(CharId char_id, CharId partner_id)
{
dumb_ptr<map_session_data> sd = NULL;
@@ -749,7 +746,7 @@ int chrif_divorce(int char_id, int partner_id)
sd = map_nick2sd(map_charid2nick(char_id));
if (sd && sd->status.partner_id == partner_id)
{
- sd->status.partner_id = 0;
+ sd->status.partner_id = CharId();
if (sd->npc_flags.divorce)
{
@@ -761,7 +758,7 @@ int chrif_divorce(int char_id, int partner_id)
sd = map_nick2sd(map_charid2nick(partner_id));
nullpo_ret(sd);
if (sd->status.partner_id == char_id)
- sd->status.partner_id = 0;
+ sd->status.partner_id = CharId();
return 0;
}
@@ -771,13 +768,13 @@ int chrif_divorce(int char_id, int partner_id)
* Needed to divorce when partner is not connected to map server
*-------------------------------------
*/
-int chrif_send_divorce(int char_id)
+int chrif_send_divorce(CharId char_id)
{
if (!char_session)
return -1;
WFIFOW(char_session, 0) = 0x2b16;
- WFIFOL(char_session, 2) = char_id;
+ WFIFOL(char_session, 2) = unwrap<CharId>(char_id);
WFIFOSET(char_session, 6);
return 0;
}
@@ -789,14 +786,13 @@ int chrif_send_divorce(int char_id)
static
int chrif_accountdeletion(Session *s)
{
- int acc;
dumb_ptr<map_session_data> sd;
- acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
if (battle_config.etc_log)
PRINTF("chrif_accountdeletion %d.\n"_fmt, acc);
- sd = map_id2sd(acc);
- if (acc > 0)
+ sd = map_id2sd(account_to_block(acc));
+ if (acc)
{
if (sd != NULL)
{
@@ -822,14 +818,13 @@ int chrif_accountdeletion(Session *s)
static
int chrif_accountban(Session *s)
{
- int acc;
dumb_ptr<map_session_data> sd;
- acc = RFIFOL(s, 2);
+ AccountId acc = wrap<AccountId>(RFIFOL(s, 2));
if (battle_config.etc_log)
PRINTF("chrif_accountban %d.\n"_fmt, acc);
- sd = map_id2sd(acc);
- if (acc > 0)
+ sd = map_id2sd(account_to_block(acc));
+ if (acc)
{
if (sd != NULL)
{
@@ -937,7 +932,7 @@ int chrif_reloadGMdb(void)
*/
static
-void ladmin_itemfrob_fix_item(int source, int dest, struct item *item)
+void ladmin_itemfrob_fix_item(ItemNameId source, ItemNameId dest, struct item *item)
{
if (item && item->nameid == source)
{
@@ -947,7 +942,7 @@ void ladmin_itemfrob_fix_item(int source, int dest, struct item *item)
}
static
-void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id)
+void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameId dest_id)
{
#define IFIX(v) if (v == source_id) {v = dest_id; }
#define FIX(item) ladmin_itemfrob_fix_item(source_id, dest_id, &item)
@@ -1011,7 +1006,7 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id)
}
static
-void ladmin_itemfrob_c(dumb_ptr<block_list> bl, int source_id, int dest_id)
+void ladmin_itemfrob_c(dumb_ptr<block_list> bl, ItemNameId source_id, ItemNameId dest_id)
{
ladmin_itemfrob_c2(bl, source_id, dest_id);
}
@@ -1019,8 +1014,8 @@ void ladmin_itemfrob_c(dumb_ptr<block_list> bl, int source_id, int dest_id)
static
void ladmin_itemfrob(Session *s)
{
- int source_id = RFIFOL(s, 2);
- int dest_id = RFIFOL(s, 6);
+ ItemNameId source_id = wrap<ItemNameId>(static_cast<uint16_t>(RFIFOL(s, 2)));
+ ItemNameId dest_id = wrap<ItemNameId>(static_cast<uint16_t>(RFIFOL(s, 6)));
dumb_ptr<block_list> bl = map_get_first_session();
// flooritems
@@ -1104,7 +1099,7 @@ void chrif_parse(Session *s)
break;
case 0x2afd:
{
- int id = RFIFOL(s, 4);
+ AccountId id = wrap<AccountId>(RFIFOL(s, 4));
int login_id2 = RFIFOL(s, 8);
TimeT connect_until_time = static_cast<time_t>(RFIFOL(s, 12));
short tmw_version = RFIFOW(s, 16);
@@ -1118,13 +1113,13 @@ void chrif_parse(Session *s)
}
break;
case 0x2afe:
- pc_authfail(RFIFOL(s, 2));
+ pc_authfail(wrap<AccountId>(RFIFOL(s, 2)));
break;
case 0x2b00:
map_setusers(RFIFOL(s, 2));
break;
case 0x2b03:
- clif_charselectok(RFIFOL(s, 2));
+ clif_charselectok(wrap<BlockId>(RFIFOL(s, 2)));
break;
case 0x2b04:
chrif_recvmap(s);
@@ -1145,7 +1140,7 @@ void chrif_parse(Session *s)
chrif_accountreg2(s);
break;
case 0x2b12:
- chrif_divorce(RFIFOL(s, 2), RFIFOL(s, 6));
+ chrif_divorce(wrap<CharId>(RFIFOL(s, 2)), wrap<CharId>(RFIFOL(s, 6)));
break;
case 0x2b13:
chrif_accountdeletion(s);
@@ -1193,7 +1188,7 @@ void send_users_tochar(TimerData *, tick_t)
|| sd->state.shroud_active
|| bool(sd->status.option & Option::HIDE)) && pc_isGM(sd)))
{
- WFIFOL(char_session, 6 + 4 * users) = sd->status_key.char_id;
+ WFIFOL(char_session, 6 + 4 * users) = unwrap<CharId>(sd->status_key.char_id);
users++;
}
}
diff --git a/src/map/chrif.hpp b/src/map/chrif.hpp
index afeba75..f3fc152 100644
--- a/src/map/chrif.hpp
+++ b/src/map/chrif.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/fwd.hpp"
@@ -48,13 +48,13 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd,
MapName name, int x, int y,
IP4Address ip, short port);
-void chrif_changegm(int id, ZString pass);
-void chrif_changeemail(int id, AccountEmail actual_email, AccountEmail new_email);
-void chrif_char_ask_name(int id, CharName character_name, short operation_type,
+void chrif_changegm(AccountId id, ZString pass);
+void chrif_changeemail(AccountId id, AccountEmail actual_email, AccountEmail new_email);
+void chrif_char_ask_name(AccountId id, CharName character_name, short operation_type,
HumanTimeDiff modif);
int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd);
int chrif_reloadGMdb(void);
-int chrif_send_divorce(int char_id);
+int chrif_send_divorce(CharId char_id);
void do_init_chrif(void);
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 6c4d821..be544db 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -419,13 +419,13 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
if (bl->bl_type == BL::PC)
{
dumb_ptr<map_session_data> sd = bl->is_player();
- if (sd->partyspy > 0)
+ if (sd->partyspy)
{
p = party_search(sd->partyspy);
}
else
{
- if (sd->status.party_id > 0)
+ if (sd->status.party_id)
p = party_search(sd->status.party_id);
}
}
@@ -547,7 +547,7 @@ int clif_authfail_fd(Session *s, int type)
*
*------------------------------------------
*/
-int clif_charselectok(int id)
+int clif_charselectok(BlockId id)
{
dumb_ptr<map_session_data> sd;
@@ -576,8 +576,8 @@ int clif_set009e(dumb_ptr<flooritem_data> fitem, uint8_t *buf)
//009e <ID>.l <name ID>.w <identify flag>.B <X>.w <Y>.w <subX>.B <subY>.B <amount>.w
WBUFW(buf, 0) = 0x9e;
- WBUFL(buf, 2) = fitem->bl_id;
- WBUFW(buf, 6) = fitem->item_data.nameid;
+ WBUFL(buf, 2) = unwrap<BlockId>(fitem->bl_id);
+ WBUFW(buf, 6) = unwrap<ItemNameId>(fitem->item_data.nameid);
WBUFB(buf, 8) = 1; //identify;
WBUFW(buf, 9) = fitem->bl_x;
WBUFW(buf, 11) = fitem->bl_y;
@@ -598,7 +598,7 @@ int clif_dropflooritem(dumb_ptr<flooritem_data> fitem)
nullpo_ret(fitem);
- if (fitem->item_data.nameid <= 0)
+ if (!fitem->item_data.nameid)
return 0;
clif_set009e(fitem, buf);
clif_send(buf, clif_parse_func_table[0x9e].len, fitem, SendWho::AREA);
@@ -617,7 +617,7 @@ int clif_clearflooritem(dumb_ptr<flooritem_data> fitem, Session *s)
nullpo_ret(fitem);
WBUFW(buf, 0) = 0xa1;
- WBUFL(buf, 2) = fitem->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(fitem->bl_id);
if (!s)
{
@@ -643,7 +643,7 @@ int clif_clearchar(dumb_ptr<block_list> bl, BeingRemoveWhy type)
nullpo_ret(bl);
WBUFW(buf, 0) = 0x80;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
if (type == BeingRemoveWhy::DISGUISE)
{
WBUFB(buf, 6) = static_cast<uint8_t>(BeingRemoveWhy::GONE);
@@ -694,10 +694,10 @@ int clif_clearchar_delay(tick_t tick,
*
*------------------------------------------
*/
-void clif_clearchar_id(int id, BeingRemoveWhy type, Session *s)
+void clif_clearchar_id(BlockId id, BeingRemoveWhy type, Session *s)
{
WFIFOW(s, 0) = 0x80;
- WFIFOL(s, 2) = id;
+ WFIFOL(s, 2) = unwrap<BlockId>(id);
WFIFOB(s, 6) = static_cast<uint8_t>(type);
WFIFOSET(s, clif_parse_func_table[0x80].len);
}
@@ -712,12 +712,12 @@ int clif_set0078(dumb_ptr<map_session_data> sd, unsigned char *buf)
nullpo_ret(sd);
WBUFW(buf, 0) = 0x1d8;
- WBUFL(buf, 2) = sd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(sd->bl_id);
WBUFW(buf, 6) = static_cast<uint16_t>(sd->speed.count());
WBUFW(buf, 8) = static_cast<uint16_t>(sd->opt1);
WBUFW(buf, 10) = static_cast<uint16_t>(sd->opt2);
WBUFW(buf, 12) = static_cast<uint16_t>(sd->status.option);
- WBUFW(buf, 14) = sd->status.species;
+ WBUFW(buf, 14) = unwrap<Species>(sd->status.species);
WBUFW(buf, 16) = sd->status.hair;
int widx = sd->equip_index_maybe[EQUIP::WEAPON];
@@ -728,20 +728,20 @@ int clif_set0078(dumb_ptr<map_session_data> sd, unsigned char *buf)
{
if (widx >= 0 && sd->inventory_data[widx])
{
- WBUFW(buf, 18) = sd->status.inventory[widx].nameid;
+ WBUFW(buf, 18) = unwrap<ItemNameId>(sd->status.inventory[widx].nameid);
}
else
- WBUFW(buf, 18) = 0;
+ WBUFW(buf, 18) = unwrap<ItemNameId>(ItemNameId());
}
if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
{
- WBUFW(buf, 20) = sd->status.inventory[sidx].nameid;
+ WBUFW(buf, 20) = unwrap<ItemNameId>(sd->status.inventory[sidx].nameid);
}
else
- WBUFW(buf, 20) = 0;
- WBUFW(buf, 22) = sd->status.head_bottom;
- WBUFW(buf, 24) = sd->status.head_top;
- WBUFW(buf, 26) = sd->status.head_mid;
+ WBUFW(buf, 20) = unwrap<ItemNameId>(ItemNameId());
+ WBUFW(buf, 22) = unwrap<ItemNameId>(sd->status.head_bottom);
+ WBUFW(buf, 24) = unwrap<ItemNameId>(sd->status.head_top);
+ WBUFW(buf, 26) = unwrap<ItemNameId>(sd->status.head_mid);
WBUFW(buf, 28) = sd->status.hair_color;
WBUFW(buf, 30) = sd->status.clothes_color;
WBUFW(buf, 32) = static_cast<uint8_t>(sd->head_dir);
@@ -755,7 +755,7 @@ int clif_set0078(dumb_ptr<map_session_data> sd, unsigned char *buf)
// work around ICE in gcc 4.6
uint8_t dir = static_cast<uint8_t>(sd->dir);
WBUFB(buf, 48) |= dir;
- WBUFW(buf, 49) = (pc_isGM(sd) == 60 || pc_isGM(sd) == 99) ? 0x80 : 0;
+ WBUFW(buf, 49) = pc_isGM(sd).get_public_word();
WBUFB(buf, 51) = sd->state.dead_sit;
WBUFW(buf, 52) = 0;
@@ -772,31 +772,31 @@ int clif_set007b(dumb_ptr<map_session_data> sd, unsigned char *buf)
nullpo_ret(sd);
WBUFW(buf, 0) = 0x1da;
- WBUFL(buf, 2) = sd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(sd->bl_id);
WBUFW(buf, 6) = static_cast<uint16_t>(sd->speed.count());
WBUFW(buf, 8) = static_cast<uint16_t>(sd->opt1);
WBUFW(buf, 10) = static_cast<uint16_t>(sd->opt2);
WBUFW(buf, 12) = static_cast<uint16_t>(sd->status.option);
- WBUFW(buf, 14) = sd->status.species;
+ WBUFW(buf, 14) = unwrap<Species>(sd->status.species);
WBUFW(buf, 16) = 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])
{
- WBUFW(buf, 18) = sd->status.inventory[widx].nameid;
+ WBUFW(buf, 18) = unwrap<ItemNameId>(sd->status.inventory[widx].nameid);
}
else
- WBUFW(buf, 18) = 0;
+ WBUFW(buf, 18) = unwrap<ItemNameId>(ItemNameId());
if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
{
- WBUFW(buf, 20) = sd->status.inventory[sidx].nameid;
+ WBUFW(buf, 20) = unwrap<ItemNameId>(sd->status.inventory[sidx].nameid);
}
else
- WBUFW(buf, 20) = 0;
- WBUFW(buf, 22) = sd->status.head_bottom;
+ WBUFW(buf, 20) = unwrap<ItemNameId>(ItemNameId());
+ WBUFW(buf, 22) = unwrap<ItemNameId>(sd->status.head_bottom);
WBUFL(buf, 24) = gettick().time_since_epoch().count();
- WBUFW(buf, 28) = sd->status.head_top;
- WBUFW(buf, 30) = sd->status.head_mid;
+ WBUFW(buf, 28) = unwrap<ItemNameId>(sd->status.head_top);
+ WBUFW(buf, 30) = unwrap<ItemNameId>(sd->status.head_mid);
WBUFW(buf, 32) = sd->status.hair_color;
WBUFW(buf, 34) = sd->status.clothes_color;
WBUFW(buf, 36) = static_cast<uint8_t>(sd->head_dir);
@@ -807,7 +807,7 @@ int clif_set007b(dumb_ptr<map_session_data> sd, unsigned char *buf)
WBUFB(buf, 48) = sd->status.karma;
WBUFB(buf, 49) = static_cast<uint8_t>(sd->sex);
WBUFPOS2(buf, 50, sd->bl_x, sd->bl_y, sd->to_x, sd->to_y);
- WBUFW(buf, 55) = pc_isGM(sd) == 60 ? 0x80 : 0;
+ WBUFW(buf, 55) = pc_isGM(sd).get_public_word();
WBUFB(buf, 57) = 5;
WBUFW(buf, 58) = 0;
@@ -826,12 +826,12 @@ int clif_mob0078(dumb_ptr<mob_data> md, unsigned char *buf)
nullpo_ret(md);
WBUFW(buf, 0) = 0x78;
- WBUFL(buf, 2) = md->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(md->bl_id);
WBUFW(buf, 6) = static_cast<uint16_t>(battle_get_speed(md).count());
WBUFW(buf, 8) = static_cast<uint16_t>(md->opt1);
WBUFW(buf, 10) = static_cast<uint16_t>(md->opt2);
WBUFW(buf, 12) = static_cast<uint16_t>(md->option);
- WBUFW(buf, 14) = md->mob_class;
+ WBUFW(buf, 14) = unwrap<Species>(md->mob_class);
// snip: stuff do do with disguise as a PC
WBUFPOS(buf, 46, md->bl_x, md->bl_y);
// work around ICE in gcc 4.6
@@ -857,12 +857,12 @@ int clif_mob007b(dumb_ptr<mob_data> md, unsigned char *buf)
nullpo_ret(md);
WBUFW(buf, 0) = 0x7b;
- WBUFL(buf, 2) = md->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(md->bl_id);
WBUFW(buf, 6) = static_cast<uint16_t>(battle_get_speed(md).count());
WBUFW(buf, 8) = static_cast<uint16_t>(md->opt1);
WBUFW(buf, 10) = static_cast<uint16_t>(md->opt2);
WBUFW(buf, 12) = static_cast<uint16_t>(md->option);
- WBUFW(buf, 14) = md->mob_class;
+ WBUFW(buf, 14) = unwrap<Species>(md->mob_class);
// snip: stuff for monsters disguised as PCs
WBUFL(buf, 22) = gettick().time_since_epoch().count();
@@ -887,7 +887,7 @@ int clif_npc0078(dumb_ptr<npc_data> nd, unsigned char *buf)
really_memset0(buf, clif_parse_func_table[0x78].len);
WBUFW(buf, 0) = 0x78;
- WBUFL(buf, 2) = nd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(nd->bl_id);
WBUFW(buf, 6) = static_cast<uint16_t>(nd->speed.count());
WBUFW(buf, 14) = nd->npc_class;
WBUFPOS(buf, 46, nd->bl_x, nd->bl_y);
@@ -969,7 +969,7 @@ int clif_spawnnpc(dumb_ptr<npc_data> nd)
really_memset0(buf, clif_parse_func_table[0x7c].len);
WBUFW(buf, 0) = 0x7c;
- WBUFL(buf, 2) = nd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(nd->bl_id);
WBUFW(buf, 6) = static_cast<uint16_t>(nd->speed.count());
WBUFW(buf, 20) = nd->npc_class;
WBUFPOS(buf, 36, nd->bl_x, nd->bl_y);
@@ -982,7 +982,7 @@ int clif_spawnnpc(dumb_ptr<npc_data> nd)
return 0;
}
-int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, int fake_npc_id)
+int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, BlockId fake_npc_id)
{
nullpo_ret(sd);
@@ -992,7 +992,7 @@ int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, int fake_npc_i
return 0;
WFIFOW(s, 0) = 0x7c;
- WFIFOL(s, 2) = fake_npc_id;
+ WFIFOL(s, 2) = unwrap<BlockId>(fake_npc_id);
WFIFOW(s, 6) = 0;
WFIFOW(s, 8) = 0;
WFIFOW(s, 10) = 0;
@@ -1002,7 +1002,7 @@ int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, int fake_npc_i
WFIFOSET(s, clif_parse_func_table[0x7c].len);
WFIFOW(s, 0) = 0x78;
- WFIFOL(s, 2) = fake_npc_id;
+ WFIFOL(s, 2) = unwrap<BlockId>(fake_npc_id);
WFIFOW(s, 6) = 0;
WFIFOW(s, 8) = 0;
WFIFOW(s, 10) = 0;
@@ -1033,12 +1033,12 @@ int clif_spawnmob(dumb_ptr<mob_data> md)
really_memset0(buf, clif_parse_func_table[0x7c].len);
WBUFW(buf, 0) = 0x7c;
- WBUFL(buf, 2) = md->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(md->bl_id);
WBUFW(buf, 6) = md->stats[mob_stat::SPEED];
WBUFW(buf, 8) = static_cast<uint16_t>(md->opt1);
WBUFW(buf, 10) = static_cast<uint16_t>(md->opt2);
WBUFW(buf, 12) = static_cast<uint16_t>(md->option);
- WBUFW(buf, 20) = md->mob_class;
+ WBUFW(buf, 20) = unwrap<Species>(md->mob_class);
WBUFPOS(buf, 36, md->bl_x, md->bl_y);
clif_send(buf, clif_parse_func_table[0x7c].len, md, SendWho::AREA);
}
@@ -1186,7 +1186,7 @@ void clif_fixpos(dumb_ptr<block_list> bl)
nullpo_retv(bl);
WBUFW(buf, 0) = 0x88;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFW(buf, 6) = bl->bl_x;
WBUFW(buf, 8) = bl->bl_y;
@@ -1197,13 +1197,13 @@ void clif_fixpos(dumb_ptr<block_list> bl)
*
*------------------------------------------
*/
-int clif_npcbuysell(dumb_ptr<map_session_data> sd, int id)
+int clif_npcbuysell(dumb_ptr<map_session_data> sd, BlockId id)
{
nullpo_ret(sd);
Session *s = sd->sess;
WFIFOW(s, 0) = 0xc4;
- WFIFOL(s, 2) = id;
+ WFIFOL(s, 2) = unwrap<BlockId>(id);
WFIFOSET(s, clif_parse_func_table[0xc4].len);
return 0;
@@ -1230,7 +1230,7 @@ int clif_buylist(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data_shop> nd)
WFIFOL(s, 4 + i * 11) = val; // base price
WFIFOL(s, 8 + i * 11) = val; // actual price
WFIFOB(s, 12 + i * 11) = static_cast<uint8_t>(id->type);
- WFIFOW(s, 13 + i * 11) = nd->shop_items[i].nameid;
+ WFIFOW(s, 13 + i * 11) = unwrap<ItemNameId>(nd->shop_items[i].nameid);
}
WFIFOW(s, 2) = i * 11 + 4;
WFIFOSET(s, WFIFOW(s, 2));
@@ -1252,7 +1252,7 @@ int clif_selllist(dumb_ptr<map_session_data> sd)
WFIFOW(s, 0) = 0xc7;
for (i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid > 0 && sd->inventory_data[i])
+ if (sd->status.inventory[i].nameid && sd->inventory_data[i])
{
val = sd->inventory_data[i]->value_sell;
if (val < 0)
@@ -1273,7 +1273,7 @@ int clif_selllist(dumb_ptr<map_session_data> sd)
*
*------------------------------------------
*/
-void clif_scriptmes(dumb_ptr<map_session_data> sd, int npcid, XString mes)
+void clif_scriptmes(dumb_ptr<map_session_data> sd, BlockId npcid, XString mes)
{
nullpo_retv(sd);
@@ -1282,7 +1282,7 @@ void clif_scriptmes(dumb_ptr<map_session_data> sd, int npcid, XString mes)
size_t len = mes.size() + 1;
WFIFOW(s, 0) = 0xb4;
WFIFOW(s, 2) = len + 8;
- WFIFOL(s, 4) = npcid;
+ WFIFOL(s, 4) = unwrap<BlockId>(npcid);
WFIFO_STRING(s, 8, mes, len);
WFIFOSET(s, WFIFOW(s, 2));
}
@@ -1291,13 +1291,13 @@ void clif_scriptmes(dumb_ptr<map_session_data> sd, int npcid, XString mes)
*
*------------------------------------------
*/
-void clif_scriptnext(dumb_ptr<map_session_data> sd, int npcid)
+void clif_scriptnext(dumb_ptr<map_session_data> sd, BlockId npcid)
{
nullpo_retv(sd);
Session *s = sd->sess;
WFIFOW(s, 0) = 0xb5;
- WFIFOL(s, 2) = npcid;
+ WFIFOL(s, 2) = unwrap<BlockId>(npcid);
WFIFOSET(s, clif_parse_func_table[0xb5].len);
}
@@ -1305,13 +1305,13 @@ void clif_scriptnext(dumb_ptr<map_session_data> sd, int npcid)
*
*------------------------------------------
*/
-void clif_scriptclose(dumb_ptr<map_session_data> sd, int npcid)
+void clif_scriptclose(dumb_ptr<map_session_data> sd, BlockId npcid)
{
nullpo_retv(sd);
Session *s = sd->sess;
WFIFOW(s, 0) = 0xb6;
- WFIFOL(s, 2) = npcid;
+ WFIFOL(s, 2) = unwrap<BlockId>(npcid);
WFIFOSET(s, clif_parse_func_table[0xb6].len);
}
@@ -1319,7 +1319,7 @@ void clif_scriptclose(dumb_ptr<map_session_data> sd, int npcid)
*
*------------------------------------------
*/
-void clif_scriptmenu(dumb_ptr<map_session_data> sd, int npcid, XString mes)
+void clif_scriptmenu(dumb_ptr<map_session_data> sd, BlockId npcid, XString mes)
{
nullpo_retv(sd);
@@ -1327,7 +1327,7 @@ void clif_scriptmenu(dumb_ptr<map_session_data> sd, int npcid, XString mes)
size_t len = mes.size() + 1;
WFIFOW(s, 0) = 0xb7;
WFIFOW(s, 2) = len + 8;
- WFIFOL(s, 4) = npcid;
+ WFIFOL(s, 4) = unwrap<BlockId>(npcid);
WFIFO_STRING(s, 8, mes, len);
WFIFOSET(s, WFIFOW(s, 2));
}
@@ -1336,13 +1336,13 @@ void clif_scriptmenu(dumb_ptr<map_session_data> sd, int npcid, XString mes)
*
*------------------------------------------
*/
-void clif_scriptinput(dumb_ptr<map_session_data> sd, int npcid)
+void clif_scriptinput(dumb_ptr<map_session_data> sd, BlockId npcid)
{
nullpo_retv(sd);
Session *s = sd->sess;
WFIFOW(s, 0) = 0x142;
- WFIFOL(s, 2) = npcid;
+ WFIFOL(s, 2) = unwrap<BlockId>(npcid);
WFIFOSET(s, clif_parse_func_table[0x142].len);
}
@@ -1350,13 +1350,13 @@ void clif_scriptinput(dumb_ptr<map_session_data> sd, int npcid)
*
*------------------------------------------
*/
-void clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid)
+void clif_scriptinputstr(dumb_ptr<map_session_data> sd, BlockId npcid)
{
nullpo_retv(sd);
Session *s = sd->sess;
WFIFOW(s, 0) = 0x1d4;
- WFIFOL(s, 2) = npcid;
+ WFIFOL(s, 2) = unwrap<BlockId>(npcid);
WFIFOSET(s, clif_parse_func_table[0x1d4].len);
}
@@ -1364,26 +1364,6 @@ void clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid)
*
*------------------------------------------
*/
-void clif_viewpoint(dumb_ptr<map_session_data> sd, int npc_id, int type,
- int x, int y, int id, int color)
-{
- nullpo_retv(sd);
-
- Session *s = sd->sess;
- WFIFOW(s, 0) = 0x144;
- WFIFOL(s, 2) = npc_id;
- WFIFOL(s, 6) = type;
- WFIFOL(s, 10) = x;
- WFIFOL(s, 14) = y;
- WFIFOB(s, 18) = id;
- WFIFOL(s, 19) = color;
- WFIFOSET(s, clif_parse_func_table[0x144].len);
-}
-
-/*==========================================
- *
- *------------------------------------------
- */
int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fail)
{
nullpo_ret(sd);
@@ -1408,14 +1388,14 @@ int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fa
}
else
{
- if (n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <= 0
+ if (n < 0 || n >= MAX_INVENTORY || !sd->status.inventory[n].nameid
|| sd->inventory_data[n] == NULL)
return 1;
WFIFOW(s, 0) = 0xa0;
WFIFOW(s, 2) = n + 2;
WFIFOW(s, 4) = amount;
- WFIFOW(s, 6) = sd->status.inventory[n].nameid;
+ WFIFOW(s, 6) = unwrap<ItemNameId>(sd->status.inventory[n].nameid);
WFIFOB(s, 8) = 1; //identify;
WFIFOB(s, 9) = 0; // broken or attribute;
WFIFOB(s, 10) = 0; //refine;
@@ -1466,12 +1446,12 @@ void clif_itemlist(dumb_ptr<map_session_data> sd)
WFIFOW(s, 0) = 0x1ee;
for (int i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid <= 0
+ if (!sd->status.inventory[i].nameid
|| sd->inventory_data[i] == NULL
|| itemdb_isequip2(sd->inventory_data[i]))
continue;
WFIFOW(s, n * 18 + 4) = i + 2;
- WFIFOW(s, n * 18 + 6) = sd->status.inventory[i].nameid;
+ WFIFOW(s, n * 18 + 6) = unwrap<ItemNameId>(sd->status.inventory[i].nameid);
WFIFOB(s, n * 18 + 8) = static_cast<uint8_t>(sd->inventory_data[i]->type);
WFIFOB(s, n * 18 + 9) = 1; //identify;
WFIFOW(s, n * 18 + 10) = sd->status.inventory[i].amount;
@@ -1511,12 +1491,12 @@ void clif_equiplist(dumb_ptr<map_session_data> sd)
int n = 0;
for (int i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid <= 0
+ if (!sd->status.inventory[i].nameid
|| sd->inventory_data[i] == NULL
|| !itemdb_isequip2(sd->inventory_data[i]))
continue;
WFIFOW(s, n * 20 + 4) = i + 2;
- WFIFOW(s, n * 20 + 6) = sd->status.inventory[i].nameid;
+ WFIFOW(s, n * 20 + 6) = unwrap<ItemNameId>(sd->status.inventory[i].nameid);
WFIFOB(s, n * 20 + 8) = static_cast<uint8_t>(
sd->inventory_data[i]->type == ItemType::_7
? ItemType::WEAPON
@@ -1555,7 +1535,7 @@ int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor)
int n = 0;
for (int i = 0; i < MAX_STORAGE; i++)
{
- if (stor->storage_[i].nameid <= 0)
+ if (!stor->storage_[i].nameid)
continue;
struct item_data *id;
@@ -1565,7 +1545,7 @@ int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor)
continue;
WFIFOW(s, n * 18 + 4) = i + 1;
- WFIFOW(s, n * 18 + 6) = stor->storage_[i].nameid;
+ WFIFOW(s, n * 18 + 6) = unwrap<ItemNameId>(stor->storage_[i].nameid);
WFIFOB(s, n * 18 + 8) = static_cast<uint8_t>(id->type);
WFIFOB(s, n * 18 + 9) = 0; //identify;
WFIFOW(s, n * 18 + 10) = stor->storage_[i].amount;
@@ -1598,7 +1578,7 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor)
int n = 0;
for (int i = 0; i < MAX_STORAGE; i++)
{
- if (stor->storage_[i].nameid <= 0)
+ if (!stor->storage_[i].nameid)
continue;
struct item_data *id;
@@ -1607,7 +1587,7 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor)
if (!itemdb_isequip2(id))
continue;
WFIFOW(s, n * 20 + 4) = i + 1;
- WFIFOW(s, n * 20 + 6) = stor->storage_[i].nameid;
+ WFIFOW(s, n * 20 + 6) = unwrap<ItemNameId>(stor->storage_[i].nameid);
WFIFOB(s, n * 20 + 8) = static_cast<uint8_t>(id->type);
WFIFOB(s, n * 20 + 9) = 0; //identify;
WFIFOW(s, n * 20 + 10) = static_cast<uint16_t>(id->equip);
@@ -1788,7 +1768,7 @@ int clif_updatestatus(dumb_ptr<map_session_data> sd, SP type)
break;
case SP::GM:
- WFIFOL(s, 4) = pc_isGM(sd);
+ WFIFOL(s, 4) = pc_isGM(sd).get_all_bits();
break;
default:
@@ -1829,7 +1809,7 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
&& (type == LOOK::WEAPON || type == LOOK::SHIELD || type >= LOOK::SHOES))
{
WBUFW(buf, 0) = 0x1d7;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
if (type >= LOOK::SHOES)
{
EQUIP equip_point = equip_points[type];
@@ -1838,7 +1818,7 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
int idx = sd->equip_index_maybe[equip_point];
if (idx >= 0 && sd->inventory_data[idx])
{
- WBUFW(buf, 7) = sd->status.inventory[idx].nameid;
+ WBUFW(buf, 7) = unwrap<ItemNameId>(sd->status.inventory[idx].nameid);
}
else
WBUFW(buf, 7) = 0;
@@ -1855,14 +1835,14 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
{
if (widx >= 0 && sd->inventory_data[widx])
{
- WBUFW(buf, 7) = sd->status.inventory[widx].nameid;
+ WBUFW(buf, 7) = unwrap<ItemNameId>(sd->status.inventory[widx].nameid);
}
else
WBUFW(buf, 7) = 0;
}
if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
{
- WBUFW(buf, 9) = sd->status.inventory[sidx].nameid;
+ WBUFW(buf, 9) = unwrap<ItemNameId>(sd->status.inventory[sidx].nameid);
}
else
WBUFW(buf, 9) = 0;
@@ -1875,7 +1855,7 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
else
{
WBUFW(buf, 0) = 0x1d7;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFB(buf, 6) = static_cast<uint8_t>(type);
WBUFW(buf, 7) = val;
WBUFW(buf, 9) = 0;
@@ -1952,8 +1932,7 @@ int clif_arrowequip(dumb_ptr<map_session_data> sd, int val)
{
nullpo_ret(sd);
- if (sd->attacktarget && sd->attacktarget > 0) // [Valaris]
- sd->attacktarget = 0;
+ sd->attacktarget = BlockId();
Session *s = sd->sess;
WFIFOW(s, 0) = 0x013c;
@@ -2047,7 +2026,7 @@ int clif_misceffect(dumb_ptr<block_list> bl, int type)
nullpo_ret(bl);
WBUFW(buf, 0) = 0x19b;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFL(buf, 6) = type;
clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::AREA);
@@ -2070,7 +2049,7 @@ int clif_changeoption(dumb_ptr<block_list> bl)
sc_data = battle_get_sc_data(bl);
WBUFW(buf, 0) = 0x119;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFW(buf, 6) = static_cast<uint16_t>(*battle_get_opt1(bl));
WBUFW(buf, 8) = static_cast<uint16_t>(*battle_get_opt2(bl));
WBUFW(buf, 10) = static_cast<uint16_t>(option);
@@ -2105,8 +2084,8 @@ int clif_useitemack(dumb_ptr<map_session_data> sd, int index, int amount,
WBUFW(buf, 0) = 0x1c8;
WBUFW(buf, 2) = index + 2;
- WBUFW(buf, 4) = sd->status.inventory[index].nameid;
- WBUFL(buf, 6) = sd->bl_id;
+ WBUFW(buf, 4) = unwrap<ItemNameId>(sd->status.inventory[index].nameid);
+ WBUFL(buf, 6) = unwrap<BlockId>(sd->bl_id);
WBUFW(buf, 10) = amount;
WBUFB(buf, 12) = ok;
clif_send(buf, clif_parse_func_table[0x1c8].len, sd, SendWho::SELF);
@@ -2170,7 +2149,7 @@ void clif_tradeadditem(dumb_ptr<map_session_data> sd,
else
{
index -= 2;
- WFIFOW(s, 6) = sd->status.inventory[index].nameid; // type id
+ WFIFOW(s, 6) = unwrap<ItemNameId>(sd->status.inventory[index].nameid); // type id
WFIFOB(s, 8) = 0; //identify;
WFIFOB(s, 9) = 0; //broken or attribute;
WFIFOB(s, 10) = 0; //refine;
@@ -2286,7 +2265,7 @@ int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor,
/* if ((view = itemdb_viewid(stor->storage_[index].nameid)) > 0)
WFIFOW(fd,8) =view;
else*/
- WFIFOW(s, 8) = stor->storage_[index].nameid;
+ WFIFOW(s, 8) = unwrap<ItemNameId>(stor->storage_[index].nameid);
WFIFOB(s, 10) = 0; //identify;
WFIFOB(s, 11) = 0; //broken or attribute;
WFIFOB(s, 12) = 0; //refine;
@@ -2484,8 +2463,8 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
sc_data = battle_get_sc_data(dst);
WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = src->bl_id;
- WBUFL(buf, 6) = dst->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(src->bl_id);
+ WBUFL(buf, 6) = unwrap<BlockId>(dst->bl_id);
WBUFL(buf, 10) = tick.time_since_epoch().count();
WBUFL(buf, 14) = sdelay.count();
WBUFL(buf, 18) = ddelay.count();
@@ -2535,8 +2514,8 @@ void clif_getareachar_item(dumb_ptr<map_session_data> sd,
Session *s = sd->sess;
//009d <ID>.l <item ID>.w <identify flag>.B <X>.w <Y>.w <amount>.w <subX>.B <subY>.B
WFIFOW(s, 0) = 0x9d;
- WFIFOL(s, 2) = fitem->bl_id;
- WFIFOW(s, 6) = fitem->item_data.nameid;
+ WFIFOL(s, 2) = unwrap<BlockId>(fitem->bl_id);
+ WFIFOW(s, 6) = unwrap<ItemNameId>(fitem->item_data.nameid);
WFIFOB(s, 8) = 0; //identify;
WFIFOW(s, 9) = fitem->bl_x;
WFIFOW(s, 11) = fitem->bl_y;
@@ -2799,7 +2778,7 @@ int clif_skillcastcancel(dumb_ptr<block_list> bl)
nullpo_ret(bl);
WBUFW(buf, 0) = 0x1b9;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
clif_send(buf, clif_parse_func_table[0x1b9].len, bl, SendWho::AREA);
return 0;
@@ -2850,8 +2829,8 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
WBUFW(buf, 0) = 0x1de;
WBUFW(buf, 2) = static_cast<uint16_t>(skill_id);
- WBUFL(buf, 4) = src->bl_id;
- WBUFL(buf, 8) = dst->bl_id;
+ WBUFL(buf, 4) = unwrap<BlockId>(src->bl_id);
+ WBUFL(buf, 8) = unwrap<BlockId>(dst->bl_id);
WBUFL(buf, 12) = static_cast<uint32_t>(tick.time_since_epoch().count());
WBUFL(buf, 16) = static_cast<uint32_t>(sdelay.count());
WBUFL(buf, 20) = static_cast<uint32_t>(ddelay.count());
@@ -2876,7 +2855,7 @@ int clif_status_change(dumb_ptr<block_list> bl, StatusChange type, int flag)
WBUFW(buf, 0) = 0x0196;
WBUFW(buf, 2) = static_cast<uint16_t>(type);
- WBUFL(buf, 4) = bl->bl_id;
+ WBUFL(buf, 4) = unwrap<BlockId>(bl->bl_id);
WBUFB(buf, 8) = flag;
clif_send(buf, clif_parse_func_table[0x196].len, bl, SendWho::AREA);
return 0;
@@ -2930,7 +2909,7 @@ void clif_resurrection(dumb_ptr<block_list> bl, int type)
nullpo_retv(bl);
WBUFW(buf, 0) = 0x148;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFW(buf, 6) = type;
clif_send(buf, clif_parse_func_table[0x148].len, bl,
@@ -3002,11 +2981,11 @@ int clif_party_info(struct party *p, Session *s)
for (i = c = 0; i < MAX_PARTY; i++)
{
struct party_member *m = &p->member[i];
- if (m->account_id > 0)
+ if (m->account_id)
{
if (sd == NULL)
sd = dumb_ptr<map_session_data>(m->sd);
- WBUFL(buf, 28 + c * 46) = m->account_id;
+ WBUFL(buf, 28 + c * 46) = unwrap<AccountId>(m->account_id);
WBUF_STRING(buf, 28 + c * 46 + 4, m->name.to__actual(), 24);
WBUF_STRING(buf, 28 + c * 46 + 28, m->map, 16);
WBUFB(buf, 28 + c * 46 + 44) = (m->leader) ? 0 : 1;
@@ -3050,7 +3029,7 @@ void clif_party_invite(dumb_ptr<map_session_data> sd,
return;
WFIFOW(s, 0) = 0xfe;
- WFIFOL(s, 2) = sd->status_key.account_id;
+ WFIFOL(s, 2) = unwrap<AccountId>(sd->status_key.account_id);
WFIFO_STRING(s, 6, p->name, 24);
WFIFOSET(s, clif_parse_func_table[0xfe].len);
}
@@ -3097,7 +3076,7 @@ void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag)
{
int i;
for (i = 0; i < MAX_PARTY; i++)
- if ((sd = map_id2sd(p->member[i].account_id)) != NULL)
+ if ((sd = map_id2sd(account_to_block(p->member[i].account_id))) != NULL)
break;
}
if (sd == NULL)
@@ -3119,7 +3098,7 @@ void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag)
*------------------------------------------
*/
void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd,
- int account_id, CharName name, int flag)
+ AccountId account_id, CharName name, int flag)
{
unsigned char buf[64];
int i;
@@ -3127,7 +3106,7 @@ void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd,
nullpo_retv(p);
WBUFW(buf, 0) = 0x105;
- WBUFL(buf, 2) = account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(account_id);
WBUF_STRING(buf, 6, name.to__actual(), 24);
WBUFB(buf, 30) = flag & 0x0f;
@@ -3154,7 +3133,7 @@ void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd,
* パーティメッセージ送信
*------------------------------------------
*/
-void clif_party_message(struct party *p, int account_id, XString mes)
+void clif_party_message(struct party *p, AccountId account_id, XString mes)
{
// always set, but clang is not smart enough
dumb_ptr<map_session_data> sd = nullptr;
@@ -3174,7 +3153,7 @@ void clif_party_message(struct party *p, int account_id, XString mes)
unsigned char buf[len + 8];
WBUFW(buf, 0) = 0x109;
WBUFW(buf, 2) = len + 8;
- WBUFL(buf, 4) = account_id;
+ WBUFL(buf, 4) = unwrap<AccountId>(account_id);
WBUF_STRING(buf, 8, mes, len);
clif_send(buf, len + 8, sd, SendWho::PARTY);
}
@@ -3191,7 +3170,7 @@ int clif_party_xy(struct party *, dumb_ptr<map_session_data> sd)
nullpo_ret(sd);
WBUFW(buf, 0) = 0x107;
- WBUFL(buf, 2) = sd->status_key.account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(sd->status_key.account_id);
WBUFW(buf, 6) = sd->bl_x;
WBUFW(buf, 8) = sd->bl_y;
clif_send(buf, clif_parse_func_table[0x107].len, sd, SendWho::PARTY_SAMEMAP_WOS);
@@ -3209,7 +3188,7 @@ int clif_party_hp(struct party *, dumb_ptr<map_session_data> sd)
nullpo_ret(sd);
WBUFW(buf, 0) = 0x106;
- WBUFL(buf, 2) = sd->status_key.account_id;
+ WBUFL(buf, 2) = unwrap<AccountId>(sd->status_key.account_id);
WBUFW(buf, 6) = (sd->status.hp > 0x7fff) ? 0x7fff : sd->status.hp;
WBUFW(buf, 8) =
(sd->status.max_hp > 0x7fff) ? 0x7fff : sd->status.max_hp;
@@ -3228,7 +3207,7 @@ int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl)
Session *s = sd->sess;
WFIFOW(s, 0) = 0x139;
- WFIFOL(s, 2) = bl->bl_id;
+ WFIFOL(s, 2) = unwrap<BlockId>(bl->bl_id);
WFIFOW(s, 6) = bl->bl_x;
WFIFOW(s, 8) = bl->bl_y;
WFIFOW(s, 10) = sd->bl_x;
@@ -3249,7 +3228,7 @@ int clif_mvp_effect(dumb_ptr<map_session_data> sd)
nullpo_ret(sd);
WBUFW(buf, 0) = 0x10c;
- WBUFL(buf, 2) = sd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(sd->bl_id);
clif_send(buf, clif_parse_func_table[0x10c].len, sd, SendWho::AREA);
return 0;
}
@@ -3265,7 +3244,7 @@ void clif_emotion(dumb_ptr<block_list> bl, int type)
nullpo_retv(bl);
WBUFW(buf, 0) = 0xc0;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFB(buf, 6) = type;
clif_send(buf, clif_parse_func_table[0xc0].len, bl, SendWho::AREA);
}
@@ -3285,7 +3264,7 @@ void clif_emotion_towards(dumb_ptr<block_list> bl,
return;
WBUFW(buf, 0) = 0xc0;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFB(buf, 6) = type;
WFIFO_BUF_CLONE(sd->sess, buf, len);
@@ -3303,7 +3282,7 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = sd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(sd->bl_id);
WBUFB(buf, 26) = 2;
clif_send(buf, clif_parse_func_table[0x8a].len, sd, SendWho::AREA);
}
@@ -3313,13 +3292,13 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-int clif_GM_kickack(dumb_ptr<map_session_data> sd, int id)
+int clif_GM_kickack(dumb_ptr<map_session_data> sd, AccountId id)
{
nullpo_ret(sd);
Session *s = sd->sess;
WFIFOW(s, 0) = 0xcd;
- WFIFOL(s, 2) = id;
+ WFIFOL(s, 2) = unwrap<AccountId>(id);
WFIFOSET(s, clif_parse_func_table[0xcd].len);
return 0;
}
@@ -3351,7 +3330,7 @@ int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag)
WBUF_ZERO(buf, 0, clif_parse_func_table[0x19b].len);
WBUFW(buf, 0) = 0x19b;
- WBUFL(buf, 2) = bl->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(bl->bl_id);
WBUFL(buf, 6) = type;
if (flag == 2)
@@ -3386,7 +3365,7 @@ int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag)
static
void clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd)
{
- int account_id; // account_id in the packet
+ AccountId account_id; // account_id in the packet
if (sd)
{
@@ -3397,16 +3376,16 @@ void clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd)
if (RFIFOW(s, 0) == 0x72)
{
- account_id = RFIFOL(s, 2);
+ account_id = wrap<AccountId>(RFIFOL(s, 2));
}
else
return; // Not the auth packet
- WFIFOL(s, 0) = account_id;
+ WFIFOL(s, 0) = unwrap<AccountId>(account_id);
WFIFOSET(s, 4);
// if same account already connected, we disconnect the 2 sessions
- dumb_ptr<map_session_data> old_sd = map_id2sd(account_id);
+ dumb_ptr<map_session_data> old_sd = map_id2sd(account_to_block(account_id));
if (old_sd)
{
clif_authfail_fd(s, 2); // same id
@@ -3420,7 +3399,7 @@ void clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd)
s->session_data.reset(sd.operator->());
sd->sess = s;
- pc_setnewpc(sd, account_id, RFIFOL(s, 6), RFIFOL(s, 10),
+ pc_setnewpc(sd, account_id, wrap<CharId>(RFIFOL(s, 6)), RFIFOL(s, 10),
tick_t(static_cast<interval_t>(RFIFOL(s, 14))),
static_cast<SEX>(RFIFOB(s, 18)));
@@ -3558,7 +3537,7 @@ void clif_parse_WalkToXY(Session *s, dumb_ptr<map_session_data> sd)
return;
}
- if (sd->npc_id != 0 || sd->state.storage_open)
+ if (sd->npc_id || sd->state.storage_open)
return;
if (sd->canmove_tick > gettick())
@@ -3621,15 +3600,15 @@ static
void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
{
dumb_ptr<block_list> bl;
- int account_id;
+ BlockId account_id;
- account_id = RFIFOL(s, 2);
+ account_id = wrap<BlockId>(RFIFOL(s, 2));
bl = map_id2bl(account_id);
if (bl == NULL)
return;
WFIFOW(s, 0) = 0x95;
- WFIFOL(s, 2) = account_id;
+ WFIFOL(s, 2) = unwrap<BlockId>(account_id);
switch (bl->bl_type)
{
@@ -3651,7 +3630,7 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
int send = 0;
- if (ssd->status.party_id > 0 && (p = party_search(ssd->status.party_id)) != NULL)
+ if (ssd->status.party_id && (p = party_search(ssd->status.party_id)) != NULL)
{
party_name = p->name;
send = 1;
@@ -3660,7 +3639,7 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
if (send)
{
WFIFOW(s, 0) = 0x195;
- WFIFOL(s, 2) = account_id;
+ WFIFOL(s, 2) = unwrap<BlockId>(account_id);
WFIFO_STRING(s, 6, party_name, 24);
WFIFO_STRING(s, 30, ""_s, 24);
WFIFO_STRING(s, 54, ""_s, 24);
@@ -3669,7 +3648,7 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
}
- if (pc_isGM(sd) >= battle_config.hack_info_GM_level)
+ if (pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.hack_info_GM_level))))
{
IP4Address ip = ssd->get_ip();
WFIFOW(s, 0) = 0x20C;
@@ -3678,7 +3657,7 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
if (battle_config.mask_ip_gms)
ip = MD5_ip(ip);
- WFIFOL(s, 2) = account_id;
+ WFIFOL(s, 2) = unwrap<BlockId>(account_id);
WFIFOIP(s, 6) = ip;
WFIFOSET(s, clif_parse_func_table[0x20C].len);
}
@@ -3731,7 +3710,7 @@ void clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd)
return;
}
- if (is_atcommand(s, sd, mbuf, 0))
+ if (is_atcommand(s, sd, mbuf, GmLevel()))
return;
if (!magic_message(sd, mbuf))
@@ -3748,7 +3727,7 @@ void clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd)
uint8_t sendbuf[mbuf_size + 8];
WBUFW(sendbuf, 0) = 0x8d;
WBUFW(sendbuf, 2) = mbuf_size + 8; /* Header(2) + length(2) + ID(4). */
- WBUFL(sendbuf, 4) = sd->bl_id;
+ WBUFL(sendbuf, 4) = unwrap<BlockId>(sd->bl_id);
WBUF_STRING(sendbuf, 8, mbuf, mbuf_size);
clif_send(sendbuf, mbuf_size + 8, sd, SendWho::AREA_CHAT_WOC);
@@ -3773,7 +3752,7 @@ void clif_message(dumb_ptr<block_list> bl, XString msg)
WBUFW(buf, 0) = 0x8d;
WBUFW(buf, 2) = msg_len + 8;
- WBUFL(buf, 4) = bl->bl_id;
+ WBUFL(buf, 4) = unwrap<BlockId>(bl->bl_id);
WBUF_STRING(buf, 8, msg, msg_len);
clif_send(buf, WBUFW(buf, 2), bl, SendWho::AREA);
@@ -3815,7 +3794,7 @@ void clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd)
pc_setdir(sd, dir);
WBUFW(buf, 0) = 0x9c;
- WBUFL(buf, 2) = sd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(sd->bl_id);
WBUFW(buf, 6) = 0;
WBUFB(buf, 8) = client_dir;
@@ -3839,7 +3818,7 @@ void clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd)
{
uint8_t emote = RFIFOB(s, 2);
WBUFW(buf, 0) = 0xc0;
- WBUFL(buf, 2) = sd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(sd->bl_id);
WBUFB(buf, 6) = emote;
clif_send(buf, clif_parse_func_table[0xc0].len, sd, SendWho::AREA);
}
@@ -3867,7 +3846,8 @@ static
void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
{
unsigned char buf[64];
- int action_type, target_id;
+ int action_type;
+ BlockId target_id;
nullpo_retv(sd);
@@ -3876,7 +3856,7 @@ void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
clif_clearchar(sd, BeingRemoveWhy::DEAD);
return;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| bool(sd->opt1)
|| sd->state.storage_open)
return;
@@ -3886,7 +3866,7 @@ void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
pc_stop_walking(sd, 0);
pc_stopattack(sd);
- target_id = RFIFOL(s, 2);
+ target_id = wrap<BlockId>(RFIFOL(s, 2));
action_type = RFIFOB(s, 6);
switch (action_type)
@@ -3905,8 +3885,7 @@ void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
}
if (sd->invincible_timer)
pc_delinvincibletimer(sd);
- if (sd->attacktarget > 0) // [Valaris]
- sd->attacktarget = 0;
+ sd->attacktarget = BlockId();
pc_attack(sd, target_id, action_type != 0);
break;
case 0x02: // sitdown
@@ -3917,7 +3896,7 @@ void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
case 0x03: // standup
pc_setstand(sd);
WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = sd->bl_id;
+ WBUFL(buf, 2) = unwrap<BlockId>(sd->bl_id);
WBUFB(buf, 26) = 3;
clif_send(buf, clif_parse_func_table[0x8a].len, sd, SendWho::AREA);
break;
@@ -3996,7 +3975,7 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd)
return;
}
- if (is_atcommand(s, sd, mbuf, 0))
+ if (is_atcommand(s, sd, mbuf, GmLevel()))
{
return;
}
@@ -4048,11 +4027,10 @@ static
void clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd)
{
dumb_ptr<flooritem_data> fitem;
- int map_object_id;
nullpo_retv(sd);
- map_object_id = RFIFOL(s, 2);
+ BlockId map_object_id = wrap<BlockId>(RFIFOL(s, 2));
fitem = map_id_is_item(map_object_id);
if (pc_isdead(sd))
@@ -4061,7 +4039,7 @@ void clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd)
return;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO) //会話禁止
return;
@@ -4099,7 +4077,7 @@ void clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd)
clif_displaymessage(sd->sess, "Can't drop items here."_s);
return;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO)
{
clif_displaymessage(sd->sess, "Can't drop items right now."_s);
@@ -4126,7 +4104,7 @@ void clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd)
clif_clearchar(sd, BeingRemoveWhy::DEAD);
return;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO) //会話禁止
return;
@@ -4153,7 +4131,7 @@ void clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd)
return;
}
index = RFIFOW(s, 2) - 2;
- if (sd->npc_id != 0)
+ if (sd->npc_id)
return;
if (sd->inventory_data[index])
@@ -4185,7 +4163,7 @@ void clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd)
}
index = RFIFOW(s, 2) - 2;
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO)
return;
pc_unequipitem(sd, index, CalcStatus::NOW);
@@ -4205,9 +4183,9 @@ void clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd)
clif_clearchar(sd, BeingRemoveWhy::DEAD);
return;
}
- if (sd->npc_id != 0)
+ if (sd->npc_id)
return;
- npc_click(sd, RFIFOL(s, 2));
+ npc_click(sd, wrap<BlockId>(RFIFOL(s, 2)));
}
/*==========================================
@@ -4217,7 +4195,7 @@ void clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd)
static
void clif_parse_NpcBuySellSelected(Session *s, dumb_ptr<map_session_data> sd)
{
- npc_buysellsel(sd, RFIFOL(s, 2), RFIFOB(s, 6));
+ npc_buysellsel(sd, wrap<BlockId>(RFIFOL(s, 2)), RFIFOB(s, 6));
}
/*==========================================
@@ -4268,7 +4246,7 @@ void clif_parse_TradeRequest(Session *, dumb_ptr<map_session_data> sd)
if (battle_config.basic_skill_check == 0
|| pc_checkskill(sd, SkillID::NV_TRADE) >= 1)
{
- trade_traderequest(sd, RFIFOL(sd->sess, 2));
+ trade_traderequest(sd, wrap<BlockId>(RFIFOL(sd->sess, 2)));
}
else
clif_skill_fail(sd, SkillID::ONE, 0, 0);
@@ -4368,7 +4346,7 @@ void clif_parse_NpcSelectMenu(Session *s, dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
sd->npc_menu = RFIFOB(s, 6);
- map_scriptcont(sd, RFIFOL(s, 2));
+ map_scriptcont(sd, wrap<BlockId>(RFIFOL(s, 2)));
}
/*==========================================
@@ -4378,7 +4356,7 @@ void clif_parse_NpcSelectMenu(Session *s, dumb_ptr<map_session_data> sd)
static
void clif_parse_NpcNextClicked(Session *s, dumb_ptr<map_session_data> sd)
{
- map_scriptcont(sd, RFIFOL(s, 2));
+ map_scriptcont(sd, wrap<BlockId>(RFIFOL(s, 2)));
}
/*==========================================
@@ -4391,7 +4369,7 @@ void clif_parse_NpcAmountInput(Session *s, dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
sd->npc_amount = RFIFOL(s, 6);
- map_scriptcont(sd, RFIFOL(s, 2));
+ map_scriptcont(sd, wrap<BlockId>(RFIFOL(s, 2)));
}
/*==========================================
@@ -4416,7 +4394,7 @@ void clif_parse_NpcStringInput(Session *s, dumb_ptr<map_session_data> sd)
return;
sd->npc_str = RFIFO_STRING(s, 8, len);
- map_scriptcont(sd, RFIFOL(s, 4));
+ map_scriptcont(sd, wrap<BlockId>(RFIFOL(s, 4)));
}
/*==========================================
@@ -4426,7 +4404,7 @@ void clif_parse_NpcStringInput(Session *s, dumb_ptr<map_session_data> sd)
static
void clif_parse_NpcCloseClicked(Session *s, dumb_ptr<map_session_data> sd)
{
- map_scriptcont(sd, RFIFOL(s, 2));
+ map_scriptcont(sd, wrap<BlockId>(RFIFOL(s, 2)));
}
/*==========================================
@@ -4443,7 +4421,7 @@ void clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd)
item_index = RFIFOW(s, 2) - 2;
item_amount = RFIFOL(s, 4);
- if ((sd->npc_id != 0 && !sd->npc_flags.storage) || sd->trade_partner != 0
+ if ((sd->npc_id && !sd->npc_flags.storage) || sd->trade_partner
|| !sd->state.storage_open)
return;
@@ -4465,7 +4443,7 @@ void clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd)
item_index = RFIFOW(s, 2) - 1;
item_amount = RFIFOL(s, 4);
- if ((sd->npc_id != 0 && !sd->npc_flags.storage) || sd->trade_partner != 0
+ if ((sd->npc_id && !sd->npc_flags.storage) || sd->trade_partner
|| !sd->state.storage_open)
return;
@@ -4516,7 +4494,7 @@ void clif_parse_CreateParty(Session *s, dumb_ptr<map_session_data> sd)
static
void clif_parse_PartyInvite(Session *s, dumb_ptr<map_session_data> sd)
{
- party_invite(sd, RFIFOL(s, 2));
+ party_invite(sd, wrap<AccountId>(RFIFOL(s, 2)));
}
/*==========================================
@@ -4532,11 +4510,11 @@ void clif_parse_ReplyPartyInvite(Session *s, dumb_ptr<map_session_data> sd)
if (battle_config.basic_skill_check == 0
|| pc_checkskill(sd, SkillID::NV_PARTY) >= 1)
{
- party_reply_invite(sd, RFIFOL(s, 2), RFIFOL(s, 6));
+ party_reply_invite(sd, wrap<AccountId>(RFIFOL(s, 2)), RFIFOL(s, 6));
}
else
{
- party_reply_invite(sd, RFIFOL(s, 2), 0);
+ party_reply_invite(sd, wrap<AccountId>(RFIFOL(s, 2)), 0);
clif_skill_fail(sd, SkillID::ONE, 0, 4);
}
}
@@ -4558,7 +4536,7 @@ void clif_parse_LeaveParty(Session *, dumb_ptr<map_session_data> sd)
static
void clif_parse_RemovePartyMember(Session *s, dumb_ptr<map_session_data> sd)
{
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
// unused RFIFO_STRING<24>(fd, 6);
party_removemember(sd, account_id);
}
@@ -4593,7 +4571,7 @@ void clif_parse_PartyMessage(Session *s, dumb_ptr<map_session_data> sd)
return;
}
- if (is_atcommand(s, sd, mbuf, 0))
+ if (is_atcommand(s, sd, mbuf, GmLevel()))
return;
/* Don't send chat that results in an automatic ban. */
diff --git a/src/map/clif.hpp b/src/map/clif.hpp
index 1fdd67c..cb84ee9 100644
--- a/src/map/clif.hpp
+++ b/src/map/clif.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "clif.t.hpp"
@@ -47,16 +47,16 @@ void clif_setwaitclose(Session *);
int clif_authok(dumb_ptr<map_session_data>);
int clif_authfail_fd(Session *, int);
-int clif_charselectok(int);
+int clif_charselectok(BlockId);
int clif_dropflooritem(dumb_ptr<flooritem_data>);
int clif_clearflooritem(dumb_ptr<flooritem_data>, Session *);
int clif_clearchar(dumb_ptr<block_list>, BeingRemoveWhy); // area or fd
int clif_clearchar_delay(tick_t, dumb_ptr<block_list>, BeingRemoveWhy);
-void clif_clearchar_id(int, BeingRemoveWhy, Session *);
+void clif_clearchar_id(BlockId, BeingRemoveWhy, Session *);
int clif_spawnpc(dumb_ptr<map_session_data>); //area
int clif_spawnnpc(dumb_ptr<npc_data>); // area
int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd,
- int fake_npc_id);
+ BlockId fake_npc_id);
int clif_spawnmob(dumb_ptr<mob_data>); // area
int clif_walkok(dumb_ptr<map_session_data>); // self
int clif_movechar(dumb_ptr<map_session_data>); // area
@@ -66,16 +66,16 @@ void clif_changemapserver(dumb_ptr<map_session_data>, MapName, int, int, IP4Addr
void clif_fixpos(dumb_ptr<block_list>); // area
int clif_fixmobpos(dumb_ptr<mob_data> md);
int clif_fixpcpos(dumb_ptr<map_session_data> sd);
-int clif_npcbuysell(dumb_ptr<map_session_data>, int); //self
+int clif_npcbuysell(dumb_ptr<map_session_data>, BlockId); //self
int clif_buylist(dumb_ptr<map_session_data>, dumb_ptr<npc_data_shop>); //self
int clif_selllist(dumb_ptr<map_session_data>); //self
-void clif_scriptmes(dumb_ptr<map_session_data>, int, XString); //self
-void clif_scriptnext(dumb_ptr<map_session_data>, int); //self
-void clif_scriptclose(dumb_ptr<map_session_data>, int); //self
-void clif_scriptmenu(dumb_ptr<map_session_data>, int, XString); //self
-void clif_scriptinput(dumb_ptr<map_session_data>, int); //self
-void clif_scriptinputstr(dumb_ptr<map_session_data> sd, int npcid); // self
-void clif_viewpoint(dumb_ptr<map_session_data>, int, int, int, int, int, int); //self
+void clif_scriptmes(dumb_ptr<map_session_data>, BlockId, XString); //self
+void clif_scriptnext(dumb_ptr<map_session_data>, BlockId); //self
+void clif_scriptclose(dumb_ptr<map_session_data>, BlockId); //self
+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_updatestatus(dumb_ptr<map_session_data>, SP); //self
@@ -164,8 +164,8 @@ void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag
void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd,
int flag);
void clif_party_leaved(struct party *p, dumb_ptr<map_session_data> sd,
- int account_id, CharName name, int flag);
-void clif_party_message(struct party *p, int account_id, XString mes);
+ AccountId account_id, CharName name, int flag);
+void clif_party_message(struct party *p, AccountId account_id, XString mes);
int clif_party_xy(struct party *p, dumb_ptr<map_session_data> sd);
int clif_party_hp(struct party *p, dumb_ptr<map_session_data> sd);
diff --git a/src/map/fwd.hpp b/src/map/fwd.hpp
new file mode 100644
index 0000000..9801f5c
--- /dev/null
+++ b/src/map/fwd.hpp
@@ -0,0 +1,27 @@
+#ifndef TMWA_MAP_FWD_HPP
+#define TMWA_MAP_FWD_HPP
+// map/fwd.hpp - list of type names for map server
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+struct map_session_data;
+
+#endif // TMWA_MAP_FWD_HPP
diff --git a/src/map/intif.cpp b/src/map/intif.cpp
index 3395974..52ea8b0 100644
--- a/src/map/intif.cpp
+++ b/src/map/intif.cpp
@@ -103,13 +103,13 @@ void intif_wis_replay(int id, int flag)
}
// The transmission of GM only Wisp/Page from server to inter-server
-void intif_wis_message_to_gm(CharName Wisp_name, int min_gm_level, ZString mes)
+void intif_wis_message_to_gm(CharName Wisp_name, GmLevel min_gm_level, ZString mes)
{
size_t mes_len = mes.size() + 1;
WFIFOW(char_session, 0) = 0x3003;
WFIFOW(char_session, 2) = mes_len + 30;
WFIFO_STRING(char_session, 4, Wisp_name.to__actual(), 24);
- WFIFOW(char_session, 28) = min_gm_level;
+ WFIFOW(char_session, 28) = static_cast<uint16_t>(min_gm_level.get_all_bits());
WFIFO_STRING(char_session, 30, mes, mes_len);
WFIFOSET(char_session, WFIFOW(char_session, 2));
@@ -127,7 +127,7 @@ void intif_saveaccountreg(dumb_ptr<map_session_data> sd)
assert (sd->status.account_reg_num < ACCOUNT_REG_NUM);
WFIFOW(char_session, 0) = 0x3004;
- WFIFOL(char_session, 4) = sd->bl_id;
+ WFIFOL(char_session, 4) = unwrap<BlockId>(sd->bl_id);
for (j = 0, p = 8; j < sd->status.account_reg_num; j++, p += 36)
{
WFIFO_STRING(char_session, p, sd->status.account_reg[j].str, 32);
@@ -143,15 +143,15 @@ void intif_request_accountreg(dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
WFIFOW(char_session, 0) = 0x3005;
- WFIFOL(char_session, 2) = sd->bl_id;
+ WFIFOL(char_session, 2) = unwrap<BlockId>(sd->bl_id);
WFIFOSET(char_session, 6);
}
// 倉庫データ要求
-void intif_request_storage(int account_id)
+void intif_request_storage(AccountId account_id)
{
WFIFOW(char_session, 0) = 0x3010;
- WFIFOL(char_session, 2) = account_id;
+ WFIFOL(char_session, 2) = unwrap<AccountId>(account_id);
WFIFOSET(char_session, 6);
}
@@ -161,7 +161,7 @@ void intif_send_storage(struct storage *stor)
nullpo_retv(stor);
WFIFOW(char_session, 0) = 0x3011;
WFIFOW(char_session, 2) = sizeof(struct storage) + 8;
- WFIFOL(char_session, 4) = stor->account_id;
+ WFIFOL(char_session, 4) = unwrap<AccountId>(stor->account_id);
WFIFO_STRUCT(char_session, 8, *stor);
WFIFOSET(char_session, WFIFOW(char_session, 2));
}
@@ -172,7 +172,7 @@ void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name)
nullpo_retv(sd);
WFIFOW(char_session, 0) = 0x3020;
- WFIFOL(char_session, 2) = sd->status_key.account_id;
+ WFIFOL(char_session, 2) = unwrap<AccountId>(sd->status_key.account_id);
WFIFO_STRING(char_session, 6, name, 24);
WFIFO_STRING(char_session, 30, sd->status_key.name.to__actual(), 24);
WFIFO_STRING(char_session, 54, sd->bl_m->name_, 16);
@@ -181,23 +181,23 @@ void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name)
}
// パーティ情報要求
-void intif_request_partyinfo(int party_id)
+void intif_request_partyinfo(PartyId party_id)
{
WFIFOW(char_session, 0) = 0x3021;
- WFIFOL(char_session, 2) = party_id;
+ WFIFOL(char_session, 2) = unwrap<PartyId>(party_id);
WFIFOSET(char_session, 6);
}
// パーティ追加要求
-void intif_party_addmember(int party_id, int account_id)
+void intif_party_addmember(PartyId party_id, AccountId account_id)
{
dumb_ptr<map_session_data> sd;
- sd = map_id2sd(account_id);
+ sd = map_id2sd(account_to_block(account_id));
if (sd != NULL)
{
WFIFOW(char_session, 0) = 0x3022;
- WFIFOL(char_session, 2) = party_id;
- WFIFOL(char_session, 6) = account_id;
+ WFIFOL(char_session, 2) = unwrap<PartyId>(party_id);
+ WFIFOL(char_session, 6) = unwrap<AccountId>(account_id);
WFIFO_STRING(char_session, 10, sd->status_key.name.to__actual(), 24);
WFIFO_STRING(char_session, 34, sd->bl_m->name_, 16);
WFIFOW(char_session, 50) = sd->status.base_level;
@@ -206,22 +206,22 @@ void intif_party_addmember(int party_id, int account_id)
}
// パーティ設定変更
-void intif_party_changeoption(int party_id, int account_id, int exp, int item)
+void intif_party_changeoption(PartyId party_id, AccountId account_id, int exp, int item)
{
WFIFOW(char_session, 0) = 0x3023;
- WFIFOL(char_session, 2) = party_id;
- WFIFOL(char_session, 6) = account_id;
+ WFIFOL(char_session, 2) = unwrap<PartyId>(party_id);
+ WFIFOL(char_session, 6) = unwrap<AccountId>(account_id);
WFIFOW(char_session, 10) = exp;
WFIFOW(char_session, 12) = item;
WFIFOSET(char_session, 14);
}
// パーティ脱退要求
-void intif_party_leave(int party_id, int account_id)
+void intif_party_leave(PartyId party_id, AccountId account_id)
{
WFIFOW(char_session, 0) = 0x3024;
- WFIFOL(char_session, 2) = party_id;
- WFIFOL(char_session, 6) = account_id;
+ WFIFOL(char_session, 2) = unwrap<PartyId>(party_id);
+ WFIFOL(char_session, 6) = unwrap<AccountId>(account_id);
WFIFOSET(char_session, 10);
}
@@ -231,8 +231,8 @@ void intif_party_changemap(dumb_ptr<map_session_data> sd, int online)
if (sd != NULL)
{
WFIFOW(char_session, 0) = 0x3025;
- WFIFOL(char_session, 2) = sd->status.party_id;
- WFIFOL(char_session, 6) = sd->status_key.account_id;
+ WFIFOL(char_session, 2) = unwrap<PartyId>(sd->status.party_id);
+ WFIFOL(char_session, 6) = unwrap<AccountId>(sd->status_key.account_id);
WFIFO_STRING(char_session, 10, sd->bl_m->name_, 16);
WFIFOB(char_session, 26) = online;
WFIFOW(char_session, 27) = sd->status.base_level;
@@ -241,23 +241,23 @@ void intif_party_changemap(dumb_ptr<map_session_data> sd, int online)
}
// パーティ会話送信
-void intif_party_message(int party_id, int account_id, XString mes)
+void intif_party_message(PartyId party_id, AccountId account_id, XString mes)
{
size_t len = mes.size() + 1;
WFIFOW(char_session, 0) = 0x3027;
WFIFOW(char_session, 2) = len + 12;
- WFIFOL(char_session, 4) = party_id;
- WFIFOL(char_session, 8) = account_id;
+ WFIFOL(char_session, 4) = unwrap<PartyId>(party_id);
+ WFIFOL(char_session, 8) = unwrap<AccountId>(account_id);
WFIFO_STRING(char_session, 12, mes, len);
WFIFOSET(char_session, len + 12);
}
// パーティ競合チェック要求
-void intif_party_checkconflict(int party_id, int account_id, CharName nick)
+void intif_party_checkconflict(PartyId party_id, AccountId account_id, CharName nick)
{
WFIFOW(char_session, 0) = 0x3028;
- WFIFOL(char_session, 2) = party_id;
- WFIFOL(char_session, 6) = account_id;
+ WFIFOL(char_session, 2) = unwrap<PartyId>(party_id);
+ WFIFOL(char_session, 6) = unwrap<AccountId>(account_id);
WFIFO_STRING(char_session, 10, nick.to__actual(), 24);
WFIFOSET(char_session, 34);
}
@@ -326,14 +326,12 @@ static
void mapif_parse_WisToGM(Session *s)
{
// 0x3003/0x3803 <packet_len>.w <wispname>.24B <min_gm_level>.w <message>.?B
- int min_gm_level, len;
-
if (RFIFOW(s, 2) - 30 <= 0)
return;
- len = RFIFOW(s, 2) - 30;
+ int len = RFIFOW(s, 2) - 30;
- min_gm_level = RFIFOW(s, 28);
+ GmLevel min_gm_level = GmLevel::from(static_cast<uint32_t>(RFIFOW(s, 28)));
CharName Wisp_name = stringish<CharName>(RFIFO_STRING<24>(s, 4));
AString message = RFIFO_STRING(s, 30, len);
// information is sended to all online GM
@@ -345,7 +343,7 @@ void mapif_parse_WisToGM(Session *s)
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
if (pl_sd && pl_sd->state.auth)
{
- if (pc_isGM(pl_sd) >= min_gm_level)
+ if (pc_isGM(pl_sd).satisfies(min_gm_level))
clif_wis_message(s2, Wisp_name, message);
}
}
@@ -356,7 +354,7 @@ static
int intif_parse_AccountReg(Session *s)
{
int j, p;
- dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 4));
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(wrap<AccountId>(RFIFOL(s, 4))));
if (sd == NULL)
return 1;
for (p = 8, j = 0; p < RFIFOW(s, 2) && j < ACCOUNT_REG_NUM;
@@ -377,7 +375,7 @@ int intif_parse_LoadStorage(Session *s)
struct storage *stor;
dumb_ptr<map_session_data> sd;
- sd = map_id2sd(RFIFOL(s, 4));
+ sd = map_id2sd(account_to_block(wrap<AccountId>(RFIFOL(s, 4))));
if (sd == NULL)
{
if (battle_config.error_log)
@@ -385,7 +383,7 @@ int intif_parse_LoadStorage(Session *s)
RFIFOL(s, 4));
return 1;
}
- stor = account2storage(RFIFOL(s, 4));
+ stor = account2storage(wrap<AccountId>(RFIFOL(s, 4)));
if (stor->storage_status == 1)
{ // Already open.. lets ignore this update
if (battle_config.error_log)
@@ -428,7 +426,7 @@ void intif_parse_SaveStorage(Session *s)
if (battle_config.save_log)
PRINTF("intif_savestorage: done %d %d\n"_fmt, RFIFOL(s, 2),
RFIFOB(s, 6));
- storage_storage_saved(RFIFOL(s, 2));
+ storage_storage_saved(wrap<AccountId>(RFIFOL(s, 2)));
}
// パーティ作成可否
@@ -437,9 +435,9 @@ void intif_parse_PartyCreated(Session *s)
{
if (battle_config.etc_log)
PRINTF("intif: party created\n"_fmt);
- int account_id = RFIFOL(s, 2);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 2));
int fail = RFIFOB(s, 6);
- int party_id = RFIFOL(s, 7);
+ PartyId party_id = wrap<PartyId>(RFIFOL(s, 7));
PartyName name = stringish<PartyName>(RFIFO_STRING<24>(s, 11));
party_created(account_id, fail, party_id, name);
}
@@ -452,7 +450,7 @@ void intif_parse_PartyInfo(Session *s)
{
if (battle_config.error_log)
PRINTF("intif: party noinfo %d\n"_fmt, RFIFOL(s, 4));
- party_recv_noinfo(RFIFOL(s, 4));
+ party_recv_noinfo(wrap<PartyId>(RFIFOL(s, 4)));
return;
}
@@ -475,14 +473,14 @@ void intif_parse_PartyMemberAdded(Session *s)
if (battle_config.etc_log)
PRINTF("intif: party member added %d %d %d\n"_fmt, RFIFOL(s, 2),
RFIFOL(s, 6), RFIFOB(s, 10));
- party_member_added(RFIFOL(s, 2), RFIFOL(s, 6), RFIFOB(s, 10));
+ party_member_added(wrap<PartyId>(RFIFOL(s, 2)), wrap<AccountId>(RFIFOL(s, 6)), RFIFOB(s, 10));
}
// パーティ設定変更通知
static
void intif_parse_PartyOptionChanged(Session *s)
{
- party_optionchanged(RFIFOL(s, 2), RFIFOL(s, 6), RFIFOW(s, 10),
+ party_optionchanged(wrap<PartyId>(RFIFOL(s, 2)), wrap<AccountId>(RFIFOL(s, 6)), RFIFOW(s, 10),
RFIFOW(s, 12), RFIFOB(s, 14));
}
@@ -490,8 +488,8 @@ void intif_parse_PartyOptionChanged(Session *s)
static
void intif_parse_PartyMemberLeaved(Session *s)
{
- int party_id = RFIFOL(s, 2);
- int account_id = RFIFOL(s, 6);
+ PartyId party_id = wrap<PartyId>(RFIFOL(s, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 6));
CharName name = stringish<CharName>(RFIFO_STRING<24>(s, 10));
if (battle_config.etc_log)
PRINTF("intif: party member leaved %d %d %s\n"_fmt,
@@ -503,15 +501,15 @@ void intif_parse_PartyMemberLeaved(Session *s)
static
void intif_parse_PartyBroken(Session *s)
{
- party_broken(RFIFOL(s, 2));
+ party_broken(wrap<PartyId>(RFIFOL(s, 2)));
}
// パーティ移動通知
static
void intif_parse_PartyMove(Session *s)
{
- int party_id = RFIFOL(s, 2);
- int account_id = RFIFOL(s, 6);
+ PartyId party_id = wrap<PartyId>(RFIFOL(s, 2));
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, 6));
MapName map = stringish<MapName>(RFIFO_STRING<16>(s, 10));
uint8_t online = RFIFOB(s, 26);
uint16_t lv = RFIFOW(s, 27);
@@ -524,7 +522,7 @@ void intif_parse_PartyMessage(Session *s)
{
size_t len = RFIFOW(s, 2) - 12;
AString buf = RFIFO_STRING(s, 12, len);
- party_recv_message(RFIFOL(s, 4), RFIFOL(s, 8), buf);
+ party_recv_message(wrap<PartyId>(RFIFOL(s, 4)), wrap<AccountId>(RFIFOL(s, 8)), buf);
}
//-----------------------------------------------------------------
diff --git a/src/map/intif.hpp b/src/map/intif.hpp
index 80de797..529c42e 100644
--- a/src/map/intif.hpp
+++ b/src/map/intif.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/fwd.hpp"
@@ -32,22 +32,22 @@ int intif_parse(Session *);
void intif_GMmessage(XString mes);
void intif_wis_message(dumb_ptr<map_session_data> sd, CharName nick, ZString mes);
-void intif_wis_message_to_gm(CharName Wisp_name, int min_gm_level, ZString mes);
+void intif_wis_message_to_gm(CharName Wisp_name, GmLevel min_gm_level, ZString mes);
void intif_saveaccountreg(dumb_ptr<map_session_data> sd);
void intif_request_accountreg(dumb_ptr<map_session_data> sd);
-void intif_request_storage(int account_id);
+void intif_request_storage(AccountId account_id);
void intif_send_storage(struct storage *stor);
void intif_create_party(dumb_ptr<map_session_data> sd, PartyName name);
-void intif_request_partyinfo(int party_id);
-void intif_party_addmember(int party_id, int account_id);
-void intif_party_changeoption(int party_id, int account_id, int exp,
+void intif_request_partyinfo(PartyId party_id);
+void intif_party_addmember(PartyId party_id, AccountId account_id);
+void intif_party_changeoption(PartyId party_id, AccountId account_id, int exp,
int item);
-void intif_party_leave(int party_id, int accound_id);
+void intif_party_leave(PartyId party_id, AccountId accound_id);
void intif_party_changemap(dumb_ptr<map_session_data> sd, int online);
-void intif_party_message(int party_id, int account_id, XString mes);
-void intif_party_checkconflict(int party_id, int account_id, CharName nick);
+void intif_party_message(PartyId party_id, AccountId account_id, XString mes);
+void intif_party_checkconflict(PartyId party_id, AccountId account_id, CharName nick);
#endif // TMWA_MAP_INTIF_HPP
diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp
index 2cc9e49..810c488 100644
--- a/src/map/itemdb.cpp
+++ b/src/map/itemdb.cpp
@@ -42,7 +42,7 @@
#include "../poison.hpp"
static
-Map<int, struct item_data> item_db;
+Map<ItemNameId, struct item_data> item_db;
// Function declarations
@@ -77,7 +77,7 @@ struct item_data *itemdb_searchname(XString str_)
* DBの存在確認
*------------------------------------------
*/
-struct item_data *itemdb_exists(int nameid)
+struct item_data *itemdb_exists(ItemNameId nameid)
{
return item_db.search(nameid);
}
@@ -86,7 +86,7 @@ struct item_data *itemdb_exists(int nameid)
* DBの検索
*------------------------------------------
*/
-struct item_data *itemdb_search(int nameid)
+struct item_data *itemdb_search(ItemNameId nameid)
{
struct item_data *id = item_db.search(nameid);
if (id)
@@ -101,22 +101,7 @@ struct item_data *itemdb_search(int nameid)
id->sex = SEX::NEUTRAL;
id->elv = 0;
- if (nameid > 500 && nameid < 600)
- id->type = ItemType::USE;
- else if (nameid > 600 && nameid < 700)
- id->type = ItemType::_2;
- else if ((nameid > 700 && nameid < 1100) ||
- (nameid > 7000 && nameid < 8000))
- id->type = ItemType::JUNK;
- else if (nameid >= 1750 && nameid < 1771)
- id->type = ItemType::ARROW;
- else if (nameid > 1100 && nameid < 2000)
- id->type = ItemType::WEAPON;
- else if ((nameid > 2100 && nameid < 3000) ||
- (nameid > 5000 && nameid < 6000))
- id->type = ItemType::ARMOR;
- else if (nameid > 4000 && nameid < 5000)
- id->type = ItemType::_6;
+ id->type = ItemType::JUNK;
return id;
}
@@ -125,7 +110,7 @@ struct item_data *itemdb_search(int nameid)
*
*------------------------------------------
*/
-int itemdb_isequip(int nameid)
+int itemdb_isequip(ItemNameId nameid)
{
ItemType type = itemdb_type(nameid);
return !(type == ItemType::USE
@@ -155,7 +140,7 @@ int itemdb_isequip2(struct item_data *data)
*
*------------------------------------------
*/
-int itemdb_isequip3(int nameid)
+int itemdb_isequip3(ItemNameId nameid)
{
ItemType type = itemdb_type(nameid);
return (type == ItemType::WEAPON
diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp
index 16802da..06a4af9 100644
--- a/src/map/itemdb.hpp
+++ b/src/map/itemdb.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../mmo/mmo.hpp"
@@ -30,7 +30,7 @@
struct item_data
{
- int nameid;
+ ItemNameId nameid;
ItemName name, jname;
int value_buy;
int value_sell;
@@ -58,43 +58,44 @@ struct random_item_data
inline
struct item_data *itemdb_searchname(ItemName) = delete;
struct item_data *itemdb_searchname(XString name);
-struct item_data *itemdb_search(int nameid);
-struct item_data *itemdb_exists(int nameid);
+// TODO this function should die
+struct item_data *itemdb_search(ItemNameId nameid);
+struct item_data *itemdb_exists(ItemNameId nameid);
inline
-ItemType itemdb_type(int n)
+ItemType itemdb_type(ItemNameId n)
{
return itemdb_search(n)->type;
}
inline
-ItemLook itemdb_look(int n)
+ItemLook itemdb_look(ItemNameId n)
{
return itemdb_search(n)->look;
}
inline
-int itemdb_weight(int n)
+int itemdb_weight(ItemNameId n)
{
return itemdb_search(n)->weight;
}
inline
-const ScriptBuffer *itemdb_equipscript(int n)
+const ScriptBuffer *itemdb_equipscript(ItemNameId n)
{
return itemdb_search(n)->equip_script.get();
}
inline
-int itemdb_wlv(int n)
+int itemdb_wlv(ItemNameId n)
{
return itemdb_search(n)->wlv;
}
inline
-int itemdb_value_sell(int n)
+int itemdb_value_sell(ItemNameId n)
{
return itemdb_search(n)->value_sell;
}
-int itemdb_isequip(int);
+int itemdb_isequip(ItemNameId);
int itemdb_isequip2(struct item_data *);
-int itemdb_isequip3(int);
+int itemdb_isequip3(ItemNameId);
void itemdb_reload(void);
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index b6f3208..6a411b7 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -190,7 +190,7 @@ void stringify(val_t *v, int within_op)
{
dumb_ptr<invocation> invocation_ = within_op
? v->v.v_invocation
- : map_id2bl(v->v.v_int)->is_spell();
+ : map_id2bl(wrap<BlockId>(static_cast<uint32_t>(v->v.v_int)))->is_spell();
buf = invocation_->spell->name;
}
break;
@@ -725,7 +725,7 @@ int fun_mob_id(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (ENTITY_TYPE(0) != BL::MOB)
return 1;
- RESULTINT = ARGMOB(0)->mob_class;
+ RESULTINT = unwrap<Species>(ARGMOB(0)->mob_class);
return 0;
}
@@ -783,7 +783,7 @@ int fun_random_dir(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
static
int fun_hash_entity(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGENTITY(0)->bl_id;
+ RESULTINT = unwrap<BlockId>(ARGENTITY(0)->bl_id);
return 0;
}
@@ -794,7 +794,7 @@ magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable
int must_add_sequentially;
if (ARG_TYPE(index) == TYPE::INT)
- item_data = itemdb_exists(ARGINT(index));
+ item_data = itemdb_exists(wrap<ItemNameId>(static_cast<uint16_t>(ARGINT(index))));
else if (ARG_TYPE(index) == TYPE::STRING)
item_data = itemdb_searchname(ARGSTR(index));
else
@@ -1559,13 +1559,13 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature,
if (ty == TYPE::ENTITY)
{
/* Dereference entities in preparation for calling function */
- arg->v.v_entity = map_id2bl(arg->v.v_int);
+ arg->v.v_entity = map_id2bl(wrap<BlockId>(static_cast<uint32_t>(arg->v.v_int)));
if (!arg->v.v_entity)
ty = arg->ty = TYPE::FAIL;
}
else if (ty == TYPE::INVOCATION)
{
- arg->v.v_invocation = map_id2bl(arg->v.v_int)->is_spell();
+ arg->v.v_invocation = map_id2bl(wrap<BlockId>(static_cast<uint32_t>(arg->v.v_int)))->is_spell();
if (!arg->v.v_entity)
ty = arg->ty = TYPE::FAIL;
}
@@ -1674,7 +1674,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr)
if (dest->ty == TYPE::ENTITY)
{
if (dest->v.v_entity)
- dest->v.v_int = dest->v.v_entity->bl_id;
+ dest->v.v_int = static_cast<int32_t>(unwrap<BlockId>(dest->v.v_entity->bl_id));
else
dest->ty = TYPE::FAIL;
}
@@ -1700,7 +1700,7 @@ void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr)
if (v.ty == TYPE::INVOCATION)
{
- dumb_ptr<invocation> t = map_id2bl(v.v.v_int)->is_spell();
+ dumb_ptr<invocation> t = map_id2bl(wrap<BlockId>(static_cast<uint32_t>(v.v.v_int)))->is_spell();
if (!t)
dest->ty = TYPE::UNDEF;
diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp
index c734908..5d8aa35 100644
--- a/src/map/magic-interpreter-base.cpp
+++ b/src/map/magic-interpreter-base.cpp
@@ -58,14 +58,14 @@ static
void set_entity(val_t *v, dumb_ptr<block_list> e)
{
v->ty = TYPE::ENTITY;
- v->v.v_int = e->bl_id;
+ v->v.v_int = static_cast<int32_t>(unwrap<BlockId>(e->bl_id));
}
static
void set_invocation(val_t *v, dumb_ptr<invocation> i)
{
v->ty = TYPE::INVOCATION;
- v->v.v_int = i->bl_id;
+ v->v.v_int = static_cast<int32_t>(unwrap<BlockId>(i->bl_id));
}
static
@@ -208,7 +208,7 @@ void free_components(dumb_ptr<component_t> *component_holder)
*component_holder = NULL;
}
-void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count)
+void magic_add_component(dumb_ptr<component_t> *component_holder, ItemNameId id, int count)
{
if (count <= 0)
return;
@@ -449,7 +449,7 @@ dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t>
retval->env = env;
- retval->caster = env->VAR(VAR_CASTER).v.v_int;
+ retval->caster = wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_CASTER).v.v_int));
retval->spell = env->VAR(VAR_SPELL).v.v_spell;
retval->stack_size = 0;
retval->current_effect = effect_set->effect;
@@ -483,7 +483,7 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base)
dumb_ptr<env_t> env = retval->env = clone_env(base->env);
retval->spell = base->spell;
retval->caster = base->caster;
- retval->subject = 0;
+ retval->subject = BlockId();
// retval->timer = 0;
retval->stack_size = 0;
// retval->stack = undef;
@@ -494,7 +494,7 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base)
retval->end_effect = NULL;
// retval->status_change_refs = NULL;
- retval->bl_id = 0;
+ retval->bl_id = BlockId();
retval->bl_prev = NULL;
retval->bl_next = NULL;
retval->bl_m = base->bl_m;
@@ -546,7 +546,7 @@ int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invoca
invocation_->flags &= ~INVOCATION_FLAG::BOUND;
invocation_->next_invocation = NULL;
- invocation_->subject = 0;
+ invocation_->subject = BlockId();
return 0;
}
diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp
index 7d529ee..65c64e3 100644
--- a/src/map/magic-interpreter.hpp
+++ b/src/map/magic-interpreter.hpp
@@ -20,7 +20,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "magic-interpreter.t.hpp"
@@ -223,7 +223,7 @@ struct effect_t
struct component_t
{
dumb_ptr<component_t> next;
- int item_id;
+ ItemNameId item_id;
int count;
};
@@ -349,7 +349,7 @@ struct cont_activation_record_t
int id;
TYPE ty;
dumb_ptr<effect_t> body;
- dumb_ptr<std::vector<int>> entities_vp;
+ dumb_ptr<std::vector<BlockId>> entities_vp;
int index;
} c_foreach;
struct
@@ -377,7 +377,7 @@ struct cont_activation_record_t
struct status_change_ref_t
{
StatusChange sc_type;
- int bl_id;
+ BlockId bl_id;
};
struct invocation : block_list
@@ -387,8 +387,8 @@ struct invocation : block_list
dumb_ptr<env_t> env;
dumb_ptr<spell_t> spell;
- int caster; /* this is the person who originally invoked the spell */
- int subject; /* when this person dies, the spell dies with it */
+ BlockId caster; /* this is the person who originally invoked the spell */
+ BlockId subject; /* when this person dies, the spell dies with it */
Timer timer; /* spell timer, if any */
@@ -414,7 +414,7 @@ extern env_t magic_default_env; /* Fake default environment */
/**
* Adds a component selection to a component holder (which may initially be NULL)
*/
-void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int count);
+void magic_add_component(dumb_ptr<component_t> *component_holder, ItemNameId id, int count);
dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name);
diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp
index 5d1fd97..8e4751d 100644
--- a/src/map/magic-stmt.cpp
+++ b/src/map/magic-stmt.cpp
@@ -108,7 +108,7 @@ void clear_activation_record(cont_activation_record_t *ar)
}
static
-void invocation_timer_callback(TimerData *, tick_t, int id)
+void invocation_timer_callback(TimerData *, tick_t, BlockId id)
{
dumb_ptr<invocation> invocation = map_id_is_spell(id);
@@ -202,7 +202,7 @@ void magic_stop_completely(dumb_ptr<map_session_data> c)
{
// Zap all status change references to spells
for (StatusChange i : erange(StatusChange(), StatusChange::MAX_STATUSCHANGE))
- c->sc_data[i].spell_invocation = 0;
+ c->sc_data[i].spell_invocation = BlockId();
while (c->active_spells)
spell_free_invocation(c->active_spells);
@@ -212,7 +212,7 @@ void magic_stop_completely(dumb_ptr<map_session_data> c)
dumb_ptr<invocation> attack_spell = map_id_is_spell(c->attack_spell_override);
if (attack_spell)
spell_free_invocation(attack_spell);
- c->attack_spell_override = 0;
+ c->attack_spell_override = BlockId();
char_set_weapon_icon(c, 0, StatusChange::ZERO, 0);
char_set_attack_info(c, interval_t::zero(), 0);
}
@@ -237,19 +237,19 @@ void try_to_finish_invocation(dumb_ptr<invocation> invocation)
}
static
-int trigger_spell(int subject, int spell)
+BlockId trigger_spell(BlockId subject, BlockId spell)
{
dumb_ptr<invocation> invocation_ = map_id_is_spell(spell);
if (!invocation_)
- return 0;
+ return BlockId();
invocation_ = spell_clone_effect(invocation_);
spell_bind(map_id_is_player(subject), invocation_);
magic_clear_var(&invocation_->env->varu[VAR_CASTER]);
invocation_->env->varu[VAR_CASTER].ty = TYPE::ENTITY;
- invocation_->env->varu[VAR_CASTER].v.v_int = subject;
+ invocation_->env->varu[VAR_CASTER].v.v_int = static_cast<int32_t>(unwrap<BlockId>(subject));
return invocation_->bl_id;
}
@@ -265,7 +265,7 @@ void char_update(dumb_ptr<map_session_data> character)
}
static
-void timer_callback_effect(TimerData *, tick_t, int id, int data)
+void timer_callback_effect(TimerData *, tick_t, BlockId id, int data)
{
dumb_ptr<block_list> target = map_id2bl(id);
if (target)
@@ -291,7 +291,7 @@ void magic_unshroud(dumb_ptr<map_session_data> other_char)
}
static
-void timer_callback_effect_npc_delete(TimerData *, tick_t, int npc_id)
+void timer_callback_effect_npc_delete(TimerData *, tick_t, BlockId npc_id)
{
dumb_ptr<npc_data> effect_npc = map_id_is_npc(npc_id);
npc_free(effect_npc);
@@ -305,7 +305,7 @@ dumb_ptr<npc_data> local_spell_effect(map_local *m, int x, int y, int effect,
std::chrono::seconds delay = std::chrono::seconds(30);
dumb_ptr<npc_data> effect_npc = npc_spawn_text(m, x, y,
INVISIBLE_NPC, NpcName(), "?"_s);
- int effect_npc_id = effect_npc->bl_id;
+ BlockId effect_npc_id = effect_npc->bl_id;
entity_effect(effect_npc, effect, tdelay);
Timer(gettick() + delay,
@@ -341,7 +341,7 @@ static
int op_instaheal(dumb_ptr<env_t> env, Slice<val_t> args)
{
dumb_ptr<block_list> caster = (env->VAR(VAR_CASTER).ty == TYPE::ENTITY)
- ? map_id2bl(env->VAR(VAR_CASTER).v.v_int) : NULL;
+ ? map_id2bl(wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_CASTER).v.v_int))) : NULL;
dumb_ptr<block_list> subject = ARGENTITY(0);
if (!caster)
caster = subject;
@@ -430,7 +430,7 @@ int op_message(dumb_ptr<env_t>, Slice<val_t> args)
}
static
-void timer_callback_kill_npc(TimerData *, tick_t, int npc_id)
+void timer_callback_kill_npc(TimerData *, tick_t, BlockId npc_id)
{
dumb_ptr<npc_data> npc = map_id_is_npc(npc_id);
if (npc)
@@ -537,7 +537,7 @@ int op_banish(dumb_ptr<env_t>, Slice<val_t> args)
}
static
-void record_status_change(dumb_ptr<invocation> invocation_, int bl_id,
+void record_status_change(dumb_ptr<invocation> invocation_, BlockId bl_id,
StatusChange sc_id)
{
status_change_ref_t cr {};
@@ -551,8 +551,8 @@ static
int op_status_change(dumb_ptr<env_t> env, Slice<val_t> args)
{
dumb_ptr<block_list> subject = ARGENTITY(0);
- int invocation_id = env->VAR(VAR_INVOCATION).ty == TYPE::INVOCATION
- ? env->VAR(VAR_INVOCATION).v.v_int : 0;
+ BlockId invocation_id = env->VAR(VAR_INVOCATION).ty == TYPE::INVOCATION
+ ? wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_INVOCATION).v.v_int)) : BlockId();
dumb_ptr<invocation> invocation_ = map_id_is_spell(invocation_id);
assert (!ARGINT(3));
@@ -563,7 +563,7 @@ int op_status_change(dumb_ptr<env_t> env, Slice<val_t> args)
static_cast<interval_t>(ARGINT(6)), invocation_id);
if (invocation_ && subject->bl_type == BL::PC)
- record_status_change(invocation_, subject->bl_id, StatusChange(ARGINT(1)));
+ record_status_change(invocation_, subject->bl_id, static_cast<StatusChange>(ARGINT(1)));
return 0;
}
@@ -604,7 +604,7 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args)
}
subject->attack_spell_override =
- trigger_spell(subject->bl_id, env->VAR(VAR_INVOCATION).v.v_int);
+ trigger_spell(subject->bl_id, wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_INVOCATION).v.v_int)));
subject->attack_spell_charges = charges;
if (subject->attack_spell_override)
@@ -698,7 +698,7 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args)
{
dumb_ptr<area_t> area = ARGAREA(0);
dumb_ptr<block_list> owner_e = ARGENTITY(1);
- int monster_id = ARGINT(2);
+ Species monster_id = wrap<Species>(ARGINT(2));
MonsterAttitude monster_attitude = static_cast<MonsterAttitude>(ARGINT(3));
int monster_count = ARGINT(4);
interval_t monster_lifetime = static_cast<interval_t>(ARGINT(5));
@@ -714,7 +714,7 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args)
location_t loc;
magic_random_location(&loc, area);
- int mob_id;
+ BlockId mob_id;
dumb_ptr<mob_data> mob;
mob_id = mob_once_spawn(owner, loc.m->name_, loc.x, loc.y, JAPANESE_NAME, // Is that needed?
@@ -724,7 +724,7 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args)
if (mob)
{
- mob->mode = mob_db[monster_id].mode;
+ mob->mode = get_mob_db(monster_id).mode;
switch (monster_attitude)
{
@@ -776,7 +776,7 @@ ZString get_invocation_name(dumb_ptr<env_t> env)
if (env->VAR(VAR_INVOCATION).ty != TYPE::INVOCATION)
return "?"_s;
- invocation_ = map_id_is_spell(env->VAR(VAR_INVOCATION).v.v_int);
+ invocation_ = map_id_is_spell(wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_INVOCATION).v.v_int)));
if (invocation_)
return invocation_->spell->name;
@@ -979,7 +979,7 @@ op_t *magic_get_op(ZString name)
return &it->second;
}
-void spell_effect_report_termination(int invocation_id, int bl_id,
+void spell_effect_report_termination(BlockId invocation_id, BlockId bl_id,
StatusChange sc_id, int)
{
dumb_ptr<invocation> invocation_ = map_id_is_spell(invocation_id);
@@ -1042,7 +1042,7 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_)
case CONT_STACK::FOREACH:
{
- int entity_id;
+ BlockId entity_id;
val_t *var = &invocation_->env->varu[ar->c.c_foreach.id];
do
@@ -1065,7 +1065,7 @@ dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_)
magic_clear_var(var);
var->ty = ar->c.c_foreach.ty;
- var->v.v_int = entity_id;
+ var->v.v_int = static_cast<int32_t>(unwrap<BlockId>(entity_id));
return ar->c.c_foreach.body;
}
@@ -1118,7 +1118,7 @@ cont_activation_record_t *add_stack_entry(dumb_ptr<invocation> invocation_,
static
void find_entities_in_area_c(dumb_ptr<block_list> target,
- std::vector<int> *entities_vp,
+ std::vector<BlockId> *entities_vp,
FOREACH_FILTER filter)
{
switch (target->bl_type)
@@ -1180,7 +1180,7 @@ void find_entities_in_area_c(dumb_ptr<block_list> target,
static
void find_entities_in_area(area_t& area_,
- std::vector<int> *entities_vp,
+ std::vector<BlockId> *entities_vp,
FOREACH_FILTER filter)
{
area_t *area = &area_; // temporary hack to "keep diff small". Heh.
@@ -1233,7 +1233,7 @@ dumb_ptr<effect_t> run_foreach(dumb_ptr<invocation> invocation,
if (!ar)
return return_location;
- std::vector<int> entities_v;
+ std::vector<BlockId> entities_v;
find_entities_in_area(*area.v.v_area,
&entities_v, filter);
entities_v.shrink_to_fit();
@@ -1391,7 +1391,7 @@ void print_cfg(int i, effect_t *e)
static
interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
{
- const int invocation_id = invocation_->bl_id;
+ const BlockId invocation_id = invocation_->bl_id;
#define REFRESH_INVOCATION invocation_ = map_id_is_spell(invocation_id); if (!invocation_) return interval_t::zero();
#ifdef DEBUG
@@ -1465,13 +1465,13 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
argrec_t arg[3] =
{
{"@target"_s, env->VAR(VAR_TARGET).ty == TYPE::ENTITY ? 0 : env->VAR(VAR_TARGET).v.v_int},
- {"@caster"_s, invocation_->caster},
+ {"@caster"_s, static_cast<int32_t>(unwrap<BlockId>(invocation_->caster))},
{"@caster_name$"_s, caster_name},
};
- int message_recipient =
- env->VAR(VAR_SCRIPTTARGET).ty ==
- TYPE::ENTITY ? env->VAR(VAR_SCRIPTTARGET).
- v.v_int : invocation_->caster;
+ BlockId message_recipient =
+ env->VAR(VAR_SCRIPTTARGET).ty == TYPE::ENTITY
+ ? wrap<BlockId>(static_cast<uint32_t>(env->VAR(VAR_SCRIPTTARGET).v.v_int))
+ : invocation_->caster;
dumb_ptr<map_session_data> recipient = map_id_is_player(message_recipient);
if (recipient->npc_id
@@ -1583,7 +1583,7 @@ void spell_execute_script(dumb_ptr<invocation> invocation)
* running the same spell twice! */
}
-int spell_attack(int caster_id, int target_id)
+int spell_attack(BlockId caster_id, BlockId target_id)
{
dumb_ptr<map_session_data> caster = map_id_is_player(caster_id);
dumb_ptr<invocation> invocation_;
@@ -1601,7 +1601,7 @@ int spell_attack(int caster_id, int target_id)
{
magic_clear_var(&invocation_->env->varu[VAR_TARGET]);
invocation_->env->varu[VAR_TARGET].ty = TYPE::ENTITY;
- invocation_->env->varu[VAR_TARGET].v.v_int = target_id;
+ invocation_->env->varu[VAR_TARGET].v.v_int = static_cast<int32_t>(unwrap<BlockId>(target_id));
invocation_->current_effect = invocation_->trigger_effect;
invocation_->flags &= ~INVOCATION_FLAG::ABORTED;
@@ -1622,7 +1622,7 @@ int spell_attack(int caster_id, int target_id)
}
else if (!invocation_ || caster->attack_spell_charges <= 0)
{
- caster->attack_spell_override = 0;
+ caster->attack_spell_override = BlockId();
char_set_weapon_icon(caster, 0, StatusChange::ZERO, 0);
char_set_attack_info(caster, interval_t::zero(), 0);
diff --git a/src/map/magic-v2.cpp b/src/map/magic-v2.cpp
index 20abc00..288e512 100644
--- a/src/map/magic-v2.cpp
+++ b/src/map/magic-v2.cpp
@@ -559,7 +559,7 @@ namespace magic_v2
}
static
- bool parse_item(const SExpr& s, int& id, int& count)
+ bool parse_item(const SExpr& s, ItemNameId& id, int& count)
{
if (s._type == sexpr::STRING)
{
@@ -679,7 +679,8 @@ namespace magic_v2
dumb_ptr<component_t> items = nullptr;
for (auto it = s._list.begin() + 1, end = s._list.end(); it != end; ++it)
{
- int id, count;
+ ItemNameId id;
+ int count;
if (!parse_item(*it, id, count))
return false;
magic_add_component(&items, id, count);
@@ -693,7 +694,8 @@ namespace magic_v2
dumb_ptr<component_t> items = nullptr;
for (auto it = s._list.begin() + 1, end = s._list.end(); it != end; ++it)
{
- int id, count;
+ ItemNameId id;
+ int count;
if (!parse_item(*it, id, count))
return false;
magic_add_component(&items, id, count);
diff --git a/src/map/magic.hpp b/src/map/magic.hpp
index a5a966c..7a1a6e0 100644
--- a/src/map/magic.hpp
+++ b/src/map/magic.hpp
@@ -20,7 +20,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/fwd.hpp"
@@ -59,7 +59,7 @@ void magic_unshroud(dumb_ptr<map_session_data> character);
* \param sc_id ID of the status change entry that finished
* \param supplanted Whether the status_change finished normally (0) or was supplanted by a new status_change (1)
*/
-void spell_effect_report_termination(int invocation, int bl_id,
+void spell_effect_report_termination(BlockId invocation, BlockId bl_id,
StatusChange sc_id, int supplanted);
/**
@@ -97,7 +97,7 @@ void magic_stop_completely(dumb_ptr<map_session_data> c);
*
* Returns 0 if there is no charged spell or the spell is depleted.
*/
-int spell_attack(int caster, int target);
+int spell_attack(BlockId caster, BlockId target);
void spell_free_invocation(dumb_ptr<invocation> invocation);
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 5c77e7b..8ca0ba7 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -76,7 +76,7 @@
#include "../poison.hpp"
-DMap<int, dumb_ptr<block_list>> id_db;
+DMap<BlockId, dumb_ptr<block_list>> id_db;
UPMap<MapName, map_abstract> maps_db;
@@ -90,14 +90,14 @@ struct charid2nick
};
static
-Map<int, struct charid2nick> charid_db;
+Map<CharId, struct charid2nick> charid_db;
static
int users = 0;
static
-Array<dumb_ptr<block_list>, MAX_FLOORITEM> object;
+Array<dumb_ptr<block_list>, unwrap<BlockId>(MAX_FLOORITEM)> object;
static
-int first_free_object_id = 0, last_object_id = 0;
+BlockId first_free_object_id = BlockId();
interval_t autosave_time = DEFAULT_AUTOSAVE_INTERVAL;
int save_settings = 0xFFFF;
@@ -535,29 +535,27 @@ void map_foreachincell(std::function<void(dumb_ptr<block_list>)> func,
* bl->bl_idもこの中で設定して問題無い?
*------------------------------------------
*/
-int map_addobject(dumb_ptr<block_list> bl)
+BlockId map_addobject(dumb_ptr<block_list> bl)
{
- int i;
+ BlockId i;
if (!bl)
{
PRINTF("map_addobject nullpo?\n"_fmt);
- return 0;
+ return BlockId();
}
- if (first_free_object_id < 2 || first_free_object_id >= MAX_FLOORITEM)
- first_free_object_id = 2;
- for (i = first_free_object_id; i < MAX_FLOORITEM; i++)
- if (!object[i])
+ if (first_free_object_id < wrap<BlockId>(2) || first_free_object_id == MAX_FLOORITEM)
+ first_free_object_id = wrap<BlockId>(2);
+ for (i = first_free_object_id; i < MAX_FLOORITEM; i = next(i))
+ if (!object[i._value])
break;
- if (i >= MAX_FLOORITEM)
+ if (i == MAX_FLOORITEM)
{
if (battle_config.error_log)
PRINTF("no free object id\n"_fmt);
- return 0;
+ return BlockId();
}
first_free_object_id = i;
- if (last_object_id < i)
- last_object_id = i;
- object[i] = bl;
+ object[i._value] = bl;
id_db.put(i, bl);
return i;
}
@@ -567,32 +565,26 @@ int map_addobject(dumb_ptr<block_list> bl)
* map_delobjectのfreeしないバージョン
*------------------------------------------
*/
-int map_delobjectnofree(int id, BL type)
+void map_delobjectnofree(BlockId id, BL type)
{
assert (id < MAX_FLOORITEM);
- if (!object[id])
- return 0;
+ if (!object[id._value])
+ return;
- if (object[id]->bl_type != type)
+ if (object[id._value]->bl_type != type)
{
FPRINTF(stderr, "Incorrect type: expected %d, got %d\n"_fmt,
type,
- object[id]->bl_type);
+ object[id._value]->bl_type);
abort();
}
- map_delblock(object[id]);
+ map_delblock(object[id._value]);
id_db.put(id, dumb_ptr<block_list>());
-// map_freeblock(object[id]);
- object[id] = nullptr;
+ object[id._value] = nullptr;
- if (first_free_object_id > id)
+ if (id < first_free_object_id)
first_free_object_id = id;
-
- while (last_object_id > 2 && object[last_object_id] == NULL)
- last_object_id--;
-
- return 0;
}
/*==========================================
@@ -603,21 +595,19 @@ int map_delobjectnofree(int id, BL type)
* addとの対称性が無いのが気になる
*------------------------------------------
*/
-int map_delobject(int id, BL type)
+void map_delobject(BlockId id, BL type)
{
assert (id < MAX_FLOORITEM);
- dumb_ptr<block_list> obj = object[id];
+ dumb_ptr<block_list> obj = object[id._value];
if (obj == NULL)
- return 0;
+ return;
map_delobjectnofree(id, type);
if (obj->bl_type == BL::PC) // [Fate] Not sure where else to put this... I'm not sure where delobject for PCs is called from
pc_cleanup(obj->is_player());
MapBlockLock::freeblock(obj);
-
- return 0;
}
/*==========================================
@@ -628,24 +618,28 @@ int map_delobject(int id, BL type)
void map_foreachobject(std::function<void(dumb_ptr<block_list>)> func,
BL type)
{
- assert (last_object_id < MAX_FLOORITEM);
std::vector<dumb_ptr<block_list>> bl_list;
- for (int i = 2; i <= last_object_id; i++)
+ for (BlockId i = wrap<BlockId>(2); i < MAX_FLOORITEM; i = next(i))
{
- if (!object[i])
+ if (!object[i._value])
continue;
{
- if (type != BL::NUL && object[i]->bl_type != type)
+ if (type != BL::NUL && object[i._value]->bl_type != type)
continue;
- bl_list.push_back(object[i]);
+ bl_list.push_back(object[i._value]);
}
}
MapBlockLock lock;
for (dumb_ptr<block_list> bl : bl_list)
+ {
+ // TODO figure out if the second branch can happen
+ // bl_prev is non-null for all that are on a map (see bl_head)
+ // bl_next is only meaningful for objects that are on a map
if (bl->bl_prev || bl->bl_next)
func(bl);
+ }
}
/*==========================================
@@ -658,10 +652,10 @@ void map_foreachobject(std::function<void(dumb_ptr<block_list>)> func,
* map.h内で#defineしてある
*------------------------------------------
*/
-void map_clearflooritem_timer(TimerData *tid, tick_t, int id)
+void map_clearflooritem_timer(TimerData *tid, tick_t, BlockId id)
{
assert (id < MAX_FLOORITEM);
- dumb_ptr<block_list> obj = object[id];
+ dumb_ptr<block_list> obj = object[id._value];
assert (obj && obj->bl_type == BL::ITEM);
dumb_ptr<flooritem_data> fitem = obj->is_item();
if (!tid)
@@ -697,17 +691,17 @@ std::pair<uint16_t, uint16_t> map_searchrandfreecell(map_local *m, int x, int y,
* item_dataはamount以外をcopyする
*------------------------------------------
*/
-int map_addflooritem_any(struct item *item_data, int amount,
+BlockId map_addflooritem_any(struct item *item_data, int amount,
map_local *m, int x, int y,
dumb_ptr<map_session_data> *owners, interval_t *owner_protection,
interval_t lifetime, int dispersal)
{
dumb_ptr<flooritem_data> fitem = NULL;
- nullpo_ret(item_data);
+ nullpo_retr(BlockId(), item_data);
auto xy = map_searchrandfreecell(m, x, y, dispersal);
if (xy.first == 0 && xy.second == 0)
- return 0;
+ return BlockId();
fitem.new_();
fitem->bl_type = BL::ITEM;
@@ -715,18 +709,18 @@ int map_addflooritem_any(struct item *item_data, int amount,
fitem->bl_m = m;
fitem->bl_x = xy.first;
fitem->bl_y = xy.second;
- fitem->first_get_id = 0;
+ fitem->first_get_id = BlockId();
fitem->first_get_tick = tick_t();
- fitem->second_get_id = 0;
+ fitem->second_get_id = BlockId();
fitem->second_get_tick = tick_t();
- fitem->third_get_id = 0;
+ fitem->third_get_id = BlockId();
fitem->third_get_tick = tick_t();
fitem->bl_id = map_addobject(fitem);
- if (fitem->bl_id == 0)
+ if (!fitem->bl_id)
{
fitem.delete_();
- return 0;
+ return BlockId();
}
tick_t tick = gettick();
@@ -762,7 +756,7 @@ int map_addflooritem_any(struct item *item_data, int amount,
return fitem->bl_id;
}
-int map_addflooritem(struct item *item_data, int amount,
+BlockId map_addflooritem(struct item *item_data, int amount,
map_local *m, int x, int y,
dumb_ptr<map_session_data> first_sd,
dumb_ptr<map_session_data> second_sd,
@@ -786,7 +780,7 @@ int map_addflooritem(struct item *item_data, int amount,
* charid_dbへ追加(返信待ちがあれば返信)
*------------------------------------------
*/
-void map_addchariddb(int charid, CharName name)
+void map_addchariddb(CharId charid, CharName name)
{
struct charid2nick *p = charid_db.search(charid);
if (p == NULL)
@@ -842,7 +836,7 @@ void map_quit(dumb_ptr<map_session_data> sd)
if (sd->trade_partner) // 取引を中断する
trade_tradecancel(sd);
- if (sd->party_invite > 0) // パーティ勧誘を拒否する
+ if (sd->party_invite) // パーティ勧誘を拒否する
party_reply_invite(sd, sd->party_invite_account, 0);
party_send_logout(sd); // パーティのログアウトメッセージ送信
@@ -885,7 +879,7 @@ void map_quit(dumb_ptr<map_session_data> sd)
* id番号のPCを探す。居なければNULL
*------------------------------------------
*/
-dumb_ptr<map_session_data> map_id2sd(int id)
+dumb_ptr<map_session_data> map_id2sd(BlockId id)
{
// This is bogus.
// However, there might be differences for de-auth'ed accounts.
@@ -923,7 +917,7 @@ dumb_ptr<map_session_data> map_id2sd(int id)
* char_id番号の名前を探す
*------------------------------------------
*/
-CharName map_charid2nick(int id)
+CharName map_charid2nick(CharId id)
{
struct charid2nick *p = charid_db.search(id);
@@ -1028,11 +1022,11 @@ dumb_ptr<map_session_data> map_nick2sd(CharName nick)
* 一時objectの場合は配列を引くのみ
*------------------------------------------
*/
-dumb_ptr<block_list> map_id2bl(int id)
+dumb_ptr<block_list> map_id2bl(BlockId id)
{
dumb_ptr<block_list> bl = NULL;
- if (id < sizeof(object) / sizeof(object[0]))
- bl = object[id];
+ if (id < MAX_FLOORITEM)
+ bl = object[id._value];
else
bl = id_db.get(id);
@@ -1768,7 +1762,7 @@ int do_init(Slice<ZString> argv)
return 0;
}
-int map_scriptcont(dumb_ptr<map_session_data> sd, int id)
+int map_scriptcont(dumb_ptr<map_session_data> sd, BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 6d945d0..620dc52 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "map.t.hpp"
@@ -30,6 +30,8 @@
# include <functional>
# include <list>
+# include "../ints/udl.hpp"
+
# include "../strings/fwd.hpp"
# include "../strings/rstring.hpp"
# include "../strings/astring.hpp"
@@ -57,7 +59,7 @@ constexpr std::chrono::seconds LIFETIME_FLOORITEM = std::chrono::minutes(1);
constexpr int MAX_SKILL_LEVEL = 100;
constexpr int MAX_EVENTTIMER = 32;
constexpr interval_t NATURAL_HEAL_INTERVAL = std::chrono::milliseconds(500);
-constexpr int MAX_FLOORITEM = 500000;
+constexpr BlockId MAX_FLOORITEM = wrap<BlockId>(500000_u32);
constexpr int MAX_LEVEL = 255;
constexpr int MAX_WALKPATH = 48;
constexpr int MAX_DROP_PER_MAP = 48;
@@ -106,7 +108,7 @@ struct map_local;
struct block_list
{
dumb_ptr<block_list> bl_next, bl_prev;
- int bl_id;
+ BlockId bl_id;
map_local *bl_m;
short bl_x, bl_y;
BL bl_type;
@@ -141,7 +143,7 @@ struct status_change
{
Timer timer;
int val1;
- int spell_invocation; /* [Fate] If triggered by a spell, record here */
+ BlockId spell_invocation; /* [Fate] If triggered by a spell, record here */
};
struct invocation;
@@ -190,7 +192,8 @@ struct map_session_data : block_list, SessionData
unsigned unbreakable_armor:1;
unsigned deaf:1;
} special_state;
- int char_id, login_id1, login_id2;
+ CharId char_id_;
+ int login_id1, login_id2;
SEX sex;
unsigned char tmw_version; // tmw client version
CharKey status_key;
@@ -209,7 +212,7 @@ struct map_session_data : block_list, SessionData
tick_t client_tick, server_tick;
struct walkpath_data walkpath;
Timer walktimer;
- int npc_id, areanpc_id, npc_shopid;
+ BlockId npc_id, areanpc_id, npc_shopid;
// this is important
int npc_pos;
int npc_menu;
@@ -226,16 +229,16 @@ struct map_session_data : block_list, SessionData
} npc_flags;
Timer attacktimer;
- int attacktarget;
+ BlockId attacktarget;
ATK attacktarget_lv;
tick_t attackabletime;
// used by @hugo and @linus
- int followtarget;
+ BlockId followtarget;
tick_t cast_tick; // [Fate] Next tick at which spellcasting is allowed
dumb_ptr<invocation> active_spells; // [Fate] Singly-linked list of active spells linked to this PC
- int attack_spell_override; // [Fate] When an attack spell is active for this player, they trigger it
+ BlockId attack_spell_override; // [Fate] When an attack spell is active for this player, they trigger it
// like a weapon. Check pc_attack_timer() for details.
// Weapon equipment slot (slot 4) item override
StatusChange attack_spell_icon_override;
@@ -296,16 +299,18 @@ struct map_session_data : block_list, SessionData
earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
short sc_count;
- int trade_partner;
+ AccountId trade_partner;
Array<int, TRADE_MAX> deal_item_index;
Array<int, TRADE_MAX> deal_item_amount;
int deal_zeny;
short deal_locked;
- int party_sended, party_invite, party_invite_account;
+ int party_sended;
+ PartyId party_invite;
+ AccountId party_invite_account;
int party_hp, party_x, party_y;
- int partyspy; // [Syrus22]
+ PartyId partyspy; // [Syrus22]
int catch_target_class;
@@ -349,7 +354,8 @@ struct npc_label_list
};
struct npc_item_list
{
- int nameid, value;
+ ItemNameId nameid;
+ int value;
};
class npc_data_script;
@@ -446,7 +452,7 @@ constexpr int MOB_XP_BONUS_SHIFT = 10;
struct mob_data : block_list
{
short n;
- short mob_class;
+ Species mob_class;
DIR dir;
MobMode mode;
struct
@@ -472,7 +478,7 @@ struct mob_data : block_list
Timer timer;
short to_x, to_y;
int hp;
- int target_id, attacked_id;
+ BlockId target_id, attacked_id;
ATK target_lv;
struct walkpath_data walkpath;
tick_t next_walktime;
@@ -482,7 +488,7 @@ struct mob_data : block_list
short move_fail_count;
struct DmgLogEntry
{
- int id;
+ BlockId id;
int dmg;
};
// logically a map ...
@@ -499,14 +505,15 @@ struct mob_data : block_list
Timer deletetimer;
Timer skilltimer;
- int skilltarget;
+ BlockId skilltarget;
short skillx, skilly;
SkillID skillid;
short skilllv;
struct mob_skill *skillidx;
std::unique_ptr<tick_t[]> skilldelayup; // [MAX_MOBSKILL];
LevelElement def_ele;
- int master_id, master_dist;
+ BlockId master_id;
+ int master_dist;
int exclusion_src, exclusion_party;
NpcEvent npc_event;
// [Fate] mob-specific stats
@@ -560,7 +567,7 @@ struct flooritem_data : block_list
{
short subx, suby;
Timer cleartimer;
- int first_get_id, second_get_id, third_get_id;
+ BlockId first_get_id, second_get_id, third_get_id;
tick_t first_get_tick, second_get_tick, third_get_tick;
struct item item_data;
};
@@ -607,9 +614,9 @@ void map_foreachinmovearea(std::function<void(dumb_ptr<block_list>)>,
//block関連に追加
int map_count_oncell(map_local *m, int x, int y);
// 一時的object関連
-int map_addobject(dumb_ptr<block_list>);
-int map_delobject(int, BL type);
-int map_delobjectnofree(int id, BL type);
+BlockId map_addobject(dumb_ptr<block_list>);
+void map_delobject(BlockId, BL type);
+void map_delobjectnofree(BlockId id, BL type);
void map_foreachobject(std::function<void(dumb_ptr<block_list>)>,
BL);
//
@@ -626,56 +633,56 @@ void map_log(XString line);
sd->status_key.char_id, (sd->bl_m ? sd->bl_m->name_ : stringish<MapName>("undefined.gat"_s)), sd->bl_x, sd->bl_y, ## __VA_ARGS__)
// 床アイテム関連
-void map_clearflooritem_timer(TimerData *, tick_t, int);
+void map_clearflooritem_timer(TimerData *, tick_t, BlockId);
inline
-void map_clearflooritem(int id)
+void map_clearflooritem(BlockId id)
{
map_clearflooritem_timer(nullptr, tick_t(), id);
}
-int map_addflooritem_any(struct item *, int amount,
+BlockId map_addflooritem_any(struct item *, int amount,
map_local *m, int x, int y,
dumb_ptr<map_session_data> *owners, interval_t *owner_protection,
interval_t lifetime, int dispersal);
-int map_addflooritem(struct item *, int,
+BlockId map_addflooritem(struct item *, int,
map_local *, int, int,
dumb_ptr<map_session_data>, dumb_ptr<map_session_data>,
dumb_ptr<map_session_data>);
// キャラid=>キャラ名 変換関連
extern
-DMap<int, dumb_ptr<block_list>> id_db;
-void map_addchariddb(int charid, CharName name);
-CharName map_charid2nick(int);
+DMap<BlockId, dumb_ptr<block_list>> id_db;
+void map_addchariddb(CharId charid, CharName name);
+CharName map_charid2nick(CharId);
-dumb_ptr<map_session_data> map_id2sd(int);
-dumb_ptr<block_list> map_id2bl(int);
+dumb_ptr<map_session_data> map_id2sd(BlockId);
+dumb_ptr<block_list> map_id2bl(BlockId);
inline
-dumb_ptr<map_session_data> map_id_is_player(int id)
+dumb_ptr<map_session_data> map_id_is_player(BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
return bl ? bl->is_player() : nullptr;
}
inline
-dumb_ptr<npc_data> map_id_is_npc(int id)
+dumb_ptr<npc_data> map_id_is_npc(BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
return bl ? bl->is_npc() : nullptr;
}
inline
-dumb_ptr<mob_data> map_id_is_mob(int id)
+dumb_ptr<mob_data> map_id_is_mob(BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
return bl ? bl->is_mob() : nullptr;
}
inline
-dumb_ptr<flooritem_data> map_id_is_item(int id)
+dumb_ptr<flooritem_data> map_id_is_item(BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
return bl ? bl->is_item() : nullptr;
}
inline
-dumb_ptr<invocation> map_id_is_spell(int id)
+dumb_ptr<invocation> map_id_is_spell(BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
return bl ? bl->is_spell() : nullptr;
@@ -688,7 +695,7 @@ int map_setipport(MapName name, IP4Address ip, int port);
void map_addiddb(dumb_ptr<block_list>);
void map_deliddb(dumb_ptr<block_list> bl);
void map_addnickdb(dumb_ptr<map_session_data>);
-int map_scriptcont(dumb_ptr<map_session_data> sd, int id); /* Continues a script either on a spell or on an NPC */
+int map_scriptcont(dumb_ptr<map_session_data> sd, BlockId id); /* Continues a script either on a spell or on an NPC */
dumb_ptr<map_session_data> map_nick2sd(CharName);
int compare_item(struct item *a, struct item *b);
diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp
index b6b14bb..d9e3c1f 100644
--- a/src/map/map.t.hpp
+++ b/src/map/map.t.hpp
@@ -21,10 +21,11 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../strings/vstring.hpp"
+# include "../mmo/ids.hpp"
# include "../mmo/mmo.hpp"
namespace e
@@ -585,4 +586,10 @@ struct NpcName : VString<23> {};
struct ScriptLabel : VString<23> {};
struct ItemName : VString<23> {};
+class BlockId : public Wrapped<uint32_t> { public: BlockId() : Wrapped<uint32_t>() {} protected: template<class... A> constexpr explicit BlockId(A... a) : Wrapped<uint32_t>(a...) {} };
+inline
+BlockId account_to_block(AccountId a) { return wrap<BlockId>(unwrap<AccountId>(a)); }
+inline
+AccountId block_to_account(BlockId b) { return wrap<AccountId>(unwrap<BlockId>(b)); }
+
#endif // TMWA_MAP_MAP_T_HPP
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 2bf4ad1..122fa98 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -63,7 +63,12 @@ constexpr random_::Fraction MOB_LAZYMOVEPERC {50, 1000};
// Warp probability in the negligent mode MOB (rate of 1000 minute)
constexpr random_::Fraction MOB_LAZYWARPPERC {20, 1000};
+static
struct mob_db_ mob_db[2001];
+struct mob_db_& get_mob_db(Species s)
+{
+ return mob_db[unwrap<Species>(s)];
+}
/*==========================================
* Local prototype declaration (only required thing)
@@ -72,9 +77,9 @@ struct mob_db_ mob_db[2001];
static
int distance(int, int, int, int);
static
-int mob_makedummymobdb(int);
+int mob_makedummymobdb(Species);
static
-void mob_timer(TimerData *, tick_t, int, unsigned char);
+void mob_timer(TimerData *, tick_t, BlockId, unsigned char);
static
int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target,
mob_skill& skill_idx);
@@ -83,30 +88,29 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target,
* Mob is searched with a name.
*------------------------------------------
*/
-int mobdb_searchname(MobName str)
+Species mobdb_searchname(MobName str)
{
int i;
for (i = 0; i < sizeof(mob_db) / sizeof(mob_db[0]); i++)
{
if (mob_db[i].name == str || mob_db[i].jname == str)
- return i;
+ return wrap<Species>(i);
}
- return 0;
+ return Species();
}
/*==========================================
* Id Mob is checked.
*------------------------------------------
*/
-int mobdb_checkid(const int id)
+Species mobdb_checkid(Species id)
{
- if (id <= 0 || id >= (sizeof(mob_db) / sizeof(mob_db[0]))
- || !mob_db[id].name)
- return 0;
-
- return id;
+ // value range is [1001, 2000]
+ if (wrap<Species>(1000) < id && id < wrap<Species>(2001))
+ return id;
+ return Species();
}
static
@@ -117,14 +121,14 @@ void mob_init(dumb_ptr<mob_data> md);
*------------------------------------------
*/
static
-void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, int mob_class)
+void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, Species mob_class)
{
nullpo_retv(md);
if (mobname == ENGLISH_NAME)
- md->name = mob_db[mob_class].name;
+ md->name = get_mob_db(mob_class).name;
else if (mobname == JAPANESE_NAME)
- md->name = mob_db[mob_class].jname;
+ md->name = get_mob_db(mob_class).jname;
else
md->name = mobname;
@@ -136,8 +140,8 @@ void mob_spawn_dataset(dumb_ptr<mob_data> md, MobName mobname, int mob_class)
really_memzero_this(&md->state);
// md->timer = nullptr;
- md->target_id = 0;
- md->attacked_id = 0;
+ md->target_id = BlockId();
+ md->attacked_id = BlockId();
mob_init(md);
}
@@ -330,24 +334,24 @@ static
void mob_init(dumb_ptr<mob_data> md)
{
int i;
- const int mob_class = md->mob_class;
- const int mutations_nr = mob_db[mob_class].mutations_nr;
- const int mutation_power = mob_db[mob_class].mutation_power;
-
- md->stats[mob_stat::LV] = mob_db[mob_class].lv;
- md->stats[mob_stat::MAX_HP] = mob_db[mob_class].max_hp;
- md->stats[mob_stat::STR] = mob_db[mob_class].attrs[ATTR::STR];
- md->stats[mob_stat::AGI] = mob_db[mob_class].attrs[ATTR::AGI];
- md->stats[mob_stat::VIT] = mob_db[mob_class].attrs[ATTR::VIT];
- md->stats[mob_stat::INT] = mob_db[mob_class].attrs[ATTR::INT];
- md->stats[mob_stat::DEX] = mob_db[mob_class].attrs[ATTR::DEX];
- md->stats[mob_stat::LUK] = mob_db[mob_class].attrs[ATTR::LUK];
- md->stats[mob_stat::ATK1] = mob_db[mob_class].atk1;
- md->stats[mob_stat::ATK2] = mob_db[mob_class].atk2;
- md->stats[mob_stat::ADELAY] = mob_db[mob_class].adelay;
- md->stats[mob_stat::DEF] = mob_db[mob_class].def;
- md->stats[mob_stat::MDEF] = mob_db[mob_class].mdef;
- md->stats[mob_stat::SPEED] = mob_db[mob_class].speed;
+ const Species mob_class = md->mob_class;
+ const int mutations_nr = get_mob_db(mob_class).mutations_nr;
+ const int mutation_power = get_mob_db(mob_class).mutation_power;
+
+ md->stats[mob_stat::LV] = get_mob_db(mob_class).lv;
+ md->stats[mob_stat::MAX_HP] = get_mob_db(mob_class).max_hp;
+ md->stats[mob_stat::STR] = get_mob_db(mob_class).attrs[ATTR::STR];
+ md->stats[mob_stat::AGI] = get_mob_db(mob_class).attrs[ATTR::AGI];
+ md->stats[mob_stat::VIT] = get_mob_db(mob_class).attrs[ATTR::VIT];
+ md->stats[mob_stat::INT] = get_mob_db(mob_class).attrs[ATTR::INT];
+ md->stats[mob_stat::DEX] = get_mob_db(mob_class).attrs[ATTR::DEX];
+ md->stats[mob_stat::LUK] = get_mob_db(mob_class).attrs[ATTR::LUK];
+ md->stats[mob_stat::ATK1] = get_mob_db(mob_class).atk1;
+ md->stats[mob_stat::ATK2] = get_mob_db(mob_class).atk2;
+ md->stats[mob_stat::ADELAY] = get_mob_db(mob_class).adelay;
+ md->stats[mob_stat::DEF] = get_mob_db(mob_class).def;
+ md->stats[mob_stat::MDEF] = get_mob_db(mob_class).mdef;
+ md->stats[mob_stat::SPEED] = get_mob_db(mob_class).speed;
md->stats[mob_stat::XP_BONUS] = MOB_XP_BONUS_BASE;
for (i = 0; i < mutations_nr; i++)
@@ -391,22 +395,22 @@ void mob_init(dumb_ptr<mob_data> md)
* The MOB appearance for one time (for scripts)
*------------------------------------------
*/
-int mob_once_spawn(dumb_ptr<map_session_data> sd,
+BlockId mob_once_spawn(dumb_ptr<map_session_data> sd,
MapName mapname, int x, int y,
- MobName mobname, int mob_class, int amount,
+ MobName mobname, Species mob_class, int amount,
NpcEvent event)
{
dumb_ptr<mob_data> md = NULL;
map_local *m;
- int count, r = mob_class;
+ int count;
if (sd && mapname == MOB_THIS_MAP)
m = sd->bl_m;
else
m = map_mapname2mapid(mapname);
- if (m == nullptr || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // 値が異常なら召喚を止める
- return 0;
+ if (m == nullptr || amount <= 0 || mobdb_checkid(mob_class) == Species())
+ return BlockId();
if (sd)
{
@@ -429,9 +433,6 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd,
md->bl_m = m;
md->bl_x = x;
md->bl_y = y;
- if (r < 0 && battle_config.dead_branch_active == 1)
- //移動してアクティブで反撃する
- md->mode = MobMode::war;
md->spawn.m = m;
md->spawn.x0 = x;
md->spawn.y0 = y;
@@ -446,19 +447,20 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd,
map_addiddb(md);
mob_spawn(md->bl_id);
}
- return (amount > 0) ? md->bl_id : 0;
+ return (amount > 0) ? md->bl_id : BlockId();
}
/*==========================================
* The MOB appearance for one time (& area specification for scripts)
*------------------------------------------
*/
-int mob_once_spawn_area(dumb_ptr<map_session_data> sd,
+BlockId mob_once_spawn_area(dumb_ptr<map_session_data> sd,
MapName mapname, int x0, int y0, int x1, int y1,
- MobName mobname, int mob_class, int amount,
+ MobName mobname, Species mob_class, int amount,
NpcEvent event)
{
- int x, y, i, max, lx = -1, ly = -1, id = 0;
+ int x, y, i, max, lx = -1, ly = -1;
+ BlockId id;
map_local *m;
if (mapname == MOB_THIS_MAP)
@@ -470,8 +472,8 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd,
if (max > 1000)
max = 1000;
- if (m == nullptr || amount <= 0 || (mob_class >= 0 && mob_class <= 1000) || mob_class > 2000) // A summon is stopped if a value is unusual
- return 0;
+ if (m == nullptr || amount <= 0 || (mobdb_checkid(mob_class) == Species())) // A summon is stopped if a value is unusual
+ return BlockId();
for (i = 0; i < amount; i++)
{
@@ -491,7 +493,7 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd,
y = ly;
}
else
- return 0; // Since reference of the place which boils first went wrong, it stops.
+ return BlockId(); // Since reference of the place which boils first went wrong, it stops.
}
id = mob_once_spawn(sd, mapname, x, y, mobname, mob_class, 1, event);
lx = x;
@@ -501,49 +503,49 @@ int mob_once_spawn_area(dumb_ptr<map_session_data> sd,
}
// TODO: deprecate these
-short mob_get_hair(int mob_class)
+short mob_get_hair(Species mob_class)
{
- return mob_db[mob_class].hair;
+ return get_mob_db(mob_class).hair;
}
-short mob_get_hair_color(int mob_class)
+short mob_get_hair_color(Species mob_class)
{
- return mob_db[mob_class].hair_color;
+ return get_mob_db(mob_class).hair_color;
}
-short mob_get_weapon(int mob_class)
+short mob_get_weapon(Species mob_class)
{
- return mob_db[mob_class].weapon;
+ return get_mob_db(mob_class).weapon;
}
-short mob_get_shield(int mob_class)
+ItemNameId mob_get_shield(Species mob_class)
{
- return mob_db[mob_class].shield;
+ return get_mob_db(mob_class).shield;
}
-short mob_get_head_top(int mob_class)
+ItemNameId mob_get_head_top(Species mob_class)
{
- return mob_db[mob_class].head_top;
+ return get_mob_db(mob_class).head_top;
}
-short mob_get_head_mid(int mob_class)
+ItemNameId mob_get_head_mid(Species mob_class)
{
- return mob_db[mob_class].head_mid;
+ return get_mob_db(mob_class).head_mid;
}
-short mob_get_head_buttom(int mob_class)
+ItemNameId mob_get_head_buttom(Species mob_class)
{
- return mob_db[mob_class].head_buttom;
+ return get_mob_db(mob_class).head_buttom;
}
-short mob_get_clothes_color(int mob_class) // Add for player monster dye - Valaris
+short mob_get_clothes_color(Species mob_class) // Add for player monster dye - Valaris
{
- return mob_db[mob_class].clothes_color; // End
+ return get_mob_db(mob_class).clothes_color; // End
}
-int mob_get_equip(int mob_class) // mob equip [Valaris]
+int mob_get_equip(Species mob_class) // mob equip [Valaris]
{
- return mob_db[mob_class].equip;
+ return get_mob_db(mob_class).equip;
}
/*==========================================
@@ -707,7 +709,7 @@ int mob_check_attack(dumb_ptr<mob_data> md)
if ((tbl = map_id2bl(md->target_id)) == NULL)
{
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
return 0;
}
@@ -725,7 +727,7 @@ int mob_check_attack(dumb_ptr<mob_data> md)
|| pc_isinvisible(tsd) || md->bl_m != tbl->bl_m || tbl->bl_prev == NULL
|| distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) >= 13)
{
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
return 0;
}
@@ -735,21 +737,21 @@ int mob_check_attack(dumb_ptr<mob_data> md)
if (md->bl_m != tbl->bl_m || tbl->bl_prev == NULL
|| distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) >= 13)
{
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
return 0;
}
}
if (md->mode == MobMode::ZERO)
- mode = mob_db[md->mob_class].mode;
+ mode = get_mob_db(md->mob_class).mode;
else
mode = md->mode;
- Race race = mob_db[md->mob_class].race;
+ Race race = get_mob_db(md->mob_class).race;
if (!bool(mode & MobMode::CAN_ATTACK))
{
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
return 0;
}
@@ -759,12 +761,12 @@ int mob_check_attack(dumb_ptr<mob_data> md)
&& race != Race::_insect
&& race != Race::_demon))
{
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
return 0;
}
- range = mob_db[md->mob_class].range;
+ range = get_mob_db(md->mob_class).range;
if (bool(mode & MobMode::CAN_MOVE))
range++;
if (distance(md->bl_x, md->bl_y, tbl->bl_x, tbl->bl_y) > range)
@@ -834,7 +836,7 @@ int mob_attack(dumb_ptr<mob_data> md, tick_t tick)
*------------------------------------------
*/
static
-void mob_stopattacked(dumb_ptr<map_session_data> sd, int id)
+void mob_stopattacked(dumb_ptr<map_session_data> sd, BlockId id)
{
nullpo_retv(sd);
@@ -903,7 +905,8 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type)
clif_foreachclient(std::bind(mob_stopattacked, ph::_1, md->bl_id));
skill_status_change_clear(md, 2); // The abnormalities in status are canceled.
md->deletetimer.cancel();
- md->hp = md->target_id = md->attacked_id = 0;
+ md->hp = 0;
+ md->target_id = md->attacked_id = BlockId();
md->state.attackable = false;
}
break;
@@ -918,7 +921,7 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type)
*------------------------------------------
*/
static
-void mob_timer(TimerData *, tick_t tick, int id, unsigned char data)
+void mob_timer(TimerData *, tick_t tick, BlockId id, unsigned char data)
{
dumb_ptr<mob_data> md;
dumb_ptr<block_list> bl;
@@ -1012,7 +1015,7 @@ int mob_walktoxy(dumb_ptr<mob_data> md, int x, int y, int easy)
*------------------------------------------
*/
static
-void mob_delayspawn(TimerData *, tick_t, int m)
+void mob_delayspawn(TimerData *, tick_t, BlockId m)
{
mob_spawn(m);
}
@@ -1022,7 +1025,7 @@ void mob_delayspawn(TimerData *, tick_t, int m)
*------------------------------------------
*/
static
-int mob_setdelayspawn(int id)
+int mob_setdelayspawn(BlockId id)
{
dumb_ptr<mob_data> md;
dumb_ptr<block_list> bl;
@@ -1066,7 +1069,7 @@ int mob_setdelayspawn(int id)
* Mob spawning. Initialization is also variously here.
*------------------------------------------
*/
-int mob_spawn(int id)
+int mob_spawn(BlockId id)
{
int x = 0, y = 0;
tick_t tick = gettick();
@@ -1130,15 +1133,15 @@ int mob_spawn(int id)
map_addblock(md);
really_memzero_this(&md->state);
- md->attacked_id = 0;
- md->target_id = 0;
+ md->attacked_id = BlockId();
+ md->target_id = BlockId();
md->move_fail_count = 0;
mob_init(md);
if (!md->stats[mob_stat::SPEED])
- md->stats[mob_stat::SPEED] = mob_db[md->mob_class].speed;
- md->def_ele = mob_db[md->mob_class].element;
- md->master_id = 0;
+ md->stats[mob_stat::SPEED] = get_mob_db(md->mob_class).speed;
+ md->def_ele = get_mob_db(md->mob_class).element;
+ md->master_id = BlockId();
md->master_dist = 0;
md->state.state = MS::IDLE;
@@ -1152,8 +1155,8 @@ int mob_spawn(int id)
// md->deletetimer = nullptr;
// md->skilltimer = nullptr;
- md->skilldelayup = make_unique<tick_t[]>(mob_db[md->mob_class].skills.size());
- for (size_t i = 0; i < mob_db[md->mob_class].skills.size(); i++)
+ md->skilldelayup = make_unique<tick_t[]>(get_mob_db(md->mob_class).skills.size());
+ for (size_t i = 0; i < get_mob_db(md->mob_class).skills.size(); i++)
md->skilldelayup[i] = tick - std::chrono::hours(10);
md->skillid = SkillID();
md->skilllv = 0;
@@ -1204,9 +1207,9 @@ int distance(int x0, int y0, int x1, int y1)
*/
int mob_stopattack(dumb_ptr<mob_data> md)
{
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
- md->attacked_id = 0;
+ md->attacked_id = BlockId();
return 0;
}
@@ -1331,11 +1334,11 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist)
sc_data = battle_get_sc_data(bl);
Option *option = battle_get_option(bl);
- Race race = mob_db[md->mob_class].race;
+ Race race = get_mob_db(md->mob_class).race;
if (md->mode == MobMode::ZERO)
{
- mode = mob_db[md->mob_class].mode;
+ mode = get_mob_db(md->mob_class).mode;
}
else
{
@@ -1343,11 +1346,11 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist)
}
if (!bool(mode & MobMode::CAN_ATTACK))
{
- md->target_id = 0;
+ md->target_id = BlockId();
return 0;
}
// Nothing will be carried out if there is no mind of changing TAGE by TAGE ending.
- if ((md->target_id > 0 && md->state.attackable)
+ if ((md->target_id && md->state.attackable)
&& (!bool(mode & MobMode::AGGRESSIVE)
|| !random_::chance({25 + 1, 100})))
return 0;
@@ -1410,14 +1413,14 @@ void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl,
return;
if (smd->mode == MobMode::ZERO)
- mode = mob_db[smd->mob_class].mode;
+ mode = get_mob_db(smd->mob_class).mode;
else
mode = smd->mode;
// アクティブでターゲット射程内にいるなら、ロックする
if (bool(mode & MobMode::AGGRESSIVE))
{
- Race race = mob_db[smd->mob_class].race;
+ Race race = get_mob_db(smd->mob_class).race;
//対象がPCの場合
if (tsd &&
!pc_isdead(tsd) &&
@@ -1477,7 +1480,7 @@ void mob_ai_sub_hard_lootsearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md,
if (md->mode == MobMode::ZERO)
{
- mode = mob_db[md->mob_class].mode;
+ mode = get_mob_db(md->mob_class).mode;
}
else
{
@@ -1516,8 +1519,8 @@ void mob_ai_sub_hard_linksearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md,
nullpo_retv(md);
nullpo_retv(target);
- if (md->attacked_id > 0
- && bool(mob_db[md->mob_class].mode & MobMode::ASSIST))
+ if (md->attacked_id
+ && bool(get_mob_db(md->mob_class).mode & MobMode::ASSIST))
{
if (tmd->mob_class == md->mob_class
&& tmd->bl_m == md->bl_m
@@ -1551,7 +1554,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
if ((bl = map_id2bl(md->master_id)) != NULL)
mmd = bl->is_mob();
- mode = mob_db[md->mob_class].mode;
+ mode = get_mob_db(md->mob_class).mode;
// It is not main monster/leader.
if (!mmd || mmd->bl_type != BL::MOB || mmd->bl_id != md->master_id)
@@ -1639,7 +1642,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
}
// There is the master, the master locks a target and he does not lock.
- if ((mmd->target_id > 0 && mmd->state.attackable)
+ if ((mmd->target_id && mmd->state.attackable)
&& (!md->target_id || !md->state.attackable))
{
dumb_ptr<map_session_data> sd = map_id2sd(mmd->target_id);
@@ -1647,7 +1650,7 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
&& !pc_isinvisible(sd))
{
- Race race = mob_db[md->mob_class].race;
+ Race race = get_mob_db(md->mob_class).race;
if (bool(mode & MobMode::BOSS)
|| (!sd->state.gangsterparadise
|| race == Race::_insect
@@ -1675,7 +1678,7 @@ int mob_unlocktarget(dumb_ptr<mob_data> md, tick_t tick)
{
nullpo_ret(md);
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
md->state.skillstate = MobSkillState::MSS_IDLE;
md->next_walktime = tick + std::chrono::seconds(3) + std::chrono::milliseconds(random_::to(3000));
@@ -1770,20 +1773,20 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
}
if (md->mode == MobMode::ZERO)
- mode = mob_db[md->mob_class].mode;
+ mode = get_mob_db(md->mob_class).mode;
else
mode = md->mode;
- Race race = mob_db[md->mob_class].race;
+ Race race = get_mob_db(md->mob_class).race;
// Abnormalities
if (bool(md->opt1) && md->opt1 != Opt1::_stone6)
return;
- if (!bool(mode & MobMode::CAN_ATTACK) && md->target_id > 0)
- md->target_id = 0;
+ if (!bool(mode & MobMode::CAN_ATTACK) && md->target_id)
+ md->target_id = BlockId();
- if (md->attacked_id > 0 && bool(mode & MobMode::ASSIST))
+ if (md->attacked_id && bool(mode & MobMode::ASSIST))
{ // Link monster
dumb_ptr<map_session_data> asd = map_id2sd(md->attacked_id);
if (asd)
@@ -1800,7 +1803,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
}
// It checks to see it was attacked first (if active, it is target change at 25% of probability).
- if (mode != MobMode::ZERO && md->attacked_id > 0
+ if (mode != MobMode::ZERO && md->attacked_id
&& (!md->target_id || !md->state.attackable
|| (bool(mode & MobMode::AGGRESSIVE) && random_::chance({25, 100}))))
{
@@ -1815,13 +1818,13 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
|| (dist =
distance(md->bl_x, md->bl_y, abl->bl_x, abl->bl_y)) >= 32
|| battle_check_target(bl, abl, BCT_ENEMY) == 0)
- md->attacked_id = 0;
+ md->attacked_id = BlockId();
else
{
md->target_id = md->attacked_id; // set target
md->state.attackable = true;
attack_type = 1;
- md->attacked_id = 0;
+ md->attacked_id = BlockId();
md->min_chase = dist + 13;
if (md->min_chase > 26)
md->min_chase = 26;
@@ -1831,7 +1834,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
md->state.master_check = 0;
// Processing of slave monster
- if (md->master_id > 0 && md->state.special_mob_ai == 0)
+ if (md->master_id && md->state.special_mob_ai == 0)
mob_ai_sub_hard_slavemob(md, tick);
// アクティヴモンスターの策敵 (?? of a bitter taste TIVU monster)
@@ -1872,7 +1875,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
}
// It will attack, if the candidate for an attack is.
- if (md->target_id > 0)
+ if (md->target_id)
{
if ((tbl = map_id2bl(md->target_id)))
{
@@ -1892,7 +1895,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
&& race != Race::_insect
&& race != Race::_demon))
mob_unlocktarget(md, tick); // スキルなどによる策敵妨害
- else if (!battle_check_range(md, tbl, mob_db[md->mob_class].range))
+ else if (!battle_check_range(md, tbl, get_mob_db(md->mob_class).range))
{
// 攻撃範囲外なので移動
if (!bool(mode & MobMode::CAN_MOVE))
@@ -1975,7 +1978,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
|| (dist =
distance(md->bl_x, md->bl_y, tbl->bl_x,
tbl->bl_y)) >= md->min_chase
- || !bool(mob_db[md->mob_class].mode & MobMode::LOOTER))
+ || !bool(get_mob_db(md->mob_class).mode & MobMode::LOOTER))
{
// 遠すぎるかアイテムがなくなった
mob_unlocktarget(md, tick);
@@ -2034,7 +2037,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
// mobs that are not slaves can random-walk
if (bool(mode & MobMode::CAN_MOVE)
&& mob_can_move(md)
- && (md->master_id == 0 || md->state.special_mob_ai
+ && (!md->master_id || md->state.special_mob_ai
|| md->master_dist > 10))
{
// if walktime is more than 7 seconds in the future,
@@ -2110,7 +2113,7 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick)
}
if (md->next_walktime < tick
- && bool(mob_db[md->mob_class].mode & MobMode::CAN_MOVE)
+ && bool(get_mob_db(md->mob_class).mode & MobMode::CAN_MOVE)
&& mob_can_move(md))
{
@@ -2125,8 +2128,8 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick)
// MOB which is not not the summons MOB but BOSS, either sometimes reboils.
else if (random_::chance(MOB_LAZYWARPPERC)
&& md->spawn.x0 <= 0
- && md->master_id != 0
- && !bool(mob_db[md->mob_class].mode & MobMode::BOSS))
+ && md->master_id
+ && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS))
mob_spawn(md->bl_id);
}
@@ -2137,8 +2140,8 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick)
// MOB which is not BOSS which is not Summons MOB, either -- a case -- sometimes -- leaping
if (random_::chance(MOB_LAZYWARPPERC)
&& md->spawn.x0 <= 0
- && md->master_id != 0
- && !bool(mob_db[md->mob_class].mode & MobMode::BOSS))
+ && md->master_id
+ && !bool(get_mob_db(md->mob_class).mode & MobMode::BOSS))
mob_warp(md, nullptr, -1, -1, BeingRemoveWhy::NEGATIVE1);
}
@@ -2167,7 +2170,8 @@ struct delay_item_drop
{
map_local *m;
int x, y;
- int nameid, amount;
+ ItemNameId nameid;
+ int amount;
dumb_ptr<map_session_data> first_sd, second_sd, third_sd;
};
@@ -2273,7 +2277,7 @@ int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type)
return 0;
}
-void mob_timer_delete(TimerData *, tick_t, int id)
+void mob_timer_delete(TimerData *, tick_t, BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
dumb_ptr<mob_data> md;
@@ -2289,14 +2293,14 @@ void mob_timer_delete(TimerData *, tick_t, int id)
*------------------------------------------
*/
static
-void mob_deleteslave_sub(dumb_ptr<block_list> bl, int id)
+void mob_deleteslave_sub(dumb_ptr<block_list> bl, BlockId id)
{
dumb_ptr<mob_data> md;
nullpo_retv(bl);
md = bl->is_mob();
- if (md->master_id > 0 && md->master_id == id)
+ if (md->master_id && md->master_id == id)
mob_damage(NULL, md, md->hp, 1);
}
@@ -2342,7 +2346,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
&& bool(md->mode & MobMode::TURNS_AGAINST_BAD_MASTER))
{
/* If the master hits a monster, have the monster turn against him */
- md->master_id = 0;
+ md->master_id = BlockId();
md->mode = MobMode::war; /* Regular war mode */
md->target_id = src->bl_id;
md->attacked_id = src->bl_id;
@@ -2410,7 +2414,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
}
damage_logged_pc:
- if (md->attacked_id <= 0 && md->state.special_mob_ai == 0)
+ if (!md->attacked_id && md->state.special_mob_ai == 0)
md->attacked_id = sd->bl_id;
}
if (src && src->bl_type == BL::MOB
@@ -2442,7 +2446,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
app.dmg = damage;
md->dmglogv.push_back(app);
- if (md->attacked_id <= 0 && md->state.special_mob_ai == 0)
+ if (!md->attacked_id && md->state.special_mob_ai == 0)
md->attacked_id = md2->master_id;
}
damage_logged_slave:
@@ -2544,23 +2548,23 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
per = 1;
base_exp =
- ((mob_db[md->mob_class].base_exp *
+ ((get_mob_db(md->mob_class).base_exp *
md->stats[mob_stat::XP_BONUS]) >> MOB_XP_BONUS_SHIFT) * per / 256;
if (base_exp < 1)
base_exp = 1;
if (sd && md && battle_config.pk_mode == 1
- && (mob_db[md->mob_class].lv - sd->status.base_level >= 20))
+ && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20))
{
base_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris]
}
if (md->state.special_mob_ai >= 1
&& battle_config.alchemist_summon_reward != 1)
base_exp = 0; // Added [Valaris]
- job_exp = mob_db[md->mob_class].job_exp * per / 256;
+ job_exp = get_mob_db(md->mob_class).job_exp * per / 256;
if (job_exp < 1)
job_exp = 1;
if (sd && md && battle_config.pk_mode == 1
- && (mob_db[md->mob_class].lv - sd->status.base_level >= 20))
+ && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20))
{
job_exp *= 1.15; // pk_mode additional exp if monster >20 levels [Valaris]
}
@@ -2568,8 +2572,8 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
&& battle_config.alchemist_summon_reward != 1)
job_exp = 0; // Added [Valaris]
- int pid = tmpsdi->status.party_id;
- if (pid > 0)
+ PartyId pid = tmpsdi->status.party_id;
+ if (pid)
{
std::vector<DmgLogParty>::iterator it = std::find_if(ptv.begin(), ptv.end(),
[pid](const DmgLogParty& dlp)
@@ -2613,19 +2617,19 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
if (md->state.special_mob_ai >= 1 && battle_config.alchemist_summon_reward != 1) // Added [Valaris]
break; // End
- if (mob_db[md->mob_class].dropitem[i].nameid <= 0)
+ if (!get_mob_db(md->mob_class).dropitem[i].nameid)
continue;
- random_::Fixed<int, 10000> drop_rate = mob_db[md->mob_class].dropitem[i].p;
+ random_::Fixed<int, 10000> drop_rate = get_mob_db(md->mob_class).dropitem[i].p;
if (battle_config.drops_by_luk > 0 && sd && md)
drop_rate.num += (sd->status.attrs[ATTR::LUK] * battle_config.drops_by_luk) / 100; // drops affected by luk [Valaris]
if (sd && md && battle_config.pk_mode == 1
- && (mob_db[md->mob_class].lv - sd->status.base_level >= 20))
+ && (get_mob_db(md->mob_class).lv - sd->status.base_level >= 20))
drop_rate.num *= 1.25; // pk_mode increase drops if 20 level difference [Valaris]
if (!random_::chance(drop_rate))
continue;
struct delay_item_drop ditem {};
- ditem.nameid = mob_db[md->mob_class].dropitem[i].nameid;
+ ditem.nameid = get_mob_db(md->mob_class).dropitem[i].nameid;
ditem.amount = 1;
ditem.m = md->bl_m;
ditem.x = md->bl_x;
@@ -2721,7 +2725,7 @@ int mob_heal(dumb_ptr<mob_data> md, int heal)
*------------------------------------------
*/
static
-void mob_warpslave_sub(dumb_ptr<block_list> bl, int id, int x, int y)
+void mob_warpslave_sub(dumb_ptr<block_list> bl, BlockId id, int x, int y)
{
dumb_ptr<mob_data> md = bl->is_mob();
@@ -2806,9 +2810,9 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t
PRINTF("MOB %d warp failed, mob_class = %d\n"_fmt, md->bl_id, md->mob_class);
}
- md->target_id = 0; // タゲを解除する
+ md->target_id = BlockId(); // タゲを解除する
md->state.attackable = false;
- md->attacked_id = 0;
+ md->attacked_id = BlockId();
md->state.skillstate = MobSkillState::MSS_IDLE;
mob_changestate(md, MS::IDLE, 0);
@@ -2835,7 +2839,7 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t
*------------------------------------------
*/
static
-void mob_countslave_sub(dumb_ptr<block_list> bl, int id, int *c)
+void mob_countslave_sub(dumb_ptr<block_list> bl, BlockId id, int *c)
{
dumb_ptr<mob_data> md;
@@ -2869,36 +2873,38 @@ int mob_countslave(dumb_ptr<mob_data> md)
* 手下MOB召喚
*------------------------------------------
*/
-int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag)
+int mob_summonslave(dumb_ptr<mob_data> md2, int *value_, int amount, int flag)
{
dumb_ptr<mob_data> md;
- int bx, by, count = 0, mob_class, k, a = amount;
+ int bx, by, count = 0, a = amount;
nullpo_ret(md2);
- nullpo_ret(value);
+ nullpo_ret(value_);
bx = md2->bl_x;
by = md2->bl_y;
map_local *m = md2->bl_m;
- if (value[0] <= 1000 || value[0] > 2000) // 値が異常なら召喚を止める
- return 0;
- while (count < 5 && value[count] > 1000 && value[count] <= 2000)
- count++;
+ Species values[5];
+ for (count = 0; count < 5 && values[count] != Species(); ++count)
+ values[count] = wrap<Species>(value_[count]);
if (count < 1)
return 0;
- for (k = 0; k < count; k++)
+ for (int k = 0; k < count; k++)
{
amount = a;
- mob_class = value[k];
- if (mob_class <= 1000 || mob_class > 2000)
+ Species mob_class = values[k];
+ if (mobdb_checkid(mob_class) == Species())
+ {
+ PRINTF("Warning: bad slave class %u\n"_fmt, mob_class);
continue;
+ }
for (; amount > 0; amount--)
{
int x = 0, y = 0, i = 0;
md.new_();
- if (bool(mob_db[mob_class].mode & MobMode::LOOTER))
+ if (bool(get_mob_db(mob_class).mode & MobMode::LOOTER))
md->lootitemv.clear();
while ((x <= 0
@@ -2949,7 +2955,7 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag)
*/
static
void mob_counttargeted_sub(dumb_ptr<block_list> bl,
- int id, int *c, dumb_ptr<block_list> src, ATK target_lv)
+ BlockId id, int *c, dumb_ptr<block_list> src, ATK target_lv)
{
nullpo_retv(bl);
nullpo_retv(c);
@@ -2999,7 +3005,7 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src,
* スキル使用(詠唱完了、ID指定)
*------------------------------------------
*/
-void mobskill_castend_id(TimerData *, tick_t tick, int id)
+void mobskill_castend_id(TimerData *, tick_t tick, BlockId id)
{
dumb_ptr<mob_data> md = NULL;
dumb_ptr<block_list> bl;
@@ -3038,7 +3044,7 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id)
if (range + battle_config.monster_skill_add_range < distance(md->bl_x, md->bl_y, bl->bl_x, bl->bl_y))
return;
- md->skilldelayup[md->skillidx - &mob_db[md->mob_class].skills.front()] = tick;
+ md->skilldelayup[md->skillidx - &get_mob_db(md->mob_class).skills.front()] = tick;
if (battle_config.monster_skill_log == 1)
PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt,
@@ -3065,7 +3071,7 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id)
* スキル使用(詠唱完了、場所指定)
*------------------------------------------
*/
-void mobskill_castend_pos(TimerData *, tick_t tick, int id)
+void mobskill_castend_pos(TimerData *, tick_t tick, BlockId id)
{
dumb_ptr<mob_data> md = NULL;
dumb_ptr<block_list> bl;
@@ -3089,7 +3095,7 @@ void mobskill_castend_pos(TimerData *, tick_t tick, int id)
range = battle_get_range(md) - (range + 1);
if (range + battle_config.monster_skill_add_range < distance(md->bl_x, md->bl_y, md->skillx, md->skilly))
return;
- md->skilldelayup[md->skillidx - &mob_db[md->mob_class].skills.front()] = tick;
+ md->skilldelayup[md->skillidx - &get_mob_db(md->mob_class).skills.front()] = tick;
if (battle_config.monster_skill_log == 1)
PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt,
@@ -3139,7 +3145,7 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target,
interval_t casttime = skill_castfix(md, ms->casttime);
md->state.skillcastcancel = ms->cancel;
- md->skilldelayup[ms - &mob_db[md->mob_class].skills.front()] = gettick();
+ md->skilldelayup[ms - &get_mob_db(md->mob_class).skills.front()] = gettick();
if (battle_config.monster_skill_log == 1)
PRINTF("MOB skill use target_id=%d skill=%d lv=%d cast=%d, mob_class = %d\n"_fmt,
@@ -3209,7 +3215,7 @@ int mobskill_use_pos(dumb_ptr<mob_data> md,
// delay=skill_delayfix(sd, skill_get_delay( skill_id,skill_lv) );
interval_t casttime = skill_castfix(md, ms->casttime);
- md->skilldelayup[ms - &mob_db[md->mob_class].skills.front()] = gettick();
+ md->skilldelayup[ms - &get_mob_db(md->mob_class).skills.front()] = gettick();
md->state.skillcastcancel = ms->cancel;
if (battle_config.monster_skill_log == 1)
@@ -3223,7 +3229,7 @@ int mobskill_use_pos(dumb_ptr<mob_data> md,
md->skillx = skill_x;
md->skilly = skill_y;
- md->skilltarget = 0;
+ md->skilltarget = BlockId();
md->skillid = skill_id;
md->skilllv = skill_lv;
md->skillidx = &skill_idx;
@@ -3252,7 +3258,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick,
int max_hp;
nullpo_ret(md);
- std::vector<mob_skill>& ms = mob_db[md->mob_class].skills;
+ std::vector<mob_skill>& ms = get_mob_db(md->mob_class).skills;
max_hp = battle_get_max_hp(md);
@@ -3374,42 +3380,42 @@ int mobskill_event(dumb_ptr<mob_data> md, BF flag)
*------------------------------------------
*/
static
-int mob_makedummymobdb(int mob_class)
+int mob_makedummymobdb(Species mob_class)
{
int i;
- SNPRINTF(mob_db[mob_class].name, 24, "mob%d"_fmt, mob_class);
- SNPRINTF(mob_db[mob_class].jname, 24, "mob%d"_fmt, mob_class);
- mob_db[mob_class].lv = 1;
- mob_db[mob_class].max_hp = 1000;
- mob_db[mob_class].max_sp = 1;
- mob_db[mob_class].base_exp = 2;
- mob_db[mob_class].job_exp = 1;
- mob_db[mob_class].range = 1;
- mob_db[mob_class].atk1 = 7;
- mob_db[mob_class].atk2 = 10;
- mob_db[mob_class].def = 0;
- mob_db[mob_class].mdef = 0;
- mob_db[mob_class].attrs[ATTR::STR] = 1;
- mob_db[mob_class].attrs[ATTR::AGI] = 1;
- mob_db[mob_class].attrs[ATTR::VIT] = 1;
- mob_db[mob_class].attrs[ATTR::INT] = 1;
- mob_db[mob_class].attrs[ATTR::DEX] = 6;
- mob_db[mob_class].attrs[ATTR::LUK] = 2;
- mob_db[mob_class].range2 = 10;
- mob_db[mob_class].range3 = 10;
- mob_db[mob_class].size = 0; // 1
- mob_db[mob_class].race = Race::formless;
- mob_db[mob_class].element = LevelElement{0, Element::neutral};
- mob_db[mob_class].mode = MobMode::ZERO;
- mob_db[mob_class].speed = 300;
- mob_db[mob_class].adelay = 1000;
- mob_db[mob_class].amotion = 500;
- mob_db[mob_class].dmotion = 500;
+ SNPRINTF(get_mob_db(mob_class).name, 24, "mob%d"_fmt, mob_class);
+ SNPRINTF(get_mob_db(mob_class).jname, 24, "mob%d"_fmt, mob_class);
+ get_mob_db(mob_class).lv = 1;
+ get_mob_db(mob_class).max_hp = 1000;
+ get_mob_db(mob_class).max_sp = 1;
+ get_mob_db(mob_class).base_exp = 2;
+ get_mob_db(mob_class).job_exp = 1;
+ get_mob_db(mob_class).range = 1;
+ get_mob_db(mob_class).atk1 = 7;
+ get_mob_db(mob_class).atk2 = 10;
+ get_mob_db(mob_class).def = 0;
+ get_mob_db(mob_class).mdef = 0;
+ get_mob_db(mob_class).attrs[ATTR::STR] = 1;
+ get_mob_db(mob_class).attrs[ATTR::AGI] = 1;
+ get_mob_db(mob_class).attrs[ATTR::VIT] = 1;
+ get_mob_db(mob_class).attrs[ATTR::INT] = 1;
+ get_mob_db(mob_class).attrs[ATTR::DEX] = 6;
+ get_mob_db(mob_class).attrs[ATTR::LUK] = 2;
+ get_mob_db(mob_class).range2 = 10;
+ get_mob_db(mob_class).range3 = 10;
+ get_mob_db(mob_class).size = 0; // 1
+ get_mob_db(mob_class).race = Race::formless;
+ get_mob_db(mob_class).element = LevelElement{0, Element::neutral};
+ get_mob_db(mob_class).mode = MobMode::ZERO;
+ get_mob_db(mob_class).speed = 300;
+ get_mob_db(mob_class).adelay = 1000;
+ get_mob_db(mob_class).amotion = 500;
+ get_mob_db(mob_class).dmotion = 500;
for (i = 0; i < 8; i++)
{
- mob_db[mob_class].dropitem[i].nameid = 0;
- mob_db[mob_class].dropitem[i].p.num = 0;
+ get_mob_db(mob_class).dropitem[i].nameid = ItemNameId();
+ get_mob_db(mob_class).dropitem[i].p.num = 0;
}
return 0;
}
@@ -3439,7 +3445,7 @@ bool mob_readdb(ZString filename)
AString line;
while (in.getline(line))
{
- int mob_class;
+ Species mob_class;
if (is_comment(line))
continue;
@@ -3509,7 +3515,7 @@ bool mob_readdb(ZString filename)
)
);
- if (!okay || mob_class <= 1000 || mob_class > 2000)
+ if (!okay || mobdb_checkid(mob_class) == Species())
{
PRINTF("bad mob line: %s\n"_fmt, line);
rv = false;
@@ -3517,52 +3523,52 @@ bool mob_readdb(ZString filename)
}
// TODO move this lower
- mob_db[mob_class] = std::move(mdbv);
+ get_mob_db(mob_class) = std::move(mdbv);
- if (mob_db[mob_class].base_exp < 0)
- mob_db[mob_class].base_exp = 0;
- else if (mob_db[mob_class].base_exp > 0
- && (mob_db[mob_class].base_exp *
+ if (get_mob_db(mob_class).base_exp < 0)
+ get_mob_db(mob_class).base_exp = 0;
+ else if (get_mob_db(mob_class).base_exp > 0
+ && (get_mob_db(mob_class).base_exp *
battle_config.base_exp_rate / 100 > 1000000000
- || mob_db[mob_class].base_exp *
+ || get_mob_db(mob_class).base_exp *
battle_config.base_exp_rate / 100 < 0))
- mob_db[mob_class].base_exp = 1000000000;
+ get_mob_db(mob_class).base_exp = 1000000000;
else
- mob_db[mob_class].base_exp = mob_db[mob_class].base_exp * battle_config.base_exp_rate / 100;
+ get_mob_db(mob_class).base_exp = get_mob_db(mob_class).base_exp * battle_config.base_exp_rate / 100;
- if (mob_db[mob_class].job_exp < 0)
- mob_db[mob_class].job_exp = 0;
- else if (mob_db[mob_class].job_exp > 0
- && (mob_db[mob_class].job_exp * battle_config.job_exp_rate /
+ if (get_mob_db(mob_class).job_exp < 0)
+ get_mob_db(mob_class).job_exp = 0;
+ else if (get_mob_db(mob_class).job_exp > 0
+ && (get_mob_db(mob_class).job_exp * battle_config.job_exp_rate /
100 > 1000000000
- || mob_db[mob_class].job_exp *
+ || get_mob_db(mob_class).job_exp *
battle_config.job_exp_rate / 100 < 0))
- mob_db[mob_class].job_exp = 1000000000;
+ get_mob_db(mob_class).job_exp = 1000000000;
else
- mob_db[mob_class].job_exp = mob_db[mob_class].job_exp * battle_config.job_exp_rate / 100;
+ get_mob_db(mob_class).job_exp = get_mob_db(mob_class).job_exp * battle_config.job_exp_rate / 100;
for (int i = 0; i < 8; i++)
{
- int rate = mob_db[mob_class].dropitem[i].p.num;
+ int rate = get_mob_db(mob_class).dropitem[i].p.num;
if (rate < 1) rate = 1;
if (rate > 10000) rate = 10000;
- mob_db[mob_class].dropitem[i].p.num = rate;
+ get_mob_db(mob_class).dropitem[i].p.num = rate;
}
- mob_db[mob_class].skills.clear();
+ get_mob_db(mob_class).skills.clear();
- mob_db[mob_class].hair = 0;
- mob_db[mob_class].hair_color = 0;
- mob_db[mob_class].weapon = 0;
- mob_db[mob_class].shield = 0;
- mob_db[mob_class].head_top = 0;
- mob_db[mob_class].head_mid = 0;
- mob_db[mob_class].head_buttom = 0;
- mob_db[mob_class].clothes_color = 0; //Add for player monster dye - Valaris
+ get_mob_db(mob_class).hair = 0;
+ get_mob_db(mob_class).hair_color = 0;
+ get_mob_db(mob_class).weapon = 0;
+ get_mob_db(mob_class).shield = ItemNameId();
+ get_mob_db(mob_class).head_top = ItemNameId();
+ get_mob_db(mob_class).head_mid = ItemNameId();
+ get_mob_db(mob_class).head_buttom = ItemNameId();
+ get_mob_db(mob_class).clothes_color = 0; //Add for player monster dye - Valaris
- if (mob_db[mob_class].base_exp == 0)
- mob_db[mob_class].base_exp = mob_gen_exp(&mob_db[mob_class]);
+ if (get_mob_db(mob_class).base_exp == 0)
+ get_mob_db(mob_class).base_exp = mob_gen_exp(&get_mob_db(mob_class));
}
PRINTF("read %s done\n"_fmt, filename);
}
@@ -3650,15 +3656,15 @@ bool mob_readskilldb(ZString filename)
AString line;
while (in.getline(line))
{
- int mob_id;
+ Species mob_id;
if (is_comment(line))
continue;
XString blah;
- if (extract(line, record<','>(&mob_id, &blah)) && mob_id > 0 && blah == "clear"_s)
+ if (extract(line, record<','>(&mob_id, &blah)) && mobdb_checkid(mob_id) != Species() && blah == "clear"_s)
{
- mob_db[mob_id].skills.clear();
+ get_mob_db(mob_id).skills.clear();
continue;
}
@@ -3706,13 +3712,13 @@ bool mob_readskilldb(ZString filename)
msv.casttime = std::chrono::milliseconds(casttime);
msv.delay = std::chrono::milliseconds(delay);
- if (mob_id <= 0)
+ if (mobdb_checkid(mob_id) == Species())
{
rv = false;
continue;
}
- mob_db[mob_id].skills.push_back(std::move(msv));
+ get_mob_db(mob_id).skills.push_back(std::move(msv));
}
PRINTF("read %s done\n"_fmt, filename);
}
diff --git a/src/map/mob.hpp b/src/map/mob.hpp
index 570b5a9..d39a2ac 100644
--- a/src/map/mob.hpp
+++ b/src/map/mob.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "mob.t.hpp"
@@ -72,41 +72,43 @@ struct mob_db_
int mutations_nr, mutation_power;
struct
{
- int nameid;
+ ItemNameId nameid;
random_::Fixed<int, 10000> p;
} dropitem[8];
- short hair, hair_color, weapon, shield, head_top, head_mid, head_buttom, option, clothes_color; // [Valaris]
+ short hair, hair_color, weapon;
+ ItemNameId shield, head_top, head_mid, head_buttom;
+ short option, clothes_color; // [Valaris]
int equip; // [Valaris]
std::vector<struct mob_skill> skills;
};
-extern struct mob_db_ mob_db[];
+struct mob_db_& get_mob_db(Species);
-int mobdb_searchname(MobName str);
-int mobdb_checkid(const int id);
-int mob_once_spawn(dumb_ptr<map_session_data> sd,
+Species mobdb_searchname(MobName str);
+Species mobdb_checkid(Species id);
+BlockId mob_once_spawn(dumb_ptr<map_session_data> sd,
MapName mapname, int x, int y,
- MobName mobname, int class_, int amount,
+ MobName mobname, Species class_, int amount,
NpcEvent event);
-int mob_once_spawn_area(dumb_ptr<map_session_data> sd,
+BlockId mob_once_spawn_area(dumb_ptr<map_session_data> sd,
MapName mapname, int x0, int y0, int x1, int y1,
- MobName mobname, int class_, int amount,
+ MobName mobname, Species class_, int amount,
NpcEvent event);
int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist);
int mob_stop_walking(dumb_ptr<mob_data> md, int type);
int mob_stopattack(dumb_ptr<mob_data>);
-int mob_spawn(int);
+int mob_spawn(BlockId);
int mob_damage(dumb_ptr<block_list>, dumb_ptr<mob_data>, int, int);
int mob_heal(dumb_ptr<mob_data>, int);
-short mob_get_hair(int);
-short mob_get_hair_color(int);
-short mob_get_weapon(int);
-short mob_get_shield(int);
-short mob_get_head_top(int);
-short mob_get_head_mid(int);
-short mob_get_head_buttom(int);
-short mob_get_clothes_color(int); //player mob dye [Valaris]
-int mob_get_equip(int); // mob equip [Valaris]
+short mob_get_hair(Species);
+short mob_get_hair_color(Species);
+short mob_get_weapon(Species);
+ItemNameId mob_get_shield(Species);
+ItemNameId mob_get_head_top(Species);
+ItemNameId mob_get_head_mid(Species);
+ItemNameId mob_get_head_buttom(Species);
+short mob_get_clothes_color(Species); //player mob dye [Valaris]
+int mob_get_equip(Species); // mob equip [Valaris]
bool mob_readdb(ZString filename);
bool mob_readskilldb(ZString filename);
@@ -114,7 +116,7 @@ void do_init_mob2(void);
int mob_delete(dumb_ptr<mob_data> md);
int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type);
-void mob_timer_delete(TimerData *, tick_t, int);
+void mob_timer_delete(TimerData *, tick_t, BlockId);
int mob_deleteslave(dumb_ptr<mob_data> md);
@@ -125,8 +127,8 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t
int mobskill_use(dumb_ptr<mob_data> md, tick_t tick, MobSkillCondition event);
int mobskill_event(dumb_ptr<mob_data> md, BF flag);
-void mobskill_castend_id(TimerData *tid, tick_t tick, int id);
-void mobskill_castend_pos(TimerData *tid, tick_t tick, int id);
+void mobskill_castend_id(TimerData *tid, tick_t tick, BlockId id);
+void mobskill_castend_pos(TimerData *tid, tick_t tick, BlockId id);
int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag);
void mob_reload(void);
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 3cef7c0..9f606de 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -60,13 +60,15 @@ static
std::list<AString> npc_srcs;
static
-int npc_id = START_NPC_NUM;
+BlockId npc_id = START_NPC_NUM;
static
int npc_warp, npc_shop, npc_script, npc_mob;
-int npc_get_new_npc_id(void)
+BlockId npc_get_new_npc_id(void)
{
- return npc_id++;
+ BlockId rv = npc_id;
+ npc_id = next(npc_id);
+ return rv;
}
struct event_data
@@ -169,7 +171,7 @@ int npc_event_dequeue(dumb_ptr<map_session_data> sd)
{
nullpo_ret(sd);
- sd->npc_id = 0;
+ sd->npc_id = BlockId();
if (!sd->eventqueuel.empty())
{
@@ -220,7 +222,7 @@ void npc_timer_event(NpcEvent eventname)
*/
static
void npc_event_doall_sub(NpcEvent key, struct event_data *ev,
- int *c, ScriptLabel name, int rid, Slice<argrec_t> argv)
+ int *c, ScriptLabel name, BlockId rid, Slice<argrec_t> argv)
{
ScriptLabel p = key.label;
@@ -234,7 +236,7 @@ void npc_event_doall_sub(NpcEvent key, struct event_data *ev,
}
}
-int npc_event_doall_l(ScriptLabel name, int rid, Slice<argrec_t> args)
+int npc_event_doall_l(ScriptLabel name, BlockId rid, Slice<argrec_t> args)
{
int c = 0;
@@ -245,7 +247,7 @@ int npc_event_doall_l(ScriptLabel name, int rid, Slice<argrec_t> args)
static
void npc_event_do_sub(NpcEvent key, struct event_data *ev,
- int *c, NpcEvent name, int rid, Slice<argrec_t> argv)
+ int *c, NpcEvent name, BlockId rid, Slice<argrec_t> argv)
{
nullpo_retv(ev);
@@ -257,7 +259,7 @@ void npc_event_do_sub(NpcEvent key, struct event_data *ev,
}
}
-int npc_event_do_l(NpcEvent name, int rid, Slice<argrec_t> args)
+int npc_event_do_l(NpcEvent name, BlockId rid, Slice<argrec_t> args)
{
int c = 0;
@@ -322,7 +324,7 @@ int npc_event_do_oninit(void)
/// This will be called later if you call npc_timerevent_start.
/// This function may only expire, but not deactivate, the counter.
static
-void npc_timerevent(TimerData *, tick_t tick, int id, interval_t data)
+void npc_timerevent(TimerData *, tick_t tick, BlockId id, interval_t data)
{
dumb_ptr<npc_data_script> nd = map_id2bl(id)->is_npc()->is_script();
assert (nd != NULL);
@@ -345,7 +347,7 @@ void npc_timerevent(TimerData *, tick_t tick, int id, interval_t data)
id, next));
}
- run_script(ScriptPointer(nd->scr.script.get(), te->pos), 0, nd->bl_id);
+ run_script(ScriptPointer(nd->scr.script.get(), te->pos), BlockId(), nd->bl_id);
}
/// Start (or resume) counting ticks to the next npc_timerevent.
@@ -500,7 +502,7 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname,
return 1;
}
- if (sd->npc_id != 0)
+ if (sd->npc_id)
{
sd->eventqueuel.push_back(eventname);
return 1;
@@ -526,7 +528,7 @@ void npc_command_sub(NpcEvent key, struct event_data *ev, NpcName npcname, XStri
XString temp = key.label.xslice_t(9);
if (command == temp)
- run_script(ScriptPointer(ev->nd->scr.script.get(), ev->pos), 0, ev->nd->bl_id);
+ run_script(ScriptPointer(ev->nd->scr.script.get(), ev->pos), BlockId(), ev->nd->bl_id);
}
}
@@ -626,7 +628,7 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y)
*------------------------------------------
*/
static
-int npc_checknear(dumb_ptr<map_session_data> sd, int id)
+int npc_checknear(dumb_ptr<map_session_data> sd, BlockId id)
{
dumb_ptr<npc_data> nd;
@@ -657,13 +659,13 @@ int npc_checknear(dumb_ptr<map_session_data> sd, int id)
* クリック時のNPC処理
*------------------------------------------
*/
-int npc_click(dumb_ptr<map_session_data> sd, int id)
+int npc_click(dumb_ptr<map_session_data> sd, BlockId id)
{
dumb_ptr<npc_data> nd;
nullpo_retr(1, sd);
- if (sd->npc_id != 0)
+ if (sd->npc_id)
{
if (battle_config.error_log)
PRINTF("npc_click: npc_id != 0\n"_fmt);
@@ -706,7 +708,7 @@ int npc_click(dumb_ptr<map_session_data> sd, int id)
*
*------------------------------------------
*/
-int npc_scriptcont(dumb_ptr<map_session_data> sd, int id)
+int npc_scriptcont(dumb_ptr<map_session_data> sd, BlockId id)
{
dumb_ptr<npc_data> nd;
@@ -738,7 +740,7 @@ int npc_scriptcont(dumb_ptr<map_session_data> sd, int id)
*
*------------------------------------------
*/
-int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type)
+int npc_buysellsel(dumb_ptr<map_session_data> sd, BlockId id, int type)
{
dumb_ptr<npc_data> nd;
@@ -752,7 +754,7 @@ int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type)
{
if (battle_config.error_log)
PRINTF("no such shop npc : %d\n"_fmt, id);
- sd->npc_id = 0;
+ sd->npc_id = BlockId();
return 1;
}
if (nd->flag & 1) // 無効化されている
@@ -794,24 +796,28 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
for (i = 0, w = 0, z = 0; i < n; i++)
{
+ // TODO this *really needs to be made into a struct
+ const uint16_t& item_l_count = item_list[i * 2];
+ const ItemNameId& item_l_id = wrap<ItemNameId>(item_list[i * 2 + 1]);
+
for (j = 0; j < nd->is_shop()->shop_items.size(); j++)
{
- if (nd->is_shop()->shop_items[j].nameid == item_list[i * 2 + 1])
+ if (nd->is_shop()->shop_items[j].nameid == item_l_id)
break;
}
if (j == nd->is_shop()->shop_items.size())
return 3;
- z += static_cast<double>(nd->is_shop()->shop_items[j].value) * item_list[i * 2];
- itemamount += item_list[i * 2];
+ z += static_cast<double>(nd->is_shop()->shop_items[j].value) * item_l_count;
+ itemamount += item_l_count;
- switch (pc_checkadditem(sd, item_list[i * 2 + 1], item_list[i * 2]))
+ switch (pc_checkadditem(sd, item_l_id, item_l_count))
{
case ADDITEM::EXIST:
break;
case ADDITEM::NEW:
- if (itemdb_isequip(item_list[i * 2 + 1]))
- new_stacks += item_list[i * 2];
+ if (itemdb_isequip(item_l_id))
+ new_stacks += item_l_count;
else
new_stacks++;
break;
@@ -819,7 +825,7 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
return 2;
}
- w += itemdb_weight(item_list[i * 2 + 1]) * item_list[i * 2];
+ w += itemdb_weight(item_l_id) * item_l_count;
}
if (z > static_cast<double>(sd->status.zeny))
@@ -828,17 +834,20 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
return 2; // 重量超過
if (pc_inventoryblank(sd) < new_stacks)
return 3; // 種類数超過
- if (sd->trade_partner != 0)
+ if (sd->trade_partner)
return 4; // cant buy while trading
pc_payzeny(sd, static_cast<int>(z));
for (i = 0; i < n; i++)
{
+ const uint16_t& item_l_count = item_list[i * 2];
+ const ItemNameId& item_l_id = wrap<ItemNameId>(item_list[i * 2 + 1]);
+
struct item_data *item_data;
- if ((item_data = itemdb_exists(item_list[i * 2 + 1])) != NULL)
+ if ((item_data = itemdb_exists(item_l_id)) != NULL)
{
- int amount = item_list[i * 2];
+ int amount = item_l_count;
struct item item_tmp {};
item_tmp.nameid = item_data->nameid;
@@ -881,14 +890,13 @@ int npc_selllist(dumb_ptr<map_session_data> sd, int n,
return 1;
for (i = 0, z = 0; i < n; i++)
{
- int nameid;
if (item_list[i * 2] - 2 < 0 || item_list[i * 2] - 2 >= MAX_INVENTORY)
return 1;
- nameid = sd->status.inventory[item_list[i * 2] - 2].nameid;
- if (nameid == 0 ||
+ ItemNameId nameid = sd->status.inventory[item_list[i * 2] - 2].nameid;
+ if (!nameid ||
sd->status.inventory[item_list[i * 2] - 2].amount < item_list[i * 2 + 1])
return 1;
- if (sd->trade_partner != 0)
+ if (sd->trade_partner)
return 2; // cant sell while trading
z += static_cast<double>(itemdb_value_sell(nameid)) * item_list[i * 2 + 1];
itemamount += item_list[i * 2 + 1];
@@ -1076,7 +1084,7 @@ bool extract(XString xs, npc_item_list *itv)
if (!extract(xs, record<':'>(&name_or_id, &itv->value)))
return false;
struct item_data *id = nullptr;
- if (extract(name_or_id, &itv->nameid) && itv->nameid > 0)
+ if (extract(name_or_id, &itv->nameid) && itv->nameid)
goto return_true;
id = itemdb_searchname(name_or_id.rstrip());
@@ -1456,7 +1464,8 @@ int npc_parse_function(XString, XString, XString w3, ZString,
static
int npc_parse_mob(XString w1, XString, MobName w3, ZString w4)
{
- int x, y, xs, ys, mob_class, num;
+ int x, y, xs, ys, num;
+ Species mob_class;
int i;
MapName mapname;
NpcEvent eventname;
@@ -1491,9 +1500,9 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4)
md->bl_x = x;
md->bl_y = y;
if (w3 == ENGLISH_NAME)
- md->name = mob_db[mob_class].name;
+ md->name = get_mob_db(mob_class).name;
else if (w3 == JAPANESE_NAME)
- md->name = mob_db[mob_class].jname;
+ md->name = get_mob_db(mob_class).jname;
else
md->name = w3;
@@ -1510,8 +1519,8 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4)
really_memzero_this(&md->state);
// md->timer = nullptr;
- md->target_id = 0;
- md->attacked_id = 0;
+ md->target_id = BlockId();
+ md->attacked_id = BlockId();
md->lootitemv.clear();
@@ -1680,7 +1689,7 @@ bool do_init_npc(void)
rv = false;
continue;
}
- PRINTF("\rLoading NPCs [%d]: %-54s"_fmt, npc_id - START_NPC_NUM,
+ PRINTF("\rLoading NPCs [%d]: %-54s"_fmt, unwrap<BlockId>(npc_id) - unwrap<BlockId>(START_NPC_NUM),
nsl);
int lines = 0;
AString zline;
@@ -1760,7 +1769,7 @@ bool do_init_npc(void)
fflush(stdout);
}
PRINTF("\rNPCs Loaded: %d [Warps:%d Shops:%d Scripts:%d Mobs:%d] %20s\n"_fmt,
- npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, ""_s);
+ unwrap<BlockId>(npc_id) - unwrap<BlockId>(START_NPC_NUM), npc_warp, npc_shop, npc_script, npc_mob, ""_s);
if (script_errors)
{
diff --git a/src/map/npc.hpp b/src/map/npc.hpp
index eb9a5eb..3800fb7 100644
--- a/src/map/npc.hpp
+++ b/src/map/npc.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cstddef>
# include <cstdint>
@@ -32,7 +32,7 @@
# include "map.hpp"
-constexpr int START_NPC_NUM = 110000000;
+constexpr BlockId START_NPC_NUM = wrap<BlockId>(110000000);
constexpr int WARP_CLASS = 45;
constexpr int WARP_DEBUG_CLASS = 722;
@@ -43,9 +43,9 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent npcname, int);
void npc_timer_event(NpcEvent eventname); // Added by RoVeRT
int npc_command(dumb_ptr<map_session_data> sd, NpcName npcname, XString command);
int npc_touch_areanpc(dumb_ptr<map_session_data>, map_local *, int, int);
-int npc_click(dumb_ptr<map_session_data>, int);
-int npc_scriptcont(dumb_ptr<map_session_data>, int);
-int npc_buysellsel(dumb_ptr<map_session_data>, int, int);
+int npc_click(dumb_ptr<map_session_data>, BlockId);
+int npc_scriptcont(dumb_ptr<map_session_data>, BlockId);
+int npc_buysellsel(dumb_ptr<map_session_data>, BlockId, int);
int npc_buylist(dumb_ptr<map_session_data>, int, const uint16_t *);
int npc_selllist(dumb_ptr<map_session_data>, int, const uint16_t *);
int npc_parse_warp(XString w1, XString, NpcName w3, XString w4);
@@ -53,7 +53,7 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4);
int npc_enable(NpcName name, bool flag);
dumb_ptr<npc_data> npc_name2id(NpcName name);
-int npc_get_new_npc_id(void);
+BlockId npc_get_new_npc_id(void);
/**
* Spawns and installs a talk-only NPC
@@ -73,17 +73,17 @@ void npc_delsrcfile(XString);
bool do_init_npc(void);
int npc_event_do_oninit(void);
-int npc_event_doall_l(ScriptLabel name, int rid, Slice<argrec_t> argv);
-int npc_event_do_l(NpcEvent name, int rid, Slice<argrec_t> argv);
+int npc_event_doall_l(ScriptLabel name, BlockId rid, Slice<argrec_t> argv);
+int npc_event_do_l(NpcEvent name, BlockId rid, Slice<argrec_t> argv);
inline
int npc_event_doall(ScriptLabel name)
{
- return npc_event_doall_l(name, 0, nullptr);
+ return npc_event_doall_l(name, BlockId(), nullptr);
}
inline
int npc_event_do(NpcEvent name)
{
- return npc_event_do_l(name, 0, nullptr);
+ return npc_event_do_l(name, BlockId(), nullptr);
}
void npc_timerevent_start(dumb_ptr<npc_data_script> nd);
diff --git a/src/map/party.cpp b/src/map/party.cpp
index 876e6bb..7d3c89c 100644
--- a/src/map/party.cpp
+++ b/src/map/party.cpp
@@ -47,7 +47,7 @@
constexpr interval_t PARTY_SEND_XYHP_INVERVAL = std::chrono::seconds(1);
static
-Map<int, struct party> party_db;
+Map<PartyId, struct party> party_db;
static
void party_check_conflict(dumb_ptr<map_session_data> sd);
@@ -64,7 +64,7 @@ void do_init_party(void)
}
// 検索
-struct party *party_search(int party_id)
+struct party *party_search(PartyId party_id)
{
return party_db.search(party_id);
}
@@ -97,7 +97,7 @@ int party_create(dumb_ptr<map_session_data> sd, PartyName name)
clif_party_created(sd, 1);
/* Make sure the character isn't already in a party. */
- if (sd->status.party_id == 0)
+ if (!sd->status.party_id)
intif_create_party(sd, name);
else
clif_party_created(sd, 2);
@@ -106,10 +106,10 @@ int party_create(dumb_ptr<map_session_data> sd, PartyName name)
}
/* Relay the result of a party creation request. */
-void party_created(int account_id, int fail, int party_id, PartyName name)
+void party_created(AccountId account_id, int fail, PartyId party_id, PartyName name)
{
dumb_ptr<map_session_data> sd;
- sd = map_id2sd(account_id);
+ sd = map_id2sd(account_to_block(account_id));
nullpo_retv(sd);
@@ -138,7 +138,7 @@ void party_created(int account_id, int fail, int party_id, PartyName name)
}
// 情報要求
-void party_request_info(int party_id)
+void party_request_info(PartyId party_id)
{
intif_request_partyinfo(party_id);
}
@@ -175,7 +175,7 @@ int party_check_member(struct party *p)
}
if (f)
{
- sd->status.party_id = 0;
+ sd->status.party_id = PartyId();
if (battle_config.error_log)
PRINTF("party: check_member %d[%s] is not member\n"_fmt,
sd->status_key.account_id, sd->status_key.name);
@@ -187,7 +187,7 @@ int party_check_member(struct party *p)
}
// 情報所得失敗(そのIDのキャラを全部未所属にする)
-int party_recv_noinfo(int party_id)
+int party_recv_noinfo(PartyId party_id)
{
for (io::FD i : iter_fds())
{
@@ -198,7 +198,7 @@ int party_recv_noinfo(int party_id)
if (sd && sd->state.auth)
{
if (sd->status.party_id == party_id)
- sd->status.party_id = 0;
+ sd->status.party_id = PartyId();
}
}
return 0;
@@ -225,7 +225,7 @@ int party_recv_info(const struct party *sp)
for (i = 0; i < MAX_PARTY; i++)
{ // sdの設定
- dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id);
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id));
p->member[i].sd = (sd != NULL
&& sd->status.party_id == p->party_id) ? sd.operator->() : NULL;
}
@@ -247,9 +247,9 @@ int party_recv_info(const struct party *sp)
}
/* Process party invitation from sd to account_id. */
-int party_invite(dumb_ptr<map_session_data> sd, int account_id)
+int party_invite(dumb_ptr<map_session_data> sd, AccountId account_id)
{
- dumb_ptr<map_session_data> tsd = map_id2sd(account_id);
+ dumb_ptr<map_session_data> tsd = map_id2sd(account_to_block(account_id));
struct party *p = party_search(sd->status.party_id);
int i;
int full = 1; /* Indicates whether or not there's room for one more. */
@@ -271,7 +271,7 @@ int party_invite(dumb_ptr<map_session_data> sd, int account_id)
}
/* The target player is already in a party, or has a pending invitation. */
- if (tsd->status.party_id > 0 || tsd->party_invite > 0)
+ if (tsd->status.party_id || tsd->party_invite)
{
clif_party_inviteack(sd, tsd->status_key.name, 0);
return 0;
@@ -311,7 +311,7 @@ int party_invite(dumb_ptr<map_session_data> sd, int account_id)
}
/* Process response to party invitation. */
-int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id, int flag)
+int party_reply_invite(dumb_ptr<map_session_data> sd, AccountId account_id, int flag)
{
nullpo_ret(sd);
@@ -335,19 +335,19 @@ int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id, int flag)
/* This is the player who sent the invitation. */
dumb_ptr<map_session_data> tsd = NULL;
- sd->party_invite = 0;
- sd->party_invite_account = 0;
+ sd->party_invite = PartyId();
+ sd->party_invite_account = AccountId();
- if ((tsd = map_id2sd(account_id)))
+ if ((tsd = map_id2sd(account_to_block(account_id))))
clif_party_inviteack(tsd, sd->status_key.name, 1);
}
return 0;
}
// パーティが追加された
-int party_member_added(int party_id, int account_id, int flag)
+int party_member_added(PartyId party_id, AccountId account_id, int flag)
{
- dumb_ptr<map_session_data> sd = map_id2sd(account_id), sd2;
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)), sd2;
struct party *p = party_search(party_id);
if (sd == NULL)
@@ -361,9 +361,9 @@ int party_member_added(int party_id, int account_id, int flag)
}
return 0;
}
- sd2 = map_id2sd(sd->party_invite_account);
- sd->party_invite = 0;
- sd->party_invite_account = 0;
+ sd2 = map_id2sd(account_to_block(sd->party_invite_account));
+ sd->party_invite = PartyId();
+ sd->party_invite_account = AccountId();
if (p == NULL)
{
@@ -395,7 +395,7 @@ int party_member_added(int party_id, int account_id, int flag)
}
// パーティ除名要求
-int party_removemember(dumb_ptr<map_session_data> sd, int account_id)
+int party_removemember(dumb_ptr<map_session_data> sd, AccountId account_id)
{
struct party *p;
int i;
@@ -446,9 +446,9 @@ int party_leave(dumb_ptr<map_session_data> sd)
}
// パーティメンバが脱退した
-int party_member_leaved(int party_id, int account_id, CharName name)
+int party_member_leaved(PartyId party_id, AccountId account_id, CharName name)
{
- dumb_ptr<map_session_data> sd = map_id2sd(account_id);
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id));
struct party *p = party_search(party_id);
if (p != NULL)
{
@@ -457,20 +457,20 @@ int party_member_leaved(int party_id, int account_id, CharName name)
if (p->member[i].account_id == account_id)
{
clif_party_leaved(p, sd, account_id, name, 0x00);
- p->member[i].account_id = 0;
+ p->member[i].account_id = AccountId();
p->member[i].sd = NULL;
}
}
if (sd != NULL && sd->status.party_id == party_id)
{
- sd->status.party_id = 0;
+ sd->status.party_id = PartyId();
sd->party_sended = 0;
}
return 0;
}
// パーティ解散通知
-int party_broken(int party_id)
+int party_broken(PartyId party_id)
{
struct party *p;
int i;
@@ -484,7 +484,7 @@ int party_broken(int party_id)
clif_party_leaved(p, dumb_ptr<map_session_data>(p->member[i].sd),
p->member[i].account_id, p->member[i].name,
0x10);
- p->member[i].sd->status.party_id = 0;
+ p->member[i].sd->status.party_id = PartyId();
p->member[i].sd->party_sended = 0;
}
}
@@ -499,7 +499,7 @@ int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item)
nullpo_ret(sd);
- if (sd->status.party_id == 0
+ if (!sd->status.party_id
|| (p = party_search(sd->status.party_id)) == NULL)
return 0;
intif_party_changeoption(sd->status.party_id, sd->status_key.account_id, exp,
@@ -508,11 +508,11 @@ int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item)
}
// パーティの設定変更通知
-int party_optionchanged(int party_id, int account_id, int exp, int item,
+int party_optionchanged(PartyId party_id, AccountId account_id, int exp, int item,
int flag)
{
struct party *p;
- dumb_ptr<map_session_data> sd = map_id2sd(account_id);
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id));
if ((p = party_search(party_id)) == NULL)
return 0;
@@ -525,7 +525,7 @@ int party_optionchanged(int party_id, int account_id, int exp, int item,
}
// パーティメンバの移動通知
-void party_recv_movemap(int party_id, int account_id, MapName mapname,
+void party_recv_movemap(PartyId party_id, AccountId account_id, MapName mapname,
int online, int lv)
{
struct party *p;
@@ -558,7 +558,7 @@ void party_recv_movemap(int party_id, int account_id, MapName mapname,
for (i = 0; i < MAX_PARTY; i++)
{ // sd再設定
- dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id);
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id));
p->member[i].sd = (sd != NULL
&& sd->status.party_id == p->party_id) ? sd.operator->() : NULL;
}
@@ -575,7 +575,7 @@ int party_send_movemap(dumb_ptr<map_session_data> sd)
nullpo_ret(sd);
- if (sd->status.party_id == 0)
+ if (!sd->status.party_id)
return 0;
intif_party_changemap(sd, 1);
@@ -607,7 +607,7 @@ int party_send_logout(dumb_ptr<map_session_data> sd)
nullpo_ret(sd);
- if (sd->status.party_id > 0)
+ if (sd->status.party_id)
intif_party_changemap(sd, 0);
// sdが無効になるのでパーティ情報から削除
@@ -625,13 +625,13 @@ int party_send_logout(dumb_ptr<map_session_data> sd)
// パーティメッセージ送信
void party_send_message(dumb_ptr<map_session_data> sd, XString mes)
{
- if (sd->status.party_id == 0)
+ if (!sd->status.party_id)
return;
intif_party_message(sd->status.party_id, sd->status_key.account_id, mes);
}
// パーティメッセージ受信
-void party_recv_message(int party_id, int account_id, XString mes)
+void party_recv_message(PartyId party_id, AccountId account_id, XString mes)
{
struct party *p;
if ((p = party_search(party_id)) == NULL)
@@ -706,7 +706,7 @@ void party_send_xy_clear(struct party *p)
}
// HP通知の必要性検査用(map_foreachinmoveareaから呼ばれる)
-void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag)
+void party_send_hp_check(dumb_ptr<block_list> bl, PartyId party_id, int *flag)
{
dumb_ptr<map_session_data> sd;
diff --git a/src/map/party.hpp b/src/map/party.hpp
index 007de6b..bf9777b 100644
--- a/src/map/party.hpp
+++ b/src/map/party.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <functional>
@@ -34,25 +34,25 @@ struct map_session_data;
struct block_list;
void do_init_party(void);
-struct party *party_search(int party_id);
+struct party *party_search(PartyId party_id);
struct party *party_searchname(PartyName str);
int party_create(dumb_ptr<map_session_data> sd, PartyName name);
-void party_created(int account_id, int fail, int party_id, PartyName name);
-void party_request_info(int party_id);
-int party_invite(dumb_ptr<map_session_data> sd, int account_id);
-int party_member_added(int party_id, int account_id, int flag);
+void party_created(AccountId account_id, int fail, PartyId party_id, PartyName name);
+void party_request_info(PartyId party_id);
+int party_invite(dumb_ptr<map_session_data> sd, AccountId account_id);
+int party_member_added(PartyId party_id, AccountId account_id, int flag);
int party_leave(dumb_ptr<map_session_data> sd);
-int party_removemember(dumb_ptr<map_session_data> sd, int account_id);
-int party_member_leaved(int party_id, int account_id, CharName name);
-int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id,
+int party_removemember(dumb_ptr<map_session_data> sd, AccountId account_id);
+int party_member_leaved(PartyId party_id, AccountId account_id, CharName name);
+int party_reply_invite(dumb_ptr<map_session_data> sd, AccountId account_id,
int flag);
-int party_recv_noinfo(int party_id);
+int party_recv_noinfo(PartyId party_id);
int party_recv_info(const struct party *sp);
-void party_recv_movemap(int party_id, int account_id, MapName map,
+void party_recv_movemap(PartyId party_id, AccountId account_id, MapName map,
int online, int lv);
-int party_broken(int party_id);
-int party_optionchanged(int party_id, int account_id, int exp, int item,
+int party_broken(PartyId party_id);
+int party_optionchanged(PartyId party_id, AccountId account_id, int exp, int item,
int flag);
int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item);
@@ -60,10 +60,10 @@ int party_send_movemap(dumb_ptr<map_session_data> sd);
int party_send_logout(dumb_ptr<map_session_data> sd);
void party_send_message(dumb_ptr<map_session_data> sd, XString mes);
-void party_recv_message(int party_id, int account_id, XString mes);
+void party_recv_message(PartyId party_id, AccountId account_id, XString mes);
void party_send_xy_clear(struct party *p);
-void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag);
+void party_send_hp_check(dumb_ptr<block_list> bl, PartyId party_id, int *flag);
int party_exp_share(struct party *p, map_local *map, int base_exp, int job_exp);
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index a58c9ab..2526f1d 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -248,8 +248,9 @@ earray<EPOS, EQUIP, EQUIP::COUNT> equip_pos //=
EPOS::ARROW,
}};
+// TODO use DMap<>
static
-std::map<int, uint8_t> gm_accountm;
+std::map<AccountId, GmLevel> gm_accountm;
static
int pc_checkoverhp(dumb_ptr<map_session_data> sd);
@@ -265,14 +266,14 @@ void pc_setdead(dumb_ptr<map_session_data> sd)
sd->state.dead_sit = 1;
}
-uint8_t pc_isGM(dumb_ptr<map_session_data> sd)
+GmLevel pc_isGM(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retr(GmLevel(), sd);
auto it = gm_accountm.find(sd->status_key.account_id);
if (it != gm_accountm.end())
return it->second;
- return 0;
+ return GmLevel();
}
int pc_iskiller(dumb_ptr<map_session_data> src,
@@ -293,7 +294,7 @@ int pc_iskiller(dumb_ptr<map_session_data> src,
return 0;
}
-void pc_set_gm_level(int account_id, uint8_t level)
+void pc_set_gm_level(AccountId account_id, GmLevel level)
{
if (level)
gm_accountm[account_id] = level;
@@ -312,7 +313,7 @@ int distance(int x0, int y0, int x1, int y1)
}
static
-void pc_invincible_timer(TimerData *, tick_t, int id)
+void pc_invincible_timer(TimerData *, tick_t, BlockId id)
{
dumb_ptr<map_session_data> sd = map_id2sd(id);
@@ -380,7 +381,7 @@ int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type)
*/
static
void pc_counttargeted_sub(dumb_ptr<block_list> bl,
- int id, int *c, dumb_ptr<block_list> src, ATK target_lv)
+ BlockId id, int *c, dumb_ptr<block_list> src, ATK target_lv)
{
nullpo_retv(bl);
@@ -469,13 +470,18 @@ void pc_makesavestatus(dumb_ptr<map_session_data> sd)
* 接続時の初期化
*------------------------------------------
*/
-int pc_setnewpc(dumb_ptr<map_session_data> sd, int account_id, int char_id,
+int pc_setnewpc(dumb_ptr<map_session_data> sd, AccountId account_id, CharId char_id,
int login_id1, tick_t client_tick, SEX sex)
{
nullpo_ret(sd);
- sd->bl_id = account_id;
- sd->char_id = char_id;
+ // TODO this is the primary surface
+ sd->bl_id = account_to_block(account_id);
+ sd->char_id_ = char_id;
+ // TODO figure out wtf is going on here.
+ // shouldn't these things be in the .status_key.char_id ?
+ // My guess is that this stuff happens even for non-auth'ed connections
+ // Possible fix: char send auth before client is allowed to know my IP?
sd->login_id1 = login_id1;
sd->login_id2 = 0; // at this point, we can not know the value :(
sd->client_tick = client_tick;
@@ -504,13 +510,11 @@ EPOS pc_equippoint(dumb_ptr<map_session_data> sd, int n)
static
int pc_setinventorydata(dumb_ptr<map_session_data> sd)
{
- int i, id;
-
nullpo_ret(sd);
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (int i = 0; i < MAX_INVENTORY; i++)
{
- id = sd->status.inventory[i].nameid;
+ ItemNameId id = sd->status.inventory[i].nameid;
sd->inventory_data[i] = itemdb_search(id);
}
return 0;
@@ -569,7 +573,7 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd)
for (int i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid <= 0)
+ if (!sd->status.inventory[i].nameid)
continue;
if (bool(sd->status.inventory[i].equip))
{
@@ -619,8 +623,8 @@ int pc_isequip(dumb_ptr<map_session_data> sd, int n)
item = sd->inventory_data[n];
sc_data = battle_get_sc_data(sd);
- if (battle_config.gm_all_equipment > 0
- && pc_isGM(sd) >= battle_config.gm_all_equipment)
+ GmLevel gm_all_equipment = GmLevel::from(static_cast<uint32_t>(battle_config.gm_all_equipment));
+ if (gm_all_equipment && pc_isGM(sd).satisfies(gm_all_equipment))
return 1;
if (item == NULL)
@@ -638,7 +642,7 @@ int pc_isequip(dumb_ptr<map_session_data> sd, int n)
* char鯖から送られてきたステータスを設定
*------------------------------------------
*/
-int pc_authok(int id, int login_id2, TimeT connect_until_time,
+int pc_authok(AccountId id, int login_id2, TimeT connect_until_time,
short tmw_version, const CharKey *st_key, const CharData *st_data)
{
dumb_ptr<map_session_data> sd = NULL;
@@ -646,7 +650,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
struct party *p;
tick_t tick = gettick();
- sd = map_id2sd(id);
+ sd = map_id2sd(account_to_block(id));
if (sd == NULL)
return 1;
@@ -682,7 +686,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
// sd->invincible_timer = nullptr;
sd->deal_locked = 0;
- sd->trade_partner = 0;
+ sd->trade_partner = AccountId();
sd->inchealhptick = interval_t::zero();
sd->inchealsptick = interval_t::zero();
@@ -725,17 +729,17 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
// This would leak information.
// It's better to make it obvious that players can see you.
if (false && bool(old_option & Option::INVISIBILITY))
- is_atcommand(sd->sess, sd, "@invisible"_s, 0);
+ is_atcommand(sd->sess, sd, "@invisible"_s, GmLevel());
if (bool(old_option & Option::HIDE))
- is_atcommand(sd->sess, sd, "@hide"_s, 0);
+ is_atcommand(sd->sess, sd, "@hide"_s, GmLevel());
// atcommand_hide might already send it, but also might not
clif_changeoption(sd);
}
// パーティー関係の初期化
sd->party_sended = 0;
- sd->party_invite = 0;
+ sd->party_invite = PartyId();
sd->party_x = -1;
sd->party_y = -1;
sd->party_hp = -1;
@@ -748,7 +752,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
sd->status.last_point.y, BeingRemoveWhy::GONE);
// パーティ、ギルドデータの要求
- if (sd->status.party_id > 0
+ if (sd->status.party_id
&& (p = party_search(sd->status.party_id)) == NULL)
party_request_info(sd->status.party_id);
@@ -835,11 +839,11 @@ void pc_show_motd(dumb_ptr<map_session_data> sd)
* session idに問題ありなので後始末
*------------------------------------------
*/
-int pc_authfail(int id)
+int pc_authfail(AccountId id)
{
dumb_ptr<map_session_data> sd;
- sd = map_id2sd(id);
+ sd = map_id2sd(account_to_block(id));
if (sd == NULL)
return 1;
@@ -966,7 +970,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->weight = 0;
for (int i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid == 0
+ if (!sd->status.inventory[i].nameid
|| sd->inventory_data[i] == NULL)
continue;
sd->weight +=
@@ -1100,10 +1104,10 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
argrec_t arg[2] =
{
{"@slotId"_s, static_cast<int>(i)},
- {"@itemId"_s, sd->inventory_data[index]->nameid},
+ {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)},
};
run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0),
- sd->bl_id, 0,
+ sd->bl_id, BlockId(),
arg);
}
sd->state.lr_flag = 0;
@@ -1114,13 +1118,13 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
argrec_t arg[2] =
{
{"@slotId"_s, static_cast<int>(i)},
- {"@itemId"_s, sd->inventory_data[index]->nameid},
+ {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)},
};
sd->watk += sd->inventory_data[index]->atk;
sd->attackrange += sd->inventory_data[index]->range;
run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0),
- sd->bl_id, 0,
+ sd->bl_id, BlockId(),
arg);
}
}
@@ -1129,11 +1133,11 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
argrec_t arg[2] =
{
{"@slotId"_s, static_cast<int>(i)},
- {"@itemId"_s, sd->inventory_data[index]->nameid},
+ {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)},
};
sd->watk += sd->inventory_data[index]->atk;
run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0),
- sd->bl_id, 0,
+ sd->bl_id, BlockId(),
arg);
}
}
@@ -1156,11 +1160,11 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
argrec_t arg[2] =
{
{"@slotId"_s, static_cast<int>(EQUIP::ARROW)},
- {"@itemId"_s, sd->inventory_data[index]->nameid},
+ {"@itemId"_s, unwrap<ItemNameId>(sd->inventory_data[index]->nameid)},
};
sd->state.lr_flag = 2;
run_script_l(ScriptPointer(sd->inventory_data[index]->equip_script.get(), 0),
- sd->bl_id, 0,
+ sd->bl_id, BlockId(),
arg);
sd->state.lr_flag = 0;
sd->arrow_atk += sd->inventory_data[index]->atk;
@@ -1816,7 +1820,7 @@ int pc_skill(dumb_ptr<map_session_data> sd, SkillID id, int level, int flag)
* 3万個制限にかかるか確認
*------------------------------------------
*/
-ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, int nameid, int amount)
+ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, ItemNameId nameid, int amount)
{
int i;
@@ -1852,7 +1856,7 @@ int pc_inventoryblank(dumb_ptr<map_session_data> sd)
for (i = 0, b = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid == 0)
+ if (!sd->status.inventory[i].nameid)
b++;
}
@@ -1900,7 +1904,7 @@ int pc_getzeny(dumb_ptr<map_session_data> sd, int zeny)
* アイテムを探して、インデックスを返す
*------------------------------------------
*/
-int pc_search_inventory(dumb_ptr<map_session_data> sd, int item_id)
+int pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id)
{
int i;
@@ -1909,14 +1913,14 @@ int pc_search_inventory(dumb_ptr<map_session_data> sd, int item_id)
for (i = 0; i < MAX_INVENTORY; i++)
{
if (sd->status.inventory[i].nameid == item_id &&
- (sd->status.inventory[i].amount > 0 || item_id == 0))
+ (sd->status.inventory[i].amount > 0 || !item_id))
return i;
}
return -1;
}
-int pc_count_all_items(dumb_ptr<map_session_data> player, int item_id)
+int pc_count_all_items(dumb_ptr<map_session_data> player, ItemNameId item_id)
{
int i;
int count = 0;
@@ -1932,7 +1936,7 @@ int pc_count_all_items(dumb_ptr<map_session_data> player, int item_id)
return count;
}
-int pc_remove_items(dumb_ptr<map_session_data> player, int item_id, int count)
+int pc_remove_items(dumb_ptr<map_session_data> player, ItemNameId item_id, int count)
{
int i;
@@ -1974,7 +1978,7 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data,
nullpo_retr(PickupFail::BAD_ITEM, sd);
nullpo_retr(PickupFail::BAD_ITEM, item_data);
- if (item_data->nameid <= 0 || amount <= 0)
+ if (!item_data->nameid || amount <= 0)
return PickupFail::BAD_ITEM;
data = itemdb_search(item_data->nameid);
if ((w = data->weight * amount) + sd->weight > sd->max_weight)
@@ -1998,7 +2002,7 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data,
if (i >= MAX_INVENTORY)
{
// 装 備品か未所有品だったので空き欄へ追加
- i = pc_search_inventory(sd, 0);
+ i = pc_search_inventory(sd, ItemNameId());
if (i >= 0)
{
sd->status.inventory[i] = *item_data;
@@ -2027,10 +2031,10 @@ int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type)
{
nullpo_retr(1, sd);
- if (sd->trade_partner != 0)
+ if (sd->trade_partner)
trade_tradecancel(sd);
- if (sd->status.inventory[n].nameid == 0 || amount <= 0
+ if (!sd->status.inventory[n].nameid || amount <= 0
|| sd->status.inventory[n].amount < amount
|| sd->inventory_data[n] == NULL)
return 1;
@@ -2060,7 +2064,7 @@ int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount)
{
nullpo_retr(1, sd);
- if (sd->trade_partner != 0 || sd->npc_id != 0 || sd->state.storage_open)
+ 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)
@@ -2071,9 +2075,9 @@ int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount)
pc_unequipinvyitem(sd, n, CalcStatus::NOW);
- if (sd->status.inventory[n].nameid <= 0 ||
+ if (!sd->status.inventory[n].nameid ||
sd->status.inventory[n].amount < amount ||
- sd->trade_partner != 0 || sd->status.inventory[n].amount <= 0)
+ sd->trade_partner || sd->status.inventory[n].amount <= 0)
return 1;
map_addflooritem(&sd->status.inventory[n], amount,
sd->bl_m, sd->bl_x, sd->bl_y,
@@ -2089,7 +2093,7 @@ int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount)
*/
static
-int can_pick_item_up_from(dumb_ptr<map_session_data> self, int other_id)
+int can_pick_item_up_from(dumb_ptr<map_session_data> self, BlockId other_id)
{
struct party *p = party_search(self->status.party_id);
@@ -2139,12 +2143,12 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem)
if (fitem->first_get_id == fitem->third_get_id
|| fitem->second_get_id == fitem->third_get_id)
- fitem->third_get_id = 0;
+ fitem->third_get_id = BlockId();
if (fitem->first_get_id == fitem->second_get_id)
{
fitem->second_get_id = fitem->third_get_id;
- fitem->third_get_id = 0;
+ fitem->third_get_id = BlockId();
}
can_take = can_pick_item_up_from(sd, fitem->first_get_id);
@@ -2187,7 +2191,7 @@ static
int pc_isUseitem(dumb_ptr<map_session_data> sd, int n)
{
struct item_data *item;
- int nameid;
+ ItemNameId nameid;
nullpo_ret(sd);
@@ -2220,7 +2224,7 @@ int pc_useitem(dumb_ptr<map_session_data> sd, int n)
if (n >= 0 && n < MAX_INVENTORY && sd->inventory_data[n])
{
amount = sd->status.inventory[n].amount;
- if (sd->status.inventory[n].nameid <= 0
+ if (!sd->status.inventory[n].nameid
|| sd->status.inventory[n].amount <= 0
|| !pc_isUseitem(sd, n))
{
@@ -2232,7 +2236,7 @@ int pc_useitem(dumb_ptr<map_session_data> sd, int n)
clif_useitemack(sd, n, amount - 1, 1);
pc_delitem(sd, n, 1, 1);
- run_script(ScriptPointer(script, 0), sd->bl_id, 0);
+ run_script(ScriptPointer(script, 0), sd->bl_id, BlockId());
}
return 0;
@@ -2257,7 +2261,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd,
if (sd->state.storage_open)
storage_storage_quit(sd); // 倉庫を開いてるなら保存する
- if (sd->party_invite > 0) // パーティ勧誘を拒否する
+ if (sd->party_invite) // パーティ勧誘を拒否する
party_reply_invite(sd, sd->party_invite_account, 0);
skill_castcancel(sd, 0); // 詠唱中断
@@ -2421,7 +2425,7 @@ interval_t calc_next_walk_step(dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void pc_walk(TimerData *, tick_t tick, int id, unsigned char data)
+void pc_walk(TimerData *, tick_t tick, BlockId id, unsigned char data)
{
dumb_ptr<map_session_data> sd;
int moveblock;
@@ -2496,7 +2500,7 @@ void pc_walk(TimerData *, tick_t tick, int id, unsigned char data)
BL::NUL);
// sd->walktimer = nullptr;
- if (sd->status.party_id > 0)
+ if (sd->status.party_id)
{ // パーティのHP情報通知検査
struct party *p = party_search(sd->status.party_id);
if (p != NULL)
@@ -2516,7 +2520,7 @@ void pc_walk(TimerData *, tick_t tick, int id, unsigned char data)
if (bool(map_getcell(sd->bl_m, x, y) & MapCell::NPC_NEAR))
npc_touch_areanpc(sd, sd->bl_m, x, y);
else
- sd->areanpc_id = 0;
+ sd->areanpc_id = BlockId();
}
interval_t i = calc_next_walk_step(sd);
if (i > interval_t::zero())
@@ -2622,7 +2626,7 @@ void pc_touch_all_relevant_npcs(dumb_ptr<map_session_data> sd)
if (bool(map_getcell(sd->bl_m, sd->bl_x, sd->bl_y) & MapCell::NPC_NEAR))
npc_touch_areanpc(sd, sd->bl_m, sd->bl_x, sd->bl_y);
else
- sd->areanpc_id = 0;
+ sd->areanpc_id = BlockId();
}
/*==========================================
@@ -2670,7 +2674,7 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y)
-dx, -dy,
BL::NUL);
- if (sd->status.party_id > 0)
+ if (sd->status.party_id)
{ // パーティのHP情報通知検査
struct party *p = party_search(sd->status.party_id);
if (p != NULL)
@@ -2728,7 +2732,7 @@ int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos)
*------------------------------------------
*/
static
-void pc_attack_timer(TimerData *, tick_t tick, int id)
+void pc_attack_timer(TimerData *, tick_t tick, BlockId id)
{
dumb_ptr<map_session_data> sd;
dumb_ptr<block_list> bl;
@@ -2835,7 +2839,7 @@ void pc_attack_timer(TimerData *, tick_t tick, int id)
* typeが1なら継続攻撃
*------------------------------------------
*/
-int pc_attack(dumb_ptr<map_session_data> sd, int target_id, int type)
+int pc_attack(dumb_ptr<map_session_data> sd, BlockId target_id, int type)
{
dumb_ptr<block_list> bl;
@@ -2847,7 +2851,7 @@ int pc_attack(dumb_ptr<map_session_data> sd, int target_id, int type)
if (bl->bl_type == BL::NPC)
{ // monster npcs [Valaris]
- npc_click(sd, RFIFOL(sd->sess, 2));
+ npc_click(sd, wrap<BlockId>(RFIFOL(sd->sess, 2)));
return 0;
}
@@ -2884,7 +2888,7 @@ int pc_stopattack(dumb_ptr<map_session_data> sd)
sd->attacktimer.cancel();
- sd->attacktarget = 0;
+ sd->attacktarget = BlockId();
sd->state.attack_continue = 0;
return 0;
@@ -3425,7 +3429,7 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
sd->canlog_tick = gettick();
- if (sd->status.party_id > 0)
+ if (sd->status.party_id)
{ // on-the-fly party hp updates [Valaris]
struct party *p = party_search(sd->status.party_id);
if (p != NULL)
@@ -3542,8 +3546,8 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
// [Fate] PK death, trigger scripts
argrec_t arg[3] =
{
- {"@killerrid"_s, src->bl_id},
- {"@victimrid"_s, sd->bl_id},
+ {"@killerrid"_s, static_cast<int32_t>(unwrap<BlockId>(src->bl_id))},
+ {"@victimrid"_s, static_cast<int32_t>(unwrap<BlockId>(sd->bl_id))},
{"@victimlvl"_s, sd->status.base_level},
};
npc_event_doall_l(stringish<ScriptLabel>("OnPCKilledEvent"_s), sd->bl_id, arg);
@@ -3585,7 +3589,7 @@ int pc_readparam(dumb_ptr<map_session_data> sd, SP type)
val = sd->status.job_level;
break;
case SP::CLASS:
- val = sd->status.species;
+ val = unwrap<Species>(sd->status.species);
break;
case SP::SEX:
val = static_cast<uint8_t>(sd->sex);
@@ -3689,7 +3693,7 @@ int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val)
clif_updatestatus(sd, type);
break;
case SP::CLASS:
- sd->status.species = val;
+ sd->status.species = wrap<Species>(val);
break;
case SP::SKILLPOINT:
sd->status.skill_point = val;
@@ -3792,7 +3796,7 @@ int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp)
if (sp)
clif_updatestatus(sd, SP::SP);
- if (sd->status.party_id > 0)
+ if (sd->status.party_id)
{ // on-the-fly party hp updates [Valaris]
struct party *p = party_search(sd->status.party_id);
if (p != NULL)
@@ -4009,13 +4013,13 @@ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val)
sd->status.weapon = static_cast<ItemLook>(static_cast<uint16_t>(val));
break;
case LOOK::HEAD_BOTTOM:
- sd->status.head_bottom = val;
+ sd->status.head_bottom = wrap<ItemNameId>(val);
break;
case LOOK::HEAD_TOP:
- sd->status.head_top = val;
+ sd->status.head_top = wrap<ItemNameId>(val);
break;
case LOOK::HEAD_MID:
- sd->status.head_mid = val;
+ sd->status.head_mid = wrap<ItemNameId>(val);
break;
case LOOK::HAIR_COLOR:
sd->status.hair_color = val;
@@ -4024,7 +4028,7 @@ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val)
sd->status.clothes_color = val;
break;
case LOOK::SHIELD:
- sd->status.shield = val;
+ sd->status.shield = wrap<ItemNameId>(val);
break;
case LOOK::SHOES:
break;
@@ -4318,7 +4322,7 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, VarName reg, int val)
*------------------------------------------
*/
static
-void pc_eventtimer(TimerData *, tick_t, int id, NpcEvent data)
+void pc_eventtimer(TimerData *, tick_t, BlockId id, NpcEvent data)
{
dumb_ptr<map_session_data> sd = map_id2sd(id);
assert (sd != NULL);
@@ -4390,7 +4394,7 @@ int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, int n)
int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
{
- int nameid;
+ ItemNameId nameid;
struct item_data *id;
//ソス]ソスソスソスソスソス{ソスqソスフ場合ソスフ鯉ソスソスフ職ソスニゑソスソスZソスoソスソスソスソス
@@ -4463,7 +4467,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
}
sd->status.inventory[n].equip = pos;
- int view_i = 0;
+ ItemNameId view_i;
ItemLook view_l = ItemLook::NONE;
// TODO: This is ugly.
if (sd->inventory_data[n])
@@ -4490,7 +4494,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
{
if (sd->inventory_data[n]->type == ItemType::WEAPON)
{
- sd->status.shield = 0;
+ sd->status.shield = ItemNameId();
if (sd->status.inventory[n].equip == EPOS::SHIELD)
sd->weapontype2 = view_l;
}
@@ -4502,26 +4506,26 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
}
else
{
- sd->status.shield = 0;
+ sd->status.shield = ItemNameId();
sd->weapontype2 = ItemLook::NONE;
}
pc_calcweapontype(sd);
- clif_changelook(sd, LOOK::SHIELD, sd->status.shield);
+ clif_changelook(sd, LOOK::SHIELD, unwrap<ItemNameId>(sd->status.shield));
}
if (bool(sd->status.inventory[n].equip & EPOS::LEGS))
{
sd->status.head_bottom = view_i;
- clif_changelook(sd, LOOK::HEAD_BOTTOM, sd->status.head_bottom);
+ clif_changelook(sd, LOOK::HEAD_BOTTOM, unwrap<ItemNameId>(sd->status.head_bottom));
}
if (bool(sd->status.inventory[n].equip & EPOS::HAT))
{
sd->status.head_top = view_i;
- clif_changelook(sd, LOOK::HEAD_TOP, sd->status.head_top);
+ clif_changelook(sd, LOOK::HEAD_TOP, unwrap<ItemNameId>(sd->status.head_top));
}
if (bool(sd->status.inventory[n].equip & EPOS::TORSO))
{
sd->status.head_mid = view_i;
- clif_changelook(sd, LOOK::HEAD_MID, sd->status.head_mid);
+ clif_changelook(sd, LOOK::HEAD_MID, unwrap<ItemNameId>(sd->status.head_mid));
}
pc_signal_advanced_equipment_change(sd, n);
@@ -4560,26 +4564,25 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
}
if (bool(sd->status.inventory[n].equip & EPOS::SHIELD))
{
- sd->status.shield = 0;
+ sd->status.shield = ItemNameId();
sd->weapontype2 = ItemLook::NONE;
pc_calcweapontype(sd);
- clif_changelook(sd, LOOK::SHIELD, sd->status.shield);
+ clif_changelook(sd, LOOK::SHIELD, unwrap<ItemNameId>(sd->status.shield));
}
if (bool(sd->status.inventory[n].equip & EPOS::LEGS))
{
- sd->status.head_bottom = 0;
- clif_changelook(sd, LOOK::HEAD_BOTTOM,
- sd->status.head_bottom);
+ sd->status.head_bottom = ItemNameId();
+ clif_changelook(sd, LOOK::HEAD_BOTTOM, unwrap<ItemNameId>(sd->status.head_bottom));
}
if (bool(sd->status.inventory[n].equip & EPOS::HAT))
{
- sd->status.head_top = 0;
- clif_changelook(sd, LOOK::HEAD_TOP, sd->status.head_top);
+ sd->status.head_top = ItemNameId();
+ clif_changelook(sd, LOOK::HEAD_TOP, unwrap<ItemNameId>(sd->status.head_top));
}
if (bool(sd->status.inventory[n].equip & EPOS::TORSO))
{
- sd->status.head_mid = 0;
- clif_changelook(sd, LOOK::HEAD_MID, sd->status.head_mid);
+ sd->status.head_mid = ItemNameId();
+ clif_changelook(sd, LOOK::HEAD_MID, unwrap<ItemNameId>(sd->status.head_mid));
}
pc_signal_advanced_equipment_change(sd, n);
@@ -4624,14 +4627,14 @@ 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, id, calc_flag = 0;
+ int i, j, k, calc_flag = 0;
nullpo_ret(sd);
// 所持品空き詰め
for (i = j = 0; i < MAX_INVENTORY; i++)
{
- if ((id = sd->status.inventory[i].nameid) == 0)
+ if (!(sd->status.inventory[i].nameid))
continue;
if (i > j)
{
@@ -4647,7 +4650,7 @@ int pc_checkitem(dumb_ptr<map_session_data> sd)
for (i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid == 0)
+ if (!sd->status.inventory[i].nameid)
continue;
if (bool(sd->status.inventory[i].equip & ~pc_equippoint(sd, i)))
{
@@ -4737,7 +4740,7 @@ int pc_calc_pvprank(dumb_ptr<map_session_data> sd)
* PVP順位計算(timer)
*------------------------------------------
*/
-void pc_calc_pvprank_timer(TimerData *, tick_t, int id)
+void pc_calc_pvprank_timer(TimerData *, tick_t, BlockId id)
{
dumb_ptr<map_session_data> sd = NULL;
if (battle_config.pk_mode) // disable pvp ranking if pk_mode on [Valaris]
@@ -4758,14 +4761,14 @@ void pc_calc_pvprank_timer(TimerData *, tick_t, int id)
*------------------------------------------
*/
static
-int pc_ismarried(dumb_ptr<map_session_data> sd)
+CharId pc_ismarried(dumb_ptr<map_session_data> sd)
{
if (sd == NULL)
- return -1;
- if (sd->status.partner_id > 0)
+ return CharId();
+ if (sd->status.partner_id)
return sd->status.partner_id;
else
- return 0;
+ return CharId();
}
/*==========================================
@@ -4774,8 +4777,8 @@ int pc_ismarried(dumb_ptr<map_session_data> sd)
*/
int pc_marriage(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> dstsd)
{
- if (sd == NULL || dstsd == NULL || sd->status.partner_id > 0
- || dstsd->status.partner_id > 0)
+ if (sd == NULL || dstsd == NULL || sd->status.partner_id
+ || dstsd->status.partner_id)
return -1;
sd->status.partner_id = dstsd->status_key.char_id;
dstsd->status.partner_id = sd->status_key.char_id;
@@ -4803,8 +4806,8 @@ int pc_divorce(dumb_ptr<map_session_data> sd)
sd->status.partner_id, p_sd->status.partner_id);
return -1;
}
- p_sd->status.partner_id = 0;
- sd->status.partner_id = 0;
+ p_sd->status.partner_id = CharId();
+ sd->status.partner_id = CharId();
if (sd->npc_flags.divorce)
{
@@ -5179,8 +5182,8 @@ int pc_read_gm_account(Session *s)
// (RFIFOW(fd, 2) - 4) / 5
for (int i = 4; i < RFIFOW(s, 2); i += 5)
{
- int account_id = RFIFOL(s, i);
- uint8_t level = RFIFOB(s, i + 4);
+ AccountId account_id = wrap<AccountId>(RFIFOL(s, i));
+ GmLevel level = GmLevel::from(static_cast<uint32_t>(RFIFOB(s, i + 4)));
gm_accountm[account_id] = level;
}
return gm_accountm.size();
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 35d9c70..b02e5a7 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "pc.t.hpp"
@@ -66,7 +66,7 @@ bool pc_is90overweight(dumb_ptr<map_session_data> sd)
// should do something with the specified player.
void pc_touch_all_relevant_npcs(dumb_ptr<map_session_data> sd);
-uint8_t pc_isGM(dumb_ptr<map_session_data> sd);
+GmLevel pc_isGM(dumb_ptr<map_session_data> sd);
int pc_iskiller(dumb_ptr<map_session_data> src, dumb_ptr<map_session_data> target); // [MouseJstr]
void pc_invisibility(dumb_ptr<map_session_data> sd, int enabled); // [Fate]
@@ -74,9 +74,9 @@ int pc_counttargeted(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> src,
ATK target_lv);
int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type);
void pc_makesavestatus(dumb_ptr<map_session_data>);
-int pc_setnewpc(dumb_ptr<map_session_data>, int, int, int, tick_t, SEX);
-int pc_authok(int, int, TimeT, short tmw_version, const CharKey *, const CharData *);
-int pc_authfail(int accid);
+int pc_setnewpc(dumb_ptr<map_session_data>, AccountId, CharId, int, tick_t, SEX);
+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);
@@ -90,17 +90,17 @@ int pc_setpos(dumb_ptr<map_session_data>, MapName, int, int, BeingRemoveWhy);
void pc_setsavepoint(dumb_ptr<map_session_data>, MapName, int, int);
int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type);
-ADDITEM pc_checkadditem(dumb_ptr<map_session_data>, int, int);
+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, int item_id);
+int 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>, struct item *, int);
int pc_getzeny(dumb_ptr<map_session_data>, int);
int pc_delitem(dumb_ptr<map_session_data>, int, int, int);
int pc_checkitem(dumb_ptr<map_session_data>);
-int pc_count_all_items(dumb_ptr<map_session_data> player, int item_id);
+int pc_count_all_items(dumb_ptr<map_session_data> player, ItemNameId item_id);
int pc_remove_items(dumb_ptr<map_session_data> player,
- int item_id, int count);
+ 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);
@@ -112,7 +112,7 @@ int pc_bonus(dumb_ptr<map_session_data>, SP, int);
int pc_bonus2(dumb_ptr<map_session_data> sd, SP, int, int);
int pc_skill(dumb_ptr<map_session_data>, SkillID, int, int);
-int pc_attack(dumb_ptr<map_session_data>, int, int);
+int pc_attack(dumb_ptr<map_session_data>, BlockId, int);
int pc_stopattack(dumb_ptr<map_session_data>);
int pc_gainexp_reason(dumb_ptr<map_session_data>, int, int,
@@ -158,13 +158,13 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick,
int pc_cleareventtimer(dumb_ptr<map_session_data> sd);
int pc_calc_pvprank(dumb_ptr<map_session_data> sd);
-void pc_calc_pvprank_timer(TimerData *, tick_t, int);
+void pc_calc_pvprank_timer(TimerData *, tick_t, BlockId);
int pc_marriage(dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> dstsd);
int pc_divorce(dumb_ptr<map_session_data> sd);
dumb_ptr<map_session_data> pc_get_partner(dumb_ptr<map_session_data> sd);
-void pc_set_gm_level(int account_id, uint8_t level);
+void pc_set_gm_level(AccountId account_id, GmLevel level);
void pc_setstand(dumb_ptr<map_session_data> sd);
void pc_cleanup(dumb_ptr<map_session_data> sd); // [Fate] Clean up after a logged-out PC
diff --git a/src/map/script.cpp b/src/map/script.cpp
index bcc8a99..7ee6306 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -751,12 +751,34 @@ bool read_constdb(ZString filename)
{
if (is_comment(line))
continue;
+ // "%m[A-Za-z0-9_] %i %i"
+
+ // TODO promote either qsplit() or asplit()
+ auto _it = std::find(line.begin(), line.end(), ' ');
+ auto name = line.xislice_h(_it);
+ auto _rest = line.xislice_t(_it);
+ while (_rest.startswith(' '))
+ _rest = _rest.xslice_t(1);
+ auto _it2 = std::find(_rest.begin(), _rest.end(), ' ');
+ auto val_ = _rest.xislice_h(_it2);
+ auto type_ = _rest.xislice_t(_it2);
+ while (type_.startswith(' '))
+ type_ = type_.xslice_t(1);
+ // yes, the above actually DTRT even for underlength input
- AString name;
int val;
- int type = 0; // if not provided
- // TODO get rid of SSCANF - this is the last serious use
- if (SSCANF(line, "%m[A-Za-z0-9_] %i %i"_fmt, &name, &val, &type) < 2)
+ int type = 0;
+ // Note for future archeaologists: this code is indented correctly
+ if (std::find_if_not(name.begin(), name.end(),
+ [](char c)
+ {
+ return ('0' <= c && c <= '9')
+ || ('A' <= c && c <= 'Z')
+ || ('a' <= c && c <= 'z')
+ || (c == '_');
+ }) != name.end()
+ || !extract(val_, &val)
+ || (!extract(type_, &type) && type_))
{
PRINTF("Bad const line: %s\n"_fmt, line);
rv = false;
@@ -1897,7 +1919,8 @@ void builtin_setlook(ScriptState *st)
static
void builtin_countitem(ScriptState *st)
{
- int nameid = 0, count = 0, i;
+ ItemNameId nameid;
+ int count = 0, i;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -1914,14 +1937,16 @@ void builtin_countitem(ScriptState *st)
nameid = item_data->nameid;
}
else
- nameid = conv_num(st, data);
+ nameid = wrap<ItemNameId>(conv_num(st, data));
- if (nameid >= 500) //if no such ID then skip this iteration
+ if (nameid)
+ {
for (i = 0; i < MAX_INVENTORY; i++)
{
if (sd->status.inventory[i].nameid == nameid)
count += sd->status.inventory[i].amount;
}
+ }
else
{
if (battle_config.error_log)
@@ -1938,7 +1963,8 @@ void builtin_countitem(ScriptState *st)
static
void builtin_checkweight(ScriptState *st)
{
- int nameid = 0, amount;
+ ItemNameId nameid;
+ int amount;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -1954,10 +1980,10 @@ void builtin_checkweight(ScriptState *st)
nameid = item_data->nameid;
}
else
- nameid = conv_num(st, data);
+ nameid = wrap<ItemNameId>(conv_num(st, data));
amount = conv_num(st, &AARGO2(3));
- if (amount <= 0 || nameid < 500)
+ if (amount <= 0 || !nameid)
{
//if get wrong item ID or amount<=0, don't count weight of non existing items
push_int(st->stack, ByteCode::INT, 0);
@@ -1982,7 +2008,8 @@ void builtin_checkweight(ScriptState *st)
static
void builtin_getitem(ScriptState *st)
{
- int nameid, amount;
+ ItemNameId nameid;
+ int amount;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -1994,12 +2021,11 @@ void builtin_getitem(ScriptState *st)
{
ZString name = ZString(conv_str(st, data));
struct item_data *item_data = itemdb_searchname(name);
- nameid = 727; //Default to iten
if (item_data != NULL)
nameid = item_data->nameid;
}
else
- nameid = conv_num(st, data);
+ nameid = wrap<ItemNameId>(conv_num(st, data));
if ((amount =
conv_num(st, &AARGO2(3))) <= 0)
@@ -2007,12 +2033,12 @@ void builtin_getitem(ScriptState *st)
return; //return if amount <=0, skip the useles iteration
}
- if (nameid > 0)
+ if (nameid)
{
struct item item_tmp {};
item_tmp.nameid = nameid;
if (HARGO2(5)) //アイテムを指定したIDに渡す
- sd = map_id2sd(conv_num(st, &AARGO2(5)));
+ sd = map_id2sd(wrap<BlockId>(conv_num(st, &AARGO2(5))));
if (sd == NULL) //アイテムを渡す相手がいなかったらお帰り
return;
PickupFail flag;
@@ -2034,7 +2060,8 @@ void builtin_getitem(ScriptState *st)
static
void builtin_makeitem(ScriptState *st)
{
- int nameid, amount;
+ ItemNameId nameid;
+ int amount;
int x, y;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -2047,12 +2074,11 @@ void builtin_makeitem(ScriptState *st)
{
ZString name = ZString(conv_str(st, data));
struct item_data *item_data = itemdb_searchname(name);
- nameid = 512; //Apple Item ID
if (item_data)
nameid = item_data->nameid;
}
else
- nameid = conv_num(st, data);
+ nameid = wrap<ItemNameId>(conv_num(st, data));
amount = conv_num(st, &AARGO2(3));
MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(4))));
@@ -2065,7 +2091,7 @@ void builtin_makeitem(ScriptState *st)
else
m = map_mapname2mapid(mapname);
- if (nameid > 0)
+ if (nameid)
{
struct item item_tmp {};
item_tmp.nameid = nameid;
@@ -2081,7 +2107,8 @@ void builtin_makeitem(ScriptState *st)
static
void builtin_delitem(ScriptState *st)
{
- int nameid = 0, amount, i;
+ ItemNameId nameid;
+ int amount, i;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -2093,16 +2120,15 @@ void builtin_delitem(ScriptState *st)
{
ZString name = ZString(conv_str(st, data));
struct item_data *item_data = itemdb_searchname(name);
- //nameid=512;
if (item_data)
nameid = item_data->nameid;
}
else
- nameid = conv_num(st, data);
+ nameid = wrap<ItemNameId>(conv_num(st, data));
amount = conv_num(st, &AARGO2(3));
- if (nameid < 500 || amount <= 0)
+ if (!nameid || amount <= 0)
{
//by Lupus. Don't run FOR if u got wrong item ID or amount<=0
return;
@@ -2110,14 +2136,6 @@ void builtin_delitem(ScriptState *st)
for (i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid <= 0
- || sd->inventory_data[i] == NULL
- || sd->inventory_data[i]->type != ItemType::_7
- || sd->status.inventory[i].amount <= 0)
- continue;
- }
- for (i = 0; i < MAX_INVENTORY; i++)
- {
if (sd->status.inventory[i].nameid == nameid)
{
if (sd->status.inventory[i].amount >= amount)
@@ -2184,13 +2202,13 @@ void builtin_getcharid(ScriptState *st)
return;
}
if (num == 0)
- push_int(st->stack, ByteCode::INT, sd->status_key.char_id);
+ push_int(st->stack, ByteCode::INT, unwrap<CharId>(sd->status_key.char_id));
if (num == 1)
- push_int(st->stack, ByteCode::INT, sd->status.party_id);
+ push_int(st->stack, ByteCode::INT, unwrap<PartyId>(sd->status.party_id));
if (num == 2)
push_int(st->stack, ByteCode::INT, 0/*guild_id*/);
if (num == 3)
- push_int(st->stack, ByteCode::INT, sd->status_key.account_id);
+ push_int(st->stack, ByteCode::INT, unwrap<AccountId>(sd->status_key.account_id));
}
/*==========================================
@@ -2198,7 +2216,7 @@ void builtin_getcharid(ScriptState *st)
*------------------------------------------
*/
static
-dumb_string builtin_getpartyname_sub(int party_id)
+dumb_string builtin_getpartyname_sub(PartyId party_id)
{
struct party *p = party_search(party_id);
@@ -2282,7 +2300,7 @@ void builtin_getequipid(ScriptState *st)
{
item = sd->inventory_data[i];
if (item)
- push_int(st->stack, ByteCode::INT, item->nameid);
+ push_int(st->stack, ByteCode::INT, unwrap<ItemNameId>(item->nameid));
else
push_int(st->stack, ByteCode::INT, 0);
}
@@ -2423,7 +2441,7 @@ void builtin_getskilllv(ScriptState *st)
static
void builtin_getgmlevel(ScriptState *st)
{
- push_int(st->stack, ByteCode::INT, pc_isGM(script_rid2sd(st)));
+ push_int(st->stack, ByteCode::INT, pc_isGM(script_rid2sd(st)).get_all_bits());
}
/*==========================================
@@ -2613,14 +2631,15 @@ void builtin_getexp(ScriptState *st)
static
void builtin_monster(ScriptState *st)
{
- int mob_class, amount, x, y;
+ Species mob_class;
+ int amount, x, y;
NpcEvent event;
MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
x = conv_num(st, &AARGO2(3));
y = conv_num(st, &AARGO2(4));
MobName str = stringish<MobName>(ZString(conv_str(st, &AARGO2(5))));
- mob_class = conv_num(st, &AARGO2(6));
+ mob_class = wrap<Species>(conv_num(st, &AARGO2(6)));
amount = conv_num(st, &AARGO2(7));
if (HARGO2(8))
extract(ZString(conv_str(st, &AARGO2(8))), &event);
@@ -2636,7 +2655,8 @@ void builtin_monster(ScriptState *st)
static
void builtin_areamonster(ScriptState *st)
{
- int mob_class, amount, x0, y0, x1, y1;
+ Species mob_class;
+ int amount, x0, y0, x1, y1;
NpcEvent event;
MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
@@ -2645,7 +2665,7 @@ void builtin_areamonster(ScriptState *st)
x1 = conv_num(st, &AARGO2(5));
y1 = conv_num(st, &AARGO2(6));
MobName str = stringish<MobName>(ZString(conv_str(st, &AARGO2(7))));
- mob_class = conv_num(st, &AARGO2(8));
+ mob_class = wrap<Species>(conv_num(st, &AARGO2(8)));
amount = conv_num(st, &AARGO2(9));
if (HARGO2(10))
extract(ZString(conv_str(st, &AARGO2(10))), &event);
@@ -2997,7 +3017,7 @@ void builtin_getareausers(ScriptState *st)
*------------------------------------------
*/
static
-void builtin_getareadropitem_sub(dumb_ptr<block_list> bl, int item, int *amount)
+void builtin_getareadropitem_sub(dumb_ptr<block_list> bl, ItemNameId item, int *amount)
{
dumb_ptr<flooritem_data> drop = bl->is_item();
@@ -3007,7 +3027,7 @@ void builtin_getareadropitem_sub(dumb_ptr<block_list> bl, int item, int *amount)
}
static
-void builtin_getareadropitem_sub_anddelete(dumb_ptr<block_list> bl, int item, int *amount)
+void builtin_getareadropitem_sub_anddelete(dumb_ptr<block_list> bl, ItemNameId item, int *amount)
{
dumb_ptr<flooritem_data> drop = bl->is_item();
@@ -3022,7 +3042,8 @@ void builtin_getareadropitem_sub_anddelete(dumb_ptr<block_list> bl, int item, in
static
void builtin_getareadropitem(ScriptState *st)
{
- int x0, y0, x1, y1, item, amount = 0, delitems = 0;
+ ItemNameId item;
+ int x0, y0, x1, y1, amount = 0, delitems = 0;
struct script_data *data;
MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
@@ -3037,12 +3058,11 @@ void builtin_getareadropitem(ScriptState *st)
{
ZString name = ZString(conv_str(st, data));
struct item_data *item_data = itemdb_searchname(name);
- item = 512;
if (item_data)
item = item_data->nameid;
}
else
- item = conv_num(st, data);
+ item = wrap<ItemNameId>(conv_num(st, data));
if (HARGO2(8))
delitems = conv_num(st, &AARGO2(8));
@@ -3113,7 +3133,7 @@ void builtin_sc_start(ScriptState *st)
tick *= 1000;
val1 = conv_num(st, &AARGO2(4));
if (HARGO2(5)) //指定したキャラを状態異常にする
- bl = map_id2bl(conv_num(st, &AARGO2(5)));
+ bl = map_id2bl(wrap<BlockId>(conv_num(st, &AARGO2(5))));
else
bl = map_id2bl(st->rid);
skill_status_change_start(bl, type, val1, tick);
@@ -3177,7 +3197,7 @@ void builtin_changesex(ScriptState *st)
dumb_ptr<map_session_data> sd = NULL;
sd = script_rid2sd(st);
- chrif_char_ask_name(-1, sd->status_key.name, 5, HumanTimeDiff()); // type: 5 - changesex
+ chrif_char_ask_name(AccountId(), sd->status_key.name, 5, HumanTimeDiff()); // type: 5 - changesex
chrif_save(sd);
}
@@ -3188,7 +3208,7 @@ void builtin_changesex(ScriptState *st)
static
void builtin_attachrid(ScriptState *st)
{
- st->rid = conv_num(st, &AARGO2(2));
+ st->rid = wrap<BlockId>(conv_num(st, &AARGO2(2)));
push_int(st->stack, ByteCode::INT, (map_id2sd(st->rid) != NULL));
}
@@ -3199,7 +3219,7 @@ void builtin_attachrid(ScriptState *st)
static
void builtin_detachrid(ScriptState *st)
{
- st->rid = 0;
+ st->rid = BlockId();
}
/*==========================================
@@ -3210,8 +3230,7 @@ static
void builtin_isloggedin(ScriptState *st)
{
push_int(st->stack, ByteCode::INT,
- map_id2sd(conv_num(st,
- &AARGO2(2))) != NULL);
+ map_id2sd(wrap<BlockId>(conv_num(st, &AARGO2(2)))) != NULL);
}
static
@@ -3456,7 +3475,7 @@ void builtin_getitemname(ScriptState *st)
}
else
{
- int item_id = conv_num(st, data);
+ ItemNameId item_id = wrap<ItemNameId>(conv_num(st, data));
i_data = itemdb_search(item_id);
}
@@ -3486,7 +3505,7 @@ void builtin_getpartnerid2(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- push_int(st->stack, ByteCode::INT, sd->status.partner_id);
+ push_int(st->stack, ByteCode::INT, unwrap<CharId>(sd->status.partner_id));
}
/*==========================================
@@ -3502,11 +3521,11 @@ void builtin_getinventorylist(ScriptState *st)
return;
for (i = 0; i < MAX_INVENTORY; i++)
{
- if (sd->status.inventory[i].nameid > 0
+ if (sd->status.inventory[i].nameid
&& sd->status.inventory[i].amount > 0)
{
pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_id"_s), j),
- sd->status.inventory[i].nameid);
+ unwrap<ItemNameId>(sd->status.inventory[i].nameid));
pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_amount"_s), j),
sd->status.inventory[i].amount);
pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_equip"_s), j),
@@ -3616,7 +3635,7 @@ static
void builtin_misceffect(ScriptState *st)
{
int type;
- int id = 0;
+ BlockId id;
CharName name;
dumb_ptr<block_list> bl = NULL;
@@ -3631,7 +3650,7 @@ void builtin_misceffect(ScriptState *st)
if (sdata->type == ByteCode::STR || sdata->type == ByteCode::CONSTSTR)
name = stringish<CharName>(ZString(conv_str(st, sdata)));
else
- id = conv_num(st, sdata);
+ id = wrap<BlockId>(conv_num(st, sdata));
}
if (name.to__actual())
@@ -3753,7 +3772,7 @@ void builtin_gmcommand(ScriptState *st)
sd = script_rid2sd(st);
dumb_string cmd = conv_str(st, &AARGO2(2));
- is_atcommand(sd->sess, sd, cmd, 99);
+ is_atcommand(sd->sess, sd, cmd, GmLevel::from(-1U));
}
@@ -3852,13 +3871,13 @@ void builtin_getlook(ScriptState *st)
val = static_cast<uint16_t>(sd->status.weapon);
break;
case LOOK::HEAD_BOTTOM: //3
- val = sd->status.head_bottom;
+ val = unwrap<ItemNameId>(sd->status.head_bottom);
break;
case LOOK::HEAD_TOP: //4
- val = sd->status.head_top;
+ val = unwrap<ItemNameId>(sd->status.head_top);
break;
case LOOK::HEAD_MID: //5
- val = sd->status.head_mid;
+ val = unwrap<ItemNameId>(sd->status.head_mid);
break;
case LOOK::HAIR_COLOR: //6
val = sd->status.hair_color;
@@ -3867,7 +3886,7 @@ void builtin_getlook(ScriptState *st)
val = sd->status.clothes_color;
break;
case LOOK::SHIELD: //8
- val = sd->status.shield;
+ val = unwrap<ItemNameId>(sd->status.shield);
break;
case LOOK::SHOES: //9
break;
@@ -4735,12 +4754,12 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript)
* スクリプトの実行
*------------------------------------------
*/
-int run_script(ScriptPointer sp, int rid, int oid)
+int run_script(ScriptPointer sp, BlockId rid, BlockId oid)
{
return run_script_l(sp, rid, oid, nullptr);
}
-int run_script_l(ScriptPointer sp, int rid, int oid,
+int run_script_l(ScriptPointer sp, BlockId rid, BlockId oid,
Slice<argrec_t> args)
{
struct script_stack stack;
diff --git a/src/map/script.hpp b/src/map/script.hpp
index 9ae893d..9b9c805 100644
--- a/src/map/script.hpp
+++ b/src/map/script.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cstdint>
# include <cstring> // for inlined get_str - TODO remove
@@ -155,7 +155,7 @@ public:
struct script_stack *stack;
int start, end;
ScriptEndState state;
- int rid, oid;
+ BlockId rid, oid;
ScriptPointer scriptp, new_scriptp;
int defsp, new_defsp;
};
@@ -177,8 +177,8 @@ struct argrec_t
argrec_t(ZString n, int i) : name(n), v(i) {}
argrec_t(ZString n, ZString z) : name(n), v(z) {}
};
-int run_script_l(ScriptPointer, int, int, Slice<argrec_t> args);
-int run_script(ScriptPointer, int, int);
+int run_script_l(ScriptPointer, BlockId, BlockId, Slice<argrec_t> args);
+int run_script(ScriptPointer, BlockId, BlockId);
struct ScriptLabel;
extern
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index 1506c6c..f9eeff1 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -94,7 +94,7 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src,
static
void skill_status_change_timer(TimerData *tid, tick_t tick,
- int id, StatusChange type);
+ BlockId id, StatusChange type);
int skill_get_hit(SkillID id)
{
@@ -316,8 +316,7 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src,
dumb_ptr<mob_data> md = bl->is_mob();
if (battle_config.mob_changetarget_byskill == 1)
{
- int target;
- target = md->target_id;
+ BlockId target = md->target_id;
if (src->bl_type == BL::PC)
md->target_id = src->bl_id;
mobskill_use(md, tick, MobSkillCondition::ANY);
@@ -389,7 +388,9 @@ void skill_area_sub(dumb_ptr<block_list> bl,
// these variables are set in the 'else' branches,
// and used in the (recursive) 'if' branch
-static int skill_area_temp_id, skill_area_temp_hp;
+// TODO kill it, kill it with fire.
+static BlockId skill_area_temp_id;
+static int skill_area_temp_hp;
/*==========================================
@@ -823,7 +824,7 @@ int skill_update_heal_animation(dumb_ptr<map_session_data> sd)
* ステータス異常終了タイマー
*------------------------------------------
*/
-void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange type)
+void skill_status_change_timer(TimerData *tid, tick_t tick, BlockId id, StatusChange type)
{
dumb_ptr<block_list> bl;
dumb_ptr<map_session_data> sd = NULL;
@@ -846,7 +847,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange
{ // Must report termination
spell_effect_report_termination(sc_data[type].spell_invocation,
bl->bl_id, type, 0);
- sc_data[type].spell_invocation = 0;
+ sc_data[type].spell_invocation = BlockId();
}
switch (type)
@@ -920,12 +921,12 @@ int skill_status_change_start(dumb_ptr<block_list> bl, StatusChange type,
int val1,
interval_t tick)
{
- return skill_status_effect(bl, type, val1, tick, 0);
+ return skill_status_effect(bl, type, val1, tick, BlockId());
}
int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
int val1,
- interval_t tick, int spell_invocation)
+ interval_t tick, BlockId spell_invocation)
{
dumb_ptr<map_session_data> sd = NULL;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
diff --git a/src/map/skill.hpp b/src/map/skill.hpp
index 91fa070..87cc576 100644
--- a/src/map/skill.hpp
+++ b/src/map/skill.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "skill.t.hpp"
# include "skill-pools.hpp"
@@ -110,7 +110,7 @@ int skill_castcancel(dumb_ptr<block_list> bl, int type);
// ステータス異常
int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
int val1,
- interval_t tick, int spell_invocation);
+ interval_t tick, BlockId spell_invocation);
int skill_status_change_start(dumb_ptr<block_list> bl, StatusChange type,
int val1,
interval_t tick);
diff --git a/src/map/storage.cpp b/src/map/storage.cpp
index 89357b9..41c31cc 100644
--- a/src/map/storage.cpp
+++ b/src/map/storage.cpp
@@ -19,14 +19,14 @@
#include "../poison.hpp"
static
-Map<int, struct storage> storage_db;
+Map<AccountId, struct storage> storage_db;
void do_final_storage(void)
{
storage_db.clear();
}
-struct storage *account2storage(int account_id)
+struct storage *account2storage(AccountId account_id)
{
struct storage *stor = storage_db.search(account_id);
if (stor == NULL)
@@ -38,13 +38,13 @@ struct storage *account2storage(int account_id)
}
// Just to ask storage, without creation
-struct storage *account2storage2(int account_id)
+struct storage *account2storage2(AccountId account_id)
{
return storage_db.search(account_id);
}
static
-void storage_delete(int account_id)
+void storage_delete(AccountId account_id)
{
storage_db.erase(account_id);
}
@@ -89,7 +89,7 @@ int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor,
struct item_data *data;
int i;
- if (item_data->nameid <= 0 || amount <= 0)
+ if (!item_data->nameid || amount <= 0)
return 1;
data = itemdb_search(item_data->nameid);
@@ -133,7 +133,7 @@ int storage_delitem(dumb_ptr<map_session_data> sd, struct storage *stor,
int n, int amount)
{
- if (stor->storage_[n].nameid == 0 || stor->storage_[n].amount < amount)
+ if (!stor->storage_[n].nameid || stor->storage_[n].amount < amount)
return 1;
stor->storage_[n].amount -= amount;
@@ -167,7 +167,7 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount)
if (index < 0 || index >= MAX_INVENTORY)
return 0;
- if (sd->status.inventory[index].nameid <= 0)
+ if (!sd->status.inventory[index].nameid)
return 0; //No item on that spot
if (amount < 1 || amount > sd->status.inventory[index].amount)
@@ -200,7 +200,7 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount)
if (index < 0 || index >= MAX_STORAGE)
return 0;
- if (stor->storage_[index].nameid <= 0)
+ if (!stor->storage_[index].nameid)
return 0; //Nothing there
if (amount < 1 || amount > stor->storage_[index].amount)
@@ -267,7 +267,7 @@ int storage_storage_quit(dumb_ptr<map_session_data> sd)
return 0;
}
-int storage_storage_save(int account_id, int final)
+int storage_storage_save(AccountId account_id, int final)
{
struct storage *stor;
@@ -295,7 +295,7 @@ int storage_storage_save(int account_id, int final)
}
//Ack from Char-server indicating the storage was saved. [Skotlex]
-int storage_storage_saved(int account_id)
+int storage_storage_saved(AccountId account_id)
{
struct storage *stor = account2storage2(account_id);
diff --git a/src/map/storage.hpp b/src/map/storage.hpp
index 702c908..bdfc049 100644
--- a/src/map/storage.hpp
+++ b/src/map/storage.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "map.hpp"
@@ -30,10 +30,10 @@ 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_storageclose(dumb_ptr<map_session_data> sd);
void do_final_storage(void);
-struct storage *account2storage(int account_id);
-struct storage *account2storage2(int account_id);
+struct storage *account2storage(AccountId account_id);
+struct storage *account2storage2(AccountId account_id);
int storage_storage_quit(dumb_ptr<map_session_data> sd);
-int storage_storage_save(int account_id, int final);
-int storage_storage_saved(int account_id);
+int storage_storage_save(AccountId account_id, int final);
+int storage_storage_saved(AccountId account_id);
#endif // TMWA_MAP_STORAGE_HPP
diff --git a/src/map/tmw.cpp b/src/map/tmw.cpp
index 7874e8e..8a1c9f7 100644
--- a/src/map/tmw.cpp
+++ b/src/map/tmw.cpp
@@ -130,7 +130,7 @@ void tmw_AutoBan(dumb_ptr<map_session_data> sd, ZString reason, int length)
/* type: 2 - ban(year, month, day, hour, minute, second) */
HumanTimeDiff ban_len {};
ban_len.hour = length;
- chrif_char_ask_name(-1, sd->status_key.name, 2, ban_len);
+ chrif_char_ask_name(AccountId(), sd->status_key.name, 2, ban_len);
clif_setwaitclose(sd->sess);
}
@@ -159,6 +159,6 @@ bool tmw_CheckChatLameness(dumb_ptr<map_session_data>, XString message)
void tmw_GmHackMsg(ZString line)
{
intif_wis_message_to_gm(wisp_server_name,
- battle_config.hack_info_GM_level,
+ GmLevel::from(static_cast<uint32_t>(battle_config.hack_info_GM_level)),
line);
}
diff --git a/src/map/trade.cpp b/src/map/trade.cpp
index 86d876f..08c1c6f 100644
--- a/src/map/trade.cpp
+++ b/src/map/trade.cpp
@@ -38,7 +38,7 @@
* 取引要請を相手に送る
*------------------------------------------
*/
-void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id)
+void trade_traderequest(dumb_ptr<map_session_data> sd, BlockId target_id)
{
dumb_ptr<map_session_data> target_sd;
@@ -48,7 +48,7 @@ void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id)
{
if (!battle_config.invite_request_check)
{
- if (target_sd->party_invite > 0)
+ if (target_sd->party_invite)
{
clif_tradestart(sd, 2); // 相手はPT要請中かGuild要請中
return;
@@ -60,7 +60,7 @@ void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id)
clif_tradestart(sd, 2);
return;
}
- if ((target_sd->trade_partner != 0) || (sd->trade_partner != 0))
+ if ((target_sd->trade_partner) || (sd->trade_partner))
{
trade_tradecancel(sd); //person is in another trade
}
@@ -97,20 +97,20 @@ void trade_tradeack(dumb_ptr<map_session_data> sd, int type)
dumb_ptr<map_session_data> target_sd;
nullpo_retv(sd);
- if ((target_sd = map_id2sd(sd->trade_partner)) != NULL)
+ if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
{
clif_tradestart(target_sd, type);
clif_tradestart(sd, type);
if (type == 4)
{ // Cancel
sd->deal_locked = 0;
- sd->trade_partner = 0;
+ sd->trade_partner = AccountId();
target_sd->deal_locked = 0;
- target_sd->trade_partner = 0;
+ target_sd->trade_partner = AccountId();
}
- if (sd->npc_id != 0)
+ if (sd->npc_id)
npc_event_dequeue(sd);
- if (target_sd->npc_id != 0)
+ if (target_sd->npc_id)
npc_event_dequeue(target_sd);
//close STORAGE window if it's open. It protects from spooffing packets [Lupus]
@@ -135,7 +135,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
nullpo_retv(sd);
- if (((target_sd = map_id2sd(sd->trade_partner)) != NULL)
+ if (((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
&& (sd->deal_locked < 1))
{
if (index < 2 || index >= MAX_INVENTORY + 2)
@@ -153,7 +153,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
// determine free slots of receiver
for (i = 0; i < MAX_INVENTORY; i++)
{
- if (target_sd->status.inventory[i].nameid == 0
+ if (!target_sd->status.inventory[i].nameid
&& target_sd->inventory_data[i] == NULL)
free_++;
}
@@ -273,7 +273,7 @@ void trade_tradeok(dumb_ptr<map_session_data> sd)
}
- if ((target_sd = map_id2sd(sd->trade_partner)) != NULL)
+ if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
{
sd->deal_locked = 1;
clif_tradeitemok(sd, 0, 0, 0);
@@ -293,7 +293,7 @@ void trade_tradecancel(dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
- if ((target_sd = map_id2sd(sd->trade_partner)) != NULL)
+ if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
{
for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
{ //give items back (only virtual)
@@ -327,9 +327,9 @@ void trade_tradecancel(dumb_ptr<map_session_data> sd)
target_sd->deal_zeny = 0;
}
sd->deal_locked = 0;
- sd->trade_partner = 0;
+ sd->trade_partner = AccountId();
target_sd->deal_locked = 0;
- target_sd->trade_partner = 0;
+ target_sd->trade_partner = AccountId();
clif_tradecancelled(sd);
clif_tradecancelled(target_sd);
}
@@ -346,7 +346,7 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
- if ((target_sd = map_id2sd(sd->trade_partner)) != NULL)
+ if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
{
MAP_LOG_PC(sd, " TRADECOMMIT WITH %d GIVE %d GET %d"_fmt,
target_sd->status_key.char_id, sd->deal_zeny,
@@ -373,8 +373,8 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
MAP_LOG_PC(sd, " TRADECANCEL"_fmt);
return;
}
- sd->trade_partner = 0;
- target_sd->trade_partner = 0;
+ sd->trade_partner = AccountId();
+ target_sd->trade_partner = AccountId();
for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
{
if (sd->deal_item_amount[trade_i] != 0)
@@ -449,7 +449,7 @@ void trade_verifyzeny(dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
- if ((target_sd = map_id2sd(sd->trade_partner)) != NULL)
+ if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != NULL)
{
if (sd->deal_zeny > sd->status.zeny)
{
diff --git a/src/map/trade.hpp b/src/map/trade.hpp
index dc81c54..da0d2b2 100644
--- a/src/map/trade.hpp
+++ b/src/map/trade.hpp
@@ -21,11 +21,11 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "map.hpp"
-void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id);
+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_tradeok(dumb_ptr<map_session_data> sd);
diff --git a/src/mmo/extract.cpp b/src/mmo/extract.cpp
index 378986d..f25126f 100644
--- a/src/mmo/extract.cpp
+++ b/src/mmo/extract.cpp
@@ -22,6 +22,8 @@
#include "../strings/xstring.hpp"
#include "../strings/vstring.hpp"
+#include "mmo.hpp"
+
#include "../poison.hpp"
bool extract(XString str, XString *rv)
@@ -47,7 +49,7 @@ bool extract(XString str, struct item *it)
XString ignored;
return extract(str,
record<',', 11>(
- &it->id,
+ &ignored,
&it->nameid,
&it->amount,
&it->equip,
@@ -60,3 +62,24 @@ bool extract(XString str, struct item *it)
&ignored,
&ignored));
}
+
+bool extract(XString str, MapName *m)
+{
+ XString::iterator it = std::find(str.begin(), str.end(), '.');
+ str = str.xislice_h(it);
+ VString<15> tmp;
+ bool rv = extract(str, &tmp);
+ *m = tmp;
+ return rv;
+}
+
+bool extract(XString str, CharName *out)
+{
+ VString<23> tmp;
+ if (extract(str, &tmp))
+ {
+ *out = CharName(tmp);
+ return true;
+ }
+ return false;
+}
diff --git a/src/mmo/extract.hpp b/src/mmo/extract.hpp
index f3df0f3..ab65661 100644
--- a/src/mmo/extract.hpp
+++ b/src/mmo/extract.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cerrno>
# include <cstdlib>
@@ -27,11 +27,17 @@
# include <algorithm>
# include <vector>
+# include "../ints/wrap.hpp"
+
# include "../strings/xstring.hpp"
-# include "mmo.hpp"
+# include "../generic/enum.hpp"
+
# include "utils.hpp"
+template<class T>
+bool do_extract(XString str, T t);
+
template<class T, typename=typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, char>::value && !std::is_same<T, bool>::value>::type>
bool extract(XString str, T *iv)
{
@@ -98,6 +104,12 @@ bool extract(XString str, VString<N> *out)
return true;
}
+inline
+bool extract(XString str, LString exact)
+{
+ return str == exact;
+}
+
template<class T>
class LStripper
{
@@ -200,27 +212,20 @@ bool extract(XString str, struct global_reg *var);
bool extract(XString str, struct item *it);
-inline
-bool extract(XString str, MapName *m)
-{
- XString::iterator it = std::find(str.begin(), str.end(), '.');
- str = str.xislice_h(it);
- VString<15> tmp;
- bool rv = extract(str, &tmp);
- *m = tmp;
- return rv;
+bool extract(XString str, MapName *m);
+
+bool extract(XString str, CharName *out);
+
+template<class T>
+bool do_extract(XString str, T t)
+{
+ return extract(str, t);
}
-inline
-bool extract(XString str, CharName *out)
+template<class R>
+bool extract(XString str, Wrapped<R> *w)
{
- VString<23> tmp;
- if (extract(str, &tmp))
- {
- *out = CharName(tmp);
- return true;
- }
- return false;
+ return extract(str, &w->_value);
}
#endif // TMWA_MMO_EXTRACT_HPP
diff --git a/src/mmo/extract_test.cpp b/src/mmo/extract_test.cpp
index c405de1..126cb14 100644
--- a/src/mmo/extract_test.cpp
+++ b/src/mmo/extract_test.cpp
@@ -22,6 +22,8 @@
#include "../strings/xstring.hpp"
+#include "mmo.hpp"
+
#include "../poison.hpp"
TEST(extract, record_int)
diff --git a/src/mmo/fwd.hpp b/src/mmo/fwd.hpp
new file mode 100644
index 0000000..f9c176c
--- /dev/null
+++ b/src/mmo/fwd.hpp
@@ -0,0 +1,37 @@
+#ifndef TMWA_MMO_FWD_HPP
+#define TMWA_MMO_FWD_HPP
+// mmo/fwd.hpp - list of type names for mmo lib
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+class MapName;
+class CharName;
+
+class Session;
+
+class AccountId;
+class CharId;
+class PartyId;
+class ItemUnkId;
+class ItemNameId;
+class GmLevel;
+
+#endif // TMWA_MMO_FWD_HPP
diff --git a/src/mmo/ids.cpp b/src/mmo/ids.cpp
new file mode 100644
index 0000000..971013b
--- /dev/null
+++ b/src/mmo/ids.cpp
@@ -0,0 +1,21 @@
+#include "ids.hpp"
+// ids.cpp - special integer classes for various object IDs
+//
+// 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 "../poison.hpp"
diff --git a/src/mmo/ids.hpp b/src/mmo/ids.hpp
new file mode 100644
index 0000000..71164ff
--- /dev/null
+++ b/src/mmo/ids.hpp
@@ -0,0 +1,109 @@
+#ifndef TMWA_MMO_IDS_HPP
+#define TMWA_MMO_IDS_HPP
+// ids.hpp - special integer classes for various object IDs
+//
+// 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 "../ints/wrap.hpp"
+
+# include "extract.hpp"
+
+class Species : public Wrapped<uint16_t> { public: explicit operator bool() const = delete; bool operator !() const = delete; Species() : Wrapped<uint16_t>() {} protected: template<class... A> constexpr explicit Species(A... a) : Wrapped<uint16_t>(a...) {} };
+
+class AccountId : public Wrapped<uint32_t> { public: AccountId() : Wrapped<uint32_t>() {} protected: template<class... A> constexpr explicit AccountId(A... a) : Wrapped<uint32_t>(a...) {} };
+class CharId : public Wrapped<uint32_t> { public: CharId() : Wrapped<uint32_t>() {} protected: template<class... A> constexpr explicit CharId(A... a) : Wrapped<uint32_t>(a...) {} };
+// important note: slave mobs synthesize PartyId as -BlockId of master
+class PartyId : public Wrapped<uint32_t> { public: PartyId() : Wrapped<uint32_t>() {} protected: template<class... A> constexpr explicit PartyId(A... a) : Wrapped<uint32_t>(a...) {} };
+class ItemNameId : public Wrapped<uint16_t> { public: ItemNameId() : Wrapped<uint16_t>() {} protected: template<class... A> constexpr explicit ItemNameId(A... a) : Wrapped<uint16_t>(a...) {} };
+
+class GmLevel
+{
+ uint32_t bits;
+
+ friend bool extract(XString str, GmLevel *lvl) { return extract(str, &lvl->bits); }
+ constexpr explicit
+ GmLevel(uint32_t b) : bits(b) {}
+ constexpr explicit
+ operator uint32_t() { return bits; }
+
+ template<class T>
+ explicit
+ GmLevel(T) = delete;
+ template<class T, typename=typename std::enable_if<!std::is_same<T, uint32_t>::value && !std::is_same<T, bool>::value>::type>
+ explicit
+ operator T() = delete;
+public:
+ constexpr
+ GmLevel() : bits() {}
+ constexpr static
+ GmLevel from(uint32_t bits) { return GmLevel(bits); }
+ template<class T>
+ constexpr static
+ GmLevel from(T) = delete;
+
+ constexpr explicit
+ operator bool() const { return bits; }
+ constexpr
+ bool operator !() const { return !bits; }
+
+ // the argument is the level of a command
+ constexpr
+ bool satisfies(GmLevel perm) { return bits >= perm.bits; }
+ // the argument is another player's gm level, for info commands
+ constexpr
+ bool detects(GmLevel other) { return bits >= other.bits; }
+ // the argument is another player's gm level, for aggressive commands
+ constexpr
+ bool overwhelms(GmLevel other) { return bits >= other.bits; }
+ // the argument is another potential permission level
+ constexpr
+ bool obsoletes(GmLevel plvl) { return bits >= plvl.bits; }
+
+ constexpr
+ uint16_t get_public_word() const
+ {
+ return (bits == 60 || bits == 99) ? 0x0080 : 0;
+ }
+
+ constexpr
+ uint32_t get_all_bits() const
+ {
+ return bits;
+ }
+
+ friend constexpr
+ bool operator == (GmLevel l, GmLevel r)
+ {
+ return l.bits == r.bits;
+ }
+ friend constexpr
+ bool operator != (GmLevel l, GmLevel r)
+ {
+ return l.bits != r.bits;
+ }
+};
+
+inline
+uint32_t convert_for_printf(GmLevel g)
+{
+ return g.get_all_bits();
+}
+
+#endif // TMWA_MMO_IDS_HPP
diff --git a/src/mmo/mmo.hpp b/src/mmo/mmo.hpp
index 3fba7e6..fdfc478 100644
--- a/src/mmo/mmo.hpp
+++ b/src/mmo/mmo.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include "../compat/memory.hpp"
@@ -29,6 +29,7 @@
# include "../generic/enum.hpp"
+# include "ids.hpp"
# include "timer.t.hpp"
// affects CharName
@@ -199,8 +200,7 @@ using e::EPOS;
struct item
{
- int id;
- short nameid;
+ ItemNameId nameid;
short amount;
EPOS equip;
};
@@ -322,28 +322,28 @@ SEX sex_from_char(char c)
struct CharKey
{
CharName name;
- int account_id;
- int char_id;
+ AccountId account_id;
+ CharId char_id;
unsigned char char_num;
};
struct CharData
{
- int partner_id;
+ CharId partner_id;
int base_exp, job_exp, zeny;
- short species;
+ Species species;
short status_point, skill_point;
int hp, max_hp, sp, max_sp;
Option option;
short karma, manner;
short hair, hair_color, clothes_color;
- int party_id;
+ PartyId party_id;
ItemLook weapon;
- short shield;
- short head_top, head_mid, head_bottom;
+ ItemNameId shield;
+ ItemNameId head_top, head_mid, head_bottom;
unsigned char base_level, job_level;
earray<short, ATTR, ATTR::COUNT> attrs;
@@ -375,8 +375,8 @@ struct CharPair
struct storage
{
- int dirty;
- int account_id;
+ bool dirty;
+ AccountId account_id;
short storage_status;
short storage_amount;
Array<struct item, MAX_STORAGE> storage_;
@@ -384,13 +384,13 @@ struct storage
struct GM_Account
{
- int account_id;
- uint8_t level;
+ AccountId account_id;
+ GmLevel level;
};
struct party_member
{
- int account_id;
+ AccountId account_id;
CharName name;
MapName map;
int leader, online, lv;
@@ -399,7 +399,7 @@ struct party_member
struct party
{
- int party_id;
+ PartyId party_id;
PartyName name;
int exp;
int item;
diff --git a/src/mmo/socket.cpp b/src/mmo/socket.cpp
index 2fec6c1..79857b1 100644
--- a/src/mmo/socket.cpp
+++ b/src/mmo/socket.cpp
@@ -33,7 +33,10 @@
#include <cstring>
#include <ctime>
+#include "../compat/memory.hpp"
+
#include "../io/cxxstdio.hpp"
+
#include "core.hpp"
#include "timer.hpp"
#include "utils.hpp"
diff --git a/src/mmo/socket.hpp b/src/mmo/socket.hpp
index c166794..f62ca7a 100644
--- a/src/mmo/socket.hpp
+++ b/src/mmo/socket.hpp
@@ -21,13 +21,14 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <netinet/in.h>
# include <cstdio>
# include <array>
+# include <memory>
# include "../compat/rawmem.hpp"
diff --git a/src/mmo/utils.hpp b/src/mmo/utils.hpp
index 3002866..ed48ad0 100644
--- a/src/mmo/utils.hpp
+++ b/src/mmo/utils.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <sys/types.h>
diff --git a/src/mmo/version.hpp b/src/mmo/version.hpp
index 1cec0ba..9e20bf1 100644
--- a/src/mmo/version.hpp
+++ b/src/mmo/version.hpp
@@ -21,7 +21,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cstdint>
diff --git a/src/range/fwd.hpp b/src/range/fwd.hpp
new file mode 100644
index 0000000..31263fb
--- /dev/null
+++ b/src/range/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_RANGE_FWD_HPP
+#define TMWA_RANGE_FWD_HPP
+// range/fwd.hpp - list of type names for range lib
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_RANGE_FWD_HPP
diff --git a/src/sexpr/fwd.hpp b/src/sexpr/fwd.hpp
new file mode 100644
index 0000000..ad8304b
--- /dev/null
+++ b/src/sexpr/fwd.hpp
@@ -0,0 +1,26 @@
+#ifndef TMWA_SEXPR_FWD_HPP
+#define TMWA_SEXPR_FWD_HPP
+// sexpr/fwd.hpp - list of type names for sexpr lib
+//
+// 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 "../sanity.hpp"
+
+// meh, add more when I feel like it
+
+#endif // TMWA_SEXPR_FWD_HPP
diff --git a/src/sexpr/lexer.hpp b/src/sexpr/lexer.hpp
index f190f9f..89380b7 100644
--- a/src/sexpr/lexer.hpp
+++ b/src/sexpr/lexer.hpp
@@ -19,7 +19,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-# include "../sanity.hpp"
+# include "fwd.hpp"
# include <vector>
diff --git a/src/sexpr/parser.hpp b/src/sexpr/parser.hpp
index 5352afc..4ce7f2d 100644
--- a/src/sexpr/parser.hpp
+++ b/src/sexpr/parser.hpp
@@ -19,7 +19,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-# include "../sanity.hpp"
+# include "fwd.hpp"
# include <cstdlib>
diff --git a/src/strings/astring.hpp b/src/strings/astring.hpp
index 7a569f9..8558a98 100644
--- a/src/strings/astring.hpp
+++ b/src/strings/astring.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cstdarg>
# include <cstring>
diff --git a/src/strings/literal.hpp b/src/strings/literal.hpp
index 54192da..a3ebecd 100644
--- a/src/strings/literal.hpp
+++ b/src/strings/literal.hpp
@@ -19,7 +19,7 @@
// 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 "../sanity.hpp"
+# include "fwd.hpp"
# include <cstring>