diff options
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> |