summaryrefslogtreecommitdiff
path: root/src/map/atcommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/atcommand.cpp')
-rw-r--r--src/map/atcommand.cpp762
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>(&param1, &param2, &param3)))
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