diff options
Diffstat (limited to 'src/map/atcommand.cpp')
-rw-r--r-- | src/map/atcommand.cpp | 762 |
1 files changed, 388 insertions, 374 deletions
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index 0d70b36..7739966 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -24,8 +24,6 @@ #include <algorithm> -#include "../conf/version.hpp" - #include "../compat/nullpo.hpp" #include "../compat/fun.hpp" @@ -39,31 +37,40 @@ #include "../generic/random.hpp" #include "../io/cxxstdio.hpp" -#include "../io/cxxstdio_enums.hpp" +#include "../io/extract.hpp" #include "../io/read.hpp" #include "../io/write.hpp" #include "../net/socket.hpp" #include "../net/timer.hpp" +#include "../net/timestamp-utils.hpp" #include "../mmo/config_parse.hpp" -#include "../mmo/core.hpp" -#include "../mmo/extract.hpp" +#include "../mmo/cxxstdio_enums.hpp" #include "../mmo/extract_enums.hpp" #include "../mmo/human_time_diff.hpp" #include "../mmo/ids.hpp" -#include "../mmo/mmo.hpp" -#include "../mmo/utils.hpp" #include "../mmo/version.hpp" +#include "../high/core.hpp" +#include "../high/extract_mmo.hpp" +#include "../high/mmo.hpp" +#include "../high/utils.hpp" + +#include "../ast/npc.hpp" + #include "battle.hpp" +#include "battle_conf.hpp" #include "chrif.hpp" #include "clif.hpp" +#include "globals.hpp" #include "intif.hpp" #include "itemdb.hpp" #include "map.hpp" +#include "map_conf.hpp" #include "mob.hpp" #include "npc.hpp" +#include "npc-parse.hpp" #include "party.hpp" #include "pc.hpp" #include "skill.hpp" @@ -76,6 +83,8 @@ namespace tmwa { +namespace map +{ enum class ATCE { OKAY, @@ -105,7 +114,7 @@ Map<XString, AtCommandInfo> atcommand_info; static -AtCommandInfo *atcommand(XString cmd); +Option<Borrowed<AtCommandInfo>> atcommand(XString cmd); // These @commands are used within other @commands. static @@ -203,9 +212,7 @@ void log_atcommand(dumb_ptr<map_session_data> sd, ZString cmd) return; timestamp_seconds_buffer tmpstr; stamp_time(tmpstr); - MapName map = (sd->bl_m - ? sd->bl_m->name_ - : stringish<MapName>("undefined.gat"_s)); + MapName map = (sd->bl_m->name_); FPRINTF(*fp, "[%s] %s(%d,%d) %s(%d) : %s\n"_fmt, tmpstr, map, sd->bl_x, sd->bl_y, @@ -213,11 +220,9 @@ void log_atcommand(dumb_ptr<map_session_data> sd, ZString cmd) cmd); } -AString gm_log; - io::AppendFile *get_gm_log() { - if (!gm_log) + if (!map_conf.gm_log) return nullptr; struct tm ctime = TimeT::now(); @@ -233,7 +238,7 @@ io::AppendFile *get_gm_log() last_logfile_nr = logfile_nr; AString fullname = STRPRINTF("%s.%04d-%02d"_fmt, - gm_log, year, month); + map_conf.gm_log, year, month); if (gm_logfile) gm_logfile.reset(); @@ -243,7 +248,7 @@ io::AppendFile *get_gm_log() if (!gm_logfile) { perror("GM log file"); - gm_log = AString(); + map_conf.gm_log = AString(); } return gm_logfile.get(); } @@ -260,8 +265,6 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd, ZString arg; asplit(message, &command, &arg); - AtCommandInfo *info = atcommand(command); - if (!gmlvl) gmlvl = pc_isGM(sd); if (battle_config.atcommand_gm_only != 0 && !gmlvl) @@ -271,14 +274,16 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd, clif_displaymessage(s, output); return true; } - if (!info) + + Option<P<AtCommandInfo>> info_ = atcommand(command); + P<AtCommandInfo> info = TRY_UNWRAP(info_, { AString output = STRPRINTF("GM command not found: %s"_fmt, AString(command)); clif_displaymessage(s, output); return true; // don't show in chat - } + }); if (!(gmlvl.satisfies(info->level))) { AString output = STRPRINTF("GM command is level %d, but you are level %d: %s"_fmt, @@ -320,15 +325,15 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd, } } -AtCommandInfo *atcommand(XString cmd) +Option<Borrowed<AtCommandInfo>> atcommand(XString cmd) { if (cmd.startswith('@')) { XString command = cmd.xslice_t(1); - AtCommandInfo *it = atcommand_info.search(command); + Option<P<AtCommandInfo>> it = atcommand_info.search(command); return it; } - return nullptr; + return None; } static @@ -344,51 +349,42 @@ void atkillmonster_sub(dumb_ptr<block_list> bl, int flag) } static -AtCommandInfo *get_atcommandinfo_byname(XString name) +Option<Borrowed<AtCommandInfo>> get_atcommandinfo_byname(XString name) { return atcommand_info.search(name); } -bool atcommand_config_read(ZString cfgName) +static +bool atcommand_config(io::Spanned<XString> w1, io::Spanned<ZString> w2) { - io::ReadFile in(cfgName); - if (!in.is_open()) - { - PRINTF("At commands configuration file not found: %s\n"_fmt, cfgName); - return false; - } - bool rv = true; - AString line; - while (in.getline(line)) { - if (is_comment(line)) - continue; - XString w1; - ZString w2; - if (!config_split(line, &w1, &w2)) + Option<P<AtCommandInfo>> p_ = get_atcommandinfo_byname(w1.data); + OMATCH_BEGIN (p_) { - PRINTF("Bad config line: %s\n"_fmt, line); - rv = false; - continue; - } - AtCommandInfo *p = get_atcommandinfo_byname(w1); - if (p != nullptr) - { - p->level = GmLevel::from(static_cast<uint32_t>(atoi(w2.c_str()))); - } - else if (w1 == "import"_s) - rv &= atcommand_config_read(w2); - else - { - PRINTF("%s: bad line: %s\n"_fmt, cfgName, line); - rv = false; + OMATCH_CASE_SOME (p) + { + p->level = GmLevel::from(static_cast<uint32_t>(atoi(w2.data.c_str()))); + } + OMATCH_CASE_NONE () + { + { + w1.span.error("Unknown @command for permission level config."_s); + rv = false; + } + } } + OMATCH_END (); } return rv; } +bool atcommand_config_read(ZString cfgName) +{ + return load_config_file(cfgName, atcommand_config); +} + /// @ command processing functions static @@ -421,9 +417,7 @@ ATCE atcommand_help(Session *s, dumb_ptr<map_session_data>, if (message.startswith('@')) { ZString cmd = message.xslice_t(1); - const AtCommandInfo *info = atcommand_info.search(cmd); - if (!info) - return ATCE::EXIST; + P<AtCommandInfo> info = TRY_UNWRAP(atcommand_info.search(cmd), return ATCE::EXIST); clif_displaymessage(s, STRPRINTF("Usage: @%s %s"_fmt, cmd, info->args)); clif_displaymessage(s, info->help); return ATCE::OKAY; @@ -534,16 +528,16 @@ ATCE atcommand_charwarp(Session *s, dumb_ptr<map_session_data> 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) - && !pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level)))) + Option<P<map_local>> m = map_mapname2mapid(map_name); + if (m.map([](P<map_local> m_){ return m_->flag.get(MapFlag::NOWARPTO); }).copy_or(false) + && !pc_isGM(sd).satisfies(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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp this player from its actual map."_s); @@ -603,16 +597,16 @@ ATCE atcommand_warp(Session *s, dumb_ptr<map_session_data> sd, if (x > 0 && x < 800 && y > 0 && y < 800) { - map_local *m = map_mapname2mapid(map_name); - if (m != nullptr && m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + Option<P<map_local>> m = map_mapname2mapid(map_name); + if (m.map([](P<map_local> m_){ return m_->flag.get(MapFlag::NOWARPTO); }).copy_or(false) + && !(pc_isGM(sd).satisfies(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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp you from your actual map."_s); @@ -645,7 +639,7 @@ ATCE atcommand_where(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = character.to__actual() ? map_nick2sd(character) : sd; if (pl_sd != nullptr && !((battle_config.hide_GM_session - || bool(pl_sd->status.option & Option::HIDE)) + || bool(pl_sd->status.option & Opt0::HIDE)) && !(pc_isGM(sd).detects(pc_isGM(pl_sd))))) { // you can look only lower or same level @@ -679,15 +673,15 @@ ATCE atcommand_goto(Session *s, dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); if (pl_sd != nullptr) { - if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (pl_sd->bl_m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp you from your actual map."_s); @@ -707,6 +701,69 @@ ATCE atcommand_goto(Session *s, dumb_ptr<map_session_data> sd, } static +ATCE atcommand_npc(Session *s, dumb_ptr<map_session_data> sd, + ZString message) +{ + NpcName npc; + + if (!asplit(message, &npc)) + { + clif_displaymessage(s, + "Please, enter a npc name (usage: @npc/@warptonpc/@gotonpc <npc>)."_s); + return ATCE::USAGE; + } + + dumb_ptr<npc_data> nd = npc_name2id(npc); + if (nd != nullptr) + { + if (nd->bl_m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) + { + clif_displaymessage(s, + "You are not authorised to warp you to the map of this npc."_s); + return ATCE::PERM; + } + if (sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) + { + clif_displaymessage(s, + "You are not authorised to warp you from your actual map."_s); + return ATCE::PERM; + } + + int x = nd->bl_x, y = nd->bl_y, x0 = (x >= 5)? (x - 5): 0, j = 0, + y0 = (y >= 5)? (y - 5): 0, x1 = (x + 5), y1 = (y + 5), max; + max = (y1 - y0 + 1) * (x1 - x0 + 1) * 3; + P<map_local> m = TRY_UNWRAP(map_mapname2mapid(nd->bl_m->name_), return ATCE::OKAY); + if (max > 1000) + max = 1000; + if (bool(map_getcell(m, x, y) & MapCell::UNWALKABLE)){ + do + { + x = random_::in(x0, x1); + y = random_::in(y0, y1); + } + while (bool(map_getcell(m, x, y) & MapCell::UNWALKABLE) + && (++j) < max); + if (j >= max) + { + return ATCE::OKAY; // Since reference of the place which boils first went wrong, it stops. + } + } + pc_setpos(sd, nd->bl_m->name_, x, y, BeingRemoveWhy::WARPED); + AString output = STRPRINTF("Jump to %s"_fmt, npc); + clif_displaymessage(s, output); + } + else + { + clif_displaymessage(s, "Npc not found."_s); + return ATCE::EXIST; + } + + return ATCE::OKAY; +} + +static ATCE atcommand_jump(Session *s, dumb_ptr<map_session_data> sd, ZString message) { @@ -720,15 +777,15 @@ ATCE atcommand_jump(Session *s, dumb_ptr<map_session_data> sd, y = random_::in(1, 399); if (x > 0 && x < 800 && y > 0 && y < 800) { - if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp you from your actual map."_s); @@ -768,7 +825,7 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd, GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session - || bool(pl_sd->status.option & Option::HIDE)) + || bool(pl_sd->status.option & Opt0::HIDE)) && !(gm_level.detects(pl_gm_level)))) { // you can look only lower or same level @@ -812,7 +869,6 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - PartyPair p; VString<23> match_text = message; match_text = match_text.to_lower(); @@ -830,7 +886,7 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session - || bool(pl_sd->status.option & Option::HIDE)) + || bool(pl_sd->status.option & Opt0::HIDE)) && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level @@ -838,8 +894,8 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd, if (player_name.contains_seq(match_text)) { // search with no case sensitive - p = party_search(pl_sd->status.party_id); - PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s); + Option<PartyPair> p_ = party_search(pl_sd->status.party_id); + PartyName temp0 = p_.pmd_pget(&PartyMost::name).move_or(stringish<PartyName>("None"_s)); AString output; if (pl_gm_level) output = STRPRINTF( @@ -870,15 +926,14 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - map_local *map_id; - { + Borrowed<map_local> map_id = + ({ MapName map_name; extract(message, &map_name); - map_id = map_mapname2mapid(map_name); - if (map_id == nullptr) - map_id = sd->bl_m; - } + + map_mapname2mapid(map_name).copy_or(sd->bl_m); + }); count = 0; GmLevel gm_level = pc_isGM(sd); @@ -893,7 +948,7 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd, GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session - || bool(pl_sd->status.option & Option::HIDE)) + || bool(pl_sd->status.option & Opt0::HIDE)) && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level @@ -929,16 +984,14 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - PartyPair p; - map_local *map_id; - { + P<map_local> map_id = + ({ MapName map_name; extract(message, &map_name); - map_id = map_mapname2mapid(map_name); - if (map_id == nullptr) - map_id = sd->bl_m; - } + + map_mapname2mapid(map_name).copy_or(sd->bl_m); + }); count = 0; GmLevel gm_level = pc_isGM(sd); @@ -953,14 +1006,14 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd, GmLevel pl_gm_level = pc_isGM(pl_sd); if (! ((battle_config.hide_GM_session - || bool(pl_sd->status.option & Option::HIDE)) + || bool(pl_sd->status.option & Opt0::HIDE)) && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level if (pl_sd->bl_m == map_id) { - p = party_search(pl_sd->status.party_id); - PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s); + Option<PartyPair> p_ = party_search(pl_sd->status.party_id); + PartyName temp0 = p_.pmd_pget(&PartyMost::name).copy_or(stringish<PartyName>("None"_s)); AString output; if (pl_gm_level) output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'"_fmt, @@ -994,7 +1047,6 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, ZString message) { int count; - PartyPair p; VString<23> match_text = message; match_text = match_text.to_lower(); @@ -1014,7 +1066,7 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, { if (! ((battle_config.hide_GM_session - || bool(pl_sd->status.option & Option::HIDE)) + || bool(pl_sd->status.option & Opt0::HIDE)) && (!(gm_level.detects(pl_gm_level))))) { // you can look only lower or same level @@ -1034,8 +1086,8 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd, "Novice/Human"_s, pl_sd->status.job_level); clif_displaymessage(s, output); - p = party_search(pl_sd->status.party_id); - PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s); + Option<PartyPair> p_ = party_search(pl_sd->status.party_id); + PartyName temp0 = p_.pmd_pget(&PartyMost::name).copy_or(stringish<PartyName>("None"_s)); output = STRPRINTF( " Party: '%s'"_fmt, temp0); @@ -1076,16 +1128,16 @@ static ATCE atcommand_load(Session *s, dumb_ptr<map_session_data> sd, ZString) { - map_local *m = map_mapname2mapid(sd->status.save_point.map_); - if (m != nullptr && m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + Option<P<map_local>> m = map_mapname2mapid(sd->status.save_point.map_); + if (m.map([](P<map_local> m_){ return m_->flag.get(MapFlag::NOWARPTO); }).copy_or(false) + && !(pc_isGM(sd).satisfies(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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp you from your actual map."_s); @@ -1148,16 +1200,13 @@ static ATCE atcommand_storage(Session *s, dumb_ptr<map_session_data> sd, ZString) { - Storage *stor; - if (sd->state.storage_open) { clif_displaymessage(s, "msg_table[250]"_s); return ATCE::EXIST; } - if ((stor = account2storage2(sd->status_key.account_id)) != nullptr - && stor->storage_status == 1) + if (account2storage2(sd->status_key.account_id).pmd_pget(&Storage::storage_status).copy_or(0) == 1) { clif_displaymessage(s, "msg_table[250]"_s); return ATCE::EXIST; @@ -1174,7 +1223,7 @@ ATCE atcommand_option(Session *s, dumb_ptr<map_session_data> sd, { Opt1 param1 = Opt1::ZERO; Opt2 param2 = Opt2::ZERO; - Option param3 = Option::ZERO; + Opt0 param3 = Opt0::ZERO; if (!extract(message, record<',', 1>(¶m1, ¶m2, ¶m3))) return ATCE::USAGE; @@ -1194,14 +1243,14 @@ static ATCE atcommand_hide(Session *s, dumb_ptr<map_session_data> sd, ZString) { - if (bool(sd->status.option & Option::HIDE)) + if (bool(sd->status.option & Opt0::HIDE)) { - sd->status.option &= ~Option::HIDE; + sd->status.option &= ~Opt0::HIDE; clif_displaymessage(s, "Invisible: Off."_s); } else { - sd->status.option |= Option::HIDE; + sd->status.option |= Opt0::HIDE; clif_displaymessage(s, "Invisible: On."_s); } clif_changeoption(sd); @@ -1259,8 +1308,8 @@ ATCE atcommand_alive(Session *s, dumb_ptr<map_session_data> sd, sd->status.hp = sd->status.max_hp; sd->status.sp = sd->status.max_sp; pc_setstand(sd); - if (static_cast<interval_t>(battle_config.player_invincible_time) > interval_t::zero()) - pc_setinvincibletimer(sd, static_cast<interval_t>(battle_config.player_invincible_time)); + if (battle_config.player_invincible_time > interval_t::zero()) + pc_setinvincibletimer(sd, battle_config.player_invincible_time); clif_updatestatus(sd, SP::HP); clif_updatestatus(sd, SP::SP); clif_resurrection(sd, 1); @@ -1312,7 +1361,7 @@ ATCE atcommand_heal(Session *s, dumb_ptr<map_session_data> sd, if (hp < 0) // display like damage - clif_damage(sd, sd, gettick(), interval_t::zero(), interval_t::zero(), -hp, 0, DamageType::RETURNED, 0); + clif_damage(sd, sd, gettick(), interval_t::zero(), interval_t::zero(), -hp, 0, DamageType::RETURNED); if (hp != 0 || sp != 0) { @@ -1332,13 +1381,27 @@ ATCE atcommand_heal(Session *s, dumb_ptr<map_session_data> sd, } static +Option<P<struct item_data>> extract_item_opt(XString item_name) +{ + Option<P<struct item_data>> item_data = itemdb_searchname(item_name); + if (item_data.is_some()) + return item_data; + + ItemNameId item_id; + if (extract(item_name, &item_id)) + { + item_data = itemdb_exists(item_id); + return item_data; + } + return None; +} + +static ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd, ZString message) { XString item_name; int number = 0; - ItemNameId item_id; - struct item_data *item_data = nullptr; int get_count, i; if (!extract(message, record<' ', 1>(&item_name, &number))) @@ -1351,14 +1414,10 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd, if (number <= 0) number = 1; - if ((item_data = itemdb_searchname(item_name)) != nullptr) - item_id = item_data->nameid; - else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != nullptr) - item_id = item_data->nameid; - else - return ATCE::EXIST; + P<struct item_data> item_data = TRY_UNWRAP(extract_item_opt(item_name), return ATCE::EXIST); + ItemNameId item_id = item_data->nameid; + assert (item_id); - if (item_id) { get_count = number; if (item_data->type == ItemType::WEAPON @@ -1379,11 +1438,6 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd, } clif_displaymessage(s, "Item created."_s); } - else - { - clif_displaymessage(s, "Invalid item ID or name."_s); - return ATCE::EXIST; - } return ATCE::OKAY; } @@ -1537,25 +1591,6 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd, } static -ATCE atcommand_gm(Session *s, dumb_ptr<map_session_data> sd, - ZString message) -{ - if (!message) - return ATCE::USAGE; - - if (pc_isGM(sd)) - { - // a GM can not use this function. only a normal player (become gm is not for gm!) - clif_displaymessage(s, "You already have some GM powers."_s); - return ATCE::PERM; - } - else - chrif_changegm(sd->status_key.account_id, message); - - return ATCE::OKAY; -} - -static ATCE atcommand_pvpoff(Session *s, dumb_ptr<map_session_data> sd, ZString) { @@ -1595,6 +1630,25 @@ ATCE atcommand_pvpoff(Session *s, dumb_ptr<map_session_data> sd, } static +ATCE atcommand_exprate(Session *s, dumb_ptr<map_session_data>, + ZString message) +{ + int rate; + + if (!extract(message, &rate) || !rate) + { + clif_displaymessage(s, + "Please, enter a rate adjustement (usage: @exprate <percent>)."_s); + return ATCE::USAGE; + } + battle_config.base_exp_rate = rate; + battle_config.job_exp_rate = rate; + AString output = STRPRINTF("All Xp at %d percent"_fmt, rate); + clif_displaymessage(s, output); + return ATCE::OKAY; +} + +static ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd, ZString) { @@ -1621,7 +1675,6 @@ ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd, pl_sd->pvp_timer = Timer(gettick() + 200_ms, std::bind(pc_calc_pvprank_timer, ph::_1, ph::_2, pl_sd->bl_id)); pl_sd->pvp_rank = 0; - pl_sd->pvp_lastusers = 0; pl_sd->pvp_point = 5; } } @@ -1809,14 +1862,13 @@ static void atcommand_killmonster_sub(Session *s, dumb_ptr<map_session_data> sd, ZString message, const int drop) { - map_local *map_id; - { + P<map_local> map_id = + ({ MapName map_name; extract(message, &map_name); - map_id = map_mapname2mapid(map_name); - if (map_id == nullptr) - map_id = sd->bl_m; - } + + map_mapname2mapid(map_name).copy_or(sd->bl_m); + }); map_foreachinarea(std::bind(atkillmonster_sub, ph::_1, drop), map_id, @@ -2080,15 +2132,15 @@ ATCE atcommand_recall(Session *s, dumb_ptr<map_session_data> 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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp this player from its actual map."_s); @@ -2127,8 +2179,8 @@ ATCE atcommand_revive(Session *s, dumb_ptr<map_session_data> sd, { pl_sd->status.hp = pl_sd->status.max_hp; pc_setstand(pl_sd); - if (static_cast<interval_t>(battle_config.player_invincible_time) > interval_t::zero()) - pc_setinvincibletimer(sd, static_cast<interval_t>(battle_config.player_invincible_time)); + if (battle_config.player_invincible_time > interval_t::zero()) + pc_setinvincibletimer(sd, battle_config.player_invincible_time); clif_updatestatus(pl_sd, SP::HP); clif_updatestatus(pl_sd, SP::SP); clif_resurrection(pl_sd, 1); @@ -2257,7 +2309,7 @@ ATCE atcommand_character_option(Session *s, dumb_ptr<map_session_data> sd, { Opt1 opt1; Opt2 opt2; - Option opt3; + Opt0 opt3; CharName character; if (!asplit(message, &opt1, &opt2, &opt3, &character)) return ATCE::USAGE; @@ -2403,16 +2455,15 @@ ATCE atcommand_character_save(Session *s, dumb_ptr<map_session_data> 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); - if (m == nullptr) + P<map_local> m = TRY_UNWRAP(map_mapname2mapid(map_name), { clif_displaymessage(s, "Map not found."_s); return ATCE::EXIST; - } - else + }); + { - if (m != nullptr && m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to set this map as a save map."_s); @@ -2976,7 +3027,6 @@ ATCE atcommand_idsearch(Session *s, dumb_ptr<map_session_data>, { ItemName item_name; int match; - struct item_data *item; if (!extract(message, &item_name) || !item_name) return ATCE::USAGE; @@ -2986,8 +3036,8 @@ ATCE atcommand_idsearch(Session *s, dumb_ptr<map_session_data>, match = 0; for (ItemNameId i = wrap<ItemNameId>(0); i < wrap<ItemNameId>(-1); i = next(i)) { - if ((item = itemdb_exists(i)) != nullptr - && item->jname.contains_seq(item_name)) + P<struct item_data> item = TRY_UNWRAP(itemdb_exists(i), continue); + if (item->jname.contains_seq(item_name)) { match++; output = STRPRINTF("%s: %d"_fmt, item->jname, item->nameid); @@ -3350,8 +3400,8 @@ ATCE atcommand_recallall(Session *s, dumb_ptr<map_session_data> sd, { int count; - if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp somenone to your actual map."_s); @@ -3371,8 +3421,8 @@ ATCE atcommand_recallall(Session *s, dumb_ptr<map_session_data> 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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) count++; else pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); @@ -3396,57 +3446,62 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd, ZString message) { PartyName party_name; - PartyPair p; int count; if (!extract(message, &party_name) || !party_name) return ATCE::USAGE; - if (sd->bl_m && sd->bl_m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(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 ((p = party_searchname(party_name)) || - // name first to avoid error when name begin with a number - (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))))) + // name first to avoid error when name begin with a number + Option<PartyPair> p_ = party_searchname(party_name); + if (p_.is_none()) + p_ = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))); + OMATCH_BEGIN (p_) { - count = 0; - for (io::FD i : iter_fds()) + OMATCH_CASE_SOME (p) { - Session *s2 = get_session(i); - if (!s2) - 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 - && sd->status_key.account_id != pl_sd->status_key.account_id - && pl_sd->status.party_id == p.party_id) + count = 0; + for (io::FD i : iter_fds()) { - if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARP) - && !(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); + Session *s2 = get_session(i); + if (!s2) + 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 + && sd->status_key.account_id != pl_sd->status_key.account_id + && pl_sd->status.party_id == p.party_id) + { + if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) + count++; + else + pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); + } + } + AString output = STRPRINTF("All online characters of the %s party are near you."_fmt, p->name); + clif_displaymessage(s, output); + if (count) + { + output = STRPRINTF( + "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, + count); + clif_displaymessage(s, output); } } - AString output = STRPRINTF("All online characters of the %s party are near you."_fmt, p->name); - clif_displaymessage(s, output); - if (count) + OMATCH_CASE_NONE () { - output = STRPRINTF( - "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, - count); - clif_displaymessage(s, output); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); + return ATCE::EXIST; } } - else - { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); - return ATCE::EXIST; - } + OMATCH_END (); return ATCE::OKAY; } @@ -3468,9 +3523,7 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd, if (!map_name) map_name = sd->mapname_; - map_local *m_id = map_mapname2mapid(map_name); - if (m_id != nullptr) - return ATCE::EXIST; + P<map_local> m_id = TRY_UNWRAP(map_mapname2mapid(map_name), return ATCE::EXIST); clif_displaymessage(s, "------ Map Info ------"_s); AString output = STRPRINTF("Map Name: %s"_fmt, map_name); @@ -3592,29 +3645,34 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr<map_session_data> sd, if (!extract(message, &party_name)) return ATCE::USAGE; - PartyPair p; - if ((p = party_searchname(party_name)) || - // name first to avoid error when name begin with a number - (p = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))))) + // name first to avoid error when name begin with a number + Option<PartyPair> p_ = party_searchname(party_name); + if (p_.is_none()) + p_ = party_search(wrap<PartyId>(static_cast<uint32_t>(atoi(message.c_str())))); + OMATCH_BEGIN (p_) { - if (sd->partyspy == p.party_id) + OMATCH_CASE_SOME (p) { - sd->partyspy = PartyId(); - AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); - clif_displaymessage(s, output); + if (sd->partyspy == p.party_id) + { + sd->partyspy = PartyId(); + AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); + clif_displaymessage(s, output); + } + else + { + sd->partyspy = p.party_id; + AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); + clif_displaymessage(s, output); + } } - else + OMATCH_CASE_NONE () { - sd->partyspy = p.party_id; - AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); - clif_displaymessage(s, output); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); + return ATCE::EXIST; } } - else - { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); - return ATCE::EXIST; - } + OMATCH_END (); return ATCE::OKAY; } @@ -3684,19 +3742,15 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd, CharName character; XString item_name; int i, number = 0; - ItemNameId item_id; int count; - struct item_data *item_data; if (!asplit(message, &item_name, &number, &character) || number < 1) return ATCE::USAGE; - if ((item_data = itemdb_searchname(item_name)) != nullptr) - item_id = item_data->nameid; - else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != nullptr) - item_id = item_data->nameid; + P<struct item_data> item_data = TRY_UNWRAP(extract_item_opt(item_name), return ATCE::EXIST); + ItemNameId item_id = item_data->nameid; + assert (item_id); - if (item_id) { dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); if (pl_sd != nullptr) @@ -3744,11 +3798,6 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd, return ATCE::EXIST; } } - else - { - clif_displaymessage(s, "Invalid item ID or name."_s); - return ATCE::RANGE; - } return ATCE::OKAY; } @@ -3855,7 +3904,6 @@ static ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd, ZString message) { - struct item_data *item_data = nullptr; int count, counter; CharName character; @@ -3872,10 +3920,10 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd, count = 0; for (IOff0 i : IOff0::iter()) { - if (pl_sd->status.inventory[i].nameid - && (item_data = - itemdb_search(pl_sd->status.inventory[i].nameid)) != - nullptr) + if (!pl_sd->status.inventory[i].nameid) + continue; + P<struct item_data> item_data = TRY_UNWRAP(itemdb_exists(pl_sd->status.inventory[i].nameid), continue); + { counter = counter + pl_sd->status.inventory[i].amount; count++; @@ -3966,8 +4014,6 @@ static ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd, ZString message) { - Storage *stor; - struct item_data *item_data = nullptr; int count, counter; CharName character; @@ -3980,50 +4026,56 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> 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)) != nullptr) + Option<P<Storage>> stor_ = account2storage2(pl_sd->status_key.account_id); + OMATCH_BEGIN (stor_) { - counter = 0; - count = 0; - for (SOff0 i : SOff0::iter()) + OMATCH_CASE_SOME (stor) { - if (stor->storage_[i].nameid - && (item_data = - itemdb_search(stor->storage_[i].nameid)) != nullptr) + counter = 0; + count = 0; + for (SOff0 i : SOff0::iter()) { - counter = counter + stor->storage_[i].amount; - count++; - if (count == 1) + if (!stor->storage_[i].nameid) + continue; + P<struct item_data> item_data = TRY_UNWRAP(itemdb_exists(stor->storage_[i].nameid), continue); + { - AString output = STRPRINTF( - "------ Storage items list of '%s' ------"_fmt, - pl_sd->status_key.name); + counter = counter + stor->storage_[i].amount; + count++; + if (count == 1) + { + AString output = STRPRINTF( + "------ Storage items list of '%s' ------"_fmt, + pl_sd->status_key.name); + clif_displaymessage(s, output); + } + AString output; + if (true) + output = STRPRINTF("%d %s (%s, id: %d)"_fmt, + stor->storage_[i].amount, + item_data->name, item_data->jname, + stor->storage_[i].nameid); clif_displaymessage(s, output); } - AString output; - if (true) - output = STRPRINTF("%d %s (%s, id: %d)"_fmt, - stor->storage_[i].amount, - item_data->name, item_data->jname, - stor->storage_[i].nameid); + } + if (count == 0) + clif_displaymessage(s, + "No item found in the storage of this player."_s); + else + { + AString output = STRPRINTF( + "%d item(s) found in %d kind(s) of items."_fmt, + counter, count); clif_displaymessage(s, output); } } - if (count == 0) - clif_displaymessage(s, - "No item found in the storage of this player."_s); - else + OMATCH_CASE_NONE () { - AString output = STRPRINTF( - "%d item(s) found in %d kind(s) of items."_fmt, - counter, count); - clif_displaymessage(s, output); + clif_displaymessage(s, "This player has no storage."_s); + return ATCE::OKAY; } } - else - { - clif_displaymessage(s, "This player has no storage."_s); - return ATCE::OKAY; - } + OMATCH_END (); } else { @@ -4041,81 +4093,40 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd, } static -ATCE atcommand_killer(Session *s, dumb_ptr<map_session_data> sd, +ATCE atcommand_pvp(Session *s, dumb_ptr<map_session_data> sd, ZString) { - sd->special_state.killer = !sd->special_state.killer; - - if (sd->special_state.killer) - clif_displaymessage(s, "You be a killa..."_s); - else - clif_displaymessage(s, "You gonna be own3d..."_s); - - return ATCE::OKAY; -} - -static -ATCE atcommand_charkiller(Session *s, dumb_ptr<map_session_data>, - ZString message) -{ - CharName character; - - if (!asplit(message, &character)) - return ATCE::USAGE; - - dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); - if (pl_sd == nullptr) - return ATCE::EXIST; - - pl_sd->special_state.killer = !pl_sd->special_state.killer; + int chan = sd->state.pvpchannel; + if (sd->pvp_timer || (chan > 1)) + return ATCE::OKAY; - if (pl_sd->special_state.killer) - { - clif_displaymessage(s, "The player is now a killer"_s); - clif_displaymessage(pl_sd->sess, "You are now a killer"_s); - } - else - { - clif_displaymessage(s, "The player is no longer a killer"_s); - clif_displaymessage(pl_sd->sess, "You are no longer a killer"_s); + if (chan < 1) { + sd->state.pvpchannel = 1; + clif_displaymessage(s, "##3PvP : ##BOn"_s); + } else { + sd->state.pvpchannel = 0; + clif_displaymessage(s, "##3PvP : ##BOff"_s); } + pc_setpvptimer(sd, battle_config.player_pvp_time); return ATCE::OKAY; } static -ATCE atcommand_killable(Session *s, dumb_ptr<map_session_data> sd, - ZString) -{ - sd->special_state.killable = !sd->special_state.killable; - - if (sd->special_state.killable) - clif_displaymessage(s, "You gonna be own3d..."_s); - else - clif_displaymessage(s, "You be a killa..."_s); - - return ATCE::OKAY; -} - -static -ATCE atcommand_charkillable(Session *s, dumb_ptr<map_session_data>, +ATCE atcommand_charpvp(Session *, dumb_ptr<map_session_data>, ZString message) { CharName character; + int channel; - if (!asplit(message, &character)) + if (!extract(message, record<' '>(&character, &channel))) return ATCE::USAGE; dumb_ptr<map_session_data> pl_sd = map_nick2sd(character); if (pl_sd == nullptr) return ATCE::EXIST; - pl_sd->special_state.killable = !pl_sd->special_state.killable; - - if (pl_sd->special_state.killable) - clif_displaymessage(s, "The player is now killable"_s); - else - clif_displaymessage(s, "The player is no longer killable"_s); + pl_sd->state.pvpchannel = channel; return ATCE::OKAY; } @@ -4155,13 +4166,21 @@ ATCE atcommand_addwarp(Session *s, dumb_ptr<map_session_data> sd, if (!extract(message, record<' '>(&mapname, &x, &y))) return ATCE::USAGE; - AString w1 = STRPRINTF("%s,%d,%d"_fmt, sd->mapname_, sd->bl_x, sd->bl_y); AString w3 = STRPRINTF("%s%d%d%d%d"_fmt, mapname, sd->bl_x, sd->bl_y, x, y); - AString w4 = STRPRINTF("1,1,%s.gat,%d,%d"_fmt, mapname, x, y); - NpcName w3name = stringish<NpcName>(w3); - int ret = npc_parse_warp(w1, "warp"_s, w3name, w4); - if (ret) + + ast::npc::Warp warp; + warp.m.data = sd->mapname_; + warp.x.data = sd->bl_x; + warp.y.data = sd->bl_y; + warp.name.data = w3name; + warp.xs.data = 1+2; + warp.ys.data = 1+2; + warp.to_m.data = mapname; + warp.to_x.data = x; + warp.to_y.data = y; + + if (!npc_load_warp(warp)) // warp failed return ATCE::RANGE; @@ -4433,14 +4452,15 @@ ATCE atcommand_adjcmdlvl(Session *s, dumb_ptr<map_session_data>, return ATCE::USAGE; } - AtCommandInfo *it = atcommand_info.search(cmd); + Option<P<AtCommandInfo>> it_ = atcommand_info.search(cmd); { - if (it) + OMATCH_BEGIN_SOME (it, it_) { it->level = newlev; clif_displaymessage(s, "@command level changed."_s); return ATCE::OKAY; } + OMATCH_END (); } clif_displaymessage(s, "@command not found."_s); @@ -4665,15 +4685,15 @@ ATCE atcommand_jump_iterate(Session *s, dumb_ptr<map_session_data> sd, pl_sd = get_start(); } - if (pl_sd->bl_m && pl_sd->bl_m->flag.get(MapFlag::NOWARPTO) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (pl_sd->bl_m->flag.get(MapFlag::NOWARPTO) + && !(pc_isGM(sd).satisfies(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) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast<uint32_t>(battle_config.any_warp_GM_min_level))))) + if (sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(battle_config.any_warp_GM_min_level))) { clif_displaymessage(s, "You are not authorised to warp you from your actual map."_s); @@ -4744,11 +4764,11 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr<map_session_data>, clif_displaymessage(s, buf); } - buf = STRPRINTF("Learned skills out of %d for %s:"_fmt, - skill_pool_skills_size, character); + buf = STRPRINTF("Learned skills out of %zu for %s:"_fmt, + skill_pool_skills.size(), character); clif_displaymessage(s, buf); - for (i = 0; i < skill_pool_skills_size; ++i) + for (i = 0; i < skill_pool_skills.size(); ++i) { const RString& name = skill_name(skill_pool_skills[i]); int lvl = pl_sd->status.skill[skill_pool_skills[i]].lv; @@ -4919,14 +4939,10 @@ static ATCE atcommand_source(Session *s, dumb_ptr<map_session_data>, ZString) { - clif_displaymessage(s, - "This server code consists of Free Software under GPL3&AGPL3"_s); - clif_displaymessage(s, - "This is commit " VERSION_HASH ", also known as " VERSION_FULL ""_s); - clif_displaymessage(s, - "The version is " VERSION_STRING ""_s); - clif_displaymessage(s, - "For source, see " VENDOR_SOURCE ""_s); + clif_displaymessage(s, VERSION_INFO_HEADER); + clif_displaymessage(s, VERSION_INFO_COMMIT); + clif_displaymessage(s, VERSION_INFO_NUMBER); + clif_displaymessage(s, VERSION_INFO_URL); return ATCE::OKAY; } @@ -4954,6 +4970,9 @@ Map<XString, AtCommandInfo> atcommand_info = {"goto"_s, {"<charname>"_s, 40, atcommand_goto, "Warp yourself to another character"_s}}, + {"npc"_s, {"<npc>"_s, + 40, atcommand_npc, + "Warp yourself to a npc"_s}}, {"jump"_s, {"[x] [y]"_s, 40, atcommand_jump, "Warp yourself within a map"_s}}, @@ -5023,12 +5042,12 @@ Map<XString, AtCommandInfo> atcommand_info = {"jlvl"_s, {"<delta>"_s, 60, atcommand_joblevelup, "Adjust your job level"_s}}, - {"gm"_s, {"<password>"_s, - 100, atcommand_gm, - "Receive GM powers"_s}}, {"pvpoff"_s, {""_s, 60, atcommand_pvpoff, "Enable PvP on your map"_s}}, + {"exprate"_s, {"<percent>"_s, + 60, atcommand_exprate, + "Set base job/exp rate"_s}}, {"pvpon"_s, {""_s, 60, atcommand_pvpon, "Disable PvP on your map"_s}}, @@ -5242,21 +5261,15 @@ Map<XString, AtCommandInfo> atcommand_info = {"addwarp"_s, {"<mapname> <x> <y>"_s, 80, atcommand_addwarp, "Create a new permanent warp"_s}}, - {"killer"_s, {""_s, - 60, atcommand_killer, - "Toggle whether you are a killer"_s}}, - {"charkiller"_s, {"<charname>"_s, - 60, atcommand_charkiller, - "Toggle whether a player is a killer"_s}}, + {"pvp"_s, {""_s, + 0, atcommand_pvp, + "Toggle your pvp flag"_s}}, {"npcmove"_s, {"<x> <y> <npc-name>"_s, 80, atcommand_npcmove, "Force an NPC to move on the map"_s}}, - {"killable"_s, {""_s, - 60, atcommand_killable, - "Toggle whether you are killable"_s}}, - {"charkillable"_s, {"<charname>"_s, - 60, atcommand_charkillable, - "Toggle whether a player is killable"_s}}, + {"charpvp"_s, {"<charname> <channel>"_s, + 40, atcommand_charpvp, + "Set the pvp channel of another player"_s}}, {"chareffect"_s, {"<type> <target>"_s, 40, atcommand_chareffect, "Apply effect type with arg 0 to a player"_s}}, @@ -5357,4 +5370,5 @@ Map<XString, AtCommandInfo> atcommand_info = 0, atcommand_source, "Legal information about source code (must be a level 0 command!)"_s}}, }; +} // namespace map } // namespace tmwa |