diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-04-22 11:46:23 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-04-22 13:20:52 -0700 |
commit | ad049a15b43b7ddba3fe7d0a898652fc8022629d (patch) | |
tree | 142624e70ead3e89a8da6d56de41651f171524d0 /src | |
parent | ceeda2e337077b2edaf1af09cc4df2c30e8205a1 (diff) | |
download | tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.tar.gz tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.tar.bz2 tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.tar.xz tmwa-ad049a15b43b7ddba3fe7d0a898652fc8022629d.zip |
Use strict ID types
Possibly some missing for the far side of the network.
AccountId and BlockId are still terribly entangled.
Diffstat (limited to 'src')
81 files changed, 2339 insertions, 1767 deletions
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> |