summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.cpp1896
-rw-r--r--src/map/atcommand.hpp21
-rw-r--r--src/map/battle.cpp271
-rw-r--r--src/map/battle.hpp33
-rw-r--r--src/map/battle.t.hpp31
-rw-r--r--src/map/chrif.cpp773
-rw-r--r--src/map/chrif.hpp29
-rw-r--r--src/map/clif.cpp4503
-rw-r--r--src/map/clif.hpp97
-rw-r--r--src/map/clif.t.hpp684
-rw-r--r--src/map/fwd.hpp (renamed from src/map/magic-interpreter-aux.cpp)44
-rw-r--r--src/map/grfio.cpp18
-rw-r--r--src/map/grfio.hpp19
-rw-r--r--src/map/intif.cpp650
-rw-r--r--src/map/intif.hpp39
-rw-r--r--src/map/itemdb.cpp51
-rw-r--r--src/map/itemdb.hpp41
-rw-r--r--src/map/magic-expr-eval.cpp8
-rw-r--r--src/map/magic-expr-eval.hpp63
-rw-r--r--src/map/magic-expr.cpp1332
-rw-r--r--src/map/magic-expr.hpp60
-rw-r--r--src/map/magic-interpreter-aux.hpp33
-rw-r--r--src/map/magic-interpreter-base.cpp229
-rw-r--r--src/map/magic-interpreter-base.hpp78
-rw-r--r--src/map/magic-interpreter.cpp10
-rw-r--r--src/map/magic-interpreter.hpp708
-rw-r--r--src/map/magic-interpreter.py14
-rw-r--r--src/map/magic-interpreter.t.hpp118
-rw-r--r--src/map/magic-stmt.cpp712
-rw-r--r--src/map/magic-stmt.hpp82
-rw-r--r--src/map/magic-v2.cpp625
-rw-r--r--src/map/magic-v2.hpp16
-rw-r--r--src/map/magic.cpp34
-rw-r--r--src/map/magic.hpp79
-rw-r--r--src/map/main.cpp8
-rw-r--r--src/map/map.cpp333
-rw-r--r--src/map/map.hpp192
-rw-r--r--src/map/map.t.hpp415
-rw-r--r--src/map/mapflag.cpp71
-rw-r--r--src/map/mapflag.hpp18
-rw-r--r--src/map/mapflag.py2
-rw-r--r--src/map/mob.cpp802
-rw-r--r--src/map/mob.hpp79
-rw-r--r--src/map/mob.t.hpp13
-rw-r--r--src/map/npc.cpp338
-rw-r--r--src/map/npc.hpp58
-rw-r--r--src/map/party.cpp285
-rw-r--r--src/map/party.hpp57
-rw-r--r--src/map/path.cpp29
-rw-r--r--src/map/path.hpp11
-rw-r--r--src/map/pc.cpp835
-rw-r--r--src/map/pc.hpp67
-rw-r--r--src/map/pc.t.hpp26
-rw-r--r--src/map/script.cpp915
-rw-r--r--src/map/script.hpp38
-rw-r--r--src/map/script.py4
-rw-r--r--src/map/skill-pools.cpp14
-rw-r--r--src/map/skill-pools.hpp10
-rw-r--r--src/map/skill.cpp220
-rw-r--r--src/map/skill.hpp34
-rw-r--r--src/map/skill.t.hpp15
-rw-r--r--src/map/storage.cpp120
-rw-r--r--src/map/storage.hpp29
-rw-r--r--src/map/tmw.cpp27
-rw-r--r--src/map/tmw.hpp15
-rw-r--r--src/map/trade.cpp120
-rw-r--r--src/map/trade.hpp19
67 files changed, 9795 insertions, 8825 deletions
diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp
index 240df8b..342f6ef 100644
--- a/src/map/atcommand.cpp
+++ b/src/map/atcommand.cpp
@@ -20,10 +20,10 @@
// 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 <cmath>
-#include <cstring>
#include <ctime>
+#include <algorithm>
+
#include "../conf/version.hpp"
#include "../compat/nullpo.hpp"
@@ -35,19 +35,25 @@
#include "../strings/xstring.hpp"
#include "../strings/vstring.hpp"
+#include "../generic/db.hpp"
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/read.hpp"
#include "../io/write.hpp"
+#include "../net/socket.hpp"
+#include "../net/timer.hpp"
+
#include "../mmo/config_parse.hpp"
#include "../mmo/core.hpp"
#include "../mmo/extract.hpp"
+#include "../mmo/extract_enums.hpp"
#include "../mmo/human_time_diff.hpp"
+#include "../mmo/ids.hpp"
#include "../mmo/mmo.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../mmo/utils.hpp"
#include "../mmo/version.hpp"
#include "battle.hpp"
@@ -60,7 +66,6 @@
#include "npc.hpp"
#include "party.hpp"
#include "pc.hpp"
-#include "script.hpp"
#include "skill.hpp"
#include "storage.hpp"
#include "tmw.hpp"
@@ -69,6 +74,8 @@
#include "../poison.hpp"
+namespace tmwa
+{
enum class ATCE
{
OKAY,
@@ -81,12 +88,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)
{}
};
@@ -121,23 +128,23 @@ void atcommand_config_write(ZString cfgName)
if (!out.is_open())
{
- FPRINTF(stderr, "Failed to write atcommand config: %s\n", cfgName);
+ FPRINTF(stderr, "Failed to write atcommand config: %s\n"_fmt, cfgName);
return;
}
- FPRINTF(out, "// Generated by %s\n", CURRENT_VERSION_STRING);
+ FPRINTF(out, "// Generated by %s\n"_fmt, CURRENT_VERSION_STRING);
for (const auto& pair : atcommand_info)
{
// This XString is really a ZString, but not declared as one
// in order to allow non-heterogenous lookup by XString.
- const char *cmd = &*pair.first.begin();
+ auto cmd = ZString(strings::really_construct_from_a_pointer, &*pair.first.begin(), nullptr);
const AtCommandInfo& info = pair.second;
FPRINTF(out,
"\n"
"// %s\n"
"// Usage: @%s %s\n"
- "%s: %d\n",
+ "%s: %d\n"_fmt,
info.help,
cmd, info.args,
cmd, info.level);
@@ -198,8 +205,8 @@ void log_atcommand(dumb_ptr<map_session_data> sd, ZString cmd)
stamp_time(tmpstr);
MapName map = (sd->bl_m
? sd->bl_m->name_
- : stringish<MapName>("undefined.gat"));
- FPRINTF(*fp, "[%s] %s(%d,%d) %s(%d) : %s\n",
+ : stringish<MapName>("undefined.gat"_s));
+ FPRINTF(*fp, "[%s] %s(%d,%d) %s(%d) : %s\n"_fmt,
tmpstr,
map, sd->bl_x, sd->bl_y,
sd->status_key.name, sd->status_key.account_id,
@@ -211,7 +218,7 @@ AString gm_log;
io::AppendFile *get_gm_log()
{
if (!gm_log)
- return NULL;
+ return nullptr;
struct tm ctime = TimeT::now();
@@ -225,7 +232,7 @@ io::AppendFile *get_gm_log()
return gm_logfile.get();
last_logfile_nr = logfile_nr;
- AString fullname = STRPRINTF("%s.%04d-%02d",
+ AString fullname = STRPRINTF("%s.%04d-%02d"_fmt,
gm_log, year, month);
if (gm_logfile)
@@ -242,7 +249,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);
@@ -259,22 +266,22 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd,
gmlvl = pc_isGM(sd);
if (battle_config.atcommand_gm_only != 0 && !gmlvl)
{
- AString output = STRPRINTF("GM command is level 0, but this server disables level 0 commands: %s",
+ AString output = STRPRINTF("GM command is level 0, but this server disables level 0 commands: %s"_fmt,
AString(command));
clif_displaymessage(s, output);
return true;
}
if (!info)
{
- AString output = STRPRINTF("GM command not found: %s",
+ AString output = STRPRINTF("GM command not found: %s"_fmt,
AString(command));
clif_displaymessage(s, output);
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",
+ AString output = STRPRINTF("GM command is level %d, but you are level %d: %s"_fmt,
info->level, gmlvl,
AString(command));
clif_displaymessage(s, output);
@@ -292,17 +299,17 @@ bool is_atcommand(Session *s, dumb_ptr<map_session_data> sd,
log_atcommand(sd, message);
break;
case ATCE::USAGE:
- clif_displaymessage(s, "Command failed: usage error");
- clif_displaymessage(s, STRPRINTF("Usage: %s %s", AString(command), info->args));
+ clif_displaymessage(s, "Command failed: usage error"_s);
+ clif_displaymessage(s, STRPRINTF("Usage: %s %s"_fmt, AString(command), info->args));
break;
case ATCE::EXIST:
- clif_displaymessage(s, "Command failed: something does not exist (or already exists)");
+ clif_displaymessage(s, "Command failed: something does not exist (or already exists)"_s);
break;
case ATCE::RANGE:
- clif_displaymessage(s, "Command failed: value out of range");
+ clif_displaymessage(s, "Command failed: value out of range"_s);
break;
case ATCE::PERM:
- clif_displaymessage(s, "Command failed: permission denied");
+ clif_displaymessage(s, "Command failed: permission denied"_s);
break;
default:
abort();
@@ -331,7 +338,7 @@ void atkillmonster_sub(dumb_ptr<block_list> bl, int flag)
dumb_ptr<mob_data> md = bl->is_mob();
if (flag)
- mob_damage(NULL, md, md->hp, 2);
+ mob_damage(nullptr, md, md->hp, 2);
else
mob_delete(md);
}
@@ -347,7 +354,7 @@ bool atcommand_config_read(ZString cfgName)
io::ReadFile in(cfgName);
if (!in.is_open())
{
- PRINTF("At commands configuration file not found: %s\n", cfgName);
+ PRINTF("At commands configuration file not found: %s\n"_fmt, cfgName);
return false;
}
@@ -361,24 +368,20 @@ bool atcommand_config_read(ZString cfgName)
ZString w2;
if (!config_split(line, &w1, &w2))
{
- PRINTF("Bad config line: %s\n", line);
+ PRINTF("Bad config line: %s\n"_fmt, line);
rv = false;
continue;
}
AtCommandInfo *p = get_atcommandinfo_byname(w1);
- if (p != NULL)
+ if (p != nullptr)
{
- 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")
+ else if (w1 == "import"_s)
rv &= atcommand_config_read(w2);
else
{
- PRINTF("%s: bad line: %s\n", cfgName, line);
+ PRINTF("%s: bad line: %s\n"_fmt, cfgName, line);
rv = false;
}
}
@@ -389,14 +392,16 @@ bool atcommand_config_read(ZString cfgName)
/// @ command processing functions
static
-void atc_do_help(Session *s, const char *cmd, const AtCommandInfo& info)
+void atc_do_help(Session *s, ZString cmd, const AtCommandInfo& info)
{
- auto msg = STRPRINTF("\u2007\u2007%d: @%s %s", info.level, cmd, info.args);
+ // 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));
}
@@ -407,9 +412,9 @@ ATCE atcommand_help(Session *s, dumb_ptr<map_session_data>,
{
if (!message)
{
- clif_displaymessage(s, "There is too much help to display it all at once");
- clif_displaymessage(s, "Try @help <@command> or @help <category> or @help <level[-level]>");
- clif_displaymessage(s, "Right now the only category is 'all'");
+ clif_displaymessage(s, "There is too much help to display it all at once"_s);
+ clif_displaymessage(s, "Try @help <@command> or @help <category> or @help <level[-level]>"_s);
+ clif_displaymessage(s, "Right now the only category is 'all'"_s);
return ATCE::OKAY;
}
@@ -419,37 +424,51 @@ ATCE atcommand_help(Session *s, dumb_ptr<map_session_data>,
const AtCommandInfo *info = atcommand_info.search(cmd);
if (!info)
return ATCE::EXIST;
- clif_displaymessage(s, STRPRINTF("Usage: @%s %s", cmd, info->args));
+ clif_displaymessage(s, STRPRINTF("Usage: @%s %s"_fmt, cmd, info->args));
clif_displaymessage(s, info->help);
return ATCE::OKAY;
}
- if (message == "all")
+ if (message == "all"_s)
{
- clif_displaymessage(s, "Synopses of GM commands in category 'all':");
+ clif_displaymessage(s, "Synopses of GM commands in category 'all':"_s);
for (const auto& pair : atcommand_info)
{
- const char *cmd = &*pair.first.begin();
+ auto cmd = ZString(strings::really_construct_from_a_pointer, &*pair.first.begin(), nullptr);
const AtCommandInfo& info = pair.second;
atc_do_help(s, cmd, info);
}
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):", 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)
{
- const char *cmd = &*pair.first.begin();
+ 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;
@@ -467,25 +486,25 @@ ATCE atcommand_setup(Session *s, dumb_ptr<map_session_data> sd,
level--;
AString buf;
- buf = STRPRINTF("-255 %s", character);
+ buf = STRPRINTF("-255 %s"_fmt, character);
atcommand_character_baselevel(s, sd, buf);
- buf = STRPRINTF("%d %s", level, character);
+ buf = STRPRINTF("%d %s"_fmt, level, character);
atcommand_character_baselevel(s, sd, buf);
// Emote skill
- buf = STRPRINTF("1 1 %s", character);
+ buf = STRPRINTF("1 1 %s"_fmt, character);
atcommand_skill_learn(s, sd, buf);
// Trade skill
- buf = STRPRINTF("2 1 %s", character);
+ buf = STRPRINTF("2 1 %s"_fmt, character);
atcommand_skill_learn(s, sd, buf);
// Party skill
- STRPRINTF("2 2 %s", character);
+ STRPRINTF("2 2 %s"_fmt, character);
atcommand_skill_learn(s, sd, buf);
- STRPRINTF("018-1.gat 24 98 %s", character);
+ STRPRINTF("018-1.gat 24 98 %s"_fmt, character);
atcommand_charwarp(s, sd, buf);
return ATCE::OKAY;
@@ -510,52 +529,52 @@ 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.");
+ "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.");
+ "You are not authorised to warp this player from its actual map."_s);
return ATCE::PERM;
}
if (pc_setpos(pl_sd, map_name, x, y, BeingRemoveWhy::WARPED) == 0)
{
- clif_displaymessage(pl_sd->sess, "Warped.");
- clif_displaymessage(s, "Player warped (message sends to player too).");
+ clif_displaymessage(pl_sd->sess, "Warped."_s);
+ clif_displaymessage(s, "Player warped (message sends to player too)."_s);
}
else
{
- clif_displaymessage(s, "Map not found.");
+ clif_displaymessage(s, "Map not found."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "Coordinates out of range.");
+ clif_displaymessage(s, "Coordinates out of range."_s);
return ATCE::RANGE;
}
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -573,7 +592,7 @@ ATCE atcommand_warp(Session *s, dumb_ptr<map_session_data> sd,
|| !extract(message, record<' ', 1>(&map_name, &x, &y)))
{
clif_displaymessage(s,
- "Please, enter a map (usage: @warp <mapname> <x> <y>).");
+ "Please, enter a map (usage: @warp <mapname> <x> <y>)."_s);
return ATCE::USAGE;
}
@@ -586,30 +605,30 @@ 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.");
+ "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.");
+ "You are not authorised to warp you from your actual map."_s);
return ATCE::PERM;
}
if (pc_setpos(sd, map_name, x, y, BeingRemoveWhy::WARPED) == 0)
- clif_displaymessage(s, "Warped.");
+ clif_displaymessage(s, "Warped."_s);
else
{
- clif_displaymessage(s, "Map not found.");
+ clif_displaymessage(s, "Map not found."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "Coordinates out of range.");
+ clif_displaymessage(s, "Coordinates out of range."_s);
return ATCE::RANGE;
}
@@ -624,20 +643,20 @@ ATCE atcommand_where(Session *s, dumb_ptr<map_session_data> sd,
extract(message, &character);
dumb_ptr<map_session_data> pl_sd = character.to__actual() ? map_nick2sd(character) : sd;
- if (pl_sd != NULL &&
+ if (pl_sd != nullptr &&
!((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)",
+ AString output = STRPRINTF("%s: %s (%d,%d)"_fmt,
pl_sd->status_key.name,
pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -653,34 +672,34 @@ ATCE atcommand_goto(Session *s, dumb_ptr<map_session_data> sd,
if (!asplit(message, &character))
{
clif_displaymessage(s,
- "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>).");
+ "Please, enter a player name (usage: @jumpto/@warpto/@goto <char name>)."_s);
return ATCE::USAGE;
}
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
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.");
+ "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.");
+ "You are not authorised to warp you from your actual map."_s);
return ATCE::PERM;
}
pc_setpos(sd, pl_sd->mapname_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED);
- AString output = STRPRINTF("Jump to %s", character);
+ AString output = STRPRINTF("Jump to %s"_fmt, character);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -702,26 +721,26 @@ 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.");
+ "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.");
+ "You are not authorised to warp you from your actual map."_s);
return ATCE::PERM;
}
pc_setpos(sd, sd->mapname_, x, y, BeingRemoveWhy::WARPED);
- AString output = STRPRINTF("Jump to %d %d", x, y);
+ AString output = STRPRINTF("Jump to %d %d"_fmt, x, y);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Coordinates out of range.");
+ clif_displaymessage(s, "Coordinates out of range."_s);
return ATCE::RANGE;
}
@@ -733,12 +752,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 +765,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,14 +777,14 @@ 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",
- 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(
- "Name: %s | Location: %s %d %d",
+ "Name: %s | Location: %s %d %d"_fmt,
pl_sd->status_key.name, pl_sd->mapname_,
pl_sd->bl_x, pl_sd->bl_y);
clif_displaymessage(s, output);
@@ -777,12 +795,12 @@ ATCE atcommand_who(Session *s, dumb_ptr<map_session_data> sd,
}
if (count == 0)
- clif_displaymessage(s, "No player found.");
+ clif_displaymessage(s, "No player found."_s);
else if (count == 1)
- clif_displaymessage(s, "1 player found.");
+ clif_displaymessage(s, "1 player found."_s);
else
{
- AString output = STRPRINTF("%d players found.", count);
+ AString output = STRPRINTF("%d players found."_fmt, count);
clif_displaymessage(s, output);
}
@@ -794,14 +812,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;
+ PartyPair 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 +827,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();
@@ -822,12 +839,12 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd,
{
// search with no case sensitive
p = party_search(pl_sd->status.party_id);
- PartyName temp0 = p ? p->name : stringish<PartyName>("None");
+ 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'",
- pl_sd->status_key.name, pl_GM_level, temp0);
+ "Name: %s (GM:%d) | Party: '%s'"_fmt,
+ pl_sd->status_key.name, pl_gm_level, temp0);
clif_displaymessage(s, output);
count++;
}
@@ -836,12 +853,12 @@ ATCE atcommand_whogroup(Session *s, dumb_ptr<map_session_data> sd,
}
if (count == 0)
- clif_displaymessage(s, "No player found.");
+ clif_displaymessage(s, "No player found."_s);
else if (count == 1)
- clif_displaymessage(s, "1 player found.");
+ clif_displaymessage(s, "1 player found."_s);
else
{
- AString output = STRPRINTF("%d players found.", count);
+ AString output = STRPRINTF("%d players found."_fmt, count);
clif_displaymessage(s, output);
}
@@ -853,7 +870,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 +881,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,24 +890,24 @@ 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",
- pl_sd->status_key.name, pl_GM_level,
+ "Name: %s (GM:%d) | 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(
- "Name: %s | Location: %s %d %d",
+ "Name: %s | Location: %s %d %d"_fmt,
pl_sd->status_key.name, pl_sd->mapname_,
pl_sd->bl_x, pl_sd->bl_y);
clif_displaymessage(s, output);
@@ -901,7 +917,7 @@ ATCE atcommand_whomap(Session *s, dumb_ptr<map_session_data> sd,
}
}
- AString output = STRPRINTF("%d players found in map '%s'.",
+ AString output = STRPRINTF("%d players found in map '%s'."_fmt,
count, map_id->name_);
clif_displaymessage(s, output);
@@ -913,8 +929,7 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
int count;
- int pl_GM_level, GM_level;
- struct party *p;
+ PartyPair p;
map_local *map_id;
{
@@ -926,7 +941,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,23 +950,23 @@ 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)
{
p = party_search(pl_sd->status.party_id);
- PartyName temp0 = p ? p->name : stringish<PartyName>("None");
+ PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s);
AString output;
- if (pl_GM_level > 0)
- output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'",
- pl_sd->status_key.name, pl_GM_level, temp0);
+ if (pl_gm_level)
+ output = STRPRINTF("Name: %s (GM:%d) | Party: '%s'"_fmt,
+ pl_sd->status_key.name, pl_gm_level, temp0);
else
- output = STRPRINTF("Name: %s | Party: '%s'",
+ output = STRPRINTF("Name: %s | Party: '%s'"_fmt,
pl_sd->status_key.name, temp0);
clif_displaymessage(s, output);
count++;
@@ -962,12 +977,12 @@ ATCE atcommand_whomapgroup(Session *s, dumb_ptr<map_session_data> sd,
AString output;
if (count == 0)
- output = STRPRINTF("No player found in map '%s'.", map_id->name_);
+ output = STRPRINTF("No player found in map '%s'."_fmt, map_id->name_);
else if (count == 1)
- output = STRPRINTF("1 player found in map '%s'.", map_id->name_);
+ output = STRPRINTF("1 player found in map '%s'."_fmt, map_id->name_);
else
{
- output = STRPRINTF("%d players found in map '%s'.", count, map_id->name_);
+ output = STRPRINTF("%d players found in map '%s'."_fmt, count, map_id->name_);
}
clif_displaymessage(s, output);
@@ -979,14 +994,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;
+ PartyPair 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 +1009,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();
@@ -1010,20 +1024,20 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd,
// search with no case sensitive
AString output;
output = STRPRINTF(
- "Name: %s (GM:%d) | Location: %s %d %d",
- pl_sd->status_key.name, pl_GM_level,
+ "Name: %s (GM:%d) | Location: %s %d %d"_fmt,
+ 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(
- " BLvl: %d | Job: %s (Lvl: %d)",
+ " BLvl: %d | Job: %s (Lvl: %d)"_fmt,
pl_sd->status.base_level,
- "Novice/Human",
+ "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");
+ PartyName temp0 = p ? p->name : stringish<PartyName>("None"_s);
output = STRPRINTF(
- " Party: '%s'",
+ " Party: '%s'"_fmt,
temp0);
clif_displaymessage(s, output);
count++;
@@ -1034,12 +1048,12 @@ ATCE atcommand_whogm(Session *s, dumb_ptr<map_session_data> sd,
}
if (count == 0)
- clif_displaymessage(s, "No GM found.");
+ clif_displaymessage(s, "No GM found."_s);
else if (count == 1)
- clif_displaymessage(s, "1 GM found.");
+ clif_displaymessage(s, "1 GM found."_s);
else
{
- AString output = STRPRINTF("%d GMs found.", count);
+ AString output = STRPRINTF("%d GMs found."_fmt, count);
clif_displaymessage(s, output);
}
@@ -1053,7 +1067,7 @@ ATCE atcommand_save(Session *s, dumb_ptr<map_session_data> sd,
pc_setsavepoint(sd, sd->mapname_, sd->bl_x, sd->bl_y);
pc_makesavestatus(sd);
chrif_save(sd);
- clif_displaymessage(s, "Character data respawn point saved.");
+ clif_displaymessage(s, "Character data respawn point saved."_s);
return ATCE::OKAY;
}
@@ -1064,17 +1078,17 @@ 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.");
+ "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.");
+ "You are not authorised to warp you from your actual map."_s);
return ATCE::PERM;
}
@@ -1089,7 +1103,7 @@ ATCE atcommand_load(Session *s, dumb_ptr<map_session_data> sd,
pc_setpos(sd, sd->status.save_point.map_, sd->status.save_point.x,
sd->status.save_point.y, BeingRemoveWhy::GONE);
}
- clif_displaymessage(s, "Warping to respawn point.");
+ clif_displaymessage(s, "Warping to respawn point."_s);
return ATCE::OKAY;
}
@@ -1101,7 +1115,7 @@ ATCE atcommand_speed(Session *s, dumb_ptr<map_session_data> sd,
if (!message)
{
AString output = STRPRINTF(
- "Please, enter a speed value (usage: @speed <%d-%d>).",
+ "Please, enter a speed value (usage: @speed <%d-%d>)."_fmt,
static_cast<uint32_t>(MIN_WALK_SPEED.count()),
static_cast<uint32_t>(MAX_WALK_SPEED.count()));
clif_displaymessage(s, output);
@@ -1115,12 +1129,12 @@ ATCE atcommand_speed(Session *s, dumb_ptr<map_session_data> sd,
//sd->walktimer = x;
//この文を追加 by れ
clif_updatestatus(sd, SP::SPEED);
- clif_displaymessage(s, "Speed changed.");
+ clif_displaymessage(s, "Speed changed."_s);
}
else
{
AString output = STRPRINTF(
- "Please, enter a valid speed value (usage: @speed <%d-%d>).",
+ "Please, enter a valid speed value (usage: @speed <%d-%d>)."_fmt,
static_cast<uint32_t>(MIN_WALK_SPEED.count()),
static_cast<uint32_t>(MAX_WALK_SPEED.count()));
clif_displaymessage(s, output);
@@ -1134,18 +1148,18 @@ static
ATCE atcommand_storage(Session *s, dumb_ptr<map_session_data> sd,
ZString)
{
- struct storage *stor;
+ Storage *stor;
if (sd->state.storage_open)
{
- clif_displaymessage(s, "msg_table[250]");
+ clif_displaymessage(s, "msg_table[250]"_s);
return ATCE::EXIST;
}
- if ((stor = account2storage2(sd->status_key.account_id)) != NULL
+ if ((stor = account2storage2(sd->status_key.account_id)) != nullptr
&& stor->storage_status == 1)
{
- clif_displaymessage(s, "msg_table[250]");
+ clif_displaymessage(s, "msg_table[250]"_s);
return ATCE::EXIST;
}
@@ -1171,7 +1185,7 @@ ATCE atcommand_option(Session *s, dumb_ptr<map_session_data> sd,
clif_changeoption(sd);
pc_calcstatus(sd, 0);
- clif_displaymessage(s, "Options changed.");
+ clif_displaymessage(s, "Options changed."_s);
return ATCE::OKAY;
}
@@ -1183,12 +1197,12 @@ ATCE atcommand_hide(Session *s, dumb_ptr<map_session_data> sd,
if (bool(sd->status.option & Option::HIDE))
{
sd->status.option &= ~Option::HIDE;
- clif_displaymessage(s, "Invisible: Off.");
+ clif_displaymessage(s, "Invisible: Off."_s);
}
else
{
sd->status.option |= Option::HIDE;
- clif_displaymessage(s, "Invisible: On.");
+ clif_displaymessage(s, "Invisible: On."_s);
}
clif_changeoption(sd);
@@ -1199,8 +1213,8 @@ static
ATCE atcommand_die(Session *s, dumb_ptr<map_session_data> sd,
ZString)
{
- pc_damage(NULL, sd, sd->status.hp + 1);
- clif_displaymessage(s, "A pity! You've died.");
+ pc_damage(nullptr, sd, sd->status.hp + 1);
+ clif_displaymessage(s, "A pity! You've died."_s);
return ATCE::OKAY;
}
@@ -1215,23 +1229,23 @@ ATCE atcommand_kill(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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);
- clif_displaymessage(s, "Character killed.");
+ pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1);
+ clif_displaymessage(s, "Character killed."_s);
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -1250,7 +1264,7 @@ ATCE atcommand_alive(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, SP::HP);
clif_updatestatus(sd, SP::SP);
clif_resurrection(sd, 1);
- clif_displaymessage(s, "You've been revived! It's a miracle!");
+ clif_displaymessage(s, "You've been revived! It's a miracle!"_s);
return ATCE::OKAY;
}
@@ -1304,13 +1318,13 @@ ATCE atcommand_heal(Session *s, dumb_ptr<map_session_data> sd,
{
pc_heal(sd, hp, sp);
if (hp >= 0 && sp >= 0)
- clif_displaymessage(s, "HP, SP recovered.");
+ clif_displaymessage(s, "HP, SP recovered."_s);
else
- clif_displaymessage(s, "HP or/and SP modified.");
+ clif_displaymessage(s, "HP or/and SP modified."_s);
}
else
{
- clif_displaymessage(s, "HP and SP are already with the good value.");
+ clif_displaymessage(s, "HP and SP are already with the good value."_s);
return ATCE::RANGE;
}
@@ -1322,29 +1336,29 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
XString item_name;
- int number = 0, item_id;
- struct item_data *item_data = NULL;
+ int number = 0;
+ ItemNameId item_id;
+ struct item_data *item_data = nullptr;
int get_count, i;
if (!extract(message, record<' ', 1>(&item_name, &number)))
{
clif_displaymessage(s,
- "Please, enter an item name/id (usage: @item <item name or ID> [quantity]).");
+ "Please, enter an item name/id (usage: @item <item name or ID> [quantity])."_s);
return ATCE::USAGE;
}
if (number <= 0)
number = 1;
- item_id = 0;
- if ((item_data = itemdb_searchname(item_name)) != NULL)
+ 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)) != NULL)
+ else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != nullptr)
item_id = item_data->nameid;
else
- item_id = 0;
+ return ATCE::EXIST;
- if (item_id >= 500)
+ if (item_id)
{
get_count = number;
if (item_data->type == ItemType::WEAPON
@@ -1356,18 +1370,18 @@ ATCE atcommand_item(Session *s, dumb_ptr<map_session_data> sd,
}
for (i = 0; i < number; i += get_count)
{
- struct item item_tmp {};
+ Item item_tmp {};
item_tmp.nameid = item_id;
PickupFail flag;
if ((flag = pc_additem(sd, &item_tmp, get_count))
!= PickupFail::OKAY)
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
}
- clif_displaymessage(s, "Item created.");
+ clif_displaymessage(s, "Item created."_s);
}
else
{
- clif_displaymessage(s, "Invalid item ID or name.");
+ clif_displaymessage(s, "Invalid item ID or name."_s);
return ATCE::EXIST;
}
@@ -1378,15 +1392,13 @@ static
ATCE atcommand_itemreset(Session *s, dumb_ptr<map_session_data> sd,
ZString)
{
- int i;
-
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount
&& sd->status.inventory[i].equip == EPOS::ZERO)
pc_delitem(sd, i, sd->status.inventory[i].amount, 0);
}
- clif_displaymessage(s, "All of your items have been removed.");
+ clif_displaymessage(s, "All of your items have been removed."_s);
return ATCE::OKAY;
}
@@ -1409,7 +1421,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd,
if (!extract(message, &level) || !level)
{
clif_displaymessage(s,
- "Please, enter a level adjustement (usage: @blvl <number of levels>).");
+ "Please, enter a level adjustement (usage: @blvl <number of levels>)."_s);
return ATCE::USAGE;
}
@@ -1417,7 +1429,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd,
{
if (sd->status.base_level == battle_config.maximum_level)
{
- clif_displaymessage(s, "Base level can't go any higher.");
+ clif_displaymessage(s, "Base level can't go any higher."_s);
return ATCE::RANGE;
}
if (level > battle_config.maximum_level || level > (battle_config.maximum_level - sd->status.base_level))
@@ -1432,13 +1444,13 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd,
pc_calcstatus(sd, 0);
pc_heal(sd, sd->status.max_hp, sd->status.max_sp);
clif_misceffect(sd, 0);
- clif_displaymessage(s, "Base level raised.");
+ clif_displaymessage(s, "Base level raised."_s);
}
else
{
if (sd->status.base_level == 1)
{
- clif_displaymessage(s, "Base level can't go any lower.");
+ clif_displaymessage(s, "Base level can't go any lower."_s);
return ATCE::USAGE;
}
if (level < -battle_config.maximum_level || level < (1 - sd->status.base_level))
@@ -1458,7 +1470,7 @@ ATCE atcommand_baselevelup(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, SP::BASELEVEL);
clif_updatestatus(sd, SP::NEXTBASEEXP);
pc_calcstatus(sd, 0);
- clif_displaymessage(s, "Base level lowered.");
+ clif_displaymessage(s, "Base level lowered."_s);
}
return ATCE::OKAY;
@@ -1481,7 +1493,7 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd,
{
if (sd->status.job_level == up_level)
{
- clif_displaymessage(s, "Job level can't go any higher.");
+ clif_displaymessage(s, "Job level can't go any higher."_s);
return ATCE::RANGE;
}
if (level > up_level || level > (up_level - sd->status.job_level))
@@ -1494,13 +1506,13 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, SP::SKILLPOINT);
pc_calcstatus(sd, 0);
clif_misceffect(sd, 1);
- clif_displaymessage(s, "Job level raised.");
+ clif_displaymessage(s, "Job level raised."_s);
}
else
{
if (sd->status.job_level == 1)
{
- clif_displaymessage(s, "Job level can't go any lower.");
+ clif_displaymessage(s, "Job level can't go any lower."_s);
return ATCE::RANGE;
}
if (level < -up_level || level < (1 - sd->status.job_level))
@@ -1518,7 +1530,7 @@ ATCE atcommand_joblevelup(Session *s, dumb_ptr<map_session_data> sd,
}
// to add: remove status points from skills
pc_calcstatus(sd, 0);
- clif_displaymessage(s, "Job level lowered.");
+ clif_displaymessage(s, "Job level lowered."_s);
}
return ATCE::OKAY;
@@ -1534,7 +1546,7 @@ ATCE atcommand_gm(Session *s, dumb_ptr<map_session_data> sd,
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.");
+ clif_displaymessage(s, "You already have some GM powers."_s);
return ATCE::PERM;
}
else
@@ -1550,7 +1562,7 @@ ATCE atcommand_pvpoff(Session *s, dumb_ptr<map_session_data> sd,
if (battle_config.pk_mode)
{
//disable command if server is in PK mode [Valaris]
- clif_displaymessage(s, "This option cannot be used in PK Mode.");
+ clif_displaymessage(s, "This option cannot be used in PK Mode."_s);
return ATCE::EXIST;
}
@@ -1571,11 +1583,11 @@ ATCE atcommand_pvpoff(Session *s, dumb_ptr<map_session_data> sd,
}
}
}
- clif_displaymessage(s, "PvP: Off.");
+ clif_displaymessage(s, "PvP: Off."_s);
}
else
{
- clif_displaymessage(s, "PvP is already Off.");
+ clif_displaymessage(s, "PvP is already Off."_s);
return ATCE::EXIST;
}
@@ -1589,7 +1601,7 @@ ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd,
if (battle_config.pk_mode)
{
//disable command if server is in PK mode [Valaris]
- clif_displaymessage(s, "This option cannot be used in PK Mode.");
+ clif_displaymessage(s, "This option cannot be used in PK Mode."_s);
return ATCE::EXIST;
}
@@ -1606,7 +1618,7 @@ ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd,
{
if (sd->bl_m == pl_sd->bl_m && !pl_sd->pvp_timer)
{
- pl_sd->pvp_timer = Timer(gettick() + std::chrono::milliseconds(200),
+ 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;
@@ -1614,11 +1626,11 @@ ATCE atcommand_pvpon(Session *s, dumb_ptr<map_session_data> sd,
}
}
}
- clif_displaymessage(s, "PvP: On.");
+ clif_displaymessage(s, "PvP: On."_s);
}
else
{
- clif_displaymessage(s, "PvP is already On.");
+ clif_displaymessage(s, "PvP is already On."_s);
return ATCE::EXIST;
}
@@ -1642,7 +1654,7 @@ ATCE atcommand_model(Session *s, dumb_ptr<map_session_data> sd,
pc_changelook(sd, LOOK::HAIR, hair_style);
pc_changelook(sd, LOOK::HAIR_COLOR, hair_color);
pc_changelook(sd, LOOK::CLOTHES_COLOR, cloth_color);
- clif_displaymessage(s, "Appearence changed.");
+ clif_displaymessage(s, "Appearence changed."_s);
}
}
else
@@ -1664,7 +1676,7 @@ ATCE atcommand_dye(Session *s, dumb_ptr<map_session_data> sd,
{
{
pc_changelook(sd, LOOK::CLOTHES_COLOR, cloth_color);
- clif_displaymessage(s, "Appearence changed.");
+ clif_displaymessage(s, "Appearence changed."_s);
}
}
else
@@ -1686,7 +1698,7 @@ ATCE atcommand_hair_style(Session *s, dumb_ptr<map_session_data> sd,
{
{
pc_changelook(sd, LOOK::HAIR, hair_style);
- clif_displaymessage(s, "Appearence changed.");
+ clif_displaymessage(s, "Appearence changed."_s);
}
}
else
@@ -1708,7 +1720,7 @@ ATCE atcommand_hair_color(Session *s, dumb_ptr<map_session_data> sd,
{
{
pc_changelook(sd, LOOK::HAIR_COLOR, hair_color);
- clif_displaymessage(s, "Appearence changed.");
+ clif_displaymessage(s, "Appearence changed."_s);
}
}
else
@@ -1722,22 +1734,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)
@@ -1749,18 +1760,18 @@ ATCE atcommand_spawn(Session *s, dumb_ptr<map_session_data> sd,
number = battle_config.atcommand_spawn_quantity_limit;
if (battle_config.etc_log)
- PRINTF("@spawn monster='%s' id=%d count=%d (%d,%d)\n",
+ PRINTF("@spawn monster='%s' id=%d count=%d (%d,%d)\n"_fmt,
monster, mob_id, number, x, y);
count = 0;
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,21 +1784,21 @@ 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)
if (number == count)
- clif_displaymessage(s, "All monster summoned!");
+ clif_displaymessage(s, "All monster summoned!"_s);
else
{
- AString output = STRPRINTF("%d monster(s) summoned!",
+ AString output = STRPRINTF("%d monster(s) summoned!"_fmt,
count);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Invalid monster ID or name.");
+ clif_displaymessage(s, "Invalid monster ID or name."_s);
return ATCE::EXIST;
}
@@ -1813,7 +1824,7 @@ void atcommand_killmonster_sub(Session *s, dumb_ptr<map_session_data> sd,
map_id->xs, map_id->ys,
BL::MOB);
- clif_displaymessage(s, "All monsters killed!");
+ clif_displaymessage(s, "All monsters killed!"_s);
}
static
@@ -1830,7 +1841,7 @@ void atlist_nearby_sub(dumb_ptr<block_list> bl, Session *s)
{
nullpo_retv(bl);
- AString buf = STRPRINTF(" - \"%s\"",
+ AString buf = STRPRINTF(" - \"%s\""_fmt,
bl->is_player()->status_key.name);
clif_displaymessage(s, buf);
}
@@ -1839,7 +1850,7 @@ static
ATCE atcommand_list_nearby(Session *s, dumb_ptr<map_session_data> sd,
ZString)
{
- clif_displaymessage(s, "Nearby players:");
+ clif_displaymessage(s, "Nearby players:"_s);
map_foreachinarea(std::bind(atlist_nearby_sub, ph::_1, s),
sd->bl_m,
sd->bl_x - 1, sd->bl_y - 1,
@@ -1867,7 +1878,7 @@ ATCE atcommand_gat(Session *s, dumb_ptr<map_session_data> sd,
for (y = 2; y >= -2; y--)
{
AString output = STRPRINTF(
- "%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
+ "%s (x= %d, y= %d) %02X %02X %02X %02X %02X"_fmt,
sd->bl_m->name_, sd->bl_x - 2, sd->bl_y + y,
map_getcell(sd->bl_m, sd->bl_x - 2, sd->bl_y + y),
map_getcell(sd->bl_m, sd->bl_x - 1, sd->bl_y + y),
@@ -1916,7 +1927,7 @@ ATCE atcommand_statuspoint(Session *s, dumb_ptr<map_session_data> sd,
{
sd->status.status_point = new_status_point;
clif_updatestatus(sd, SP::STATUSPOINT);
- clif_displaymessage(s, "Number of status points changed!");
+ clif_displaymessage(s, "Number of status points changed!"_s);
}
else
return ATCE::RANGE;
@@ -1945,7 +1956,7 @@ ATCE atcommand_skillpoint(Session *s, dumb_ptr<map_session_data> sd,
{
sd->status.skill_point = new_skill_point;
clif_updatestatus(sd, SP::SKILLPOINT);
- clif_displaymessage(s, "Number of skill points changed!");
+ clif_displaymessage(s, "Number of skill points changed!"_s);
}
else
return ATCE::RANGE;
@@ -1974,7 +1985,7 @@ ATCE atcommand_zeny(Session *s, dumb_ptr<map_session_data> sd,
{
sd->status.zeny = new_zeny;
clif_updatestatus(sd, SP::ZENY);
- clif_displaymessage(s, "Number of zenys changed!");
+ clif_displaymessage(s, "Number of zenys changed!"_s);
}
else
return ATCE::RANGE;
@@ -2006,7 +2017,7 @@ ATCE atcommand_param(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(sd, attr_to_sp(attr));
clif_updatestatus(sd, attr_to_usp(attr));
pc_calcstatus(sd, 0);
- clif_displaymessage(s, "Stat changed.");
+ clif_displaymessage(s, "Stat changed."_s);
}
else
return ATCE::RANGE;
@@ -2047,7 +2058,7 @@ ATCE atcommand_all_stats(Session *s, dumb_ptr<map_session_data> sd,
if (count > 0)
// if at least 1 stat modified
- clif_displaymessage(s, "All stats changed!");
+ clif_displaymessage(s, "All stats changed!"_s);
else
return ATCE::RANGE;
@@ -2064,38 +2075,38 @@ ATCE atcommand_recall(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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.");
+ "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.");
+ "You are not authorised to warp this player from its actual map."_s);
return ATCE::PERM;
}
pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT);
- AString output = STRPRINTF("%s recalled!", character);
+ AString output = STRPRINTF("%s recalled!"_fmt, character);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2112,7 +2123,7 @@ ATCE atcommand_revive(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
pl_sd->status.hp = pl_sd->status.max_hp;
pc_setstand(pl_sd);
@@ -2121,11 +2132,11 @@ ATCE atcommand_revive(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::HP);
clif_updatestatus(pl_sd, SP::SP);
clif_resurrection(pl_sd, 1);
- clif_displaymessage(s, "Character revived.");
+ clif_displaymessage(s, "Character revived."_s);
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2142,41 +2153,41 @@ ATCE atcommand_character_stats(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
AString output;
- output = STRPRINTF("'%s' stats:", pl_sd->status_key.name);
+ output = STRPRINTF("'%s' stats:"_fmt, pl_sd->status_key.name);
clif_displaymessage(s, output);
- output = STRPRINTF("Base Level - %d", pl_sd->status.base_level),
+ output = STRPRINTF("Base Level - %d"_fmt, pl_sd->status.base_level);
clif_displaymessage(s, output);
- output = STRPRINTF("Job - Novice/Human (level %d)", pl_sd->status.job_level);
+ output = STRPRINTF("Job - Novice/Human (level %d)"_fmt, pl_sd->status.job_level);
clif_displaymessage(s, output);
- output = STRPRINTF("Hp - %d", pl_sd->status.hp);
+ output = STRPRINTF("Hp - %d"_fmt, pl_sd->status.hp);
clif_displaymessage(s, output);
- output = STRPRINTF("MaxHp - %d", pl_sd->status.max_hp);
+ output = STRPRINTF("MaxHp - %d"_fmt, pl_sd->status.max_hp);
clif_displaymessage(s, output);
- output = STRPRINTF("Sp - %d", pl_sd->status.sp);
+ output = STRPRINTF("Sp - %d"_fmt, pl_sd->status.sp);
clif_displaymessage(s, output);
- output = STRPRINTF("MaxSp - %d", pl_sd->status.max_sp);
+ output = STRPRINTF("MaxSp - %d"_fmt, pl_sd->status.max_sp);
clif_displaymessage(s, output);
- output = STRPRINTF("Str - %3d", pl_sd->status.attrs[ATTR::STR]);
+ output = STRPRINTF("Str - %3d"_fmt, pl_sd->status.attrs[ATTR::STR]);
clif_displaymessage(s, output);
- output = STRPRINTF("Agi - %3d", pl_sd->status.attrs[ATTR::AGI]);
+ output = STRPRINTF("Agi - %3d"_fmt, pl_sd->status.attrs[ATTR::AGI]);
clif_displaymessage(s, output);
- output = STRPRINTF("Vit - %3d", pl_sd->status.attrs[ATTR::VIT]);
+ output = STRPRINTF("Vit - %3d"_fmt, pl_sd->status.attrs[ATTR::VIT]);
clif_displaymessage(s, output);
- output = STRPRINTF("Int - %3d", pl_sd->status.attrs[ATTR::INT]);
+ output = STRPRINTF("Int - %3d"_fmt, pl_sd->status.attrs[ATTR::INT]);
clif_displaymessage(s, output);
- output = STRPRINTF("Dex - %3d", pl_sd->status.attrs[ATTR::DEX]);
+ output = STRPRINTF("Dex - %3d"_fmt, pl_sd->status.attrs[ATTR::DEX]);
clif_displaymessage(s, output);
- output = STRPRINTF("Luk - %3d", pl_sd->status.attrs[ATTR::LUK]);
+ output = STRPRINTF("Luk - %3d"_fmt, pl_sd->status.attrs[ATTR::LUK]);
clif_displaymessage(s, output);
- output = STRPRINTF("Zeny - %d", pl_sd->status.zeny);
+ output = STRPRINTF("Zeny - %d"_fmt, pl_sd->status.zeny);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2199,41 +2210,41 @@ 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", pc_isGM(pl_sd));
+ if (GmLevel pl_gm_level = pc_isGM(pl_sd))
+ gmlevel = STRPRINTF("| GM Lvl: %d"_fmt, pl_gm_level);
else
- gmlevel = " ";
+ gmlevel = " "_s;
AString output;
output = STRPRINTF(
- "Name: %s | BLvl: %d | Job: Novice/Human (Lvl: %d) | HP: %d/%d | SP: %d/%d",
+ "Name: %s | BLvl: %d | Job: Novice/Human (Lvl: %d) | HP: %d/%d | SP: %d/%d"_fmt,
pl_sd->status_key.name, pl_sd->status.base_level,
pl_sd->status.job_level,
pl_sd->status.hp, pl_sd->status.max_hp,
pl_sd->status.sp, pl_sd->status.max_sp);
clif_displaymessage(s, output);
- output = STRPRINTF("STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s",
- pl_sd->status.attrs[ATTR::STR],
- pl_sd->status.attrs[ATTR::AGI],
- pl_sd->status.attrs[ATTR::VIT],
- pl_sd->status.attrs[ATTR::INT],
- pl_sd->status.attrs[ATTR::DEX],
- pl_sd->status.attrs[ATTR::LUK],
- pl_sd->status.zeny,
- gmlevel);
+ output = STRPRINTF("STR: %d | AGI: %d | VIT: %d | INT: %d | DEX: %d | LUK: %d | Zeny: %d %s"_fmt,
+ pl_sd->status.attrs[ATTR::STR],
+ pl_sd->status.attrs[ATTR::AGI],
+ pl_sd->status.attrs[ATTR::VIT],
+ pl_sd->status.attrs[ATTR::INT],
+ pl_sd->status.attrs[ATTR::DEX],
+ pl_sd->status.attrs[ATTR::LUK],
+ pl_sd->status.zeny,
+ gmlevel);
clif_displaymessage(s, output);
- clif_displaymessage(s, "--------");
+ clif_displaymessage(s, "--------"_s);
count++;
}
}
if (count == 0)
- clif_displaymessage(s, "No player found.");
+ clif_displaymessage(s, "No player found."_s);
else if (count == 1)
- clif_displaymessage(s, "1 player found.");
+ clif_displaymessage(s, "1 player found."_s);
else
{
- AString output = STRPRINTF("%d players found.", count);
+ AString output = STRPRINTF("%d players found."_fmt, count);
clif_displaymessage(s, output);
}
@@ -2252,9 +2263,9 @@ ATCE atcommand_character_option(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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;
@@ -2263,17 +2274,17 @@ ATCE atcommand_character_option(Session *s, dumb_ptr<map_session_data> sd,
clif_changeoption(pl_sd);
pc_calcstatus(pl_sd, 0);
- clif_displaymessage(s, "Character's options changed.");
+ clif_displaymessage(s, "Character's options changed."_s);
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2292,7 +2303,7 @@ ATCE atcommand_char_change_sex(Session *s, dumb_ptr<map_session_data> sd,
{
chrif_char_ask_name(sd->status_key.account_id, character, 5, HumanTimeDiff());
// type: 5 - changesex
- clif_displaymessage(s, "Character name sends to char-server to ask it.");
+ clif_displaymessage(s, "Character name sends to char-server to ask it."_s);
}
return ATCE::OKAY;
@@ -2310,7 +2321,7 @@ ATCE atcommand_char_block(Session *s, dumb_ptr<map_session_data> sd,
{
chrif_char_ask_name(sd->status_key.account_id, character, 1, HumanTimeDiff());
// type: 1 - block
- clif_displaymessage(s, "Character name sends to char-server to ask it.");
+ clif_displaymessage(s, "Character name sends to char-server to ask it."_s);
}
return ATCE::OKAY;
@@ -2330,7 +2341,7 @@ ATCE atcommand_char_ban(Session *s, dumb_ptr<map_session_data> sd,
{
chrif_char_ask_name(sd->status_key.account_id, character, 2, modif);
// type: 2 - ban
- clif_displaymessage(s, "Character name sends to char-server to ask it.");
+ clif_displaymessage(s, "Character name sends to char-server to ask it."_s);
}
return ATCE::OKAY;
@@ -2349,7 +2360,7 @@ ATCE atcommand_char_unblock(Session *s, dumb_ptr<map_session_data> sd,
// send answer to login server via char-server
chrif_char_ask_name(sd->status_key.account_id, character, 3, HumanTimeDiff());
// type: 3 - unblock
- clif_displaymessage(s, "Character name sends to char-server to ask it.");
+ clif_displaymessage(s, "Character name sends to char-server to ask it."_s);
}
return ATCE::OKAY;
@@ -2368,7 +2379,7 @@ ATCE atcommand_char_unban(Session *s, dumb_ptr<map_session_data> sd,
// send answer to login server via char-server
chrif_char_ask_name(sd->status_key.account_id, character, 4, HumanTimeDiff());
// type: 4 - unban
- clif_displaymessage(s, "Character name sends to char-server to ask it.");
+ clif_displaymessage(s, "Character name sends to char-server to ask it."_s);
}
return ATCE::OKAY;
@@ -2387,39 +2398,39 @@ ATCE atcommand_character_save(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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);
if (m == nullptr)
{
- clif_displaymessage(s, "Map not found.");
+ clif_displaymessage(s, "Map not found."_s);
return ATCE::EXIST;
}
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.");
+ "You are not authorised to set this map as a save map."_s);
return ATCE::PERM;
}
pc_setsavepoint(pl_sd, map_name, x, y);
- clif_displaymessage(s, "Character's respawn point changed.");
+ clif_displaymessage(s, "Character's respawn point changed."_s);
}
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2438,14 +2449,14 @@ 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);
- clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement.");
+ pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1);
+ clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."_s);
}
}
- clif_displaymessage(s, "Judgement was made.");
+ clif_displaymessage(s, "Judgement was made."_s);
return ATCE::OKAY;
}
@@ -2462,14 +2473,14 @@ 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);
- clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement.");
+ pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1);
+ clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."_s);
}
}
- clif_displaymessage(s, "Judgement was made.");
+ clif_displaymessage(s, "Judgement was made."_s);
return ATCE::OKAY;
}
@@ -2485,7 +2496,7 @@ void atcommand_raise_sub(dumb_ptr<map_session_data> sd)
clif_updatestatus(sd, SP::HP);
clif_updatestatus(sd, SP::SP);
clif_resurrection(sd, 1);
- clif_displaymessage(sd->sess, "Mercy has been shown.");
+ clif_displaymessage(sd->sess, "Mercy has been shown."_s);
}
}
@@ -2501,7 +2512,7 @@ ATCE atcommand_raise(Session *s, dumb_ptr<map_session_data>,
dumb_ptr<map_session_data> pl_sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s2->session_data.get()));
atcommand_raise_sub(pl_sd);
}
- clif_displaymessage(s, "Mercy has been granted.");
+ clif_displaymessage(s, "Mercy has been granted."_s);
return ATCE::OKAY;
}
@@ -2520,7 +2531,7 @@ ATCE atcommand_raisemap(Session *s, dumb_ptr<map_session_data> sd,
&& pl_sd->state.auth && sd->bl_m == pl_sd->bl_m)
atcommand_raise_sub(pl_sd);
}
- clif_displaymessage(s, "Mercy has been granted.");
+ clif_displaymessage(s, "Mercy has been granted."_s);
return ATCE::OKAY;
}
@@ -2537,16 +2548,16 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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)
{
if (pl_sd->status.base_level == battle_config.maximum_level)
{
- clif_displaymessage(s, "Character's base level can't go any higher.");
+ clif_displaymessage(s, "Character's base level can't go any higher."_s);
return ATCE::RANGE;
}
if (level > battle_config.maximum_level || level > (battle_config.maximum_level - pl_sd->status.base_level))
@@ -2564,13 +2575,13 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd,
pc_calcstatus(pl_sd, 0);
pc_heal(pl_sd, pl_sd->status.max_hp, pl_sd->status.max_sp);
clif_misceffect(pl_sd, 0);
- clif_displaymessage(s, "Character's base level raised.");
+ clif_displaymessage(s, "Character's base level raised."_s);
}
else
{
if (pl_sd->status.base_level == 1)
{
- clif_displaymessage(s, "Character's base level can't go any lower.");
+ clif_displaymessage(s, "Character's base level can't go any lower."_s);
return ATCE::RANGE;
}
if (level < -battle_config.maximum_level || level < (1 - pl_sd->status.base_level))
@@ -2592,20 +2603,20 @@ ATCE atcommand_character_baselevel(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::NEXTBASEEXP);
clif_updatestatus(pl_sd, SP::BASEEXP);
pc_calcstatus(pl_sd, 0);
- clif_displaymessage(s, "Character's base level lowered.");
+ clif_displaymessage(s, "Character's base level lowered."_s);
}
// Reset their stat points to prevent extra points from stacking
atcommand_charstreset(s, sd, character.to__actual());
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2624,9 +2635,9 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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;
@@ -2635,7 +2646,7 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
{
if (pl_sd->status.job_level == max_level)
{
- clif_displaymessage(s, "Character's job level can't go any higher.");
+ clif_displaymessage(s, "Character's job level can't go any higher."_s);
return ATCE::RANGE;
}
if (pl_sd->status.job_level + level > max_level)
@@ -2647,13 +2658,13 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::SKILLPOINT);
pc_calcstatus(pl_sd, 0);
clif_misceffect(pl_sd, 1);
- clif_displaymessage(s, "character's job level raised.");
+ clif_displaymessage(s, "character's job level raised."_s);
}
else
{
if (pl_sd->status.job_level == 1)
{
- clif_displaymessage(s, "Character's job level can't go any lower.");
+ clif_displaymessage(s, "Character's job level can't go any lower."_s);
return ATCE::RANGE;
}
if (pl_sd->status.job_level + level < 1)
@@ -2670,18 +2681,18 @@ ATCE atcommand_character_joblevel(Session *s, dumb_ptr<map_session_data> sd,
}
// to add: remove status points from skills
pc_calcstatus(pl_sd, 0);
- clif_displaymessage(s, "Character's job level lowered.");
+ clif_displaymessage(s, "Character's job level lowered."_s);
}
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2698,20 +2709,20 @@ ATCE atcommand_kick(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -2729,7 +2740,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)
@@ -2737,7 +2748,7 @@ ATCE atcommand_kickall(Session *s, dumb_ptr<map_session_data> sd,
}
}
- clif_displaymessage(s, "All players have been kicked!");
+ clif_displaymessage(s, "All players have been kicked!"_s);
return ATCE::OKAY;
}
@@ -2758,23 +2769,23 @@ ATCE atcommand_questskill(Session *s, dumb_ptr<map_session_data> sd,
if (pc_checkskill(sd, skill_id) == 0)
{
pc_skill(sd, skill_id, 1, 0);
- clif_displaymessage(s, "You have learned the skill.");
+ clif_displaymessage(s, "You have learned the skill."_s);
}
else
{
- clif_displaymessage(s, "You already have this quest skill.");
+ clif_displaymessage(s, "You already have this quest skill."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill.");
+ clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s);
return ATCE::RANGE;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist.");
+ clif_displaymessage(s, "This skill number doesn't exist."_s);
return ATCE::RANGE;
}
@@ -2796,34 +2807,34 @@ ATCE atcommand_charquestskill(Session *s, dumb_ptr<map_session_data>,
if (skill_get_inf2(skill_id) & 0x01)
{
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
if (pc_checkskill(pl_sd, skill_id) == 0)
{
pc_skill(pl_sd, skill_id, 1, 0);
- clif_displaymessage(s, "This player has learned the skill.");
+ clif_displaymessage(s, "This player has learned the skill."_s);
}
else
{
- clif_displaymessage(s, "This player already has this quest skill.");
+ clif_displaymessage(s, "This player already has this quest skill."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill.");
+ clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s);
return ATCE::RANGE;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist.");
+ clif_displaymessage(s, "This skill number doesn't exist."_s);
return ATCE::RANGE;
}
@@ -2848,23 +2859,23 @@ ATCE atcommand_lostskill(Session *s, dumb_ptr<map_session_data> sd,
sd->status.skill[skill_id].lv = 0;
sd->status.skill[skill_id].flags = SkillFlags::ZERO;
clif_skillinfoblock(sd);
- clif_displaymessage(s, "You have forgotten the skill.");
+ clif_displaymessage(s, "You have forgotten the skill."_s);
}
else
{
- clif_displaymessage(s, "You don't have this quest skill.");
+ clif_displaymessage(s, "You don't have this quest skill."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill.");
+ clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s);
return ATCE::RANGE;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist.");
+ clif_displaymessage(s, "This skill number doesn't exist."_s);
return ATCE::RANGE;
}
@@ -2886,36 +2897,36 @@ ATCE atcommand_charlostskill(Session *s, dumb_ptr<map_session_data>,
if (skill_get_inf2(skill_id) & 0x01)
{
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
if (pc_checkskill(pl_sd, skill_id) > 0)
{
pl_sd->status.skill[skill_id].lv = 0;
pl_sd->status.skill[skill_id].flags = SkillFlags::ZERO;
clif_skillinfoblock(pl_sd);
- clif_displaymessage(s, "This player has forgotten the skill.");
+ clif_displaymessage(s, "This player has forgotten the skill."_s);
}
else
{
- clif_displaymessage(s, "This player doesn't have this quest skill.");
+ clif_displaymessage(s, "This player doesn't have this quest skill."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill.");
+ clif_displaymessage(s, "This skill number doesn't exist or isn't a quest skill."_s);
return ATCE::RANGE;
}
}
else
{
- clif_displaymessage(s, "This skill number doesn't exist.");
+ clif_displaymessage(s, "This skill number doesn't exist."_s);
return ATCE::RANGE;
}
@@ -2964,26 +2975,26 @@ 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)
return ATCE::USAGE;
- AString output = STRPRINTF("The reference result of '%s' (name: id):", item_name);
+ 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
+ if ((item = itemdb_exists(i)) != nullptr
&& item->jname.contains_seq(item_name))
{
match++;
- output = STRPRINTF("%s: %d", item->jname, item->nameid);
+ output = STRPRINTF("%s: %d"_fmt, item->jname, item->nameid);
clif_displaymessage(s, output);
}
}
- output = STRPRINTF("It is %d affair above.", match);
+ output = STRPRINTF("It is %d affair above."_fmt, match);
clif_displaymessage(s, output);
return ATCE::OKAY;
@@ -2999,25 +3010,25 @@ ATCE atcommand_charskreset(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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);
AString output = STRPRINTF(
- "'%s' skill points reseted!", character);
+ "'%s' skill points reseted!"_fmt, character);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3034,26 +3045,26 @@ ATCE atcommand_charstreset(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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);
AString output = STRPRINTF(
- "'%s' stats points reseted!",
+ "'%s' stats points reseted!"_fmt,
character);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3070,30 +3081,30 @@ ATCE atcommand_charreset(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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);
pc_resetskill(pl_sd);
- pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"), 0);
+ pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"_s), 0);
// [Fate] Reset magic quest variables
- pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"), 0);
+ pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"_s), 0);
// [Fate] Reset magic experience
AString output = STRPRINTF(
- "'%s' skill and stats points reseted!", character);
+ "'%s' skill and stats points reseted!"_fmt, character);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3110,12 +3121,11 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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;
// Reset base level
pl_sd->status.base_level = 1;
@@ -3136,7 +3146,7 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
clif_updatestatus(pl_sd, SP::ZENY);
// Clear inventory
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount)
{
@@ -3147,33 +3157,33 @@ ATCE atcommand_char_wipe(Session *s, dumb_ptr<map_session_data> sd,
}
// Give knife and shirt
- struct item item;
- item.nameid = 1201;
+ Item item;
+ 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
pc_calcstatus(pl_sd, 0);
pc_resetstate(pl_sd);
pc_resetskill(pl_sd);
- pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"), 0);
+ pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_FLAGS"_s), 0);
// [Fate] Reset magic quest variables
- pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"), 0);
+ pc_setglobalreg(pl_sd, stringish<VarName>("MAGIC_EXP"_s), 0);
// [Fate] Reset magic experience
- AString output = STRPRINTF("%s: wiped.", character);
+ AString output = STRPRINTF("%s: wiped."_fmt, character);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3191,7 +3201,7 @@ ATCE atcommand_charmodel(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
if (hair_style >= MIN_HAIR_STYLE && hair_style <= MAX_HAIR_STYLE &&
hair_color >= MIN_HAIR_COLOR && hair_color <= MAX_HAIR_COLOR &&
@@ -3201,7 +3211,7 @@ ATCE atcommand_charmodel(Session *s, dumb_ptr<map_session_data>,
pc_changelook(pl_sd, LOOK::HAIR, hair_style);
pc_changelook(pl_sd, LOOK::HAIR_COLOR, hair_color);
pc_changelook(pl_sd, LOOK::CLOTHES_COLOR, cloth_color);
- clif_displaymessage(s, "Appearence changed.");
+ clif_displaymessage(s, "Appearence changed."_s);
}
}
else
@@ -3209,7 +3219,7 @@ ATCE atcommand_charmodel(Session *s, dumb_ptr<map_session_data>,
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3229,7 +3239,7 @@ ATCE atcommand_charskpoint(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
new_skill_point = pl_sd->status.skill_point + point;
if (point > 0 && (point > 0x7FFF || new_skill_point > 0x7FFF))
@@ -3242,14 +3252,14 @@ ATCE atcommand_charskpoint(Session *s, dumb_ptr<map_session_data>,
{
pl_sd->status.skill_point = new_skill_point;
clif_updatestatus(pl_sd, SP::SKILLPOINT);
- clif_displaymessage(s, "Character's number of skill points changed!");
+ clif_displaymessage(s, "Character's number of skill points changed!"_s);
}
else
return ATCE::RANGE;
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3269,7 +3279,7 @@ ATCE atcommand_charstpoint(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
new_status_point = pl_sd->status.status_point + point;
if (point > 0 && (point > 0x7FFF || new_status_point > 0x7FFF))
@@ -3282,14 +3292,14 @@ ATCE atcommand_charstpoint(Session *s, dumb_ptr<map_session_data>,
{
pl_sd->status.status_point = new_status_point;
clif_updatestatus(pl_sd, SP::STATUSPOINT);
- clif_displaymessage(s, "Character's number of status points changed!");
+ clif_displaymessage(s, "Character's number of status points changed!"_s);
}
else
return ATCE::RANGE;
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3307,7 +3317,7 @@ ATCE atcommand_charzeny(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
new_zeny = pl_sd->status.zeny + zeny;
if (zeny > 0 && (zeny > MAX_ZENY || new_zeny > MAX_ZENY))
@@ -3320,14 +3330,14 @@ ATCE atcommand_charzeny(Session *s, dumb_ptr<map_session_data>,
{
pl_sd->status.zeny = new_zeny;
clif_updatestatus(pl_sd, SP::ZENY);
- clif_displaymessage(s, "Character's number of zenys changed!");
+ clif_displaymessage(s, "Character's number of zenys changed!"_s);
}
else
return ATCE::RANGE;
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3341,10 +3351,10 @@ 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.");
+ "You are not authorised to warp somenone to your actual map."_s);
return ATCE::PERM;
}
@@ -3358,22 +3368,22 @@ 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);
}
}
- clif_displaymessage(s, "All characters recalled!");
+ clif_displaymessage(s, "All characters recalled!"_s);
if (count)
{
AString output = STRPRINTF(
- "Because you are not authorised to warp from some maps, %d player(s) have not been recalled.",
+ "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt,
count);
clif_displaymessage(s, output);
}
@@ -3386,23 +3396,23 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
PartyName party_name;
- struct party *p;
+ 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)
- && 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.");
+ "You are not authorised to warp somenone to your actual map."_s);
return ATCE::PERM;
}
- if ((p = party_searchname(party_name)) != NULL ||
+ if ((p = party_searchname(party_name)) ||
// 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()))))))
{
count = 0;
for (io::FD i : iter_fds())
@@ -3413,28 +3423,28 @@ ATCE atcommand_partyrecall(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
&& sd->status_key.account_id != pl_sd->status_key.account_id
- && pl_sd->status.party_id == p->party_id)
+ && 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);
}
}
- AString output = STRPRINTF("All online characters of the %s party are near you.", p->name);
+ 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.",
+ "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt,
count);
clif_displaymessage(s, output);
}
}
else
{
- clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online.");
+ clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s);
return ATCE::EXIST;
}
@@ -3445,9 +3455,9 @@ static
ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
- dumb_ptr<npc_data> nd = NULL;
+ dumb_ptr<npc_data> nd = nullptr;
MapName map_name;
- const char *direction = NULL;
+ LString direction = ""_s;
int list = 0;
extract(message, record<' '>(&list, &map_name));
@@ -3462,35 +3472,35 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd,
if (m_id != nullptr)
return ATCE::EXIST;
- clif_displaymessage(s, "------ Map Info ------");
- AString output = STRPRINTF("Map Name: %s", map_name);
+ clif_displaymessage(s, "------ Map Info ------"_s);
+ AString output = STRPRINTF("Map Name: %s"_fmt, map_name);
clif_displaymessage(s, output);
- output = STRPRINTF("Players In Map: %d", m_id->users);
+ output = STRPRINTF("Players In Map: %d"_fmt, m_id->users);
clif_displaymessage(s, output);
- output = STRPRINTF("NPCs In Map: %d", m_id->npc_num);
+ output = STRPRINTF("NPCs In Map: %d"_fmt, m_id->npc_num);
clif_displaymessage(s, output);
- clif_displaymessage(s, "------ Map Flags ------");
- output = STRPRINTF("Player vs Player: %s | No Party: %s",
- (m_id->flag.get(MapFlag::PVP)) ? "True" : "False",
- (m_id->flag.get(MapFlag::PVP_NOPARTY)) ? "True" : "False");
+ clif_displaymessage(s, "------ Map Flags ------"_s);
+ output = STRPRINTF("Player vs Player: %s | No Party: %s"_fmt,
+ (m_id->flag.get(MapFlag::PVP)) ? "True"_s : "False"_s,
+ (m_id->flag.get(MapFlag::PVP_NOPARTY)) ? "True"_s : "False"_s);
clif_displaymessage(s, output);
- output = STRPRINTF("No Penalty: %s",
- (m_id->flag.get(MapFlag::NOPENALTY)) ? "True" : "False");
+ output = STRPRINTF("No Penalty: %s"_fmt,
+ (m_id->flag.get(MapFlag::NOPENALTY)) ? "True"_s : "False"_s);
clif_displaymessage(s, output);
- output = STRPRINTF("No Return: %s",
- (m_id->flag.get(MapFlag::NORETURN)) ? "True" : "False");
+ output = STRPRINTF("No Return: %s"_fmt,
+ (m_id->flag.get(MapFlag::NORETURN)) ? "True"_s : "False"_s);
clif_displaymessage(s, output);
- output = STRPRINTF("No Save: %s",
- (m_id->flag.get(MapFlag::NOSAVE)) ? "True" : "False");
+ output = STRPRINTF("No Save: %s"_fmt,
+ (m_id->flag.get(MapFlag::NOSAVE)) ? "True"_s : "False"_s);
clif_displaymessage(s, output);
- output = STRPRINTF("Re Save: %s",
- (m_id->flag.get(MapFlag::RESAVE)) ? "True" : "False");
+ output = STRPRINTF("Re Save: %s"_fmt,
+ (m_id->flag.get(MapFlag::RESAVE)) ? "True"_s : "False"_s);
clif_displaymessage(s, output);
- output = STRPRINTF("No Teleport: %s",
- (m_id->flag.get(MapFlag::NOTELEPORT)) ? "True" : "False");
+ output = STRPRINTF("No Teleport: %s"_fmt,
+ (m_id->flag.get(MapFlag::NOTELEPORT)) ? "True"_s : "False"_s);
clif_displaymessage(s, output);
- output = STRPRINTF("No Monster Teleport: %s",
- (m_id->flag.get(MapFlag::MONSTER_NOTELEPORT)) ? "True" : "False");
+ output = STRPRINTF("No Monster Teleport: %s"_fmt,
+ (m_id->flag.get(MapFlag::MONSTER_NOTELEPORT)) ? "True"_s : "False"_s);
clif_displaymessage(s, output);
switch (list)
@@ -3499,7 +3509,7 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd,
// Do nothing. It's list 0, no additional display.
break;
case 1:
- clif_displaymessage(s, "----- Players in Map -----");
+ clif_displaymessage(s, "----- Players in Map -----"_s);
for (io::FD i : iter_fds())
{
Session *s2 = get_session(i);
@@ -3510,54 +3520,54 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd,
&& pl_sd->mapname_ == map_name)
{
output = STRPRINTF(
- "Player '%s' (session #%d) | Location: %d,%d",
+ "Player '%s' (session #%d) | Location: %d,%d"_fmt,
pl_sd->status_key.name, s2, pl_sd->bl_x, pl_sd->bl_y);
clif_displaymessage(s, output);
}
}
break;
case 2:
- clif_displaymessage(s, "----- NPCs in Map -----");
+ clif_displaymessage(s, "----- NPCs in Map -----"_s);
for (int i = 0; i < m_id->npc_num;)
{
nd = m_id->npc[i];
switch (nd->dir)
{
case DIR::S:
- direction = "North";
+ direction = "North"_s;
break;
case DIR::SW:
- direction = "North West";
+ direction = "North West"_s;
break;
case DIR::W:
- direction = "West";
+ direction = "West"_s;
break;
case DIR::NW:
- direction = "South West";
+ direction = "South West"_s;
break;
case DIR::N:
- direction = "South";
+ direction = "South"_s;
break;
case DIR::NE:
- direction = "South East";
+ direction = "South East"_s;
break;
case DIR::E:
- direction = "East";
+ direction = "East"_s;
break;
case DIR::SE:
- direction = "North East";
+ direction = "North East"_s;
break;
#if 0
case 9:
- direction = "North";
+ direction = "North"_s;
break;
#endif
default:
- direction = "Unknown";
+ direction = "Unknown"_s;
break;
}
output = STRPRINTF(
- "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d",
+ "NPC %d: %s | Direction: %s | Sprite: %d | Location: %d %d"_fmt,
++i, nd->name, direction, nd->npc_class, nd->bl_x,
nd->bl_y);
clif_displaymessage(s, output);
@@ -3566,7 +3576,7 @@ ATCE atcommand_mapinfo(Session *s, dumb_ptr<map_session_data> sd,
default:
// normally impossible to arrive here
clif_displaymessage(s,
- "Please, enter at least a valid list number (usage: @mapinfo <0-2> [map]).");
+ "Please, enter at least a valid list number (usage: @mapinfo <0-2> [map])."_s);
return ATCE::USAGE;
}
@@ -3582,27 +3592,27 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr<map_session_data> sd,
if (!extract(message, &party_name))
return ATCE::USAGE;
- struct party *p;
- if ((p = party_searchname(party_name)) != NULL ||
+ PartyPair p;
+ if ((p = party_searchname(party_name)) ||
// 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()))))))
{
- if (sd->partyspy == p->party_id)
+ if (sd->partyspy == p.party_id)
{
- sd->partyspy = 0;
- AString output = STRPRINTF("No longer spying on the %s party.", p->name);
+ 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.", p->name);
+ sd->partyspy = p.party_id;
+ AString output = STRPRINTF("Spying on the %s party."_fmt, p->name);
clif_displaymessage(s, output);
}
}
else
{
- clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online.");
+ clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s);
return ATCE::EXIST;
}
@@ -3618,14 +3628,14 @@ ATCE atcommand_enablenpc(Session *s, dumb_ptr<map_session_data>,
if (!extract(message, &NPCname) || !NPCname)
return ATCE::USAGE;
- if (npc_name2id(NPCname) != NULL)
+ if (npc_name2id(NPCname) != nullptr)
{
npc_enable(NPCname, 1);
- clif_displaymessage(s, "Npc Enabled.");
+ clif_displaymessage(s, "Npc Enabled."_s);
}
else
{
- clif_displaymessage(s, "This NPC doesn't exist.");
+ clif_displaymessage(s, "This NPC doesn't exist."_s);
return ATCE::EXIST;
}
@@ -3641,14 +3651,14 @@ ATCE atcommand_disablenpc(Session *s, dumb_ptr<map_session_data>,
if (!extract(message, &NPCname) || !NPCname)
return ATCE::USAGE;
- if (npc_name2id(NPCname) != NULL)
+ if (npc_name2id(NPCname) != nullptr)
{
npc_enable(NPCname, 0);
- clif_displaymessage(s, "Npc Disabled.");
+ clif_displaymessage(s, "Npc Disabled."_s);
}
else
{
- clif_displaymessage(s, "This NPC doesn't exist.");
+ clif_displaymessage(s, "This NPC doesn't exist."_s);
return ATCE::EXIST;
}
@@ -3661,7 +3671,7 @@ ATCE atcommand_servertime(Session *s, dumb_ptr<map_session_data>,
{
timestamp_seconds_buffer tsbuf;
stamp_time(tsbuf);
- AString temp = STRPRINTF("Server time: %s", tsbuf);
+ AString temp = STRPRINTF("Server time: %s"_fmt, tsbuf);
clif_displaymessage(s, temp);
return ATCE::OKAY;
@@ -3673,33 +3683,32 @@ 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 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)
+ 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)) != NULL)
+ else if (extract(item_name, &item_id) && (item_data = itemdb_exists(item_id)) != nullptr)
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 (pl_sd != nullptr)
{
- 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);
- if (item_position >= 0)
+ IOff0 item_position = pc_search_inventory(pl_sd, item_id);
+ if (item_position.ok())
{
count = 0;
- for (i = 0; i < number && item_position >= 0; i++)
+ for (i = 0; i < number && item_position.ok(); i++)
{
pc_delitem(pl_sd, item_position, 1, 0);
count++;
@@ -3707,37 +3716,37 @@ ATCE atcommand_chardelitem(Session *s, dumb_ptr<map_session_data> sd,
// for next loop
}
AString output = STRPRINTF(
- "%d item(s) removed by a GM.",
+ "%d item(s) removed by a GM."_fmt,
count);
clif_displaymessage(pl_sd->sess, output);
if (number == count)
- output = STRPRINTF("%d item(s) removed from the player.", count);
+ output = STRPRINTF("%d item(s) removed from the player."_fmt, count);
else
- output = STRPRINTF("%d item(s) removed. Player had only %d on %d items.", count, count, number);
+ output = STRPRINTF("%d item(s) removed. Player had only %d on %d items."_fmt, count, count, number);
clif_displaymessage(s, output);
}
else
{
- clif_displaymessage(s, "Character does not have the item.");
+ clif_displaymessage(s, "Character does not have the item."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
}
else
{
- clif_displaymessage(s, "Invalid item ID or name.");
+ clif_displaymessage(s, "Invalid item ID or name."_s);
return ATCE::RANGE;
}
@@ -3751,7 +3760,7 @@ ATCE atcommand_broadcast(Session *, dumb_ptr<map_session_data> sd,
if (!message)
return ATCE::USAGE;
- AString output = STRPRINTF("%s : %s", sd->status_key.name, message);
+ AString output = STRPRINTF("%s : %s"_fmt, sd->status_key.name, message);
intif_GMmessage(output);
return ATCE::OKAY;
@@ -3764,7 +3773,7 @@ ATCE atcommand_localbroadcast(Session *, dumb_ptr<map_session_data> sd,
if (!message)
return ATCE::USAGE;
- AString output = STRPRINTF("%s : %s", sd->status_key.name, message);
+ AString output = STRPRINTF("%s : %s"_fmt, sd->status_key.name, message);
clif_GMmessage(sd, output, 1);
@@ -3783,28 +3792,28 @@ ATCE atcommand_email(Session *s, dumb_ptr<map_session_data> sd,
if (!e_mail_check(actual_email))
{
- clif_displaymessage(s, "Invalid actual email. If you have default e-mail, type a@a.com.");
+ clif_displaymessage(s, "Invalid actual email. If you have default e-mail, type a@a.com."_s);
return ATCE::RANGE;
}
else if (!e_mail_check(new_email))
{
- clif_displaymessage(s, "Invalid new email. Please enter a real e-mail.");
+ clif_displaymessage(s, "Invalid new email. Please enter a real e-mail."_s);
return ATCE::RANGE;
}
else if (new_email == DEFAULT_EMAIL)
{
- clif_displaymessage(s, "New email must be a real e-mail.");
+ clif_displaymessage(s, "New email must be a real e-mail."_s);
return ATCE::RANGE;
}
else if (actual_email == new_email)
{
- clif_displaymessage(s, "New email must be different of the actual e-mail.");
+ clif_displaymessage(s, "New email must be different of the actual e-mail."_s);
return ATCE::RANGE;
}
else
{
chrif_changeemail(sd->status_key.account_id, actual_email, new_email);
- clif_displaymessage(s, "Information sended to login-server via char-server.");
+ clif_displaymessage(s, "Information sended to login-server via char-server."_s);
}
return ATCE::OKAY;
@@ -3821,7 +3830,7 @@ ATCE atcommand_effect(Session *s, dumb_ptr<map_session_data> sd,
if (flag <= 0)
{
clif_specialeffect(sd, type, flag);
- clif_displaymessage(s, "Your Effect Has Changed.");
+ clif_displaymessage(s, "Your Effect Has Changed."_s);
}
else
{
@@ -3834,7 +3843,7 @@ ATCE atcommand_effect(Session *s, dumb_ptr<map_session_data> sd,
if (pl_sd && pl_sd->state.auth)
{
clif_specialeffect(pl_sd, type, flag);
- clif_displaymessage(pl_sd->sess, "Your Effect Has Changed.");
+ clif_displaymessage(pl_sd->sess, "Your Effect Has Changed."_s);
}
}
}
@@ -3846,34 +3855,34 @@ static
ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
- struct item_data *item_data = NULL;
- int i, count, counter;
+ struct item_data *item_data = nullptr;
+ int count, counter;
CharName character;
if (!asplit(message, &character))
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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++)
+ for (IOff0 i : IOff0::iter())
{
- 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)
+ nullptr)
{
counter = counter + pl_sd->status.inventory[i].amount;
count++;
if (count == 1)
{
AString output = STRPRINTF(
- "------ Items list of '%s' ------",
+ "------ Items list of '%s' ------"_fmt,
pl_sd->status_key.name);
clif_displaymessage(s, output);
}
@@ -3881,35 +3890,35 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd,
MString equipstr;
if (bool(equip))
{
- equipstr += "| equiped: ";
+ equipstr += "| equiped: "_s;
if (bool(equip & EPOS::GLOVES))
- equipstr += "robe/gargment, ";
+ equipstr += "robe/gargment, "_s;
if (bool(equip & EPOS::CAPE))
- equipstr += "left accessory, ";
+ equipstr += "left accessory, "_s;
if (bool(equip & EPOS::MISC1))
- equipstr += "body/armor, ";
+ equipstr += "body/armor, "_s;
if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == EPOS::WEAPON)
- equipstr += "right hand, ";
+ equipstr += "right hand, "_s;
if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == EPOS::SHIELD)
- equipstr += "left hand, ";
+ equipstr += "left hand, "_s;
if ((equip & (EPOS::WEAPON | EPOS::SHIELD)) == (EPOS::WEAPON | EPOS::SHIELD))
- equipstr += "both hands, ";
+ equipstr += "both hands, "_s;
if (bool(equip & EPOS::SHOES))
- equipstr += "feet, ";
+ equipstr += "feet, "_s;
if (bool(equip & EPOS::MISC2))
- equipstr += "right accessory, ";
+ equipstr += "right accessory, "_s;
if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::LEGS)
- equipstr += "lower head, ";
+ equipstr += "lower head, "_s;
if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::HAT)
- equipstr += "top head, ";
+ equipstr += "top head, "_s;
if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::HAT | EPOS::LEGS))
- equipstr += "lower/top head, ";
+ equipstr += "lower/top head, "_s;
if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == EPOS::TORSO)
- equipstr += "mid head, ";
+ equipstr += "mid head, "_s;
if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::TORSO | EPOS::LEGS))
- equipstr += "lower/mid head, ";
+ equipstr += "lower/mid head, "_s;
if ((equip & (EPOS::TORSO | EPOS::HAT | EPOS::LEGS)) == (EPOS::TORSO | EPOS::HAT | EPOS::LEGS))
- equipstr += "lower/mid/top head, ";
+ equipstr += "lower/mid/top head, "_s;
// remove final ', '
equipstr.pop_back(2);
}
@@ -3918,35 +3927,35 @@ ATCE atcommand_character_item_list(Session *s, dumb_ptr<map_session_data> sd,
AString output;
if (true)
- output = STRPRINTF("%d %s (%s, id: %d) %s",
- pl_sd->status.inventory[i].amount,
- item_data->name, item_data->jname,
- pl_sd->status.inventory[i].nameid,
- AString(equipstr));
+ output = STRPRINTF("%d %s (%s, id: %d) %s"_fmt,
+ pl_sd->status.inventory[i].amount,
+ item_data->name, item_data->jname,
+ pl_sd->status.inventory[i].nameid,
+ AString(equipstr));
clif_displaymessage(s, output);
// snip cards
}
}
if (count == 0)
- clif_displaymessage(s, "No item found on this player.");
+ clif_displaymessage(s, "No item found on this player."_s);
else
{
AString output = STRPRINTF(
- "%d item(s) found in %d kind(s) of items.",
+ "%d item(s) found in %d kind(s) of items."_fmt,
counter, count);
clif_displaymessage(s, output);
}
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -3957,74 +3966,74 @@ static
ATCE atcommand_character_storage_list(Session *s, dumb_ptr<map_session_data> sd,
ZString message)
{
- struct storage *stor;
- struct item_data *item_data = NULL;
- int i, count, counter;
+ Storage *stor;
+ struct item_data *item_data = nullptr;
+ int count, counter;
CharName character;
if (!asplit(message, &character))
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
- 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)
+ if ((stor = account2storage2(pl_sd->status_key.account_id)) != nullptr)
{
counter = 0;
count = 0;
- for (i = 0; i < MAX_STORAGE; i++)
+ for (SOff0 i : SOff0::iter())
{
- if (stor->storage_[i].nameid > 0
+ if (stor->storage_[i].nameid
&& (item_data =
- itemdb_search(stor->storage_[i].nameid)) != NULL)
+ itemdb_search(stor->storage_[i].nameid)) != nullptr)
{
counter = counter + stor->storage_[i].amount;
count++;
if (count == 1)
{
AString output = STRPRINTF(
- "------ Storage items list of '%s' ------",
+ "------ 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)",
- stor->storage_[i].amount,
- item_data->name, item_data->jname,
- stor->storage_[i].nameid);
+ 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);
}
}
if (count == 0)
clif_displaymessage(s,
- "No item found in the storage of this player.");
+ "No item found in the storage of this player."_s);
else
{
AString output = STRPRINTF(
- "%d item(s) found in %d kind(s) of items.",
+ "%d item(s) found in %d kind(s) of items."_fmt,
counter, count);
clif_displaymessage(s, output);
}
}
else
{
- clif_displaymessage(s, "This player has no storage.");
+ clif_displaymessage(s, "This player has no storage."_s);
return ATCE::OKAY;
}
}
else
{
- clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player.");
+ clif_displaymessage(s, "Your GM level don't authorise you to do this action on this player."_s);
return ATCE::PERM;
}
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -4038,9 +4047,9 @@ ATCE atcommand_killer(Session *s, dumb_ptr<map_session_data> sd,
sd->special_state.killer = !sd->special_state.killer;
if (sd->special_state.killer)
- clif_displaymessage(s, "You be a killa...");
+ clif_displaymessage(s, "You be a killa..."_s);
else
- clif_displaymessage(s, "You gonna be own3d...");
+ clif_displaymessage(s, "You gonna be own3d..."_s);
return ATCE::OKAY;
}
@@ -4055,20 +4064,20 @@ ATCE atcommand_charkiller(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd == NULL)
+ if (pl_sd == nullptr)
return ATCE::EXIST;
pl_sd->special_state.killer = !pl_sd->special_state.killer;
if (pl_sd->special_state.killer)
{
- clif_displaymessage(s, "The player is now a killer");
- clif_displaymessage(pl_sd->sess, "You are now a 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");
- clif_displaymessage(pl_sd->sess, "You are no longer a killer");
+ clif_displaymessage(s, "The player is no longer a killer"_s);
+ clif_displaymessage(pl_sd->sess, "You are no longer a killer"_s);
}
return ATCE::OKAY;
@@ -4081,9 +4090,9 @@ ATCE atcommand_killable(Session *s, dumb_ptr<map_session_data> sd,
sd->special_state.killable = !sd->special_state.killable;
if (sd->special_state.killable)
- clif_displaymessage(s, "You gonna be own3d...");
+ clif_displaymessage(s, "You gonna be own3d..."_s);
else
- clif_displaymessage(s, "You be a killa...");
+ clif_displaymessage(s, "You be a killa..."_s);
return ATCE::OKAY;
}
@@ -4098,15 +4107,15 @@ ATCE atcommand_charkillable(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd == NULL)
+ 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");
+ clif_displaymessage(s, "The player is now killable"_s);
else
- clif_displaymessage(s, "The player is no longer killable");
+ clif_displaymessage(s, "The player is no longer killable"_s);
return ATCE::OKAY;
}
@@ -4117,13 +4126,13 @@ ATCE atcommand_npcmove(Session *, dumb_ptr<map_session_data>,
{
NpcName character;
int x = 0, y = 0;
- dumb_ptr<npc_data> nd = 0;
+ dumb_ptr<npc_data> nd = nullptr;
if (!asplit(message, &x, &y, &character))
return ATCE::USAGE;
nd = npc_name2id(character);
- if (nd == NULL)
+ if (nd == nullptr)
return ATCE::EXIST;
npc_enable(character, 0);
@@ -4146,17 +4155,17 @@ 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", sd->mapname_, sd->bl_x, sd->bl_y);
- AString w3 = STRPRINTF("%s%d%d%d%d", mapname, sd->bl_x, sd->bl_y, x, y);
- AString w4 = STRPRINTF("1,1,%s.gat,%d,%d", mapname, x, y);
+ 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, ZString("warp"), w3name, w4);
+ int ret = npc_parse_warp(w1, "warp"_s, w3name, w4);
if (ret)
// warp failed
return ATCE::RANGE;
- AString output = STRPRINTF("New warp NPC => %s", w3);
+ AString output = STRPRINTF("New warp NPC => %s"_fmt, w3);
clif_displaymessage(s, output);
return ATCE::OKAY;
@@ -4173,11 +4182,11 @@ ATCE atcommand_chareffect(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(target);
- if (pl_sd == NULL)
+ if (pl_sd == nullptr)
return ATCE::EXIST;
clif_specialeffect(pl_sd, type, 0);
- clif_displaymessage(s, "Your Effect Has Changed.");
+ clif_displaymessage(s, "Your Effect Has Changed."_s);
return ATCE::OKAY;
}
@@ -4186,8 +4195,7 @@ static
ATCE atcommand_dropall(Session *, dumb_ptr<map_session_data> sd,
ZString)
{
- int i;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount)
{
@@ -4208,9 +4216,9 @@ ATCE atcommand_chardropall(Session *s, dumb_ptr<map_session_data>,
if (!asplit(message, &character))
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd == NULL)
+ if (pl_sd == nullptr)
return ATCE::EXIST;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (pl_sd->status.inventory[i].amount)
{
@@ -4220,9 +4228,8 @@ ATCE atcommand_chardropall(Session *s, dumb_ptr<map_session_data>,
}
}
- clif_displaymessage(pl_sd->sess, "Ever play 52 card pickup?");
- clif_displaymessage(s, "It is done");
- //clif_displaymessage(s, "It is offical.. your a jerk");
+ clif_displaymessage(pl_sd->sess, "Ever play 52 card pickup?"_s);
+ clif_displaymessage(s, "It is official.. you're a jerk."_s);
return ATCE::OKAY;
}
@@ -4231,8 +4238,6 @@ static
ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd,
ZString)
{
- int i;
-
if (!sd->state.storage_open)
{
//Open storage.
@@ -4240,16 +4245,16 @@ ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd,
{
case 2:
//Try again
- clif_displaymessage(s, "run this command again..");
+ clif_displaymessage(s, "run this command again.."_s);
return ATCE::OKAY;
case 1:
//Failure
clif_displaymessage(s,
- "You can't open the storage currently.");
+ "You can't open the storage currently."_s);
return ATCE::EXIST;
}
}
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].amount)
{
@@ -4260,7 +4265,7 @@ ATCE atcommand_storeall(Session *s, dumb_ptr<map_session_data> sd,
}
storage_storageclose(sd);
- clif_displaymessage(s, "It is done");
+ clif_displaymessage(s, "It is done"_s);
return ATCE::OKAY;
}
@@ -4273,7 +4278,7 @@ ATCE atcommand_charstoreall(Session *s, dumb_ptr<map_session_data> sd,
if (!asplit(message, &character))
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd == NULL)
+ if (pl_sd == nullptr)
return ATCE::EXIST;
if (storage_storageopen(pl_sd) == 1)
@@ -4281,11 +4286,11 @@ ATCE atcommand_charstoreall(Session *s, dumb_ptr<map_session_data> sd,
// TODO figure out what the hell this is talking about,
// and especially why it's different from the other one.
clif_displaymessage(s,
- "Had to open the characters storage window...");
- clif_displaymessage(s, "run this command again..");
+ "Had to open the characters storage window..."_s);
+ clif_displaymessage(s, "run this command again.."_s);
return ATCE::OKAY;
}
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (pl_sd->status.inventory[i].amount)
{
@@ -4297,12 +4302,12 @@ ATCE atcommand_charstoreall(Session *s, dumb_ptr<map_session_data> sd,
storage_storageclose(pl_sd);
clif_displaymessage(pl_sd->sess,
- "Everything you own has been put away for safe keeping.");
+ "Everything you own has been put away for safe keeping."_s);
clif_displaymessage(pl_sd->sess,
- "go to the nearest kafka to retrieve it..");
- clif_displaymessage(pl_sd->sess, " -- the management");
+ "go to the nearest kafka to retrieve it.."_s);
+ clif_displaymessage(pl_sd->sess, " -- the management"_s);
- clif_displaymessage(s, "It is done");
+ clif_displaymessage(s, "It is done"_s);
return ATCE::OKAY;
}
@@ -4383,31 +4388,30 @@ 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->deletetimer = Timer(tick + std::chrono::minutes(1),
+ md->mode = get_mob_db(md->mob_class).mode | MobMode::AGGRESSIVE;
+ md->deletetimer = Timer(tick + 1_min,
std::bind(mob_timer_delete, ph::_1, ph::_2,
id));
clif_misceffect(md, 344);
@@ -4420,12 +4424,12 @@ 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)))
{
- clif_displaymessage(s, "usage: @adjcmdlvl <lvl> <command>.");
+ clif_displaymessage(s, "usage: @adjcmdlvl <lvl> <command>."_s);
return ATCE::USAGE;
}
@@ -4434,12 +4438,12 @@ ATCE atcommand_adjcmdlvl(Session *s, dumb_ptr<map_session_data>,
if (it)
{
it->level = newlev;
- clif_displaymessage(s, "@command level changed.");
+ clif_displaymessage(s, "@command level changed."_s);
return ATCE::OKAY;
}
}
- clif_displaymessage(s, "@command not found.");
+ clif_displaymessage(s, "@command not found."_s);
return ATCE::EXIST;
}
@@ -4447,18 +4451,17 @@ 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>.");
+ clif_displaymessage(s, "usage: @adjgmlvl <lvl> <user>."_s);
return ATCE::USAGE;
}
dumb_ptr<map_session_data> pl_sd = map_nick2sd(user);
- if (pl_sd == NULL)
+ if (pl_sd == nullptr)
return ATCE::EXIST;
pc_set_gm_level(pl_sd->status_key.account_id, newlev);
@@ -4501,14 +4504,14 @@ constexpr
size_t magic_skills_nr = sizeof(magic_skills) / sizeof(magic_skills[0]);
static
-ZString magic_skill_names[magic_skills_nr] =
+LString magic_skill_names[magic_skills_nr] =
{
- {"magic"},
- {"life"},
- {"war"},
- {"transmute"},
- {"nature"},
- {"astral"},
+ "magic"_s,
+ "life"_s,
+ "war"_s,
+ "transmute"_s,
+ "nature"_s,
+ "astral"_s,
};
static
@@ -4524,7 +4527,7 @@ ATCE atcommand_magic_info(Session *s, dumb_ptr<map_session_data>,
if (pl_sd)
{
AString buf = STRPRINTF(
- "`%s' has the following magic skills:",
+ "`%s' has the following magic skills:"_fmt,
character);
clif_displaymessage(s, buf);
@@ -4532,7 +4535,7 @@ ATCE atcommand_magic_info(Session *s, dumb_ptr<map_session_data>,
{
SkillID sk = magic_skills[i];
buf = STRPRINTF(
- "%d in %s",
+ "%d in %s"_fmt,
pl_sd->status.skill[sk].lv,
magic_skill_names[i]);
if (pl_sd->status.skill[sk].lv)
@@ -4542,7 +4545,7 @@ ATCE atcommand_magic_info(Session *s, dumb_ptr<map_session_data>,
return ATCE::OKAY;
}
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -4563,12 +4566,12 @@ ATCE atcommand_set_magic(Session *s, dumb_ptr<map_session_data>,
if (!asplit(message, &magic_type, &value, &character))
{
clif_displaymessage(s,
- "Usage: @setmagic <school> <value> <char-name>, where <school> is either `magic', one of the school names, or `all'.");
+ "Usage: @setmagic <school> <value> <char-name>, where <school> is either `magic', one of the school names, or `all'."_s);
return ATCE::USAGE;
}
SkillID skill_index = SkillID::NEGATIVE;
- if ("all" == magic_type)
+ if ("all"_s == magic_type)
skill_index = SkillID::ZERO;
else
{
@@ -4585,12 +4588,12 @@ ATCE atcommand_set_magic(Session *s, dumb_ptr<map_session_data>,
if (skill_index == SkillID::NEGATIVE)
{
clif_displaymessage(s,
- "Incorrect school of magic. Use `magic', `nature', `life', `war', `transmute', `ether', or `all'.");
+ "Incorrect school of magic. Use `magic', `nature', `life', `war', `transmute', `ether', or `all'."_s);
return ATCE::RANGE;
}
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
if (skill_index == SkillID::ZERO)
for (SkillID sk : magic_skills)
@@ -4602,7 +4605,7 @@ ATCE atcommand_set_magic(Session *s, dumb_ptr<map_session_data>,
return ATCE::OKAY;
}
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -4661,21 +4664,21 @@ 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.");
+ "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.");
+ "You are not authorised to warp you from your actual map."_s);
return ATCE::PERM;
}
pc_setpos(sd, pl_sd->bl_m->name_, pl_sd->bl_x, pl_sd->bl_y, BeingRemoveWhy::WARPED);
- AString output = STRPRINTF("Jump to %s", pl_sd->status_key.name);
+ AString output = STRPRINTF("Jump to %s"_fmt, pl_sd->status_key.name);
clif_displaymessage(s, output);
sd->followtarget = pl_sd->bl_id;
@@ -4702,9 +4705,9 @@ ATCE atcommand_wgm(Session *s, dumb_ptr<map_session_data> sd,
if (tmw_CheckChatSpam(sd, message))
return ATCE::OKAY;
- tmw_GmHackMsg(STRPRINTF("[GM] %s: %s", sd->status_key.name, message));
+ tmw_GmHackMsg(STRPRINTF("[GM] %s: %s"_fmt, sd->status_key.name, message));
if (!pc_isGM(sd))
- clif_displaymessage(s, "Message sent.");
+ clif_displaymessage(s, "Message sent."_s);
return ATCE::OKAY;
}
@@ -4720,26 +4723,26 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
SkillID pool_skills[MAX_SKILL_POOL];
int pool_skills_nr = skill_pool(pl_sd, pool_skills);
int i;
AString buf = STRPRINTF(
- "Active skills %d out of %d for %s:",
+ "Active skills %d out of %d for %s:"_fmt,
pool_skills_nr, skill_pool_max(pl_sd), character);
clif_displaymessage(s, buf);
for (i = 0; i < pool_skills_nr; ++i)
{
- buf = STRPRINTF(" - %s [%d]: power %d",
+ buf = STRPRINTF(" - %s [%d]: power %d"_fmt,
skill_name(pool_skills[i]),
pool_skills[i],
skill_power(pl_sd, pool_skills[i]));
clif_displaymessage(s, buf);
}
- buf = STRPRINTF("Learned skills out of %d for %s:",
+ buf = STRPRINTF("Learned skills out of %d for %s:"_fmt,
skill_pool_skills_size, character);
clif_displaymessage(s, buf);
@@ -4750,7 +4753,7 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr<map_session_data>,
if (lvl)
{
- buf = STRPRINTF(" - %s [%d]: lvl %d",
+ buf = STRPRINTF(" - %s [%d]: lvl %d"_fmt,
name, skill_pool_skills[i], lvl);
clif_displaymessage(s, buf);
}
@@ -4759,7 +4762,7 @@ ATCE atcommand_skillpool_info(Session *s, dumb_ptr<map_session_data>,
}
else
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -4775,20 +4778,20 @@ ATCE atcommand_skillpool_focus(Session *s, dumb_ptr<map_session_data>,
if (!asplit(message, &skill, &character))
{
- clif_displaymessage(s, "Usage: @sp-focus <skill-nr> <char_name>");
+ clif_displaymessage(s, "Usage: @sp-focus <skill-nr> <char_name>"_s);
return ATCE::USAGE;
}
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
if (skill_pool_activate(pl_sd, skill))
- clif_displaymessage(s, "Activation failed.");
+ clif_displaymessage(s, "Activation failed."_s);
else
- clif_displaymessage(s, "Activation successful.");
+ clif_displaymessage(s, "Activation successful."_s);
}
else
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::OKAY;
}
@@ -4804,15 +4807,15 @@ ATCE atcommand_skillpool_unfocus(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
if (skill_pool_deactivate(pl_sd, skill))
- clif_displaymessage(s, "Deactivation failed.");
+ clif_displaymessage(s, "Deactivation failed."_s);
else
- clif_displaymessage(s, "Deactivation successful.");
+ clif_displaymessage(s, "Deactivation successful."_s);
}
else
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::OKAY;
}
@@ -4829,13 +4832,13 @@ ATCE atcommand_skill_learn(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd != NULL)
+ if (pl_sd != nullptr)
{
set_skill(pl_sd, skill, level);
clif_skillinfoblock(pl_sd);
}
else
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::OKAY;
}
@@ -4850,9 +4853,9 @@ ATCE atcommand_ipcheck(Session *s, dumb_ptr<map_session_data>,
return ATCE::USAGE;
dumb_ptr<map_session_data> pl_sd = map_nick2sd(character);
- if (pl_sd == NULL)
+ if (pl_sd == nullptr)
{
- clif_displaymessage(s, "Character not found.");
+ clif_displaymessage(s, "Character not found."_s);
return ATCE::EXIST;
}
@@ -4873,7 +4876,7 @@ ATCE atcommand_ipcheck(Session *s, dumb_ptr<map_session_data>,
if (ip == pl_sd->get_ip())
{
AString output = STRPRINTF(
- "Name: %s | Location: %s %d %d",
+ "Name: %s | Location: %s %d %d"_fmt,
pl_sd->status_key.name, pl_sd->mapname_,
pl_sd->bl_x, pl_sd->bl_y);
clif_displaymessage(s, output);
@@ -4881,7 +4884,7 @@ ATCE atcommand_ipcheck(Session *s, dumb_ptr<map_session_data>,
}
}
- clif_displaymessage(s, "End of list");
+ clif_displaymessage(s, "End of list"_s);
return ATCE::OKAY;
}
@@ -4898,14 +4901,14 @@ 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);
- clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement.");
+ pc_damage(nullptr, pl_sd, pl_sd->status.hp + 1);
+ clif_displaymessage(pl_sd->sess, "The holy messenger has given judgement."_s);
}
}
- clif_displaymessage(s, "Judgement was made.");
+ clif_displaymessage(s, "Judgement was made."_s);
return ATCE::OKAY;
}
@@ -4915,13 +4918,13 @@ ATCE atcommand_source(Session *s, dumb_ptr<map_session_data>,
ZString)
{
clif_displaymessage(s,
- "This server code consists of Free Software under GPL3&AGPL3");
+ "This server code consists of Free Software under GPL3&AGPL3"_s);
clif_displaymessage(s,
- "This is commit " VERSION_HASH ", also known as " VERSION_FULL);
+ "This is commit " VERSION_HASH ", also known as " VERSION_FULL ""_s);
clif_displaymessage(s,
- "The version is " VERSION_STRING);
+ "The version is " VERSION_STRING ""_s);
clif_displaymessage(s,
- "For source, see " VENDOR_SOURCE);
+ "For source, see " VENDOR_SOURCE ""_s);
return ATCE::OKAY;
}
@@ -4931,424 +4934,425 @@ ATCE atcommand_source(Session *s, dumb_ptr<map_session_data>,
// declared extern above
Map<XString, AtCommandInfo> atcommand_info =
{
- {"help", {"[level[-level]|category|@command]",
+ {"help"_s, {"[level[-level]|category|@command]"_s,
0, atcommand_help,
- "Show help"}},
- {"setup", {"<level> <charname>",
+ "Show help"_s}},
+ {"setup"_s, {"<level> <charname>"_s,
40, atcommand_setup,
- "Safely set a chars levels and warp them to a special place (for TAW)"}},
- {"charwarp", {"<mapname> <x> <y> <charname>",
+ "Safely set a chars levels and warp them to a special place (for TAW)"_s}},
+ {"charwarp"_s, {"<mapname> <x> <y> <charname>"_s,
60, atcommand_charwarp,
- "Warp a character to a point on another map"}},
- {"warp", {"<mapname> [x] [y]",
+ "Warp a character to a point on another map"_s}},
+ {"warp"_s, {"<mapname> [x] [y]"_s,
40, atcommand_warp,
- "Warp yourself to another map"}},
- {"where", {"[charname]",
+ "Warp yourself to another map"_s}},
+ {"where"_s, {"[charname]"_s,
40, atcommand_where,
- "Show location of a character or yourself"}},
- {"goto", {"<charname>",
+ "Show location of a character or yourself"_s}},
+ {"goto"_s, {"<charname>"_s,
40, atcommand_goto,
- "Warp yourself to another character"}},
- {"jump", {"[x] [y]",
+ "Warp yourself to another character"_s}},
+ {"jump"_s, {"[x] [y]"_s,
40, atcommand_jump,
- "Warp yourself within a map"}},
- {"who", {"[subsequence]",
+ "Warp yourself within a map"_s}},
+ {"who"_s, {"[subsequence]"_s,
40, atcommand_who,
- "List matching players online, with location info"}},
- {"whogroup", {"[subsequence]",
+ "List matching players online, with location info"_s}},
+ {"whogroup"_s, {"[subsequence]"_s,
40, atcommand_whogroup,
- "List matching players online, with party info"}},
- {"whomap", {"[mapname]",
+ "List matching players online, with party info"_s}},
+ {"whomap"_s, {"[mapname]"_s,
40, atcommand_whomap,
- "List all players on the map, with location info"}},
- {"whomapgroup", {"[mapname]",
+ "List all players on the map, with location info"_s}},
+ {"whomapgroup"_s, {"[mapname]"_s,
40, atcommand_whomapgroup,
- "List all players on the map, with party info"}},
- {"whogm", {"[subsequence]",
+ "List all players on the map, with party info"_s}},
+ {"whogm"_s, {"[subsequence]"_s,
40, atcommand_whogm,
- "List matching GM players, with location, level, and party info"}},
- {"save", {"",
+ "List matching GM players, with location, level, and party info"_s}},
+ {"save"_s, {""_s,
40, atcommand_save,
- "Set your respawn point to your current location"}},
- {"return", {"",
+ "Set your respawn point to your current location"_s}},
+ {"return"_s, {""_s,
40, atcommand_load,
- "Return to your respawn point"}},
- {"load", {"",
+ "Return to your respawn point"_s}},
+ {"load"_s, {""_s,
40, atcommand_load,
- "Return to your respawn point"}},
- {"speed", {"<rate>",
+ "Return to your respawn point"_s}},
+ {"speed"_s, {"<rate>"_s,
60, atcommand_speed,
- "Set walk rate"}},
- {"storage", {"",
+ "Set walk rate"_s}},
+ {"storage"_s, {""_s,
99, atcommand_storage,
- "Open your storage"}},
- {"option", {"<opt1> [opt2] [option]",
+ "Open your storage"_s}},
+ {"option"_s, {"<opt1> [opt2] [option]"_s,
80, atcommand_option,
- "Set your 'option' status flags"}},
- {"hide", {"",
+ "Set your 'option' status flags"_s}},
+ {"hide"_s, {""_s,
40, atcommand_hide,
- "Toggle invisibility from monsters and certain commands"}},
- {"die", {"",
+ "Toggle invisibility from monsters and certain commands"_s}},
+ {"die"_s, {""_s,
40, atcommand_die,
- "Cause fatal damage to yourself"}},
- {"kill", {"<charname>",
+ "Cause fatal damage to yourself"_s}},
+ {"kill"_s, {"<charname>"_s,
60, atcommand_kill,
- "Cause fatal damage to another player"}},
- {"alive", {"",
+ "Cause fatal damage to another player"_s}},
+ {"alive"_s, {""_s,
60, atcommand_alive,
- "Restore life to yourself"}},
- {"kami", {"<message ...>",
+ "Restore life to yourself"_s}},
+ {"kami"_s, {"<message ...>"_s,
99, atcommand_kami,
- "Send an anonymous broadcast"}},
- {"heal", {"[hp] [sp]",
+ "Send an anonymous broadcast"_s}},
+ {"heal"_s, {"[hp] [sp]"_s,
40, atcommand_heal,
- "Restore or destroy your health"}},
- {"item", {"<item-name-or-id> [count]",
+ "Restore or destroy your health"_s}},
+ {"item"_s, {"<item-name-or-id> [count]"_s,
80, atcommand_item,
- "Summon items out of the void"}},
- {"itemreset", {"",
+ "Summon items out of the void"_s}},
+ {"itemreset"_s, {""_s,
40, atcommand_itemreset,
- "Cast all of your itens into the void (why would you ever want this?)"}},
- {"itemcheck", {"",
+ "Cast all of your itens into the void (why would you ever want this?)"_s}},
+ {"itemcheck"_s, {""_s,
80, atcommand_itemcheck,
- "Perform an internal integrity check on your items"}},
- {"blvl", {"<delta>",
+ "Perform an internal integrity check on your items"_s}},
+ {"blvl"_s, {"<delta>"_s,
60, atcommand_baselevelup,
- "Adjust your level"}},
- {"jlvl", {"<delta>",
+ "Adjust your level"_s}},
+ {"jlvl"_s, {"<delta>"_s,
60, atcommand_joblevelup,
- "Adjust your job level"}},
- {"gm", {"<password>",
+ "Adjust your job level"_s}},
+ {"gm"_s, {"<password>"_s,
100, atcommand_gm,
- "Receive GM powers"}},
- {"pvpoff", {"",
+ "Receive GM powers"_s}},
+ {"pvpoff"_s, {""_s,
60, atcommand_pvpoff,
- "Enable PvP on your map"}},
- {"pvpon", {"",
+ "Enable PvP on your map"_s}},
+ {"pvpon"_s, {""_s,
60, atcommand_pvpon,
- "Disable PvP on your map"}},
- {"model", {"<style> [color] [dye]",
+ "Disable PvP on your map"_s}},
+ {"model"_s, {"<style> [color] [dye]"_s,
99, atcommand_model,
- "Change your hairstyle and hair color"}},
- {"spawn", {"<mob-name-or-id> [count] [x] [y]",
+ "Change your hairstyle and hair color"_s}},
+ {"spawn"_s, {"<mob-name-or-id> [count] [x] [y]"_s,
50, atcommand_spawn,
- "Spawn normal monsters at location."}},
- {"killmonster", {"[map]",
+ "Spawn normal monsters at location."_s}},
+ {"killmonster"_s, {"[map]"_s,
60, atcommand_killmonster,
- "Kill all monsters (with drops)"}},
- {"killmonster2", {"[map]",
+ "Kill all monsters (with drops)"_s}},
+ {"killmonster2"_s, {"[map]"_s,
60, atcommand_killmonster2,
- "Kill all monsters (no drops)"}},
- {"gat", {"",
+ "Kill all monsters (no drops)"_s}},
+ {"gat"_s, {""_s,
99, atcommand_gat,
- "Dump the local walkmap"}},
- {"packet", {"<type> <flag>",
+ "Dump the local walkmap"_s}},
+ {"packet"_s, {"<type> <flag>"_s,
99, atcommand_packet,
- "Force a status change"}},
- {"stpoint", {"<amount>",
+ "Force a status change"_s}},
+ {"stpoint"_s, {"<amount>"_s,
60, atcommand_statuspoint,
- "Increase your stat points"}},
- {"skpoint", {"<amount>",
+ "Increase your stat points"_s}},
+ {"skpoint"_s, {"<amount>"_s,
60, atcommand_skillpoint,
- "Increase your skill points"}},
- {"zeny", {"<amount>",
+ "Increase your skill points"_s}},
+ {"zeny"_s, {"<amount>"_s,
80, atcommand_zeny,
- "Change how much money you have"}},
- {"str", {"<delta>",
+ "Change how much money you have"_s}},
+ {"str"_s, {"<delta>"_s,
60, atcommand_param<ATTR::STR>,
- "Adjust your strength"}},
- {"agi", {"<delta>",
+ "Adjust your strength"_s}},
+ {"agi"_s, {"<delta>"_s,
60, atcommand_param<ATTR::AGI>,
- "Adjust your agility"}},
- {"vit", {"<delta>",
+ "Adjust your agility"_s}},
+ {"vit"_s, {"<delta>"_s,
60, atcommand_param<ATTR::VIT>,
- "Adjust your vitality"}},
- {"int", {"<delta>",
+ "Adjust your vitality"_s}},
+ {"int"_s, {"<delta>"_s,
60, atcommand_param<ATTR::INT>,
- "Adjust your intelligence\0(TODO make this work in real life, I'm lonely)"}},
- {"dex", {"<delta>",
+ "Adjust your intelligence\0(TODO make this work in real life, I'm lonely)"_s}},
+ {"dex"_s, {"<delta>"_s,
60, atcommand_param<ATTR::DEX>,
- "Adjust your dexterity"}},
- {"luk", {"<delta>",
+ "Adjust your dexterity"_s}},
+ {"luk"_s, {"<delta>"_s,
60, atcommand_param<ATTR::LUK>,
- "Adjust your luck"}},
- {"recall", {"<charname>",
+ "Adjust your luck"_s}},
+ {"recall"_s, {"<charname>"_s,
60, atcommand_recall,
- "Warp a player to you"}},
- {"revive", {"<charname>",
+ "Warp a player to you"_s}},
+ {"revive"_s, {"<charname>"_s,
60, atcommand_revive,
- "Restore a player to full health"}},
- {"charstats", {"<charname>",
+ "Restore a player to full health"_s}},
+ {"charstats"_s, {"<charname>"_s,
40, atcommand_character_stats,
- "Show a bunch of stats about a single user"}},
- {"charstatsall", {"",
+ "Show a bunch of stats about a single user"_s}},
+ {"charstatsall"_s, {""_s,
60, atcommand_character_stats_all,
- "Show a bunch of stats about all online users"}},
- {"charoption", {"<opt1> <opt2> <opt3> <charname>",
+ "Show a bunch of stats about all online users"_s}},
+ {"charoption"_s, {"<opt1> <opt2> <opt3> <charname>"_s,
80, atcommand_character_option,
- "Set option flags on another character"}},
- {"charsave", {"<map> <x> <y> <charname>",
+ "Set option flags on another character"_s}},
+ {"charsave"_s, {"<map> <x> <y> <charname>"_s,
60, atcommand_character_save,
- "Set another character's save point"}},
- {"doom", {"",
+ "Set another character's save point"_s}},
+ {"doom"_s, {""_s,
80, atcommand_doom,
- "Kill everyone on the server"}},
- {"doommap", {"",
+ "Kill everyone on the server"_s}},
+ {"doommap"_s, {""_s,
80, atcommand_doommap,
- "Kill everyone on your map"}},
- {"raise", {"",
+ "Kill everyone on your map"_s}},
+ {"raise"_s, {""_s,
80, atcommand_raise,
- "Resurrect all players on the server"}},
- {"raisemap", {"",
+ "Resurrect all players on the server"_s}},
+ {"raisemap"_s, {""_s,
80, atcommand_raisemap,
- "Resurrect all players on your map"}},
- {"charbaselvl", {"<delta> <charname>",
+ "Resurrect all players on your map"_s}},
+ {"charbaselvl"_s, {"<delta> <charname>"_s,
60, atcommand_character_baselevel,
- "Adjust another character's level"}},
- {"charjlvl", {"<delta> <charname>",
+ "Adjust another character's level"_s}},
+ {"charjlvl"_s, {"<delta> <charname>"_s,
60, atcommand_character_joblevel,
- "Adjust another character's job level"}},
- {"kick", {"<charname>",
+ "Adjust another character's job level"_s}},
+ {"kick"_s, {"<charname>"_s,
40, atcommand_kick,
- "Transiently kick a player off the server"}},
- {"kickall", {"",
+ "Transiently kick a player off the server"_s}},
+ {"kickall"_s, {""_s,
99, atcommand_kickall,
- "Transiently kick all players off the server"}},
- {"questskill", {"<skill-id>",
+ "Transiently kick all players off the server"_s}},
+ {"questskill"_s, {"<skill-id>"_s,
99, atcommand_questskill,
- "Give yourself a quest (?) skill"}},
- {"charquestskill", {"<skill-id> <charname>",
+ "Give yourself a quest (?) skill"_s}},
+ {"charquestskill"_s, {"<skill-id> <charname>"_s,
99, atcommand_charquestskill,
- "Give another player a quest (?) skill"}},
- {"lostskill", {"<skill-id>",
+ "Give another player a quest (?) skill"_s}},
+ {"lostskill"_s, {"<skill-id>"_s,
80, atcommand_lostskill,
- "Take away one of your quest (?) skills"}},
- {"charlostskill", {"<skill-id> <charname>",
+ "Take away one of your quest (?) skills"_s}},
+ {"charlostskill"_s, {"<skill-id> <charname>"_s,
99, atcommand_charlostskill,
- "Take away one of another player's quest (?) skills"}},
- {"party", {"<name>",
+ "Take away one of another player's quest (?) skills"_s}},
+ {"party"_s, {"<name>"_s,
99, atcommand_party,
- "Create a new party"}},
- {"mapexit", {"",
+ "Create a new party"_s}},
+ {"mapexit"_s, {""_s,
99, atcommand_mapexit,
- "Try to kill the server kindly"}},
- {"idsearch", {"<item-subseq>",
+ "Try to kill the server kindly"_s}},
+ {"idsearch"_s, {"<item-subseq>"_s,
80, atcommand_idsearch,
- "Search for some items that might match"}},
- {"mapmove", {"<mapname> [x] [y]",
+ "Search for some items that might match"_s}},
+ {"mapmove"_s, {"<mapname> [x] [y]"_s,
40, atcommand_warp,
- "Warp to a different map"}},
- {"broadcast", {"<message ...>",
+ "Warp to a different map"_s}},
+ {"broadcast"_s, {"<message ...>"_s,
40, atcommand_broadcast,
- "Broadcast a message from you"}},
- {"localbroadcast", {"<message ...>",
+ "Broadcast a message from you"_s}},
+ {"localbroadcast"_s, {"<message ...>"_s,
40, atcommand_localbroadcast,
- "Broadcast a message from you locally"}},
- {"recallall", {"",
+ "Broadcast a message from you locally"_s}},
+ {"recallall"_s, {""_s,
80, atcommand_recallall,
- "Warp every online player to your current map"}},
- {"charskreset", {"<charname>",
+ "Warp every online player to your current map"_s}},
+ {"charskreset"_s, {"<charname>"_s,
60, atcommand_charskreset,
- "Reset a player's skill points"}},
- {"charstreset", {"<charname>",
+ "Reset a player's skill points"_s}},
+ {"charstreset"_s, {"<charname>"_s,
60, atcommand_charstreset,
- "Reset a player's stat points"}},
- {"charreset", {"<charname>",
+ "Reset a player's stat points"_s}},
+ {"charreset"_s, {"<charname>"_s,
60, atcommand_charreset,
- "Reset a player's skills, stats, and magic"}},
- {"charmodel", {"<hairstyle> <hair-color> <dye> <charname>",
+ "Reset a player's skills, stats, and magic"_s}},
+ {"charmodel"_s, {"<hairstyle> <hair-color> <dye> <charname>"_s,
99, atcommand_charmodel,
- "Change another character's appearance"}},
- {"charskpoint", {"<amount> <charname>",
+ "Change another character's appearance"_s}},
+ {"charskpoint"_s, {"<amount> <charname>"_s,
60, atcommand_charskpoint,
- "Adjust another player's skill points"}},
- {"charstpoint", {"<amount> <charname>",
+ "Adjust another player's skill points"_s}},
+ {"charstpoint"_s, {"<amount> <charname>"_s,
60, atcommand_charstpoint,
- "Adjust another player's stat points"}},
- {"charzeny", {"<delta> <charname>",
+ "Adjust another player's stat points"_s}},
+ {"charzeny"_s, {"<delta> <charname>"_s,
80, atcommand_charzeny,
- "Adjust another player's money"}},
- {"mapinfo", {"<0-2> [map]",
+ "Adjust another player's money"_s}},
+ {"mapinfo"_s, {"<0-2> [map]"_s,
99, atcommand_mapinfo,
- "Show some stats for the map. 1 also shows players, 2 also shows NPCs"}},
- {"dye", {"<dye>",
+ "Show some stats for the map. 1 also shows players, 2 also shows NPCs"_s}},
+ {"dye"_s, {"<dye>"_s,
40, atcommand_dye,
- "Don't use"}},
- {"ccolor", {"<dye>",
+ "Don't use"_s}},
+ {"ccolor"_s, {"<dye>"_s,
40, atcommand_dye,
- "Don't use"}},
- {"hairstyle", {"<style>",
+ "Don't use"_s}},
+ {"hairstyle"_s, {"<style>"_s,
40, atcommand_hair_style,
- "Change your hairstyle"}},
- {"haircolor", {"<color>",
+ "Change your hairstyle"_s}},
+ {"haircolor"_s, {"<color>"_s,
40, atcommand_hair_color,
- "Change your hair color"}},
- {"allstats", {"[value]",
+ "Change your hair color"_s}},
+ {"allstats"_s, {"[value]"_s,
60, atcommand_all_stats,
- "Adjust all stats by value (or maximum)"}},
- {"charchangesex", {"<charname>",
+ "Adjust all stats by value (or maximum)"_s}},
+ {"charchangesex"_s, {"<charname>"_s,
60, atcommand_char_change_sex,
- "Flip a characters sex and disconnect them"}},
- {"block", {"<charname>",
+ "Flip a characters sex and disconnect them"_s}},
+ {"block"_s, {"<charname>"_s,
60, atcommand_char_block,
- "Permanently block a player's account from the server"}},
- {"unblock", {"<charname>",
+ "Permanently block a player's account from the server"_s}},
+ {"unblock"_s, {"<charname>"_s,
60, atcommand_char_unblock,
- "Remove a permanent block from a player's account"}},
- {"ban", {"<timedelta> <charname>",
+ "Remove a permanent block from a player's account"_s}},
+ {"ban"_s, {"<timedelta> <charname>"_s,
60, atcommand_char_ban,
- "Ban a player's account from the server for a limited time"}},
- {"unban", {"<timedelta> <charname>",
+ "Ban a player's account from the server for a limited time"_s}},
+ {"unban"_s, {"<timedelta> <charname>"_s,
60, atcommand_char_unban,
- "Remove a limited ban from a player's account"}},
- {"partyspy", {"<party-name-or-id>",
+ "Remove a limited ban from a player's account"_s}},
+ {"partyspy"_s, {"<party-name-or-id>"_s,
99, atcommand_partyspy,
- "Listen to all chat within a party"}},
- {"partyrecall", {"<party-name-or-id>",
+ "Listen to all chat within a party"_s}},
+ {"partyrecall"_s, {"<party-name-or-id>"_s,
99, atcommand_partyrecall,
- "Warp all members of a party to you"}},
- {"enablenpc", {"<npc-name>",
+ "Warp all members of a party to you"_s}},
+ {"enablenpc"_s, {"<npc-name>"_s,
80, atcommand_enablenpc,
- "Enable an NPC for visibility"}},
- {"disablenpc", {"<npc-name>",
+ "Enable an NPC for visibility"_s}},
+ {"disablenpc"_s, {"<npc-name>"_s,
80, atcommand_disablenpc,
- "Disable an NPC for visibility"}},
- {"servertime", {"",
+ "Disable an NPC for visibility"_s}},
+ {"servertime"_s, {""_s,
0, atcommand_servertime,
- "Print the server's idea of the current time"}},
- {"chardelitem", {"<item-name-or-id> <count> <charname>",
+ "Print the server's idea of the current time"_s}},
+ {"chardelitem"_s, {"<item-name-or-id> <count> <charname>"_s,
60, atcommand_chardelitem,
- "Delete items from a player's inventory"}},
- {"listnearby", {"",
+ "Delete items from a player's inventory"_s}},
+ {"listnearby"_s, {""_s,
40, atcommand_list_nearby,
- "Print name of all nearby players"}},
- {"email", {"<actual@email> <new@email>",
+ "Print name of all nearby players"_s}},
+ {"email"_s, {"<actual@email> <new@email>"_s,
0, atcommand_email,
- "Changed your account's email"}},
- {"effect", {"<type> <flag>",
+ "Changed your account's email"_s}},
+ {"effect"_s, {"<type> <flag>"_s,
99, atcommand_effect,
- "Apply a special effect to yourself (or everyone! wtf?)"}},
- {"charitemlist", {"<charname>",
+ "Apply a special effect to yourself (or everyone! wtf?)"_s}},
+ {"charitemlist"_s, {"<charname>"_s,
99, atcommand_character_item_list,
- "List a player's items"}},
- {"charstoragelist", {"<charname>",
+ "List a player's items"_s}},
+ {"charstoragelist"_s, {"<charname>"_s,
99, atcommand_character_storage_list,
- "List a player's storage"}},
- {"addwarp", {"<mapname> <x> <y>",
+ "List a player's storage"_s}},
+ {"addwarp"_s, {"<mapname> <x> <y>"_s,
80, atcommand_addwarp,
- "Create a new permanent warp"}},
- {"killer", {"",
+ "Create a new permanent warp"_s}},
+ {"killer"_s, {""_s,
60, atcommand_killer,
- "Toggle whether you are a killer"}},
- {"charkiller", {"<charname>",
+ "Toggle whether you are a killer"_s}},
+ {"charkiller"_s, {"<charname>"_s,
60, atcommand_charkiller,
- "Toggle whether a player is a killer"}},
- {"npcmove", {"<x> <y> <npc-name>",
+ "Toggle whether a player is a killer"_s}},
+ {"npcmove"_s, {"<x> <y> <npc-name>"_s,
80, atcommand_npcmove,
- "Force an NPC to move on the map"}},
- {"killable", {"",
+ "Force an NPC to move on the map"_s}},
+ {"killable"_s, {""_s,
60, atcommand_killable,
- "Toggle whether you are killable"}},
- {"charkillable", {"<charname>",
+ "Toggle whether you are killable"_s}},
+ {"charkillable"_s, {"<charname>"_s,
60, atcommand_charkillable,
- "Toggle whether a player is killable"}},
- {"chareffect", {"<type> <target>",
+ "Toggle whether a player is killable"_s}},
+ {"chareffect"_s, {"<type> <target>"_s,
40, atcommand_chareffect,
- "Apply effect type with arg 0 to a player"}},
- {"dropall", {"",
+ "Apply effect type with arg 0 to a player"_s}},
+ {"dropall"_s, {""_s,
99, atcommand_dropall,
- "Drop all of your items"}},
- {"chardropall", {"<charname>",
+ "Drop all of your items"_s}},
+ {"chardropall"_s, {"<charname>"_s,
60, atcommand_chardropall,
- "Force a player to drop all of their items"}},
- {"storeall", {"",
+ "Force a player to drop all of their items"_s}},
+ {"storeall"_s, {""_s,
60, atcommand_storeall,
- "Store all of your items"}},
- {"charstoreall", {"<charname>",
+ "Store all of your items"_s}},
+ {"charstoreall"_s, {"<charname>"_s,
60, atcommand_charstoreall,
- "Store all of a player's items"}},
- {"rain", {"",
+ "Store all of a player's items"_s}},
+ {"rain"_s, {""_s,
99, atcommand_rain,
- "Enable the rain mapflag"}},
- {"snow", {"",
+ "Enable the rain mapflag"_s}},
+ {"snow"_s, {""_s,
99, atcommand_snow,
- "Enable the snow mapflag"}},
- {"sakura", {"",
+ "Enable the snow mapflag"_s}},
+ {"sakura"_s, {""_s,
99, atcommand_sakura,
- "Enable the sakura mapflag"}},
- {"fog", {"",
+ "Enable the sakura mapflag"_s}},
+ {"fog"_s, {""_s,
99, atcommand_fog,
- "Enable the fog mapflag"}},
- {"leaves", {"",
+ "Enable the fog mapflag"_s}},
+ {"leaves"_s, {""_s,
99, atcommand_leaves,
- "Enable the leaves mapflag"}},
- {"summon", {"<mob-id-or-name>",
+ "Enable the leaves mapflag"_s}},
+ {"summon"_s, {"<mob-id-or-name>"_s,
50, atcommand_summon,
- "Summon a slave monster temporarily"}},
- {"adjgmlvl", {"<level> <cmd>",
+ "Summon a slave monster temporarily"_s}},
+ {"adjgmlvl"_s, {"<level> <cmd>"_s,
99, atcommand_adjgmlvl,
- "Temporarily adjust the GM level of a command"}},
- {"adjcmdlvl", {"<level> <charname>",
+ "Temporarily adjust the GM level of a command"_s}},
+ {"adjcmdlvl"_s, {"<level> <charname>"_s,
99, atcommand_adjcmdlvl,
- "Temporarily adjust the GM level of a player"}},
- {"trade", {"<charname>",
+ "Temporarily adjust the GM level of a player"_s}},
+ {"trade"_s, {"<charname>"_s,
60, atcommand_trade,
- "Initiate trade with a player anywhere"}},
- {"charwipe", {"<charname>",
+ "Initiate trade with a player anywhere"_s}},
+ {"charwipe"_s, {"<charname>"_s,
60, atcommand_char_wipe,
- "Reset a character almost completely"}},
- {"setmagic", {"<school> <value> <charname>",
+ "Reset a character almost completely"_s}},
+ {"setmagic"_s, {"<school> <value> <charname>"_s,
80, atcommand_set_magic,
- "Force magic skill level"}},
- {"magicinfo", {"<charname>",
+ "Force magic skill level"_s}},
+ {"magicinfo"_s, {"<charname>"_s,
80, atcommand_magic_info,
- "Show magic skills of a palyer"}},
- {"log", {"<message ...>",
+ "Show magic skills of a palyer"_s}},
+ {"log"_s, {"<message ...>"_s,
40, atcommand_log,
- "Write something directly to the log"}},
- {"l", {"<message ...>",
+ "Write something directly to the log"_s}},
+ {"l"_s, {"<message ...>"_s,
40, atcommand_log,
- "Write something directly to the log"}},
- {"tee", {"<message ...>",
+ "Write something directly to the log"_s}},
+ {"tee"_s, {"<message ...>"_s,
40, atcommand_tee,
- "Duplicate a message to the log and public chat"}},
- {"t", {"<message ...>",
+ "Duplicate a message to the log and public chat"_s}},
+ {"t"_s, {"<message ...>"_s,
40, atcommand_tee,
- "Duplicate a message to the log and public chat"}},
- {"invisible", {"",
+ "Duplicate a message to the log and public chat"_s}},
+ {"invisible"_s, {""_s,
50, atcommand_invisible,
- "Make yourself invisible to players"}},
- {"visible", {"",
+ "Make yourself invisible to players"_s}},
+ {"visible"_s, {""_s,
50, atcommand_visible,
- "Make yourself visible to players"}},
- {"hugo", {"",
+ "Make yourself visible to players"_s}},
+ {"hugo"_s, {""_s,
60, atcommand_iterate_forward_over_players,
- "Jump to the next player"}},
- {"linus", {"",
+ "Jump to the next player"_s}},
+ {"linus"_s, {""_s,
60, atcommand_iterate_backwards_over_players,
- "Jump to the previous player"}},
- {"sp-info", {"<charname>",
+ "Jump to the previous player"_s}},
+ {"sp-info"_s, {"<charname>"_s,
40, atcommand_skillpool_info,
- "Show info about pool skills"}},
- {"sp-focus", {"<skill-id> <charname>",
+ "Show info about pool skills"_s}},
+ {"sp-focus"_s, {"<skill-id> <charname>"_s,
80, atcommand_skillpool_focus,
- "Focus on a pool skill"}},
- {"sp-unfocus", {"<skill-id> <charname>",
+ "Focus on a pool skill"_s}},
+ {"sp-unfocus"_s, {"<skill-id> <charname>"_s,
80, atcommand_skillpool_unfocus,
- "Unfocus off of a pool skill"}},
- {"skill-learn", {"<skill-id> <level> <charname>",
+ "Unfocus off of a pool skill"_s}},
+ {"skill-learn"_s, {"<skill-id> <level> <charname>"_s,
80, atcommand_skill_learn,
- "Change a skill level"}},
- {"wgm", {"<message ...>",
+ "Change a skill level"_s}},
+ {"wgm"_s, {"<message ...>"_s,
0, atcommand_wgm,
- "Send a message to online GMs"}},
- {"ipcheck", {"<charname>",
+ "Send a message to online GMs"_s}},
+ {"ipcheck"_s, {"<charname>"_s,
60, atcommand_ipcheck,
- "List players on the same IP address"}},
- {"doomspot", {"",
+ "List players on the same IP address"_s}},
+ {"doomspot"_s, {""_s,
60, atcommand_doomspot,
- "Kill all players on the same tile"}},
- {"source", {"",
+ "Kill all players on the same tile"_s}},
+ {"source"_s, {""_s,
0, atcommand_source,
- "Legal information about source code (must be a level 0 command!)"}},
+ "Legal information about source code (must be a level 0 command!)"_s}},
};
+} // namespace tmwa
diff --git a/src/map/atcommand.hpp b/src/map/atcommand.hpp
index 95e3814..4bf5277 100644
--- a/src/map/atcommand.hpp
+++ b/src/map/atcommand.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_ATCOMMAND_HPP
-#define TMWA_MAP_ATCOMMAND_HPP
+#pragma once
// atcommand.hpp - GM commands.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,14 +20,21 @@
// 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 "../strings/fwd.hpp"
-# include "map.hpp"
+#include "../generic/fwd.hpp"
+#include "../net/fwd.hpp"
+
+#include "../mmo/fwd.hpp"
+
+
+namespace tmwa
+{
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);
@@ -38,5 +44,4 @@ void log_atcommand(dumb_ptr<map_session_data> sd, ZString cmd);
extern AString gm_log;
void atcommand_config_write(ZString cfgName);
-
-#endif // TMWA_MAP_ATCOMMAND_HPP
+} // namespace tmwa
diff --git a/src/map/battle.cpp b/src/map/battle.cpp
index 8e4d435..856408c 100644
--- a/src/map/battle.cpp
+++ b/src/map/battle.cpp
@@ -21,17 +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 <cstring>
+#include <algorithm>
-#include "../compat/alg.hpp"
#include "../compat/nullpo.hpp"
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
+#include "../strings/xstring.hpp"
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/read.hpp"
#include "../mmo/config_parse.hpp"
@@ -47,12 +48,14 @@
#include "../poison.hpp"
+namespace tmwa
+{
static Battle_Config init_battle_config();
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
+DIAG_PUSH();
+DIAG_I(shadow);
struct Battle_Config battle_config = init_battle_config();
-#pragma GCC diagnostic pop
+DIAG_POP();
/*==========================================
* 自分をロックしている対象の数を返す(汎用)
@@ -63,7 +66,7 @@ static
int battle_counttargeted(dumb_ptr<block_list> bl, dumb_ptr<block_list> src,
ATK target_lv)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::PC)
return pc_counttargeted(bl->is_player(), src,
target_lv);
@@ -77,15 +80,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();
}
/*==========================================
@@ -111,7 +114,7 @@ DIR battle_get_dir(dumb_ptr<block_list> bl)
*/
int battle_get_lv(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::MOB)
return bl->is_mob()->stats[mob_stat::LV];
else if (bl->bl_type == BL::PC)
@@ -127,9 +130,9 @@ int battle_get_lv(dumb_ptr<block_list> bl)
*/
int battle_get_range(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(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
@@ -189,7 +192,7 @@ int battle_get_str(dumb_ptr<block_list> bl)
int str = 0;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::MOB)
str = bl->is_mob()->stats[mob_stat::STR];
@@ -212,7 +215,7 @@ int battle_get_agi(dumb_ptr<block_list> bl)
int agi = 0;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::MOB)
agi = bl->is_mob()->stats[mob_stat::AGI];
@@ -234,7 +237,7 @@ int battle_get_vit(dumb_ptr<block_list> bl)
int vit = 0;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::MOB)
vit = bl->is_mob()->stats[mob_stat::VIT];
@@ -256,7 +259,7 @@ int battle_get_int(dumb_ptr<block_list> bl)
int int_ = 0;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::MOB)
int_ = bl->is_mob()->stats[mob_stat::INT];
@@ -278,7 +281,7 @@ int battle_get_dex(dumb_ptr<block_list> bl)
int dex = 0;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::MOB)
dex = bl->is_mob()->stats[mob_stat::DEX];
@@ -300,7 +303,7 @@ int battle_get_luk(dumb_ptr<block_list> bl)
int luk = 0;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::MOB)
luk = bl->is_mob()->stats[mob_stat::LUK];
@@ -466,7 +469,7 @@ int battle_get_atk(dumb_ptr<block_list> bl)
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
int atk = 0;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::PC)
atk = bl->is_player()->watk;
@@ -486,7 +489,7 @@ int battle_get_atk(dumb_ptr<block_list> bl)
static
int battle_get_atk_(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::PC)
return bl->is_player()->watk_;
else
@@ -501,7 +504,7 @@ int battle_get_atk_(dumb_ptr<block_list> bl)
static
int battle_get_atk2(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::PC)
return bl->is_player()->watk2;
else
@@ -524,7 +527,7 @@ int battle_get_atk2(dumb_ptr<block_list> bl)
static
int battle_get_atk_2(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::PC)
return bl->is_player()->watk_2;
else
@@ -540,7 +543,7 @@ static
int battle_get_matk1(dumb_ptr<block_list> bl)
{
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::MOB)
{
@@ -563,7 +566,7 @@ int battle_get_matk1(dumb_ptr<block_list> bl)
static
int battle_get_matk2(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::MOB)
{
int matk, int_ = battle_get_int(bl);
@@ -587,7 +590,7 @@ int battle_get_def(dumb_ptr<block_list> bl)
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
int def = 0;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::PC)
{
@@ -623,7 +626,7 @@ int battle_get_mdef(dumb_ptr<block_list> bl)
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
int mdef = 0;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (bl->bl_type == BL::PC)
mdef = bl->is_player()->mdef;
@@ -685,7 +688,7 @@ int battle_get_mdef2(dumb_ptr<block_list> bl)
{
int mdef2 = 0;
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::MOB)
{
dumb_ptr<mob_data> md = bl->is_mob();
@@ -710,16 +713,16 @@ int battle_get_mdef2(dumb_ptr<block_list> bl)
*/
interval_t battle_get_speed(dumb_ptr<block_list> bl)
{
- nullpo_retr(std::chrono::seconds(1), bl);
+ nullpo_retr(1_s, bl);
if (bl->bl_type == BL::PC)
return bl->is_player()->speed;
else
{
- interval_t speed = std::chrono::seconds(1);
+ interval_t speed = 1_s;
if (bl->bl_type == BL::MOB)
speed = static_cast<interval_t>(bl->is_mob()->stats[mob_stat::SPEED]);
- return std::max(speed, std::chrono::milliseconds(1));
+ return std::max(speed, 1_ms);
}
}
@@ -731,13 +734,13 @@ interval_t battle_get_speed(dumb_ptr<block_list> bl)
// TODO figure out what all the doubling is about
interval_t battle_get_adelay(dumb_ptr<block_list> bl)
{
- nullpo_retr(std::chrono::seconds(4), bl);
+ nullpo_retr(4_s, bl);
if (bl->bl_type == BL::PC)
return bl->is_player()->aspd * 2;
else
{
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data = battle_get_sc_data(bl);
- interval_t adelay = std::chrono::seconds(4);
+ interval_t adelay = 4_s;
int aspd_rate = 100;
if (bl->bl_type == BL::MOB)
adelay = static_cast<interval_t>(bl->is_mob()->stats[mob_stat::ADELAY]);
@@ -759,16 +762,16 @@ interval_t battle_get_adelay(dumb_ptr<block_list> bl)
interval_t battle_get_amotion(dumb_ptr<block_list> bl)
{
- nullpo_retr(std::chrono::seconds(2), bl);
+ nullpo_retr(2_s, bl);
if (bl->bl_type == BL::PC)
return bl->is_player()->amotion;
else
{
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data = battle_get_sc_data(bl);
- interval_t amotion = std::chrono::seconds(2);
+ interval_t amotion = 2_s;
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,14 +792,14 @@ 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)
{
return bl->is_player()->dmotion;
}
else
- return std::chrono::seconds(2);
+ return 2_s;
}
LevelElement battle_get_element(dumb_ptr<block_list> bl)
@@ -810,26 +813,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 +843,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;
}
@@ -883,60 +886,60 @@ eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> battle_
short *battle_get_sc_count(dumb_ptr<block_list> bl)
{
- nullpo_retr(NULL, bl);
+ nullpo_retr(nullptr, bl);
if (bl->bl_type == BL::MOB)
return &bl->is_mob()->sc_count;
else if (bl->bl_type == BL::PC)
return &bl->is_player()->sc_count;
- return NULL;
+ return nullptr;
}
Opt1 *battle_get_opt1(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retn(bl);
if (bl->bl_type == BL::MOB)
return &bl->is_mob()->opt1;
else if (bl->bl_type == BL::PC)
return &bl->is_player()->opt1;
else if (bl->bl_type == BL::NPC)
return &bl->is_npc()->opt1;
- return 0;
+ return nullptr;
}
Opt2 *battle_get_opt2(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retn(bl);
if (bl->bl_type == BL::MOB)
return &bl->is_mob()->opt2;
else if (bl->bl_type == BL::PC)
return &bl->is_player()->opt2;
else if (bl->bl_type == BL::NPC)
return &bl->is_npc()->opt2;
- return 0;
+ return nullptr;
}
Opt3 *battle_get_opt3(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retn(bl);
if (bl->bl_type == BL::MOB)
return &bl->is_mob()->opt3;
else if (bl->bl_type == BL::PC)
return &bl->is_player()->opt3;
else if (bl->bl_type == BL::NPC)
return &bl->is_npc()->opt3;
- return 0;
+ return nullptr;
}
Option *battle_get_option(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retn(bl);
if (bl->bl_type == BL::MOB)
return &bl->is_mob()->option;
else if (bl->bl_type == BL::PC)
return &bl->is_player()->status.option;
else if (bl->bl_type == BL::NPC)
return &bl->is_npc()->option;
- return 0;
+ return nullptr;
}
//-------------------------------------------------------------------
@@ -953,17 +956,17 @@ struct battle_delay_damage_
int battle_damage(dumb_ptr<block_list> bl, dumb_ptr<block_list> target,
int damage, int flag)
{
- nullpo_ret(target); //blはNULLで呼ばれることがあるので他でチェック
+ nullpo_retz(target); //blはNULLで呼ばれることがあるので他でチェック
if (damage == 0)
return 0;
- if (target->bl_prev == NULL)
+ if (target->bl_prev == nullptr)
return 0;
if (bl)
{
- if (bl->bl_prev == NULL)
+ if (bl->bl_prev == nullptr)
return 0;
}
@@ -991,7 +994,7 @@ int battle_damage(dumb_ptr<block_list> bl, dumb_ptr<block_list> target,
int battle_heal(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, int hp,
int sp, int flag)
{
- nullpo_ret(target); //blはNULLで呼ばれることがあるので他でチェック
+ nullpo_retz(target); //blはNULLで呼ばれることがあるので他でチェック
if (target->bl_type == BL::PC
&& pc_isdead(target->is_player()))
@@ -1012,7 +1015,7 @@ int battle_heal(dumb_ptr<block_list> bl, dumb_ptr<block_list> target, int hp,
// 攻撃停止
int battle_stopattack(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::MOB)
return mob_stopattack(bl->is_mob());
else if (bl->bl_type == BL::PC)
@@ -1023,7 +1026,7 @@ int battle_stopattack(dumb_ptr<block_list> bl)
// 移動停止
int battle_stopwalking(dumb_ptr<block_list> bl, int type)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::MOB)
return mob_stop_walking(bl->is_mob(), type);
else if (bl->bl_type == BL::PC)
@@ -1040,9 +1043,9 @@ int battle_calc_damage(dumb_ptr<block_list>, dumb_ptr<block_list> bl,
int damage, int div_,
SkillID, int, BF flag)
{
- dumb_ptr<mob_data> md = NULL;
+ dumb_ptr<mob_data> md = nullptr;
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::MOB)
md = bl->is_mob();
@@ -1059,7 +1062,7 @@ int battle_calc_damage(dumb_ptr<block_list>, dumb_ptr<block_list> bl,
damage = 3;
}
- if (md != NULL && md->hp > 0 && damage > 0) // 反撃などのMOBスキル判定
+ if (md != nullptr && md->hp > 0 && damage > 0) // 反撃などのMOBスキル判定
mobskill_event(md, flag);
return damage;
@@ -1071,8 +1074,8 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src,
SkillID skill_num,
int skill_lv, int)
{
- dumb_ptr<map_session_data> tsd = NULL;
- dumb_ptr<mob_data> md = src->is_mob(), tmd = NULL;
+ dumb_ptr<map_session_data> tsd = nullptr;
+ dumb_ptr<mob_data> md = src->is_mob(), tmd = nullptr;
int hitrate, flee, cri = 0, atkmin, atkmax;
int target_count = 1;
int def1 = battle_get_def(target);
@@ -1143,7 +1146,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)
@@ -1282,7 +1285,7 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src,
damage = 0;
// 完全回避の判定
- if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != NULL
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != nullptr
&& random_::chance({battle_get_flee2(target), 1000}))
{
damage = 0;
@@ -1292,7 +1295,7 @@ struct Damage battle_calc_mob_weapon_attack(dumb_ptr<block_list> src,
if (battle_config.enemy_perfect_flee)
{
- if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != NULL
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != nullptr
&& random_::chance({battle_get_flee2(target), 1000}))
{
damage = 0;
@@ -1327,9 +1330,9 @@ int battle_is_unarmed(dumb_ptr<block_list> bl)
{
dumb_ptr<map_session_data> sd = bl->is_player();
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- return sidx == -1 && widx == -1;
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ return !sidx.ok() && !widx.ok();
}
else
return 0;
@@ -1346,8 +1349,8 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src,
SkillID skill_num,
int skill_lv, int)
{
- dumb_ptr<map_session_data> sd = src->is_player(), tsd = NULL;
- dumb_ptr<mob_data> tmd = NULL;
+ dumb_ptr<map_session_data> sd = src->is_player(), tsd = nullptr;
+ dumb_ptr<mob_data> tmd = nullptr;
int hitrate, flee, cri = 0, atkmin, atkmax;
int dex, target_count = 1;
int def1 = battle_get_def(target);
@@ -1417,9 +1420,9 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src,
int dy = abs(src->bl_y - target->bl_y);
int malus_dist;
- target_distance = max(dx, dy);
+ target_distance = std::max(dx, dy);
malus_dist =
- max(0, target_distance - (skill_power(sd, SkillID::AC_OWL) / 75));
+ std::max(0, target_distance - (skill_power(sd, SkillID::AC_OWL) / 75));
hitrate -= (malus_dist * (malus_dist + 1));
}
@@ -1449,12 +1452,12 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src,
atkmin = atkmin_ = dex; //最低ATKはDEXで初期化?
sd->state.arrow_atk = 0; //arrow_atk初期化
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
- if (widx >= 0 && sd->inventory_data[widx])
+ if (widx.ok() && sd->inventory_data[widx])
atkmin = atkmin * (80 + sd->inventory_data[widx]->wlv * 20) / 100;
- if (sidx >= 0 && sd->inventory_data[sidx])
+ if (sidx.ok() && sd->inventory_data[sidx])
atkmin_ = atkmin_ * (80 + sd->inventory_data[sidx]->wlv * 20) / 100;
if (sd->status.weapon == ItemLook::BOW)
{ //武器が弓矢の場合
@@ -1708,7 +1711,7 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src,
}
// 完全回避の判定
- if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != NULL && div_ < 255
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tsd != nullptr && div_ < 255
&& random_::chance({battle_get_flee2(target), 1000}))
{
damage = damage2 = 0;
@@ -1719,7 +1722,7 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr<block_list> src,
// 対象が完全回避をする設定がONなら
if (battle_config.enemy_perfect_flee)
{
- if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != NULL && div_ < 255
+ if (skill_num == SkillID::ZERO && skill_lv >= 0 && tmd != nullptr && div_ < 255
&& random_::chance({battle_get_flee2(target), 1000}))
{
damage = damage2 = 0;
@@ -1809,7 +1812,7 @@ struct Damage battle_calc_magic_attack(dumb_ptr<block_list> bl,
int matk1, matk2, damage = 0, div_ = 1;
struct Damage md {};
int normalmagic_flag = 1;
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
nullpo_retr(md, bl);
nullpo_retr(md, target);
@@ -1885,7 +1888,7 @@ struct Damage battle_calc_misc_attack(dumb_ptr<block_list> bl,
dumb_ptr<block_list> target,
SkillID skill_num, int skill_lv, int)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
int damage = 0, div_ = 1;
struct Damage md {};
int damagefix = 1;
@@ -1965,7 +1968,7 @@ struct Damage battle_calc_attack(BF attack_type,
flag);
default:
if (battle_config.error_log)
- PRINTF("battle_calc_attack: unknwon attack type ! %d\n",
+ PRINTF("battle_calc_attack: unknwon attack type ! %d\n"_fmt,
attack_type);
break;
}
@@ -1979,7 +1982,7 @@ struct Damage battle_calc_attack(BF attack_type,
ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
tick_t tick)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> t_sc_data = battle_get_sc_data(target);
struct Damage wd;
@@ -1989,7 +1992,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
if (src->bl_type == BL::PC)
sd = src->is_player();
- if (src->bl_prev == NULL || target->bl_prev == NULL)
+ if (src->bl_prev == nullptr || target->bl_prev == nullptr)
return ATK::ZERO;
if (src->bl_type == BL::PC && pc_isdead(sd))
return ATK::ZERO;
@@ -1998,7 +2001,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
return ATK::ZERO;
Opt1 *opt1 = battle_get_opt1(src);
- if (opt1 != NULL && bool(*opt1))
+ if (opt1 != nullptr && bool(*opt1))
{
battle_stopattack(src);
return ATK::ZERO;
@@ -2010,8 +2013,8 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
// 攻撃対象となりうるので攻撃
if (sd && sd->status.weapon == ItemLook::BOW)
{
- int aidx = sd->equip_index_maybe[EQUIP::ARROW];
- if (aidx >= 0)
+ IOff0 aidx = sd->equip_index_maybe[EQUIP::ARROW];
+ if (aidx.ok())
{
if (battle_config.arrow_decrement)
pc_delitem(sd, aidx, 1, 0);
@@ -2040,7 +2043,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
wd.damage -= reduction;
MAP_LOG_PC(target->is_player(),
- "MAGIC-ABSORB-DMG %d", reduction);
+ "MAGIC-ABSORB-DMG %d"_fmt, reduction);
}
{
@@ -2050,7 +2053,7 @@ ATK battle_weapon_attack(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
&& (sd->status.weapon == ItemLook::_16
|| sd->status.weapon >= ItemLook::SINGLE_HANDED_COUNT)
&& wd.damage2 == 0)
- clif_damage(src, target, tick + std::chrono::milliseconds(10),
+ clif_damage(src, target, tick + 10_ms,
wd.amotion, wd.dmotion, 0, 1, DamageType::NORMAL, 0);
}
@@ -2058,37 +2061,37 @@ 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;
- if (weapon_index >= 0 && sd->inventory_data[weapon_index]
+ IOff0 weapon_index = sd->equip_index_maybe[EQUIP::WEAPON];
+ ItemNameId weapon;
+ if (weapon_index.ok() && sd->inventory_data[weapon_index]
&& bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON))
weapon = sd->inventory_data[weapon_index]->nameid;
- MAP_LOG("PC%d %s:%d,%d WPNDMG %s%d %d FOR %d WPN %d",
- sd->status_key.char_id, src->bl_m->name_, src->bl_x, src->bl_y,
- (target->bl_type == BL::PC) ? "PC" : "MOB",
- (target->bl_type == BL::PC)
- ? target->is_player()-> status_key.char_id
- : target->bl_id,
- battle_get_class(target),
- wd.damage + wd.damage2, weapon);
+ MAP_LOG("PC%d %s:%d,%d WPNDMG %s%d %d FOR %d WPN %d"_fmt,
+ 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)
+ ? unwrap<CharId>(target->is_player()->status_key.char_id)
+ : unwrap<BlockId>(target->bl_id),
+ battle_get_class(target),
+ wd.damage + wd.damage2, weapon);
}
if (target->bl_type == BL::PC)
{
dumb_ptr<map_session_data> sd2 = target->is_player();
- MAP_LOG("PC%d %s:%d,%d WPNINJURY %s%d %d FOR %d",
- sd2->status_key.char_id, target->bl_m->name_, target->bl_x, target->bl_y,
- (src->bl_type == BL::PC) ? "PC" : "MOB",
- (src->bl_type == BL::PC)
- ? src->is_player()->status_key.char_id
- : src->bl_id,
- battle_get_class(src),
- wd.damage + wd.damage2);
+ MAP_LOG("PC%d %s:%d,%d WPNINJURY %s%d %d FOR %d"_fmt,
+ 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)
+ ? unwrap<CharId>(src->is_player()->status_key.char_id)
+ : unwrap<BlockId>(src->bl_id),
+ battle_get_class(src),
+ wd.damage + wd.damage2);
}
battle_damage(src, target, (wd.damage + wd.damage2), 0);
- if (target->bl_prev != NULL &&
+ if (target->bl_prev != nullptr &&
(target->bl_type != BL::PC
|| (target->bl_type == BL::PC
&& !pc_isdead(target->is_player()))))
@@ -2161,11 +2164,11 @@ 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);
- nullpo_ret(target);
+ nullpo_retz(src);
+ nullpo_retz(target);
if (flag & BCT_ENEMY)
{ // 反転フラグ
@@ -2191,7 +2194,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;
@@ -2214,7 +2217,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
}
}
}
- if ((ss = map_id2bl(md->master_id)) == NULL)
+ if ((ss = map_id2bl(md->master_id)) == nullptr)
return -1;
}
}
@@ -2226,7 +2229,7 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
&& pc_isinvisible(target->is_player()))
return -1;
- if (src->bl_prev == NULL || // 死んでるならエラー
+ if (src->bl_prev == nullptr || // 死んでるならエラー
(src->bl_type == BL::PC && pc_isdead(src->is_player())))
return -1;
@@ -2246,9 +2249,6 @@ int battle_check_target(dumb_ptr<block_list> src, dumb_ptr<block_list> target,
return 0;
}
-//PRINTF("ss:%d src:%d target:%d flag:0x%x %d %d ",ss->bl_id,src->bl_id,target->bl_id,flag,src->bl_type,target->bl_type);
-//PRINTF("p:%d %d g:%d %d\n",s_p,t_p,s_g,t_g);
-
if (ss->bl_type == BL::PC && target->bl_type == BL::PC)
{ // 両方PVPモードなら否定(敵)
if (ss->bl_m->flag.get(MapFlag::PVP)
@@ -2256,7 +2256,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;
@@ -2278,8 +2278,8 @@ int battle_check_range(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
struct walkpath_data wpd;
int arange;
- nullpo_ret(src);
- nullpo_ret(bl);
+ nullpo_retz(src);
+ nullpo_retz(bl);
dx = abs(bl->bl_x - src->bl_x);
dy = abs(bl->bl_y - src->bl_y);
@@ -2313,10 +2313,10 @@ int battle_check_range(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
Battle_Config init_battle_config()
{
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
+ DIAG_PUSH();
+ DIAG_I(shadow);
Battle_Config battle_config;
-#pragma GCC diagnostic pop
+ DIAG_POP();
{
battle_config.warp_point_debug = 0;
battle_config.enemy_critical = 0;
@@ -2430,17 +2430,17 @@ bool battle_config_read(ZString cfgName)
io::ReadFile in(cfgName);
if (!in.is_open())
{
- PRINTF("file not found: %s\n", cfgName);
+ PRINTF("file not found: %s\n"_fmt, cfgName);
return false;
}
AString line;
while (in.getline(line))
{
-#define BATTLE_CONFIG_VAR(name) {{#name}, &battle_config.name}
+#define BATTLE_CONFIG_VAR(name) {#name##_s, &battle_config.name}
const struct
{
- ZString str;
+ LString str;
int *val;
} data[] =
{
@@ -2550,12 +2550,12 @@ bool battle_config_read(ZString cfgName)
ZString w2;
if (!config_split(line, &w1, &w2))
{
- PRINTF("Bad config line: %s\n", line);
+ PRINTF("Bad config line: %s\n"_fmt, line);
rv = false;
continue;
}
- if (w1 == "import")
+ if (w1 == "import"_s)
{
battle_config_read(w2);
continue;
@@ -2568,7 +2568,7 @@ bool battle_config_read(ZString cfgName)
goto continue_outer;
}
- PRINTF("WARNING: unknown battle conf key: %s\n", AString(w1));
+ PRINTF("WARNING: unknown battle conf key: %s\n"_fmt, AString(w1));
rv = false;
continue_outer:
@@ -2581,7 +2581,7 @@ bool battle_config_read(ZString cfgName)
void battle_config_check()
{
{
- if (static_cast<interval_t>(battle_config.flooritem_lifetime) < std::chrono::seconds(1))
+ if (static_cast<interval_t>(battle_config.flooritem_lifetime) < 1_s)
battle_config.flooritem_lifetime = std::chrono::duration_cast<std::chrono::milliseconds>(LIFETIME_FLOORITEM).count();
if (battle_config.restart_hp_rate < 0)
battle_config.restart_hp_rate = 0;
@@ -2686,3 +2686,4 @@ void battle_config_check()
battle_config.mask_ip_gms = 1;
}
}
+} // namespace tmwa
diff --git a/src/map/battle.hpp b/src/map/battle.hpp
index b8060a9..97a4a86 100644
--- a/src/map/battle.hpp
+++ b/src/map/battle.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_BATTLE_HPP
-#define TMWA_MAP_BATTLE_HPP
+#pragma once
// battle.hpp - Not so scary code.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,18 +20,23 @@
// 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"
+#include "battle.t.hpp"
-# include "../strings/fwd.hpp"
+#include "../strings/fwd.hpp"
-# include "../mmo/timer.t.hpp"
+#include "../generic/fwd.hpp"
-# include "magic-interpreter.t.hpp"
-# include "map.t.hpp"
-# include "skill.t.hpp"
+#include "../net/timer.t.hpp"
+#include "clif.t.hpp"
+#include "map.t.hpp"
+#include "skill.t.hpp"
+
+
+namespace tmwa
+{
// ダメージ
struct Damage
{
@@ -44,10 +48,6 @@ struct Damage
ATK dmg_lv;
};
-struct map_session_data;
-struct mob_data;
-struct block_list;
-
// ダメージ計算
struct Damage battle_calc_attack(BF attack_type,
@@ -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);
@@ -225,5 +225,4 @@ extern struct Battle_Config
bool battle_config_read(ZString cfgName);
void battle_config_check();
-
-#endif // TMWA_MAP_BATTLE_HPP
+} // namespace tmwa
diff --git a/src/map/battle.t.hpp b/src/map/battle.t.hpp
index 9685ae7..53c34ff 100644
--- a/src/map/battle.t.hpp
+++ b/src/map/battle.t.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_BATTLE_T_HPP
-#define TMWA_MAP_BATTLE_T_HPP
+#pragma once
// battle.t.hpp - Not so scary code.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,10 +20,15 @@
// 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"
+#include <cstdint>
+#include "../generic/enum.hpp"
+
+
+namespace tmwa
+{
namespace e
{
enum class BF : uint16_t
@@ -65,11 +69,11 @@ struct BCT
};
constexpr
-BCT operator & (BCT l, BCT r) { return {uint8_t(l.lo & r.lo), uint8_t(l.mid & r.mid), uint8_t(l.classic & r.classic), uint8_t(l.level & r.level), uint8_t(l.unused & r.unused) }; }
+BCT operator & (BCT l, BCT r) { return {static_cast<uint8_t>(l.lo & r.lo), static_cast<uint8_t>(l.mid & r.mid), static_cast<uint8_t>(l.classic & r.classic), static_cast<uint8_t>(l.level & r.level), static_cast<uint8_t>(l.unused & r.unused) }; }
constexpr
-BCT operator | (BCT l, BCT r) { return {uint8_t(l.lo | r.lo), uint8_t(l.mid | r.mid), uint8_t(l.classic | r.classic), uint8_t(l.level | r.level), uint8_t(l.unused | r.unused) }; }
+BCT operator | (BCT l, BCT r) { return {static_cast<uint8_t>(l.lo | r.lo), static_cast<uint8_t>(l.mid | r.mid), static_cast<uint8_t>(l.classic | r.classic), static_cast<uint8_t>(l.level | r.level), static_cast<uint8_t>(l.unused | r.unused) }; }
constexpr
-BCT operator ^ (BCT l, BCT r) { return {uint8_t(l.lo ^ r.lo), uint8_t(l.mid ^ r.mid), uint8_t(l.classic ^ r.classic), uint8_t(l.level ^ r.level), uint8_t(l.unused ^ r.unused) }; }
+BCT operator ^ (BCT l, BCT r) { return {static_cast<uint8_t>(l.lo ^ r.lo), static_cast<uint8_t>(l.mid ^ r.mid), static_cast<uint8_t>(l.classic ^ r.classic), static_cast<uint8_t>(l.level ^ r.level), static_cast<uint8_t>(l.unused ^ r.unused) }; }
inline
BCT& operator &= (BCT& l, BCT r) { return l = l & r; }
inline
@@ -237,15 +241,4 @@ earray<Races, Race, Race::COUNT> race_shift //=
Races::boss,
Races::other,
}};
-
-enum class DamageType : uint8_t
-{
- NORMAL = 0x00,
- TAKEITEM = 0x01,
- RETURNED = 0x04,
- DOUBLED = 0x08,
- CRITICAL = 0x0a,
- FLEE2 = 0x0b,
-};
-
-#endif // TMWA_MAP_BATTLE_T_HPP
+} // namespace tmwa
diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp
index fa95be7..0748f43 100644
--- a/src/map/chrif.cpp
+++ b/src/map/chrif.cpp
@@ -20,10 +20,6 @@
// 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 <arpa/inet.h>
-
-#include <cstring>
-
#include "../compat/fun.hpp"
#include "../compat/nullpo.hpp"
@@ -32,8 +28,15 @@
#include "../io/cxxstdio.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../net/ip.hpp"
+#include "../net/packets.hpp"
+#include "../net/socket.hpp"
+#include "../net/timer.hpp"
+
+#include "../proto2/char-map.hpp"
+
+#include "../mmo/human_time_diff.hpp"
+#include "../mmo/mmo.hpp"
#include "../mmo/utils.hpp"
#include "battle.hpp"
@@ -47,15 +50,9 @@
#include "../poison.hpp"
-static
-const int packet_len_table[0x20] =
-{
- 60, 3, 10, 27, 22, -1, 6, -1, // 2af8-2aff
- 6, -1, 18, 7, -1, 49, 44, 0, // 2b00-2b07
- 6, 30, -1, 10, 86, 7, 44, 34, // 2b08-2b0f
- -1, -1, 10, 6, 11, -1, 0, 0, // 2b10-2b17
-};
+namespace tmwa
+{
Session *char_session;
static
IP4Address char_ip;
@@ -132,13 +129,12 @@ int chrif_save(dumb_ptr<map_session_data> sd)
pc_makesavestatus(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;
- 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));
+ Packet_Payload<0x2b01> payload_01;
+ payload_01.account_id = block_to_account(sd->bl_id);
+ payload_01.char_id = sd->char_id_;
+ payload_01.char_key = sd->status_key;
+ payload_01.char_data = sd->status;
+ send_ppacket<0x2b01>(char_session, payload_01);
//For data sync
if (sd->state.storage_open)
@@ -154,13 +150,13 @@ int chrif_save(dumb_ptr<map_session_data> sd)
static
int chrif_connect(Session *s)
{
- WFIFOW(s, 0) = 0x2af8;
- WFIFO_STRING(s, 2, userid, 24);
- WFIFO_STRING(s, 26, passwd, 24);
- WFIFOL(s, 50) = 0;
- WFIFOIP(s, 54) = clif_getip();
- WFIFOW(s, 58) = clif_getport(); // [Valaris] thanks to fov
- WFIFOSET(s, 60);
+ Packet_Fixed<0x2af8> fixed_f8;
+ fixed_f8.account_name = userid;
+ fixed_f8.account_pass = passwd;
+ fixed_f8.unused = 0;
+ fixed_f8.ip = clif_getip();
+ fixed_f8.port = clif_getport();
+ send_fpacket<0x2af8, 60>(s, fixed_f8);
return 0;
}
@@ -172,19 +168,17 @@ int chrif_connect(Session *s)
static
int chrif_sendmap(Session *s)
{
- int i = 0;
-
- WFIFOW(s, 0) = 0x2afa;
+ std::vector<Packet_Repeat<0x2afa>> repeat_fa;
for (auto& pair : maps_db)
{
map_abstract *ma = pair.second.get();
if (!ma->gat)
continue;
- WFIFO_STRING(s, 4 + i * 16, ma->name_, 16);
- i++;
+ Packet_Repeat<0x2afa> info;
+ info.map_name = ma->name_;
+ repeat_fa.push_back(info);
}
- WFIFOW(s, 2) = 4 + i * 16;
- WFIFOSET(s, WFIFOW(s, 2));
+ send_packet_repeatonly<0x2afa, 4, 16>(s, repeat_fa);
return 0;
}
@@ -194,23 +188,21 @@ int chrif_sendmap(Session *s)
*------------------------------------------
*/
static
-int chrif_recvmap(Session *s)
+int chrif_recvmap(Session *, Packet_Head<0x2b04> head, const std::vector<Packet_Repeat<0x2b04>>& repeat)
{
- int i, j;
-
if (chrif_state < 2) // まだ準備中
return -1;
- IP4Address ip = RFIFOIP(s, 4);
- uint16_t port = RFIFOW(s, 8);
- for (i = 10, j = 0; i < RFIFOW(s, 2); i += 16, j++)
+ IP4Address ip = head.ip;
+ uint16_t port = head.port;
+ for (const Packet_Repeat<0x2b04>& i : repeat)
{
- MapName map = RFIFO_STRING<16>(s, i);
+ MapName map = i.map_name;
map_setipport(map, ip, port);
}
if (battle_config.etc_log)
- PRINTF("recv map on %s:%d (%d maps)\n",
- ip, port, j);
+ PRINTF("recv map on %s:%d (%zu maps)\n"_fmt,
+ ip, port, repeat.size());
return 0;
}
@@ -224,6 +216,9 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd,
{
nullpo_retr(-1, sd);
+ if (!char_session)
+ return -1;
+
IP4Address s_ip;
for (io::FD i : iter_fds())
{
@@ -238,19 +233,19 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd,
}
}
- WFIFOW(char_session, 0) = 0x2b05;
- WFIFOL(char_session, 2) = 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;
- WFIFO_STRING(char_session, 18, name, 16);
- WFIFOW(char_session, 34) = x;
- WFIFOW(char_session, 36) = y;
- WFIFOIP(char_session, 38) = ip;
- WFIFOL(char_session, 42) = port;
- WFIFOB(char_session, 44) = static_cast<uint8_t>(sd->status.sex);
- WFIFOIP(char_session, 45) = s_ip;
- WFIFOSET(char_session, 49);
+ Packet_Fixed<0x2b05> fixed_05;
+ fixed_05.account_id = block_to_account(sd->bl_id);
+ fixed_05.login_id1 = sd->login_id1;
+ fixed_05.login_id2 = sd->login_id2;
+ fixed_05.char_id = sd->status_key.char_id;
+ fixed_05.map_name = name;
+ fixed_05.x = x;
+ fixed_05.y = y;
+ fixed_05.map_ip = ip;
+ fixed_05.map_port = port;
+ fixed_05.sex = sd->status.sex;
+ fixed_05.client_ip = s_ip;
+ send_fpacket<0x2b05, 49>(char_session, fixed_05);
return 0;
}
@@ -260,25 +255,26 @@ int chrif_changemapserver(dumb_ptr<map_session_data> sd,
*------------------------------------------
*/
static
-int chrif_changemapserverack(Session *s)
+int chrif_changemapserverack(Session *, const Packet_Fixed<0x2b06>& fixed)
{
- dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 2));
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(fixed.account_id));
- if (sd == NULL || sd->status_key.char_id != RFIFOL(s, 14))
+ if (sd == nullptr || sd->status_key.char_id != fixed.char_id)
return -1;
- if (RFIFOL(s, 6) == 1)
+ // I am fairly certain that this is not possible
+ if (fixed.error == 1)
{
if (battle_config.error_log)
- PRINTF("map server change failed.\n");
+ PRINTF("map server change failed.\n"_fmt);
pc_authfail(sd->status_key.account_id);
return 0;
}
- MapName mapname = RFIFO_STRING<16>(s, 18);
- uint16_t x = RFIFOW(s, 34);
- uint16_t y = RFIFOW(s, 36);
- IP4Address ip = RFIFOIP(s, 38);
- uint16_t port = RFIFOW(s, 42);
+ MapName mapname = fixed.map_name;
+ uint16_t x = fixed.x;
+ uint16_t y = fixed.y;
+ IP4Address ip = fixed.map_ip;
+ uint16_t port = fixed.map_port;
clif_changemapserver(sd, mapname, x, y, ip, port);
return 0;
@@ -289,25 +285,22 @@ int chrif_changemapserverack(Session *s)
*------------------------------------------
*/
static
-int chrif_connectack(Session *s)
+int chrif_connectack(Session *s, const Packet_Fixed<0x2af9>& fixed)
{
- if (RFIFOB(s, 2))
+ if (fixed.code)
{
- PRINTF("Connected to char-server failed %d.\n", RFIFOB(s, 2));
+ PRINTF("Connected to char-server failed %d.\n"_fmt, fixed.code);
exit(1);
}
- PRINTF("Connected to char-server (connection #%d).\n", s);
+ PRINTF("Connected to char-server (connection #%d).\n"_fmt, s);
chrif_state = 1;
chrif_sendmap(s);
- PRINTF("chrif: OnCharIfInit event done. (%d events)\n",
- npc_event_doall(stringish<ScriptLabel>("OnCharIfInit")));
- PRINTF("chrif: OnInterIfInit event done. (%d events)\n",
- npc_event_doall(stringish<ScriptLabel>("OnInterIfInit")));
-
- // <Agit> Run Event [AgitInit]
-// PRINTF("NPC_Event:[OnAgitInit] do (%d) events (Agit Initialize).\n", npc_event_doall("OnAgitInit"));
+ PRINTF("chrif: OnCharIfInit event done. (%d events)\n"_fmt,
+ npc_event_doall(stringish<ScriptLabel>("OnCharIfInit"_s)));
+ PRINTF("chrif: OnInterIfInit event done. (%d events)\n"_fmt,
+ npc_event_doall(stringish<ScriptLabel>("OnInterIfInit"_s)));
return 0;
}
@@ -317,16 +310,16 @@ int chrif_connectack(Session *s)
*------------------------------------------
*/
static
-int chrif_sendmapack(Session *s)
+int chrif_sendmapack(Session *, Packet_Fixed<0x2afb> fixed)
{
- if (RFIFOB(s, 2))
+ if (fixed.unknown) //impossible
{
- PRINTF("chrif : send map list to char server failed %d\n",
- RFIFOB(s, 2));
+ PRINTF("chrif : send map list to char server failed %d\n"_fmt,
+ fixed.unknown);
exit(1);
}
- wisp_server_name = stringish<CharName>(RFIFO_STRING<24>(s, 3));
+ wisp_server_name = fixed.whisper_name;
chrif_state = 2;
@@ -352,13 +345,13 @@ int chrif_authreq(dumb_ptr<map_session_data> sd)
if (dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get())) == 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, 10) = sd->login_id1;
- WFIFOL(char_session, 14) = sd->login_id2;
- WFIFOIP(char_session, 18) = s->client_ip;
- WFIFOSET(char_session, 22);
+ Packet_Fixed<0x2afc> fixed_fc;
+ fixed_fc.account_id = block_to_account(sd->bl_id);
+ fixed_fc.char_id = sd->char_id_;
+ fixed_fc.login_id1 = sd->login_id1;
+ fixed_fc.login_id2 = sd->login_id2;
+ fixed_fc.ip = s->client_ip;
+ send_fpacket<0x2afc, 22>(char_session, fixed_fc);
break;
}
}
@@ -391,12 +384,12 @@ int chrif_charselectreq(dumb_ptr<map_session_data> sd)
}
}
- WFIFOW(char_session, 0) = 0x2b02;
- WFIFOL(char_session, 2) = sd->bl_id;
- WFIFOL(char_session, 6) = sd->login_id1;
- WFIFOL(char_session, 10) = sd->login_id2;
- WFIFOIP(char_session, 14) = s_ip;
- WFIFOSET(char_session, 18);
+ Packet_Fixed<0x2b02> fixed_02;
+ fixed_02.account_id = block_to_account(sd->bl_id);
+ fixed_02.login_id1 = sd->login_id1;
+ fixed_02.login_id2 = sd->login_id2;
+ fixed_02.ip = s_ip;
+ send_fpacket<0x2b02, 18>(char_session, fixed_02);
return 0;
}
@@ -405,35 +398,38 @@ 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 (!char_session)
+ return;
+
if (battle_config.etc_log)
- PRINTF("chrif_changegm: account: %d, password: '%s'.\n", id, pass);
-
- size_t len = pass.size() + 1;
- WFIFOW(char_session, 0) = 0x2b0a;
- WFIFOW(char_session, 2) = len + 8;
- WFIFOL(char_session, 4) = id;
- WFIFO_STRING(char_session, 8, pass, len);
- WFIFOSET(char_session, len + 8);
+ PRINTF("chrif_changegm: account: %d, password: '%s'.\n"_fmt, id, pass);
+
+ Packet_Head<0x2b0a> head_0a;
+ head_0a.account_id = id;
+ send_vpacket<0x2b0a, 8, 1>(char_session, head_0a, pass);
}
/*==========================================
* Change Email
*------------------------------------------
*/
-void chrif_changeemail(int id, AccountEmail actual_email,
+void chrif_changeemail(AccountId id, AccountEmail actual_email,
AccountEmail new_email)
{
+ if (!char_session)
+ return;
+
if (battle_config.etc_log)
- PRINTF("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n",
- id, actual_email, new_email);
-
- WFIFOW(char_session, 0) = 0x2b0c;
- WFIFOL(char_session, 2) = id;
- WFIFO_STRING(char_session, 6, actual_email, 40);
- WFIFO_STRING(char_session, 46, new_email, 40);
- WFIFOSET(char_session, 86);
+ PRINTF("chrif_changeemail: account: %d, actual_email: '%s', new_email: '%s'.\n"_fmt,
+ id, actual_email, new_email);
+
+ Packet_Fixed<0x2b0c> fixed_0c;
+ fixed_0c.account_id = id;
+ fixed_0c.old_email = actual_email;
+ fixed_0c.new_email = new_email;
+ send_fpacket<0x2b0c, 86>(char_session, fixed_0c);
}
/*==========================================
@@ -447,17 +443,20 @@ 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
- WFIFO_STRING(char_session, 6, character_name.to__actual(), 24);
- WFIFOW(char_session, 30) = operation_type; // type of operation
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x2b0e> fixed_0e;
+ fixed_0e.account_id = id; // who ask, or nobody
+ fixed_0e.char_name = character_name;
+ fixed_0e.operation = operation_type; // type of operation
if (operation_type == 2)
- WFIFO_STRUCT(char_session, 32, modif);
- PRINTF("chrif : sended 0x2b0e\n");
- WFIFOSET(char_session, 44);
+ fixed_0e.ban_add = modif;
+ PRINTF("chrif : sended 0x2b0e\n"_fmt);
+ send_fpacket<0x2b0e, 44>(char_session, fixed_0e);
}
/*==========================================
@@ -477,123 +476,123 @@ void chrif_char_ask_name(int id, CharName character_name, short operation_type,
*------------------------------------------
*/
static
-int chrif_char_ask_name_answer(Session *s)
+int chrif_char_ask_name_answer(Session *, const Packet_Fixed<0x2b0f>& fixed)
{
- int acc = RFIFOL(s, 2); // account_id of who has asked (-1 if nobody)
- CharName player_name = stringish<CharName>(RFIFO_STRING<24>(s, 6));
+ AccountId acc = fixed.account_id; // who asked, or nobody
+ CharName player_name = fixed.char_name;
- 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 != nullptr)
{
AString output;
- if (RFIFOW(s, 32) == 1) // player not found
- output = STRPRINTF("The player '%s' doesn't exist.",
+ if (fixed.error == 1) // player not found
+ output = STRPRINTF("The player '%s' doesn't exist."_fmt,
player_name);
else
{
- switch (RFIFOW(s, 30))
+ switch (fixed.operation)
{
case 1: // block
- switch (RFIFOW(s, 32))
+ switch (fixed.error)
{
case 0: // login-server resquest done
output = STRPRINTF(
- "Login-server has been asked to block the player '%s'.",
+ "Login-server has been asked to block the player '%s'."_fmt,
player_name);
break;
//case 1: // player not found
case 2: // gm level too low
output = STRPRINTF(
- "Your GM level don't authorise you to block the player '%s'.",
+ "Your GM level don't authorise you to block the player '%s'."_fmt,
player_name);
break;
case 3: // login-server offline
output = STRPRINTF(
- "Login-server is offline. Impossible to block the the player '%s'.",
+ "Login-server is offline. Impossible to block the the player '%s'."_fmt,
player_name);
break;
}
break;
case 2: // ban
- switch (RFIFOW(s, 32))
+ switch (fixed.error)
{
case 0: // login-server resquest done
output = STRPRINTF(
- "Login-server has been asked to ban the player '%s'.",
+ "Login-server has been asked to ban the player '%s'."_fmt,
player_name);
break;
//case 1: // player not found
case 2: // gm level too low
output = STRPRINTF(
- "Your GM level don't authorise you to ban the player '%s'.",
+ "Your GM level don't authorise you to ban the player '%s'."_fmt,
player_name);
break;
case 3: // login-server offline
output = STRPRINTF(
- "Login-server is offline. Impossible to ban the the player '%s'.",
+ "Login-server is offline. Impossible to ban the the player '%s'."_fmt,
player_name);
break;
}
break;
case 3: // unblock
- switch (RFIFOW(s, 32))
+ switch (fixed.error)
{
case 0: // login-server resquest done
output = STRPRINTF(
- "Login-server has been asked to unblock the player '%s'.",
+ "Login-server has been asked to unblock the player '%s'."_fmt,
player_name);
break;
//case 1: // player not found
case 2: // gm level too low
output = STRPRINTF(
- "Your GM level don't authorise you to unblock the player '%s'.",
+ "Your GM level don't authorise you to unblock the player '%s'."_fmt,
player_name);
break;
case 3: // login-server offline
output = STRPRINTF(
- "Login-server is offline. Impossible to unblock the the player '%s'.",
+ "Login-server is offline. Impossible to unblock the the player '%s'."_fmt,
player_name);
break;
}
break;
case 4: // unban
- switch (RFIFOW(s, 32))
+ switch (fixed.error)
{
case 0: // login-server resquest done
output = STRPRINTF(
- "Login-server has been asked to unban the player '%s'.",
+ "Login-server has been asked to unban the player '%s'."_fmt,
player_name);
break;
//case 1: // player not found
case 2: // gm level too low
output = STRPRINTF(
- "Your GM level don't authorise you to unban the player '%s'.",
+ "Your GM level don't authorise you to unban the player '%s'."_fmt,
player_name);
break;
case 3: // login-server offline
output = STRPRINTF(
- "Login-server is offline. Impossible to unban the the player '%s'.",
+ "Login-server is offline. Impossible to unban the the player '%s'."_fmt,
player_name);
break;
}
break;
case 5: // changesex
- switch (RFIFOW(s, 32))
+ switch (fixed.error)
{
case 0: // login-server resquest done
output = STRPRINTF(
- "Login-server has been asked to change the sex of the player '%s'.",
+ "Login-server has been asked to change the sex of the player '%s'."_fmt,
player_name);
break;
//case 1: // player not found
case 2: // gm level too low
output = STRPRINTF(
- "Your GM level don't authorise you to change the sex of the player '%s'.",
+ "Your GM level don't authorise you to change the sex of the player '%s'."_fmt,
player_name);
break;
case 3: // login-server offline
output = STRPRINTF(
- "Login-server is offline. Impossible to change the sex of the the player '%s'.",
+ "Login-server is offline. Impossible to change the sex of the the player '%s'."_fmt,
player_name);
break;
}
@@ -604,7 +603,7 @@ int chrif_char_ask_name_answer(Session *s)
clif_displaymessage(sd->sess, output);
}
else
- PRINTF("chrif_char_ask_name_answer failed - player not online.\n");
+ PRINTF("chrif_char_ask_name_answer failed - player not online.\n"_fmt);
return 0;
}
@@ -614,25 +613,22 @@ int chrif_char_ask_name_answer(Session *s)
*------------------------------------------
*/
static
-void chrif_changedgm(Session *s)
+void chrif_changedgm(Session *, const Packet_Fixed<0x2b0b>& fixed)
{
- int acc, level;
- dumb_ptr<map_session_data> sd = NULL;
-
- acc = RFIFOL(s, 2);
- level = RFIFOL(s, 6);
+ AccountId acc = fixed.account_id;
+ GmLevel level = fixed.gm_level;
- 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", acc,
+ PRINTF("chrif_changedgm: account: %d, GM level 0 -> %d.\n"_fmt, acc,
level);
- if (sd != NULL)
+ if (sd != nullptr)
{
- if (level > 0)
- clif_displaymessage(sd->sess, "GM modification success.");
+ if (level)
+ clif_displaymessage(sd->sess, "GM modification success."_s);
else
- clif_displaymessage(sd->sess, "Failure of GM modification.");
+ clif_displaymessage(sd->sess, "Failure of GM modification."_s);
}
}
@@ -641,26 +637,25 @@ void chrif_changedgm(Session *s)
*------------------------------------------
*/
static
-void chrif_changedsex(Session *s)
+void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed)
{
- int acc, i;
dumb_ptr<map_session_data> sd;
- acc = RFIFOL(s, 2);
- SEX sex = static_cast<SEX>(RFIFOB(s, 6));
+ AccountId acc = fixed.account_id;
+ SEX sex = fixed.sex;
if (battle_config.etc_log)
- PRINTF("chrif_changedsex %d.\n", acc);
- sd = map_id2sd(acc);
- if (acc > 0)
+ PRINTF("chrif_changedsex %d.\n"_fmt, acc);
+ sd = map_id2sd(account_to_block(acc));
+ if (acc)
{
- if (sd != NULL && sd->status.sex != sex)
+ if (sd != nullptr && sd->status.sex != sex)
{
if (sd->status.sex == SEX::MALE)
sd->sex = sd->status.sex = SEX::FEMALE;
else if (sd->status.sex == SEX::FEMALE)
sd->sex = sd->status.sex = SEX::MALE;
// to avoid any problem with equipment and invalid sex, equipment is unequiped.
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid
&& bool(sd->status.inventory[i].equip))
@@ -671,15 +666,15 @@ void chrif_changedsex(Session *s)
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
// do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it)
clif_displaymessage(sd->sess,
- "Your sex has been changed (need disconexion by the server)...");
+ "Your sex has been changed (need disconexion by the server)..."_s);
clif_setwaitclose(sd->sess); // forced to disconnect for the change
}
}
else
{
- if (sd != NULL)
+ if (sd != nullptr)
{
- PRINTF("chrif_changedsex failed.\n");
+ PRINTF("chrif_changedsex failed.\n"_fmt);
}
}
}
@@ -690,24 +685,27 @@ void chrif_changedsex(Session *s)
*/
int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd)
{
- int p, j;
nullpo_retr(-1, sd);
- p = 8;
- for (j = 0; j < sd->status.account_reg2_num; j++)
+ if (!char_session)
+ return -1;
+
+ std::vector<Packet_Repeat<0x2b10>> repeat_10;
+ for (size_t j = 0; j < sd->status.account_reg2_num; j++)
{
- struct global_reg *reg = &sd->status.account_reg2[j];
+ GlobalReg *reg = &sd->status.account_reg2[j];
if (reg->str && reg->value != 0)
{
- WFIFO_STRING(char_session, p, reg->str, 32);
- WFIFOL(char_session, p + 32) = reg->value;
- p += 36;
+ Packet_Repeat<0x2b10> info;
+ info.name = reg->str;
+ info.value = reg->value;
+ repeat_10.push_back(info);
}
}
- WFIFOW(char_session, 0) = 0x2b10;
- WFIFOW(char_session, 2) = p;
- WFIFOL(char_session, 4) = sd->bl_id;
- WFIFOSET(char_session, p);
+
+ Packet_Head<0x2b10> head_10;
+ head_10.account_id = block_to_account(sd->bl_id);
+ send_vpacket<0x2b10, 8, 36>(char_session, head_10, repeat_10);
return 0;
}
@@ -717,20 +715,19 @@ int chrif_saveaccountreg2(dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-int chrif_accountreg2(Session *s)
+int chrif_accountreg2(Session *, const Packet_Head<0x2b11>& head, const std::vector<Packet_Repeat<0x2b11>>& repeat)
{
- int j, p;
- dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 4));
- if (sd == NULL)
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(head.account_id));
+ if (sd == nullptr)
return 1;
- for (p = 8, j = 0; p < RFIFOW(s, 2) && j < ACCOUNT_REG2_NUM;
- p += 36, j++)
+ size_t jlim = std::min(ACCOUNT_REG2_NUM, repeat.size());
+ for (size_t j = 0; j < jlim; j++)
{
- sd->status.account_reg2[j].str = stringish<VarName>(RFIFO_STRING<32>(s, p));
- sd->status.account_reg2[j].value = RFIFOL(s, p + 32);
+ sd->status.account_reg2[j].str = repeat[j].name;
+ sd->status.account_reg2[j].value = repeat[j].value;
}
- sd->status.account_reg2_num = j;
+ sd->status.account_reg2_num = jlim;
return 0;
}
@@ -742,9 +739,9 @@ 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;
+ dumb_ptr<map_session_data> sd = nullptr;
if (!char_id || !partner_id)
return 0;
@@ -752,7 +749,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)
{
@@ -762,9 +759,9 @@ int chrif_divorce(int char_id, int partner_id)
}
sd = map_nick2sd(map_charid2nick(partner_id));
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.partner_id == char_id)
- sd->status.partner_id = 0;
+ sd->status.partner_id = CharId();
return 0;
}
@@ -774,14 +771,14 @@ 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;
- WFIFOSET(char_session, 6);
+ Packet_Fixed<0x2b16> fixed_16;
+ fixed_16.char_id = char_id;
+ send_fpacket<0x2b16, 6>(char_session, fixed_16);
return 0;
}
@@ -790,29 +787,28 @@ int chrif_send_divorce(int char_id)
*------------------------------------------
*/
static
-int chrif_accountdeletion(Session *s)
+int chrif_accountdeletion(Session *, const Packet_Fixed<0x2b13>& fixed)
{
- int acc;
dumb_ptr<map_session_data> sd;
- acc = RFIFOL(s, 2);
+ AccountId acc = fixed.account_id;
if (battle_config.etc_log)
- PRINTF("chrif_accountdeletion %d.\n", acc);
- sd = map_id2sd(acc);
- if (acc > 0)
+ PRINTF("chrif_accountdeletion %d.\n"_fmt, acc);
+ sd = map_id2sd(account_to_block(acc));
+ if (acc)
{
- if (sd != NULL)
+ if (sd != nullptr)
{
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
clif_displaymessage(sd->sess,
- "Your account has been deleted (disconnection)...");
+ "Your account has been deleted (disconnection)..."_s);
clif_setwaitclose(sd->sess); // forced to disconnect for the change
}
}
else
{
- if (sd != NULL)
- PRINTF("chrif_accountdeletion failed - player not online.\n");
+ if (sd != nullptr)
+ PRINTF("chrif_accountdeletion failed - player not online.\n"_fmt);
}
return 0;
@@ -823,85 +819,85 @@ int chrif_accountdeletion(Session *s)
*------------------------------------------
*/
static
-int chrif_accountban(Session *s)
+int chrif_accountban(Session *, const Packet_Fixed<0x2b14>& fixed)
{
- int acc;
dumb_ptr<map_session_data> sd;
- acc = RFIFOL(s, 2);
+ AccountId acc = fixed.account_id;
if (battle_config.etc_log)
- PRINTF("chrif_accountban %d.\n", acc);
- sd = map_id2sd(acc);
- if (acc > 0)
+ PRINTF("chrif_accountban %d.\n"_fmt, acc);
+ sd = map_id2sd(account_to_block(acc));
+ if (acc)
{
- if (sd != NULL)
+ if (sd != nullptr)
{
sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
- if (RFIFOB(s, 6) == 0)
+ if (fixed.ban_not_status == 0)
{ // 0: change of statut, 1: ban
- switch (RFIFOL(s, 7))
+ switch (static_cast<time_t>(fixed.status_or_ban_until))
{ // status or final date of a banishment
case 1: // 0 = Unregistered ID
clif_displaymessage(sd->sess,
- "Your account has 'Unregistered'.");
+ "Your account has 'Unregistered'."_s);
break;
case 2: // 1 = Incorrect Password
clif_displaymessage(sd->sess,
- "Your account has an 'Incorrect Password'...");
+ "Your account has an 'Incorrect Password'..."_s);
break;
case 3: // 2 = This ID is expired
clif_displaymessage(sd->sess,
- "Your account has expired.");
+ "Your account has expired."_s);
break;
case 4: // 3 = Rejected from Server
clif_displaymessage(sd->sess,
- "Your account has been rejected from server.");
+ "Your account has been rejected from server."_s);
break;
case 5: // 4 = You have been blocked by the GM Team
clif_displaymessage(sd->sess,
- "Your account has been blocked by the GM Team.");
+ "Your account has been blocked by the GM Team."_s);
break;
case 6: // 5 = Your Game's EXE file is not the latest version
clif_displaymessage(sd->sess,
- "Your Game's EXE file is not the latest version.");
+ "Your Game's EXE file is not the latest version."_s);
break;
case 7: // 6 = Your are Prohibited to log in until %s
clif_displaymessage(sd->sess,
- "Your account has been prohibited to log in.");
+ "Your account has been prohibited to log in."_s);
break;
case 8: // 7 = Server is jammed due to over populated
clif_displaymessage(sd->sess,
- "Server is jammed due to over populated.");
+ "Server is jammed due to over populated."_s);
break;
case 9: // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this)
clif_displaymessage(sd->sess,
- "Your account has not more authorised.");
+ "Your account has not more authorised."_s);
break;
case 100: // 99 = This ID has been totally erased
clif_displaymessage(sd->sess,
- "Your account has been totally erased.");
+ "Your account has been totally erased."_s);
break;
default:
clif_displaymessage(sd->sess,
- "Your account has not more authorised.");
+ "Your account has not more authorised."_s);
break;
}
}
- else if (RFIFOB(s, 6) == 1)
+ else if (fixed.ban_not_status == 1)
{
// 0: change of statut, 1: ban
- TimeT timestamp = static_cast<time_t>(RFIFOL(s, 7)); // status or final date of a banishment
- char tmpstr[] = WITH_TIMESTAMP("Your account has been banished until ");
- REPLACE_TIMESTAMP(tmpstr, timestamp);
- clif_displaymessage(sd->sess, const_(tmpstr));
+ const TimeT timestamp = fixed.status_or_ban_until; // status or final date of a banishment
+ timestamp_seconds_buffer buffer;
+ stamp_time(buffer, &timestamp);
+ AString tmpstr = STRPRINTF("Your account has been banished until %s"_fmt, buffer);
+ clif_displaymessage(sd->sess, tmpstr);
}
clif_setwaitclose(sd->sess); // forced to disconnect for the change
}
}
else
{
- if (sd != NULL)
- PRINTF("chrif_accountban failed - player not online.\n");
+ if (sd != nullptr)
+ PRINTF("chrif_accountban failed - player not online.\n"_fmt);
}
return 0;
@@ -912,10 +908,10 @@ int chrif_accountban(Session *s)
*------------------------------------------
*/
static
-int chrif_recvgmaccounts(Session *s)
+int chrif_recvgmaccounts(Session *s, const std::vector<Packet_Repeat<0x2b15>>& repeat)
{
- PRINTF("From login-server: receiving of %d GM accounts information.\n",
- pc_read_gm_account(s));
+ PRINTF("From login-server: receiving of %d GM accounts information.\n"_fmt,
+ pc_read_gm_account(s, repeat));
return 0;
}
@@ -926,9 +922,11 @@ int chrif_recvgmaccounts(Session *s)
*/
int chrif_reloadGMdb(void)
{
+ if (!char_session)
+ return -1;
- WFIFOW(char_session, 0) = 0x2af7;
- WFIFOSET(char_session, 2);
+ Packet_Fixed<0x2af7> fixed_f7;
+ send_fpacket<0x2af7, 2>(char_session, fixed_f7);
return 0;
}
@@ -939,7 +937,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, Item *item)
{
if (item && item->nameid == source)
{
@@ -949,7 +947,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)
@@ -962,10 +960,9 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id)
case BL::PC:
{
dumb_ptr<map_session_data> pc = bl->is_player();
- struct storage *stor = account2storage2(pc->status_key.account_id);
- int j;
+ Storage *stor = account2storage2(pc->status_key.account_id);
- for (j = 0; j < MAX_INVENTORY; j++)
+ for (IOff0 j : IOff0::iter())
IFIX(pc->status.inventory[j].nameid);
// cart is no longer supported
// IFIX(pc->status.weapon);
@@ -975,10 +972,12 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id)
IFIX(pc->status.head_bottom);
if (stor)
- for (j = 0; j < stor->storage_amount; j++)
+ {
+ for (SOff0 j : SOff0::iter())
FIX(stor->storage_[j]);
+ }
- for (j = 0; j < MAX_INVENTORY; j++)
+ for (IOff0 j : IOff0::iter())
{
struct item_data *item = pc->inventory_data[j];
if (item && item->nameid == source_id)
@@ -996,7 +995,7 @@ void ladmin_itemfrob_c2(dumb_ptr<block_list> bl, int source_id, int dest_id)
case BL::MOB:
{
dumb_ptr<mob_data> mob = bl->is_mob();
- for (struct item& itm : mob->lootitemv)
+ for (Item& itm : mob->lootitemv)
FIX(itm);
break;
}
@@ -1013,16 +1012,16 @@ 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);
}
static
-void ladmin_itemfrob(Session *s)
+void ladmin_itemfrob(Session *, const Packet_Fixed<0x2afa>& fixed)
{
- int source_id = RFIFOL(s, 2);
- int dest_id = RFIFOL(s, 6);
+ ItemNameId source_id = fixed.source_item_id;
+ ItemNameId dest_id = fixed.dest_item_id;
dumb_ptr<block_list> bl = map_get_first_session();
// flooritems
@@ -1041,7 +1040,7 @@ static
void chrif_delete(Session *s)
{
assert (s == char_session);
- PRINTF("Map-server can't connect to char-server (connection #%d).\n",
+ PRINTF("Map-server can't connect to char-server (connection #%d).\n"_fmt,
s);
char_session = nullptr;
}
@@ -1053,121 +1052,213 @@ void chrif_delete(Session *s)
static
void chrif_parse(Session *s)
{
- int packet_len, cmd;
-
- // only char-server can have an access to here.
- // so, if it isn't the char-server, we disconnect the session (fd != char_fd).
- if (s != char_session)
- {
- s->set_eof();
- return;
- }
+ assert (s == char_session);
- while (RFIFOREST(s) >= 2)
+ RecvResult rv = RecvResult::Complete;
+ uint16_t packet_id;
+ while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id))
{
- cmd = RFIFOW(s, 0);
- if (cmd < 0x2af8
- || cmd >=
- 0x2af8 +
- (sizeof(packet_len_table) / sizeof(packet_len_table[0]))
- || packet_len_table[cmd - 0x2af8] == 0)
- {
-
- int r = intif_parse(s); // intifに渡す
-
- if (r == 1)
- continue; // intifで処理した
- if (r == 2)
- return; // intifで処理したが、データが足りない
-
- s->set_eof();
- return;
- }
- packet_len = packet_len_table[cmd - 0x2af8];
- if (packet_len == -1)
- {
- if (RFIFOREST(s) < 4)
- return;
- packet_len = RFIFOW(s, 2);
- }
- if (RFIFOREST(s) < packet_len)
- return;
-
- switch (cmd)
+ switch (packet_id)
{
case 0x2af9:
- chrif_connectack(s);
+ {
+ Packet_Fixed<0x2af9> fixed;
+ rv = recv_fpacket<0x2af9, 3>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_connectack(s, fixed);
break;
+ }
case 0x2afa:
- ladmin_itemfrob(s);
+ {
+ Packet_Fixed<0x2afa> fixed;
+ rv = recv_fpacket<0x2afa, 10>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ ladmin_itemfrob(s, fixed);
break;
+ }
case 0x2afb:
- chrif_sendmapack(s);
+ {
+ Packet_Fixed<0x2afb> fixed;
+ rv = recv_fpacket<0x2afb, 27>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_sendmapack(s, fixed);
break;
+ }
case 0x2afd:
{
- int id = 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);
- CharKey st_key;
- CharData st_data;
- RFIFO_STRUCT(s, 18, st_key);
- RFIFO_STRUCT(s, 18 + sizeof(st_key), st_data);
+ Packet_Payload<0x2afd> payload;
+ rv = recv_ppacket<0x2afd>(s, payload);
+ if (rv != RecvResult::Complete)
+ break;
+
+ AccountId id = payload.account_id;
+ int login_id2 = payload.login_id2;
+ TimeT connect_until_time = payload.connect_until;
+ short tmw_version = payload.packet_tmw_version;
+ CharKey st_key = payload.char_key;
+ CharData st_data = payload.char_data;
pc_authok(id, login_id2,
connect_until_time, tmw_version,
&st_key, &st_data);
- }
break;
+ }
case 0x2afe:
- pc_authfail(RFIFOL(s, 2));
+ {
+ Packet_Fixed<0x2afe> fixed;
+ rv = recv_fpacket<0x2afe, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ pc_authfail(fixed.account_id);
break;
+ }
case 0x2b00:
- map_setusers(RFIFOL(s, 2));
+ {
+ Packet_Fixed<0x2b00> fixed;
+ rv = recv_fpacket<0x2b00, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ map_setusers(fixed.users);
break;
+ }
case 0x2b03:
- clif_charselectok(RFIFOL(s, 2));
+ {
+ Packet_Fixed<0x2b03> fixed;
+ rv = recv_fpacket<0x2b03, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ clif_charselectok(account_to_block(fixed.account_id));
break;
+ }
case 0x2b04:
- chrif_recvmap(s);
+ {
+ Packet_Head<0x2b04> head;
+ std::vector<Packet_Repeat<0x2b04>> repeat;
+ rv = recv_vpacket<0x2b04, 10, 16>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_recvmap(s, head, repeat);
break;
+ }
case 0x2b06:
- chrif_changemapserverack(s);
+ {
+ Packet_Fixed<0x2b06> fixed;
+ rv = recv_fpacket<0x2b06, 44>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_changemapserverack(s, fixed);
break;
+ }
case 0x2b0b:
- chrif_changedgm(s);
+ {
+ Packet_Fixed<0x2b0b> fixed;
+ rv = recv_fpacket<0x2b0b, 10>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_changedgm(s, fixed);
break;
+ }
case 0x2b0d:
- chrif_changedsex(s);
+ {
+ Packet_Fixed<0x2b0d> fixed;
+ rv = recv_fpacket<0x2b0d, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_changedsex(s, fixed);
break;
+ }
case 0x2b0f:
- chrif_char_ask_name_answer(s);
+ {
+ Packet_Fixed<0x2b0f> fixed;
+ rv = recv_fpacket<0x2b0f, 34>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_char_ask_name_answer(s, fixed);
break;
+ }
case 0x2b11:
- chrif_accountreg2(s);
+ {
+ Packet_Head<0x2b11> head;
+ std::vector<Packet_Repeat<0x2b11>> repeat;
+ rv = recv_vpacket<0x2b11, 8, 36>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_accountreg2(s, head, repeat);
break;
+ }
case 0x2b12:
- chrif_divorce(RFIFOL(s, 2), RFIFOL(s, 6));
+ {
+ Packet_Fixed<0x2b12> fixed;
+ rv = recv_fpacket<0x2b12, 10>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_divorce(fixed.char_id, fixed.partner_id);
break;
+ }
case 0x2b13:
- chrif_accountdeletion(s);
+ {
+ Packet_Fixed<0x2b13> fixed;
+ rv = recv_fpacket<0x2b13, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_accountdeletion(s, fixed);
break;
+ }
case 0x2b14:
- chrif_accountban(s);
+ {
+ Packet_Fixed<0x2b14> fixed;
+ rv = recv_fpacket<0x2b14, 11>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ chrif_accountban(s, fixed);
break;
+ }
case 0x2b15:
- chrif_recvgmaccounts(s);
- break;
+ {
+ std::vector<Packet_Repeat<0x2b15>> repeat;
+ rv = recv_packet_repeatonly<0x2b15, 4, 5>(s, repeat);
+ if (rv != RecvResult::Complete)
+ break;
+ chrif_recvgmaccounts(s, repeat);
+ break;
+ }
default:
+ {
+ RecvResult r = intif_parse(s, packet_id);
+
+ if (r == RecvResult::Complete)
+ break;
+ if (r == RecvResult::Incomplete)
+ return;
+
if (battle_config.error_log)
- PRINTF("chrif_parse : unknown packet %d %d\n", s,
- RFIFOW(s, 0));
+ PRINTF("chrif_parse : unknown packet %d %d\n"_fmt, s,
+ packet_id);
s->set_eof();
return;
+ }
}
- RFIFOSKIP(s, packet_len);
}
+ if (rv == RecvResult::Error)
+ s->set_eof();
}
/*==========================================
@@ -1178,12 +1269,11 @@ void chrif_parse(Session *s)
static
void send_users_tochar(TimerData *, tick_t)
{
- int users = 0;
-
if (!char_session)
return;
- WFIFOW(char_session, 0) = 0x2aff;
+ Packet_Head<0x2aff> head_ff;
+ std::vector<Packet_Repeat<0x2aff>> repeat_ff;
for (io::FD i : iter_fds())
{
Session *s = get_session(i);
@@ -1195,13 +1285,13 @@ 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;
- users++;
+ Packet_Repeat<0x2aff> info;
+ info.char_id = sd->status_key.char_id;
+ repeat_ff.push_back(info);
}
}
- WFIFOW(char_session, 2) = 6 + 4 * users;
- WFIFOW(char_session, 4) = users;
- WFIFOSET(char_session, 6 + 4 * users);
+ head_ff.users = repeat_ff.size();
+ send_vpacket<0x2aff, 6, 4>(char_session, head_ff, repeat_ff);
}
/*==========================================
@@ -1214,10 +1304,10 @@ void check_connect_char_server(TimerData *, tick_t)
{
if (!char_session)
{
- PRINTF("Attempt to connect to char-server...\n");
+ PRINTF("Attempt to connect to char-server...\n"_fmt);
chrif_state = 0;
char_session = make_connection(char_ip, char_port,
- SessionParsers{func_parse: chrif_parse, func_delete: chrif_delete});
+ SessionParsers{.func_parse= chrif_parse, .func_delete= chrif_delete});
if (!char_session)
return;
realloc_fifo(char_session, FIFOSIZE_SERVERLINK, FIFOSIZE_SERVERLINK);
@@ -1232,12 +1322,13 @@ void check_connect_char_server(TimerData *, tick_t)
*/
void do_init_chrif(void)
{
- Timer(gettick() + std::chrono::seconds(1),
+ Timer(gettick() + 1_s,
check_connect_char_server,
- std::chrono::seconds(10)
+ 10_s
).detach();
- Timer(gettick() + std::chrono::seconds(1),
+ Timer(gettick() + 1_s,
send_users_tochar,
- std::chrono::seconds(5)
+ 5_s
).detach();
}
+} // namespace tmwa
diff --git a/src/map/chrif.hpp b/src/map/chrif.hpp
index afeba75..4711bc5 100644
--- a/src/map/chrif.hpp
+++ b/src/map/chrif.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_CHRIF_HPP
-#define TMWA_MAP_CHRIF_HPP
+#pragma once
// chrif.hpp - Network interface to the character server.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,16 +20,19 @@
// 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 "../strings/fwd.hpp"
-# include "../mmo/dumb_ptr.hpp"
-# include "../mmo/human_time_diff.hpp"
-# include "../mmo/ip.hpp"
+#include "../generic/fwd.hpp"
-# include "map.hpp"
+#include "../net/fwd.hpp"
+#include "../mmo/fwd.hpp"
+
+
+namespace tmwa
+{
void chrif_setuserid(AccountName);
void chrif_setpasswd(AccountPass);
AccountPass chrif_getpasswd(void);
@@ -48,18 +50,17 @@ 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);
// only used by intif.cpp
// and clif.cpp for the new on_delete stuff ...
extern Session *char_session;
-
-#endif // TMWA_MAP_CHRIF_HPP
+} // namespace tmwa
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index eb008e4..fb4041c 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -20,29 +20,36 @@
// 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 <arpa/inet.h>
-
-#include <cstdlib>
-#include <cstring>
+#include <cassert>
#include <ctime>
-#include "../compat/alg.hpp"
+#include <algorithm>
+
#include "../compat/attr.hpp"
#include "../compat/fun.hpp"
#include "../compat/nullpo.hpp"
+#include "../ints/cmp.hpp"
+
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
-#include "../generic/random.hpp"
-
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/write.hpp"
+#include "../net/ip.hpp"
+#include "../net/packets.hpp"
+#include "../net/socket.hpp"
+#include "../net/timer.hpp"
+
+#include "../proto2/any-user.hpp"
+#include "../proto2/char-map.hpp"
+#include "../proto2/map-user.hpp"
+
#include "../mmo/md5more.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../mmo/utils.hpp"
#include "../mmo/version.hpp"
#include "atcommand.hpp"
@@ -51,6 +58,7 @@
#include "intif.hpp"
#include "itemdb.hpp"
#include "magic.hpp"
+#include "magic-stmt.hpp"
#include "map.hpp"
#include "npc.hpp"
#include "party.hpp"
@@ -62,8 +70,9 @@
#include "../poison.hpp"
-#define DUMP_UNKNOWN_PACKET 1
+namespace tmwa
+{
constexpr int EMOTE_IGNORED = 0x0e;
// functions list. Rate is how many milliseconds are required between
@@ -71,20 +80,20 @@ constexpr int EMOTE_IGNORED = 0x0e;
// map.h must be the same length as this table. rate 0 is default
// rate -1 is unlimited
-typedef void (*clif_func)(Session *s, dumb_ptr<map_session_data> sd);
+typedef RecvResult (*clif_func)(Session *s, dumb_ptr<map_session_data> sd);
struct func_table
{
interval_t rate;
- int len;
+ uint16_t len_unused;
clif_func func;
// ctor exists because interval_t must be explicit
- func_table(int r, int l, clif_func f)
- : rate(r), len(l), func(f)
+ func_table(int r, uint16_t l, clif_func f)
+ : rate(r), len_unused(l), func(f)
{}
};
-constexpr int VAR = -1;
+constexpr uint16_t VAR = 1;
extern // not really - defined below
func_table clif_parse_func_table[0x0220];
@@ -107,36 +116,6 @@ enum class SendWho
SELF,
};
-inline
-void WBUFPOS(uint8_t *p, size_t pos, uint16_t x, uint16_t y)
-{
- p += pos;
- p[0] = x >> 2;
- p[1] = (x << 6) | ((y >> 4) & 0x3f);
- p[2] = y << 4;
-}
-inline
-void WBUFPOS2(uint8_t *p, size_t pos, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
-{
- p += pos;
- p[0] = x0 >> 2;
- p[1] = (x0 << 6) | ((y0 >> 4) & 0x3f);
- p[2] = (y0 << 4) | ((x1 >> 6) & 0x0f);
- p[3] = (x1 << 2) | ((y1 >> 8) & 0x03);
- p[4] = y1;
-}
-
-inline
-void WFIFOPOS(Session *s, size_t pos, uint16_t x, uint16_t y)
-{
- WBUFPOS(static_cast<uint8_t *>(WFIFOP(s, pos)), 0, x, y);
-}
-inline
-void WFIFOPOS2(Session *s, size_t pos, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
-{
- WBUFPOS2(static_cast<uint8_t *>(WFIFOP(s, pos)), 0, x0, y0, x1, y1);
-}
-
static
IP4Address map_ip;
static
@@ -159,11 +138,11 @@ void clif_delete(Session *s)
pc_logout(sd);
clif_quitsave(s, sd);
- PRINTF("Player [%s] has logged off your server.\n", sd->status_key.name); // Player logout display [Valaris]
+ PRINTF("Player [%s] has logged off your server.\n"_fmt, sd->status_key.name); // Player logout display [Valaris]
}
else if (sd)
{ // not authentified! (refused by char-server or disconnect before to be authentified)
- PRINTF("Player with account [%d] has logged off your server (not auth account).\n", sd->bl_id); // Player logout display [Yor]
+ PRINTF("Player with account [%d] has logged off your server (not auth account).\n"_fmt, sd->bl_id); // Player logout display [Yor]
map_deliddb(sd); // account_id has been included in the DB before auth answer
}
}
@@ -265,14 +244,14 @@ enum class ChatType
};
static
-AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type);
+AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type, XString buf);
/*==========================================
* clif_sendでSendWho::AREA*指定時用
*------------------------------------------
*/
static
-void clif_send_sub(dumb_ptr<block_list> bl, const unsigned char *buf, int len,
+void clif_send_sub(dumb_ptr<block_list> bl, const Buffer& buf,
dumb_ptr<block_list> src_bl, SendWho type)
{
nullpo_retv(bl);
@@ -299,14 +278,11 @@ void clif_send_sub(dumb_ptr<block_list> bl, const unsigned char *buf, int len,
break;
}
- if (sd->sess != NULL)
+ if (sd->sess != nullptr)
{
{
- if (clif_parse_func_table[RBUFW(buf, 0)].len)
{
- // packet must exist
- WFIFO_BUF_CLONE(sd->sess, buf, len);
- WFIFOSET(sd->sess, len);
+ send_buffer(sd->sess, buf);
}
}
}
@@ -317,14 +293,14 @@ void clif_send_sub(dumb_ptr<block_list> bl, const unsigned char *buf, int len,
*------------------------------------------
*/
static
-int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type)
+int clif_send(const Buffer& buf, dumb_ptr<block_list> bl, SendWho type)
{
- struct party *p = NULL;
+ PartyPair p;
int x0 = 0, x1 = 0, y0 = 0, y1 = 0;
if (type != SendWho::ALL_CLIENT)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::PC)
{
@@ -360,11 +336,8 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get()));
if (sd && sd->state.auth)
{
- if (clif_parse_func_table[RBUFW(buf, 0)].len)
{
- // packet must exist
- WFIFO_BUF_CLONE(s, buf, len);
- WFIFOSET(s, len);
+ send_buffer(s, buf);
}
}
}
@@ -378,25 +351,22 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get()));
if (sd && sd->state.auth && sd->bl_m == bl->bl_m)
{
- if (clif_parse_func_table[RBUFW(buf, 0)].len)
{
- // packet must exist
- WFIFO_BUF_CLONE(s, buf, len);
- WFIFOSET(s, len);
+ send_buffer(s, buf);
}
}
}
break;
case SendWho::AREA:
case SendWho::AREA_WOS:
- map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, len, bl, type),
+ map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, type),
bl->bl_m,
bl->bl_x - AREA_SIZE, bl->bl_y - AREA_SIZE,
bl->bl_x + AREA_SIZE, bl->bl_y + AREA_SIZE,
BL::PC);
break;
case SendWho::AREA_CHAT_WOC:
- map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, len, bl, SendWho::AREA_CHAT_WOC),
+ map_foreachinarea(std::bind(clif_send_sub, ph::_1, buf, bl, SendWho::AREA_CHAT_WOC),
bl->bl_m,
bl->bl_x - (AREA_SIZE), bl->bl_y - (AREA_SIZE),
bl->bl_x + (AREA_SIZE), bl->bl_y + (AREA_SIZE),
@@ -417,13 +387,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);
}
}
@@ -444,11 +414,8 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
(sd->bl_x < x0 || sd->bl_y < y0 ||
sd->bl_x > x1 || sd->bl_y > y1))
continue;
- if (clif_parse_func_table[RBUFW(buf, 0)].len)
{
- // packet must exist
- WFIFO_BUF_CLONE(sd->sess, buf, len);
- WFIFOSET(sd->sess, len);
+ send_buffer(sd->sess, buf);
}
}
}
@@ -460,13 +427,10 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get()));
if (sd && sd->state.auth)
{
- if (sd->partyspy == p->party_id)
+ if (sd->partyspy == p.party_id)
{
- if (clif_parse_func_table[RBUFW(buf, 0)].len)
{
- // packet must exist
- WFIFO_BUF_CLONE(sd->sess, buf, len);
- WFIFOSET(sd->sess, len);
+ send_buffer(sd->sess, buf);
}
}
}
@@ -476,18 +440,16 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
case SendWho::SELF:
{
dumb_ptr<map_session_data> sd = bl->is_player();
- if (clif_parse_func_table[RBUFW(buf, 0)].len)
+
{
- // packet must exist
- WFIFO_BUF_CLONE(sd->sess, buf, len);
- WFIFOSET(sd->sess, len);
+ send_buffer(sd->sess, buf);
}
}
break;
default:
if (battle_config.error_log)
- PRINTF("clif_send まだ作ってないよー\n");
+ PRINTF("clif_send まだ作ってないよー\n"_fmt);
return -1;
}
@@ -503,7 +465,7 @@ int clif_send(const uint8_t *buf, int len, dumb_ptr<block_list> bl, SendWho type
*/
int clif_authok(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (!sd)
return 0;
@@ -513,12 +475,12 @@ int clif_authok(dumb_ptr<map_session_data> sd)
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x73;
- WFIFOL(s, 2) = gettick().time_since_epoch().count();
- WFIFOPOS(s, 6, sd->bl_x, sd->bl_y);
- WFIFOB(s, 9) = 5;
- WFIFOB(s, 10) = 5;
- WFIFOSET(s, clif_parse_func_table[0x73].len);
+ Packet_Fixed<0x0073> fixed_73;
+ fixed_73.tick = gettick();
+ fixed_73.pos = Position1{static_cast<uint16_t>(sd->bl_x), static_cast<uint16_t>(sd->bl_y), DIR::S};
+ fixed_73.five1 = 5;
+ fixed_73.five2 = 5;
+ send_fpacket<0x0073, 11>(s, fixed_73);
return 0;
}
@@ -532,9 +494,9 @@ int clif_authfail_fd(Session *s, int type)
if (!s)
return 0;
- WFIFOW(s, 0) = 0x81;
- WFIFOL(s, 2) = type;
- WFIFOSET(s, clif_parse_func_table[0x81].len);
+ Packet_Fixed<0x0081> fixed_81;
+ fixed_81.error_code = type;
+ send_fpacket<0x0081, 3>(s, fixed_81);
clif_setwaitclose(s);
@@ -545,20 +507,20 @@ int clif_authfail_fd(Session *s, int type)
*
*------------------------------------------
*/
-int clif_charselectok(int id)
+int clif_charselectok(BlockId id)
{
dumb_ptr<map_session_data> sd;
- if ((sd = map_id2sd(id)) == NULL)
+ if ((sd = map_id2sd(id)) == nullptr)
return 1;
if (!sd->sess)
return 1;
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xb3;
- WFIFOB(s, 2) = 1;
- WFIFOSET(s, clif_parse_func_table[0xb3].len);
+ Packet_Fixed<0x00b3> fixed_b3;
+ fixed_b3.one = 1;
+ send_fpacket<0x00b3, 3>(s, fixed_b3);
return 0;
}
@@ -568,22 +530,21 @@ int clif_charselectok(int id)
*------------------------------------------
*/
static
-int clif_set009e(dumb_ptr<flooritem_data> fitem, uint8_t *buf)
+void clif_set009e(dumb_ptr<flooritem_data> fitem, Buffer& buf)
{
- nullpo_ret(fitem);
+ nullpo_retv(fitem);
- //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;
- WBUFB(buf, 8) = 1; //identify;
- WBUFW(buf, 9) = fitem->bl_x;
- WBUFW(buf, 11) = fitem->bl_y;
- WBUFB(buf, 13) = fitem->subx;
- WBUFB(buf, 14) = fitem->suby;
- WBUFW(buf, 15) = fitem->item_data.amount;
+ Packet_Fixed<0x009e> fixed_9e;
+ fixed_9e.block_id = fitem->bl_id;
+ fixed_9e.name_id = fitem->item_data.nameid;
+ fixed_9e.identify = 1;
+ fixed_9e.x = fitem->bl_x;
+ fixed_9e.y = fitem->bl_y;
+ fixed_9e.subx = fitem->subx;
+ fixed_9e.suby = fitem->suby;
+ fixed_9e.amount = fitem->item_data.amount;
- return clif_parse_func_table[0x9e].len;
+ buf = create_fpacket<0x009e, 17>(fixed_9e);
}
/*==========================================
@@ -592,14 +553,14 @@ int clif_set009e(dumb_ptr<flooritem_data> fitem, uint8_t *buf)
*/
int clif_dropflooritem(dumb_ptr<flooritem_data> fitem)
{
- uint8_t buf[64];
+ nullpo_retz(fitem);
- nullpo_ret(fitem);
-
- if (fitem->item_data.nameid <= 0)
+ if (!fitem->item_data.nameid)
return 0;
+
+ Buffer buf;
clif_set009e(fitem, buf);
- clif_send(buf, clif_parse_func_table[0x9e].len, fitem, SendWho::AREA);
+ clif_send(buf, fitem, SendWho::AREA);
return 0;
}
@@ -610,21 +571,19 @@ int clif_dropflooritem(dumb_ptr<flooritem_data> fitem)
*/
int clif_clearflooritem(dumb_ptr<flooritem_data> fitem, Session *s)
{
- unsigned char buf[16];
-
- nullpo_ret(fitem);
+ nullpo_retz(fitem);
- WBUFW(buf, 0) = 0xa1;
- WBUFL(buf, 2) = fitem->bl_id;
+ Packet_Fixed<0x00a1> fixed_a1;
+ fixed_a1.block_id = fitem->bl_id;
if (!s)
{
- clif_send(buf, clif_parse_func_table[0xa1].len, fitem, SendWho::AREA);
+ Buffer buf = create_fpacket<0x00a1, 6>(fixed_a1);
+ clif_send(buf, fitem, SendWho::AREA);
}
else
{
- WFIFO_BUF_CLONE(s, buf, 6);
- WFIFOSET(s, clif_parse_func_table[0xa1].len);
+ send_fpacket<0x00a1, 6>(s, fixed_a1);
}
return 0;
@@ -636,21 +595,22 @@ int clif_clearflooritem(dumb_ptr<flooritem_data> fitem, Session *s)
*/
int clif_clearchar(dumb_ptr<block_list> bl, BeingRemoveWhy type)
{
- unsigned char buf[16];
+ nullpo_retz(bl);
- nullpo_ret(bl);
+ Packet_Fixed<0x0080> fixed_80;
+ fixed_80.block_id = bl->bl_id;
- WBUFW(buf, 0) = 0x80;
- WBUFL(buf, 2) = bl->bl_id;
if (type == BeingRemoveWhy::DISGUISE)
{
- WBUFB(buf, 6) = static_cast<uint8_t>(BeingRemoveWhy::GONE);
- clif_send(buf, clif_parse_func_table[0x80].len, bl, SendWho::AREA);
+ fixed_80.type = BeingRemoveWhy::GONE;
+ Buffer buf = create_fpacket<0x0080, 7>(fixed_80);
+ clif_send(buf, bl, SendWho::AREA);
}
else
{
- WBUFB(buf, 6) = static_cast<uint8_t>(type);
- clif_send(buf, clif_parse_func_table[0x80].len, bl,
+ fixed_80.type = type;
+ Buffer buf = create_fpacket<0x0080, 7>(fixed_80);
+ clif_send(buf, bl,
type == BeingRemoveWhy::DEAD ? SendWho::AREA : SendWho::AREA_WOS);
}
@@ -692,12 +652,12 @@ 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;
- WFIFOB(s, 6) = static_cast<uint8_t>(type);
- WFIFOSET(s, clif_parse_func_table[0x80].len);
+ Packet_Fixed<0x0080> fixed_80;
+ fixed_80.block_id = id;
+ fixed_80.type = type;
+ send_fpacket<0x0080, 7>(s, fixed_80);
}
/*==========================================
@@ -705,59 +665,111 @@ void clif_clearchar_id(int id, BeingRemoveWhy type, Session *s)
*------------------------------------------
*/
static
-int clif_set0078(dumb_ptr<map_session_data> sd, unsigned char *buf)
+void clif_set0078_main_1d8(dumb_ptr<map_session_data> sd, Buffer& buf)
{
- nullpo_ret(sd);
+ nullpo_retv(sd);
- WBUFW(buf, 0) = 0x1d8;
- WBUFL(buf, 2) = 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, 16) = sd->status.hair;
+ Packet_Fixed<0x01d8> fixed_1d8;
+ fixed_1d8.block_id = sd->bl_id;
+ fixed_1d8.speed = sd->speed;
+ fixed_1d8.opt1 = sd->opt1;
+ fixed_1d8.opt2 = sd->opt2;
+ fixed_1d8.option = sd->status.option;
+ fixed_1d8.species = sd->status.species;
+ fixed_1d8.hair_style = sd->status.hair;
+
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ if (sd->attack_spell_override)
+ fixed_1d8.weapon = sd->attack_spell_look_override;
+ else
+ {
+ if (widx.ok() && sd->inventory_data[widx])
+ {
+ fixed_1d8.weapon = sd->status.inventory[widx].nameid;
+ }
+ else
+ fixed_1d8.weapon = ItemNameId();
+ }
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
+ {
+ fixed_1d8.shield = sd->status.inventory[sidx].nameid;
+ }
+ else
+ fixed_1d8.shield = ItemNameId();
+ fixed_1d8.head_bottom = sd->status.head_bottom;
+ fixed_1d8.head_top = sd->status.head_top;
+ fixed_1d8.head_mid = sd->status.head_mid;
+ fixed_1d8.hair_color = sd->status.hair_color;
+ fixed_1d8.clothes_color = sd->status.clothes_color;
+ fixed_1d8.head_dir = sd->head_dir;
+ fixed_1d8.guild_id = 0;
+ fixed_1d8.guild_emblem_id = 0;
+ fixed_1d8.manner = sd->status.manner;
+ fixed_1d8.opt3 = sd->opt3;
+ fixed_1d8.karma = sd->status.karma;
+ fixed_1d8.sex = sd->sex;
+ fixed_1d8.pos.x = sd->bl_x;
+ fixed_1d8.pos.y = sd->bl_y;
+ fixed_1d8.pos.dir = sd->dir;
+ fixed_1d8.gm_bits = pc_isGM(sd).get_public_word();
+ fixed_1d8.dead_sit = sd->state.dead_sit;
+ fixed_1d8.unused = 0;
+
+ buf = create_fpacket<0x01d8, 54>(fixed_1d8);
+}
+static
+void clif_set0078_alt_1d9(dumb_ptr<map_session_data> sd, Buffer& buf)
+{
+ nullpo_retv(sd);
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ Packet_Fixed<0x01d9> fixed_1d8; // LIES
+ fixed_1d8.block_id = sd->bl_id;
+ fixed_1d8.speed = sd->speed;
+ fixed_1d8.opt1 = sd->opt1;
+ fixed_1d8.opt2 = sd->opt2;
+ fixed_1d8.option = sd->status.option;
+ fixed_1d8.species = sd->status.species;
+ fixed_1d8.hair_style = sd->status.hair;
+
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
if (sd->attack_spell_override)
- WBUFW(buf, 18) = sd->attack_spell_look_override;
+ fixed_1d8.weapon = sd->attack_spell_look_override;
else
{
- if (widx >= 0 && sd->inventory_data[widx])
+ if (widx.ok() && sd->inventory_data[widx])
{
- WBUFW(buf, 18) = sd->status.inventory[widx].nameid;
+ fixed_1d8.weapon = sd->status.inventory[widx].nameid;
}
else
- WBUFW(buf, 18) = 0;
+ fixed_1d8.weapon = ItemNameId();
}
- if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
{
- WBUFW(buf, 20) = sd->status.inventory[sidx].nameid;
+ fixed_1d8.shield = 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, 28) = sd->status.hair_color;
- WBUFW(buf, 30) = sd->status.clothes_color;
- WBUFW(buf, 32) = static_cast<uint8_t>(sd->head_dir);
- WBUFL(buf, 34) = 0 /*guild_id*/;
- WBUFW(buf, 38) = 0 /*guild_emblem_id*/;
- WBUFW(buf, 40) = sd->status.manner;
- WBUFW(buf, 42) = static_cast<uint16_t>(sd->opt3);
- WBUFB(buf, 44) = sd->status.karma;
- WBUFB(buf, 45) = static_cast<uint8_t>(sd->sex);
- WBUFPOS(buf, 46, sd->bl_x, sd->bl_y);
- // 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;
- WBUFB(buf, 51) = sd->state.dead_sit;
- WBUFW(buf, 52) = 0;
-
- return clif_parse_func_table[0x1d8].len;
+ fixed_1d8.shield = ItemNameId();
+ fixed_1d8.head_bottom = sd->status.head_bottom;
+ fixed_1d8.head_top = sd->status.head_top;
+ fixed_1d8.head_mid = sd->status.head_mid;
+ fixed_1d8.hair_color = sd->status.hair_color;
+ fixed_1d8.clothes_color = sd->status.clothes_color;
+ fixed_1d8.head_dir = sd->head_dir;
+ fixed_1d8.guild_id = 0;
+ fixed_1d8.guild_emblem_id = 0;
+ fixed_1d8.manner = sd->status.manner;
+ fixed_1d8.opt3 = sd->opt3;
+ fixed_1d8.karma = sd->status.karma;
+ fixed_1d8.sex = sd->sex;
+ fixed_1d8.pos.x = sd->bl_x;
+ fixed_1d8.pos.y = sd->bl_y;
+ fixed_1d8.pos.dir = sd->dir;
+ fixed_1d8.gm_bits = pc_isGM(sd).get_public_word();
+ fixed_1d8.unused = 0;
+
+ buf = create_fpacket<0x01d9, 53>(fixed_1d8);
}
/*==========================================
@@ -765,51 +777,54 @@ int clif_set0078(dumb_ptr<map_session_data> sd, unsigned char *buf)
*------------------------------------------
*/
static
-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;
- 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, 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])
+void clif_set007b(dumb_ptr<map_session_data> sd, Buffer& buf)
+{
+ nullpo_retv(sd);
+
+ Packet_Fixed<0x01da> fixed_1da;
+ fixed_1da.block_id = sd->bl_id;
+ fixed_1da.speed = sd->speed;
+ fixed_1da.opt1 = sd->opt1;
+ fixed_1da.opt2 = sd->opt2;
+ fixed_1da.option = sd->status.option;
+ fixed_1da.species = sd->status.species;
+ fixed_1da.hair_style = sd->status.hair;
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ if (widx.ok() && sd->inventory_data[widx])
{
- WBUFW(buf, 18) = sd->status.inventory[widx].nameid;
+ fixed_1da.weapon = sd->status.inventory[widx].nameid;
}
else
- WBUFW(buf, 18) = 0;
- if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
+ fixed_1da.weapon = ItemNameId();
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
{
- WBUFW(buf, 20) = sd->status.inventory[sidx].nameid;
+ fixed_1da.shield = sd->status.inventory[sidx].nameid;
}
else
- WBUFW(buf, 20) = 0;
- WBUFW(buf, 22) = 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, 32) = sd->status.hair_color;
- WBUFW(buf, 34) = sd->status.clothes_color;
- WBUFW(buf, 36) = static_cast<uint8_t>(sd->head_dir);
- WBUFL(buf, 38) = 0/*guild_id*/;
- WBUFW(buf, 42) = 0/*guild_emblem_id*/;
- WBUFW(buf, 44) = sd->status.manner;
- WBUFW(buf, 46) = static_cast<uint16_t>(sd->opt3);
- 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;
- WBUFB(buf, 57) = 5;
- WBUFW(buf, 58) = 0;
-
- return clif_parse_func_table[0x1da].len;
+ fixed_1da.shield = ItemNameId();
+ fixed_1da.head_bottom = sd->status.head_bottom;
+ fixed_1da.tick = gettick();
+ fixed_1da.head_top = sd->status.head_top;
+ fixed_1da.head_mid = sd->status.head_mid;
+ fixed_1da.hair_color = sd->status.hair_color;
+ fixed_1da.clothes_color = sd->status.clothes_color;
+ fixed_1da.head_dir = sd->head_dir;
+ fixed_1da.guild_id = 0;
+ fixed_1da.guild_emblem_id = 0;
+ fixed_1da.manner = sd->status.manner;
+ fixed_1da.opt3 = sd->opt3;
+ fixed_1da.karma = sd->status.karma;
+ fixed_1da.sex = sd->sex;
+ fixed_1da.pos2.x0 = sd->bl_x;
+ fixed_1da.pos2.y0 = sd->bl_y;
+ fixed_1da.pos2.x1 = sd->to_x;
+ fixed_1da.pos2.y1 = sd->to_y;
+ fixed_1da.gm_bits = pc_isGM(sd).get_public_word();
+ fixed_1da.five = 5;
+ fixed_1da.unused = 0;
+
+ buf = create_fpacket<0x01da, 60>(fixed_1da);
}
/*==========================================
@@ -817,30 +832,27 @@ int clif_set007b(dumb_ptr<map_session_data> sd, unsigned char *buf)
*------------------------------------------
*/
static
-int clif_mob0078(dumb_ptr<mob_data> md, unsigned char *buf)
+void clif_mob0078(dumb_ptr<mob_data> md, Buffer& buf)
{
- really_memset0(buf, clif_parse_func_table[0x78].len);
-
- nullpo_ret(md);
+ nullpo_retv(md);
- WBUFW(buf, 0) = 0x78;
- WBUFL(buf, 2) = 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;
+ Packet_Fixed<0x0078> fixed_78;
+ fixed_78.block_id = md->bl_id;
+ fixed_78.speed = battle_get_speed(md);
+ fixed_78.opt1 = md->opt1;
+ fixed_78.opt2 = md->opt2;
+ fixed_78.option = md->option;
+ fixed_78.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
- uint8_t dir = static_cast<uint8_t>(md->dir);
- WBUFB(buf, 48) |= dir;
- WBUFB(buf, 49) = 5;
- WBUFB(buf, 50) = 5;
+ fixed_78.pos.x = md->bl_x;
+ fixed_78.pos.y = md->bl_y;
+ fixed_78.pos.dir = md->dir;
+ fixed_78.five1 = 5;
+ fixed_78.five2 = 5;
int level = battle_get_lv(md);
- WBUFW(buf, 52) = (level > battle_config.max_lv) ? battle_config.max_lv : level;
+ fixed_78.level = (level > battle_config.max_lv) ? battle_config.max_lv : level;
- return clif_parse_func_table[0x78].len;
+ buf = create_fpacket<0x0078, 54>(fixed_78);
}
/*==========================================
@@ -848,29 +860,30 @@ int clif_mob0078(dumb_ptr<mob_data> md, unsigned char *buf)
*------------------------------------------
*/
static
-int clif_mob007b(dumb_ptr<mob_data> md, unsigned char *buf)
+void clif_mob007b(dumb_ptr<mob_data> md, Buffer& buf)
{
- really_memset0(buf, clif_parse_func_table[0x7b].len);
-
- nullpo_ret(md);
+ nullpo_retv(md);
- WBUFW(buf, 0) = 0x7b;
- WBUFL(buf, 2) = 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;
+ Packet_Fixed<0x007b> fixed_7b;
+ fixed_7b.block_id = md->bl_id;
+ fixed_7b.speed = battle_get_speed(md);
+ fixed_7b.opt1 = md->opt1;
+ fixed_7b.opt2 = md->opt2;
+ fixed_7b.option = md->option;
+ fixed_7b.mob_class = md->mob_class;
// snip: stuff for monsters disguised as PCs
- WBUFL(buf, 22) = gettick().time_since_epoch().count();
-
- WBUFPOS2(buf, 50, md->bl_x, md->bl_y, md->to_x, md->to_y);
- WBUFB(buf, 56) = 5;
- WBUFB(buf, 57) = 5;
+ fixed_7b.tick_and_maybe_part_of_guild_emblem = gettick();
+
+ fixed_7b.pos2.x0 = md->bl_x;
+ fixed_7b.pos2.y0 = md->bl_y;
+ fixed_7b.pos2.x1 = md->to_x;
+ fixed_7b.pos2.y1 = md->to_y;
+ fixed_7b.five1 = 5;
+ fixed_7b.five2 = 5;
int level = battle_get_lv(md);
- WBUFW(buf, 58) = (level > battle_config.max_lv) ? battle_config.max_lv : level;
+ fixed_7b.level = (level > battle_config.max_lv) ? battle_config.max_lv : level;
- return clif_parse_func_table[0x7b].len;
+ buf = create_fpacket<0x007b, 60>(fixed_7b);
}
/*==========================================
@@ -878,24 +891,23 @@ int clif_mob007b(dumb_ptr<mob_data> md, unsigned char *buf)
*------------------------------------------
*/
static
-int clif_npc0078(dumb_ptr<npc_data> nd, unsigned char *buf)
+void clif_npc0078(dumb_ptr<npc_data> nd, Buffer& buf)
{
- nullpo_ret(nd);
-
- really_memset0(buf, clif_parse_func_table[0x78].len);
+ nullpo_retv(nd);
- WBUFW(buf, 0) = 0x78;
- WBUFL(buf, 2) = 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);
- // work around ICE in gcc 4.6
- uint8_t dir = static_cast<uint8_t>(nd->dir);
- WBUFB(buf, 48) |= dir;
- WBUFB(buf, 49) = 5;
- WBUFB(buf, 50) = 5;
+ Packet_Fixed<0x0078> fixed_78;
+ fixed_78.block_id = nd->bl_id;
+ fixed_78.speed = nd->speed;
+ fixed_78.species = nd->npc_class;
+ fixed_78.pos.x = nd->bl_x;
+ fixed_78.pos.y = nd->bl_y;
+ fixed_78.pos.dir = nd->dir;
+ fixed_78.five1 = 5;
+ fixed_78.five2 = 5;
+ fixed_78.zero = 0;
+ fixed_78.level = 0;
- return clif_parse_func_table[0x78].len;
+ buf = create_fpacket<0x0078, 54>(fixed_78);
}
/* These indices are derived from equip_pos in pc.c and some guesswork */
@@ -924,15 +936,12 @@ earray<EQUIP, LOOK, LOOK::COUNT> equip_points //=
*/
int clif_spawnpc(dumb_ptr<map_session_data> sd)
{
- unsigned char buf[128];
+ nullpo_retz(sd);
- nullpo_ret(sd);
+ Buffer buf;
+ clif_set0078_alt_1d9(sd, buf);
- clif_set0078(sd, buf);
-
- WBUFW(buf, 0) = 0x1d9;
- WBUFW(buf, 51) = 0;
- clif_send(buf, clif_parse_func_table[0x1d9].len, sd, SendWho::AREA_WOS);
+ clif_send(buf, sd, SendWho::AREA_WOS);
if (sd->bl_m->flag.get(MapFlag::SNOW))
clif_specialeffect(sd, 162, 1);
@@ -945,7 +954,7 @@ int clif_spawnpc(dumb_ptr<map_session_data> sd)
if (sd->bl_m->flag.get(MapFlag::RAIN))
clif_specialeffect(sd, 161, 1);
-// clif_changelook_accessories(sd, NULL);
+// clif_changelook_accessories(sd, nullptr);
return 0;
}
@@ -956,62 +965,64 @@ int clif_spawnpc(dumb_ptr<map_session_data> sd)
*/
int clif_spawnnpc(dumb_ptr<npc_data> nd)
{
- unsigned char buf[64];
- int len;
-
- nullpo_ret(nd);
+ nullpo_retz(nd);
- if (nd->npc_class < 0 || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS)
+ if (nd->npc_class == NEGATIVE_SPECIES || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS)
return 0;
- really_memset0(buf, clif_parse_func_table[0x7c].len);
+ Packet_Fixed<0x007c> fixed_7c;
+ fixed_7c.block_id = nd->bl_id;
+ fixed_7c.speed = nd->speed;
+ fixed_7c.species = nd->npc_class;
+ fixed_7c.pos.x = nd->bl_x;
+ fixed_7c.pos.y = nd->bl_y;
- WBUFW(buf, 0) = 0x7c;
- WBUFL(buf, 2) = 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);
+ Buffer buf = create_fpacket<0x007c, 41>(fixed_7c);
+ clif_send(buf, nd, SendWho::AREA);
- clif_send(buf, clif_parse_func_table[0x7c].len, nd, SendWho::AREA);
-
- len = clif_npc0078(nd, buf);
- clif_send(buf, len, nd, SendWho::AREA);
+ clif_npc0078(nd, buf);
+ clif_send(buf, nd, SendWho::AREA);
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);
+ nullpo_retz(sd);
Session *s = sd->sess;
if (!s)
return 0;
- WFIFOW(s, 0) = 0x7c;
- WFIFOL(s, 2) = fake_npc_id;
- WFIFOW(s, 6) = 0;
- WFIFOW(s, 8) = 0;
- WFIFOW(s, 10) = 0;
- WFIFOW(s, 12) = 0;
- WFIFOW(s, 20) = 127;
- WFIFOPOS(s, 36, sd->bl_x, sd->bl_y);
- WFIFOSET(s, clif_parse_func_table[0x7c].len);
-
- WFIFOW(s, 0) = 0x78;
- WFIFOL(s, 2) = fake_npc_id;
- WFIFOW(s, 6) = 0;
- WFIFOW(s, 8) = 0;
- WFIFOW(s, 10) = 0;
- WFIFOW(s, 12) = 0;
- WFIFOW(s, 14) = 127; // identifies as NPC
- WFIFOW(s, 20) = 127;
- WFIFOPOS(s, 46, sd->bl_x, sd->bl_y);
- WFIFOPOS(s, 36, sd->bl_x, sd->bl_y);
- WFIFOB(s, 49) = 5;
- WFIFOB(s, 50) = 5;
- WFIFOSET(s, clif_parse_func_table[0x78].len);
+ Packet_Fixed<0x007c> fixed_7c;
+ fixed_7c.block_id = fake_npc_id;
+ fixed_7c.speed = interval_t();
+ fixed_7c.opt1 = Opt1::ZERO;
+ fixed_7c.opt2 = Opt2::ZERO;
+ fixed_7c.option = Option::ZERO;
+ fixed_7c.species = FAKE_NPC_CLASS;
+ fixed_7c.pos.x = sd->bl_x;
+ fixed_7c.pos.y = sd->bl_y;
+ send_fpacket<0x007c, 41>(s, fixed_7c);
+
+ Packet_Fixed<0x0078> fixed_78;
+ fixed_78.block_id = fake_npc_id;
+ fixed_78.speed = interval_t();
+ fixed_78.opt1 = Opt1::ZERO;
+ fixed_78.opt2 = Opt2::ZERO;
+ fixed_78.option = Option::ZERO;
+ fixed_78.species = FAKE_NPC_CLASS;
+ fixed_78.unused_head_bottom_or_species_again = unwrap<Species>(FAKE_NPC_CLASS);
+ fixed_78.pos.x = sd->bl_x;
+ fixed_78.pos.y = sd->bl_y;
+ fixed_78.unused_pos_again.x = sd->bl_x;
+ fixed_78.unused_pos_again.y = sd->bl_y;
+ fixed_78.five1 = 5;
+ fixed_78.five2 = 5;
+ fixed_78.zero = 0;
+ fixed_78.level = 0;
+ send_fpacket<0x0078, 54>(s, fixed_78);
return 0;
}
@@ -1022,27 +1033,25 @@ int clif_spawn_fake_npc_for_player(dumb_ptr<map_session_data> sd, int fake_npc_i
*/
int clif_spawnmob(dumb_ptr<mob_data> md)
{
- unsigned char buf[64];
- int len;
-
- nullpo_ret(md);
+ nullpo_retz(md);
{
- really_memset0(buf, clif_parse_func_table[0x7c].len);
-
- WBUFW(buf, 0) = 0x7c;
- WBUFL(buf, 2) = md->bl_id;
- WBUFW(buf, 6) = md->stats[mob_stat::SPEED];
- WBUFW(buf, 8) = uint16_t(md->opt1);
- WBUFW(buf, 10) = uint16_t(md->opt2);
- WBUFW(buf, 12) = uint16_t(md->option);
- WBUFW(buf, 20) = md->mob_class;
- WBUFPOS(buf, 36, md->bl_x, md->bl_y);
- clif_send(buf, clif_parse_func_table[0x7c].len, md, SendWho::AREA);
+ Packet_Fixed<0x007c> fixed_7c;
+ fixed_7c.block_id = md->bl_id;
+ fixed_7c.speed = interval_t(md->stats[mob_stat::SPEED]);
+ fixed_7c.opt1 = md->opt1;
+ fixed_7c.opt2 = md->opt2;
+ fixed_7c.option = md->option;
+ fixed_7c.species = md->mob_class;
+ fixed_7c.pos.x = md->bl_x;
+ fixed_7c.pos.y = md->bl_y;
+ Buffer buf = create_fpacket<0x007c, 41>(fixed_7c);
+ clif_send(buf, md, SendWho::AREA);
}
- len = clif_mob0078(md, buf);
- clif_send(buf, len, md, SendWho::AREA);
+ Buffer buf;
+ clif_mob0078(md, buf);
+ clif_send(buf, md, SendWho::AREA);
return 0;
}
@@ -1054,12 +1063,12 @@ int clif_spawnmob(dumb_ptr<mob_data> md)
static
int clif_servertick(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x7f;
- WFIFOL(s, 2) = sd->server_tick.time_since_epoch().count();
- WFIFOSET(s, clif_parse_func_table[0x7f].len);
+ Packet_Fixed<0x007f> fixed_7f;
+ fixed_7f.tick = gettick();
+ send_fpacket<0x007f, 6>(s, fixed_7f);
return 0;
}
@@ -1070,14 +1079,17 @@ int clif_servertick(dumb_ptr<map_session_data> sd)
*/
int clif_walkok(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x87;
- WFIFOL(s, 2) = gettick().time_since_epoch().count();
- WFIFOPOS2(s, 6, sd->bl_x, sd->bl_y, sd->to_x, sd->to_y);
- WFIFOB(s, 11) = 0;
- WFIFOSET(s, clif_parse_func_table[0x87].len);
+ Packet_Fixed<0x0087> fixed_87;
+ fixed_87.tick = gettick();
+ fixed_87.pos2.x0 = sd->bl_x;
+ fixed_87.pos2.y0 = sd->bl_y;
+ fixed_87.pos2.x1 = sd->to_x;
+ fixed_87.pos2.y1 = sd->to_y;
+ fixed_87.zero = 0;
+ send_fpacket<0x0087, 12>(s, fixed_87);
return 0;
}
@@ -1088,14 +1100,12 @@ int clif_walkok(dumb_ptr<map_session_data> sd)
*/
int clif_movechar(dumb_ptr<map_session_data> sd)
{
- int len;
- unsigned char buf[256];
+ nullpo_retz(sd);
- nullpo_ret(sd);
+ Buffer buf;
+ clif_set007b(sd, buf);
- len = clif_set007b(sd, buf);
-
- clif_send(buf, len, sd, SendWho::AREA_WOS);
+ clif_send(buf, sd, SendWho::AREA_WOS);
if (battle_config.save_clothcolor == 1 && sd->status.clothes_color > 0)
clif_changelook(sd, LOOK::CLOTHES_COLOR,
@@ -1131,7 +1141,7 @@ void clif_waitclose(TimerData *, tick_t, Session *s)
*/
void clif_setwaitclose(Session *s)
{
- s->timed_close = Timer(gettick() + std::chrono::seconds(5),
+ s->timed_close = Timer(gettick() + 5_s,
std::bind(clif_waitclose, ph::_1, ph::_2,
s)
);
@@ -1147,11 +1157,11 @@ void clif_changemap(dumb_ptr<map_session_data> sd, MapName mapname, int x, int y
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x91;
- WFIFO_STRING(s, 2, mapname, 16);
- WFIFOW(s, 18) = x;
- WFIFOW(s, 20) = y;
- WFIFOSET(s, clif_parse_func_table[0x91].len);
+ Packet_Fixed<0x0091> fixed_91;
+ fixed_91.map_name = mapname;
+ fixed_91.x = x;
+ fixed_91.y = y;
+ send_fpacket<0x0091, 22>(s, fixed_91);
}
/*==========================================
@@ -1164,13 +1174,13 @@ void clif_changemapserver(dumb_ptr<map_session_data> sd,
nullpo_retv(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x92;
- WFIFO_STRING(s, 2, mapname, 16);
- WFIFOW(s, 18) = x;
- WFIFOW(s, 20) = y;
- WFIFOIP(s, 22) = ip;
- WFIFOW(s, 26) = port;
- WFIFOSET(s, clif_parse_func_table[0x92].len);
+ Packet_Fixed<0x0092> fixed_92;
+ fixed_92.map_name = mapname;
+ fixed_92.x = x;
+ fixed_92.y = y;
+ fixed_92.ip = ip;
+ fixed_92.port = port;
+ send_fpacket<0x0092, 28>(s, fixed_92);
}
/*==========================================
@@ -1179,30 +1189,29 @@ void clif_changemapserver(dumb_ptr<map_session_data> sd,
*/
void clif_fixpos(dumb_ptr<block_list> bl)
{
- uint8_t buf[16];
-
nullpo_retv(bl);
- WBUFW(buf, 0) = 0x88;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFW(buf, 6) = bl->bl_x;
- WBUFW(buf, 8) = bl->bl_y;
+ Packet_Fixed<0x0088> fixed_88;
+ fixed_88.block_id = bl->bl_id;
+ fixed_88.x = bl->bl_x;
+ fixed_88.y = bl->bl_y;
- clif_send(buf, clif_parse_func_table[0x88].len, bl, SendWho::AREA);
+ Buffer buf = create_fpacket<0x0088, 10>(fixed_88);
+ clif_send(buf, bl, SendWho::AREA);
}
/*==========================================
*
*------------------------------------------
*/
-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);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xc4;
- WFIFOL(s, 2) = id;
- WFIFOSET(s, clif_parse_func_table[0xc4].len);
+ Packet_Fixed<0x00c4> fixed_c4;
+ fixed_c4.block_id = id;
+ send_fpacket<0x00c4, 6>(s, fixed_c4);
return 0;
}
@@ -1216,22 +1225,21 @@ int clif_buylist(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data_shop> nd)
struct item_data *id;
int i, val;
- nullpo_ret(sd);
- nullpo_ret(nd);
+ nullpo_retz(sd);
+ nullpo_retz(nd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xc6;
+ std::vector<Packet_Repeat<0x00c6>> repeat_c6(nd->shop_items.size());
for (i = 0; i < nd->shop_items.size(); i++)
{
id = itemdb_search(nd->shop_items[i].nameid);
val = nd->shop_items[i].value;
- WFIFOL(s, 4 + i * 11) = val; // base price
- WFIFOL(s, 8 + i * 11) = val; // actual price
- WFIFOB(s, 12 + i * 11) = uint8_t(id->type);
- WFIFOW(s, 13 + i * 11) = nd->shop_items[i].nameid;
+ repeat_c6[i].base_price = val; // base price
+ repeat_c6[i].actual_price = val; // actual price
+ repeat_c6[i].type = id->type;
+ repeat_c6[i].name_id = nd->shop_items[i].nameid;
}
- WFIFOW(s, 2) = i * 11 + 4;
- WFIFOSET(s, WFIFOW(s, 2));
+ send_packet_repeatonly<0x00c6, 4, 11>(s, repeat_c6);
return 0;
}
@@ -1242,27 +1250,25 @@ int clif_buylist(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data_shop> nd)
*/
int clif_selllist(dumb_ptr<map_session_data> sd)
{
- int i, c = 0, val;
-
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xc7;
- for (i = 0; i < MAX_INVENTORY; i++)
+ std::vector<Packet_Repeat<0x00c7>> repeat_c7;
+ for (IOff0 i : IOff0::iter())
{
- 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;
+ int val = sd->inventory_data[i]->value_sell;
if (val < 0)
continue;
- WFIFOW(s, 4 + c * 10) = i + 2;
- WFIFOL(s, 6 + c * 10) = val; // base price
- WFIFOL(s, 10 + c * 10) = val; // actual price
- c++;
+ Packet_Repeat<0x00c7> info;
+ info.ioff2 = i.shift();
+ info.base_price = val;
+ info.actual_price = val;
+ repeat_c7.push_back(info);
}
}
- WFIFOW(s, 2) = c * 10 + 4;
- WFIFOSET(s, WFIFOW(s, 2));
+ send_packet_repeatonly<0x00c7, 4, 10>(s, repeat_c7);
return 0;
}
@@ -1271,166 +1277,130 @@ 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);
Session *s = sd->sess;
- size_t len = mes.size() + 1;
- WFIFOW(s, 0) = 0xb4;
- WFIFOW(s, 2) = len + 8;
- WFIFOL(s, 4) = npcid;
- WFIFO_STRING(s, 8, mes, len);
- WFIFOSET(s, WFIFOW(s, 2));
+ Packet_Head<0x00b4> head_b4;
+ head_b4.block_id = npcid;
+ send_vpacket<0x00b4, 8, 1>(s, head_b4, 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;
- WFIFOSET(s, clif_parse_func_table[0xb5].len);
+ Packet_Fixed<0x00b5> fixed_b5;
+ fixed_b5.block_id = npcid;
+ send_fpacket<0x00b5, 6>(s, fixed_b5);
}
/*==========================================
*
*------------------------------------------
*/
-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;
- WFIFOSET(s, clif_parse_func_table[0xb6].len);
+ Packet_Fixed<0x00b6> fixed_b6;
+ fixed_b6.block_id = npcid;
+ send_fpacket<0x00b6, 6>(s, fixed_b6);
}
/*==========================================
*
*------------------------------------------
*/
-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);
Session *s = sd->sess;
- size_t len = mes.size() + 1;
- WFIFOW(s, 0) = 0xb7;
- WFIFOW(s, 2) = len + 8;
- WFIFOL(s, 4) = npcid;
- WFIFO_STRING(s, 8, mes, len);
- WFIFOSET(s, WFIFOW(s, 2));
+ Packet_Head<0x00b7> head_b7;
+ head_b7.block_id = npcid;
+ send_vpacket<0x00b7, 8, 1>(s, head_b7, 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;
- WFIFOSET(s, clif_parse_func_table[0x142].len);
+ Packet_Fixed<0x0142> fixed_142;
+ fixed_142.block_id = npcid;
+ send_fpacket<0x0142, 6>(s, fixed_142);
}
/*==========================================
*
*------------------------------------------
*/
-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;
- WFIFOSET(s, clif_parse_func_table[0x1d4].len);
+ Packet_Fixed<0x01d4> fixed_1d4;
+ fixed_1d4.block_id = npcid;
+ send_fpacket<0x01d4, 6>(s, fixed_1d4);
}
/*==========================================
*
*------------------------------------------
*/
-void clif_viewpoint(dumb_ptr<map_session_data> sd, int npc_id, int type,
- int x, int y, int id, int color)
+int clif_additem(dumb_ptr<map_session_data> sd, IOff0 n, int amount, PickupFail fail)
{
- 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);
+ nullpo_retz(sd);
Session *s = sd->sess;
+ Packet_Fixed<0x00a0> fixed_a0;
if (fail != PickupFail::OKAY)
{
- WFIFOW(s, 0) = 0xa0;
- WFIFOW(s, 2) = n + 2;
- WFIFOW(s, 4) = amount;
- WFIFOW(s, 6) = 0;
- WFIFOB(s, 8) = 0;
- WFIFOB(s, 9) = 0;
- WFIFOB(s, 10) = 0;
- WFIFOW(s, 11) = 0;
- WFIFOW(s, 13) = 0;
- WFIFOW(s, 15) = 0;
- WFIFOW(s, 17) = 0;
- WFIFOW(s, 19) = 0;
- WFIFOB(s, 21) = 0;
- WFIFOB(s, 22) = uint8_t(fail);
+ fixed_a0.ioff2 = n.shift();
+ fixed_a0.amount = amount;
+ fixed_a0.name_id = ItemNameId();
+ fixed_a0.pickup_fail = fail;
}
else
{
- if (n < 0 || n >= MAX_INVENTORY || sd->status.inventory[n].nameid <= 0
- || sd->inventory_data[n] == NULL)
+ if (!n.ok() || !sd->status.inventory[n].nameid
+ || sd->inventory_data[n] == nullptr)
return 1;
- WFIFOW(s, 0) = 0xa0;
- WFIFOW(s, 2) = n + 2;
- WFIFOW(s, 4) = amount;
- WFIFOW(s, 6) = sd->status.inventory[n].nameid;
- WFIFOB(s, 8) = 1; //identify;
- WFIFOB(s, 9) = 0; // broken or attribute;
- WFIFOB(s, 10) = 0; //refine;
+ fixed_a0.ioff2 = n.shift();
+ fixed_a0.amount = amount;
+ fixed_a0.name_id = sd->status.inventory[n].nameid;
+ fixed_a0.identify = 1;
+ fixed_a0.broken_or_attribute = 0;
+ fixed_a0.refine = 0;
{
- WFIFOW(s, 11) = 0; //card[0];
- WFIFOW(s, 13) = 0; //card[1];
- WFIFOW(s, 15) = 0; //card[2];
- WFIFOW(s, 17) = 0; //card[3];
+ fixed_a0.card0 = 0;
+ fixed_a0.card1 = 0;
+ fixed_a0.card2 = 0;
+ fixed_a0.card3 = 0;
}
- WFIFOW(s, 19) = uint16_t(pc_equippoint(sd, n));
- WFIFOB(s, 21) = uint8_t(sd->inventory_data[n]->type == ItemType::_7
+ fixed_a0.epos = pc_equippoint(sd, n);
+ fixed_a0.item_type = (sd->inventory_data[n]->type == ItemType::_7
? ItemType::WEAPON
: sd->inventory_data[n]->type);
- WFIFOB(s, 22) = uint8_t(fail);
+ fixed_a0.pickup_fail = fail;
}
- WFIFOSET(s, clif_parse_func_table[0xa0].len);
+ send_fpacket<0x00a0, 23>(s, fixed_a0);
return 0;
}
@@ -1438,16 +1408,16 @@ int clif_additem(dumb_ptr<map_session_data> sd, int n, int amount, PickupFail fa
*
*------------------------------------------
*/
-void clif_delitem(dumb_ptr<map_session_data> sd, int n, int amount)
+void clif_delitem(dumb_ptr<map_session_data> sd, IOff0 n, int amount)
{
nullpo_retv(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xaf;
- WFIFOW(s, 2) = n + 2;
- WFIFOW(s, 4) = amount;
+ Packet_Fixed<0x00af> fixed_af;
+ fixed_af.ioff2 = n.shift();
+ fixed_af.amount = amount;
- WFIFOSET(s, clif_parse_func_table[0xaf].len);
+ send_fpacket<0x00af, 6>(s, fixed_af);
}
/*==========================================
@@ -1458,41 +1428,40 @@ void clif_itemlist(dumb_ptr<map_session_data> sd)
{
nullpo_retv(sd);
- int n = 0;
- int arrow = -1;
+ IOff0 arrow = IOff0::from(-1);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x1ee;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ std::vector<Packet_Repeat<0x01ee>> repeat_1ee;
+ for (IOff0 i : IOff0::iter())
{
- if (sd->status.inventory[i].nameid <= 0
- || sd->inventory_data[i] == NULL
+ if (!sd->status.inventory[i].nameid
+ || sd->inventory_data[i] == nullptr
|| itemdb_isequip2(sd->inventory_data[i]))
continue;
- WFIFOW(s, n * 18 + 4) = i + 2;
- WFIFOW(s, n * 18 + 6) = sd->status.inventory[i].nameid;
- WFIFOB(s, n * 18 + 8) = uint8_t(sd->inventory_data[i]->type);
- WFIFOB(s, n * 18 + 9) = 1; //identify;
- WFIFOW(s, n * 18 + 10) = sd->status.inventory[i].amount;
+ Packet_Repeat<0x01ee> info;
+ info.ioff2 = i.shift();
+ info.name_id = sd->status.inventory[i].nameid;
+ info.item_type = sd->inventory_data[i]->type;
+ info.identify = 1;
+ info.amount = sd->status.inventory[i].amount;
if (sd->inventory_data[i]->equip == EPOS::ARROW)
{
- WFIFOW(s, n * 18 + 12) = uint16_t(EPOS::ARROW);
+ info.epos = EPOS::ARROW;
if (bool(sd->status.inventory[i].equip))
- arrow = i; // ついでに矢装備チェック
+ arrow = i;
}
else
- WFIFOW(s, n * 18 + 12) = uint16_t(EPOS::ZERO);
- WFIFOW(s, n * 18 + 14) = 0; //card[0];
- WFIFOW(s, n * 18 + 16) = 0; //card[1];
- WFIFOW(s, n * 18 + 18) = 0; //card[2];
- WFIFOW(s, n * 18 + 20) = 0; //card[3];
- n++;
+ info.epos = EPOS::ZERO;
+ info.card0 = 0;
+ info.card1 = 0;
+ info.card2 = 0;
+ info.card3 = 0;
+ repeat_1ee.push_back(info);
}
- if (n)
+ if (!repeat_1ee.empty())
{
- WFIFOW(s, 2) = 4 + n * 18;
- WFIFOSET(s, WFIFOW(s, 2));
+ send_packet_repeatonly<0x01ee, 4, 18>(s, repeat_1ee);
}
- if (arrow >= 0)
+ if (arrow.ok())
clif_arrowequip(sd, arrow);
}
@@ -1505,37 +1474,36 @@ void clif_equiplist(dumb_ptr<map_session_data> sd)
nullpo_retv(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xa4;
- int n = 0;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ std::vector<Packet_Repeat<0x00a4>> repeat_a4;
+ for (IOff0 i : IOff0::iter())
{
- if (sd->status.inventory[i].nameid <= 0
- || sd->inventory_data[i] == NULL
+ if (!sd->status.inventory[i].nameid
+ || sd->inventory_data[i] == nullptr
|| !itemdb_isequip2(sd->inventory_data[i]))
continue;
- WFIFOW(s, n * 20 + 4) = i + 2;
- WFIFOW(s, n * 20 + 6) = sd->status.inventory[i].nameid;
- WFIFOB(s, n * 20 + 8) = uint8_t(
+ Packet_Repeat<0x00a4> info;
+ info.ioff2 = i.shift();
+ info.name_id = sd->status.inventory[i].nameid;
+ info.item_type = (
sd->inventory_data[i]->type == ItemType::_7
? ItemType::WEAPON
: sd->inventory_data[i]->type);
- WFIFOB(s, n * 20 + 9) = 0; //identify;
- WFIFOW(s, n * 20 + 10) = uint16_t(pc_equippoint(sd, i));
- WFIFOW(s, n * 20 + 12) = uint16_t(sd->status.inventory[i].equip);
- WFIFOB(s, n * 20 + 14) = 0; //broken or attribute;
- WFIFOB(s, n * 20 + 15) = 0; //refine;
+ info.identify = 0;
+ info.epos_pc = pc_equippoint(sd, i);
+ info.epos_inv = sd->status.inventory[i].equip;
+ info.broken_or_attribute = 0;
+ info.refine = 0;
{
- WFIFOW(s, n * 20 + 16) = 0; //card[0];
- WFIFOW(s, n * 20 + 18) = 0; //card[1];
- WFIFOW(s, n * 20 + 20) = 0; //card[2];
- WFIFOW(s, n * 20 + 22) = 0; //card[3];
+ info.card0 = 0;
+ info.card1 = 0;
+ info.card2 = 0;
+ info.card3 = 0;
}
- n++;
+ repeat_a4.push_back(info);
}
- if (n)
+ if (!repeat_a4.empty())
{
- WFIFOW(s, 2) = 4 + n * 20;
- WFIFOSET(s, WFIFOW(s, 2));
+ send_packet_repeatonly<0x00a4, 4, 20>(s, repeat_a4);
}
}
@@ -1543,41 +1511,40 @@ void clif_equiplist(dumb_ptr<map_session_data> sd)
* カプラさんに預けてある消耗品&収集品リスト
*------------------------------------------
*/
-int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor)
+int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor)
{
- nullpo_ret(sd);
- nullpo_ret(stor);
+ nullpo_retz(sd);
+ nullpo_retz(stor);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x1f0;
- int n = 0;
- for (int i = 0; i < MAX_STORAGE; i++)
+ std::vector<Packet_Repeat<0x01f0>> repeat_1f0;
+ for (SOff0 i : SOff0::iter())
{
- if (stor->storage_[i].nameid <= 0)
+ if (!stor->storage_[i].nameid)
continue;
struct item_data *id;
id = itemdb_search(stor->storage_[i].nameid);
- nullpo_ret(id);
+ nullpo_retz(id);
if (itemdb_isequip2(id))
continue;
- WFIFOW(s, n * 18 + 4) = i + 1;
- WFIFOW(s, n * 18 + 6) = stor->storage_[i].nameid;
- WFIFOB(s, n * 18 + 8) = uint8_t(id->type);
- WFIFOB(s, n * 18 + 9) = 0; //identify;
- WFIFOW(s, n * 18 + 10) = stor->storage_[i].amount;
- WFIFOW(s, n * 18 + 12) = 0;
- WFIFOW(s, n * 18 + 14) = 0; //card[0];
- WFIFOW(s, n * 18 + 16) = 0; //card[1];
- WFIFOW(s, n * 18 + 18) = 0; //card[2];
- WFIFOW(s, n * 18 + 20) = 0; //card[3];
- n++;
+ Packet_Repeat<0x01f0> info;
+ info.soff1 = i.shift();
+ info.name_id = stor->storage_[i].nameid;
+ info.item_type = id->type;
+ info.identify = 0;
+ info.amount = stor->storage_[i].amount;
+ info.epos_zero = EPOS::ZERO;
+ info.card0 = 0;
+ info.card1 = 0;
+ info.card2 = 0;
+ info.card3 = 0;
+ repeat_1f0.push_back(info);
}
- if (n)
+ if (!repeat_1f0.empty())
{
- WFIFOW(s, 2) = 4 + n * 18;
- WFIFOSET(s, WFIFOW(s, 2));
+ send_packet_repeatonly<0x01f0, 4, 18>(s, repeat_1f0);
}
return 0;
}
@@ -1586,44 +1553,43 @@ int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor)
* カプラさんに預けてある装備リスト
*------------------------------------------
*/
-int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor)
+int clif_storageequiplist(dumb_ptr<map_session_data> sd, Storage *stor)
{
- nullpo_ret(sd);
- nullpo_ret(stor);
+ nullpo_retz(sd);
+ nullpo_retz(stor);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xa6;
- int n = 0;
- for (int i = 0; i < MAX_STORAGE; i++)
+ std::vector<Packet_Repeat<0x00a6>> repeat_a6;
+ for (SOff0 i : SOff0::iter())
{
- if (stor->storage_[i].nameid <= 0)
+ if (!stor->storage_[i].nameid)
continue;
struct item_data *id;
id = itemdb_search(stor->storage_[i].nameid);
- nullpo_ret(id);
+ nullpo_retz(id);
if (!itemdb_isequip2(id))
continue;
- WFIFOW(s, n * 20 + 4) = i + 1;
- WFIFOW(s, n * 20 + 6) = stor->storage_[i].nameid;
- WFIFOB(s, n * 20 + 8) = uint8_t(id->type);
- WFIFOB(s, n * 20 + 9) = 0; //identify;
- WFIFOW(s, n * 20 + 10) = uint16_t(id->equip);
- WFIFOW(s, n * 20 + 12) = uint16_t(stor->storage_[i].equip);
- WFIFOB(s, n * 20 + 14) = 0; //broken or attribute
- WFIFOB(s, n * 20 + 15) = 0; //refine;
+ Packet_Repeat<0x00a6> info;
+ info.soff1 = i.shift();
+ info.name_id = stor->storage_[i].nameid;
+ info.item_type = id->type;
+ info.identify = 0;
+ info.epos_id = id->equip;
+ info.epos_stor = stor->storage_[i].equip;
+ info.broken_or_attribute = 0;
+ info.refine = 0;
{
- WFIFOW(s, n * 20 + 16) = 0; //card[0];
- WFIFOW(s, n * 20 + 18) = 0; //card[1];
- WFIFOW(s, n * 20 + 20) = 0; //card[2];
- WFIFOW(s, n * 20 + 22) = 0; //card[3];
+ info.card0 = 0;
+ info.card1 = 0;
+ info.card2 = 0;
+ info.card3 = 0;
}
- n++;
+ repeat_a6.push_back(info);
}
- if (n)
+ if (!repeat_a6.empty())
{
- WFIFOW(s, 2) = 4 + n * 20;
- WFIFOSET(s, WFIFOW(s, 2));
+ send_packet_repeatonly<0x00a6, 4, 20>(s, repeat_a6);
}
return 0;
}
@@ -1635,140 +1601,183 @@ int clif_storageequiplist(dumb_ptr<map_session_data> sd, struct storage *stor)
*/
int clif_updatestatus(dumb_ptr<map_session_data> sd, SP type)
{
- int len = 8;
-
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xb0;
- WFIFOW(s, 2) = static_cast<uint16_t>(type);
- switch (type)
{
- // 00b0
+ Packet_Fixed<0x00b0> fixed_b0;
+ fixed_b0.sp_type = type;
+ switch (type)
+ {
case SP::WEIGHT:
pc_checkweighticon(sd);
- // is this because pc_checkweighticon can send other packets?
- WFIFOW(s, 0) = 0xb0;
- WFIFOW(s, 2) = static_cast<uint16_t>(type);
- WFIFOL(s, 4) = sd->weight;
+ fixed_b0.value = sd->weight;
break;
case SP::MAXWEIGHT:
- WFIFOL(s, 4) = sd->max_weight;
+ fixed_b0.value = sd->max_weight;
break;
case SP::SPEED:
- // ...
- WFIFOL(s, 4) = static_cast<uint16_t>(sd->speed.count());
+ // 'speed' is actually delay, in milliseconds
+ fixed_b0.value = sd->speed.count();
break;
case SP::BASELEVEL:
- WFIFOL(s, 4) = sd->status.base_level;
+ fixed_b0.value = sd->status.base_level;
break;
case SP::JOBLEVEL:
- WFIFOL(s, 4) = 0;
+ fixed_b0.value = sd->status.job_level;
break;
case SP::STATUSPOINT:
- WFIFOL(s, 4) = sd->status.status_point;
+ fixed_b0.value = sd->status.status_point;
break;
case SP::SKILLPOINT:
- WFIFOL(s, 4) = sd->status.skill_point;
+ fixed_b0.value = sd->status.skill_point;
break;
case SP::HIT:
- WFIFOL(s, 4) = sd->hit;
+ fixed_b0.value = sd->hit;
break;
case SP::FLEE1:
- WFIFOL(s, 4) = sd->flee;
+ fixed_b0.value = sd->flee;
break;
case SP::FLEE2:
- WFIFOL(s, 4) = sd->flee2 / 10;
+ fixed_b0.value = sd->flee2 / 10;
break;
case SP::MAXHP:
- WFIFOL(s, 4) = sd->status.max_hp;
+ fixed_b0.value = sd->status.max_hp;
break;
case SP::MAXSP:
- WFIFOL(s, 4) = sd->status.max_sp;
+ fixed_b0.value = sd->status.max_sp;
break;
case SP::HP:
- WFIFOL(s, 4) = sd->status.hp;
+ fixed_b0.value = sd->status.hp;
break;
case SP::SP:
- WFIFOL(s, 4) = sd->status.sp;
+ fixed_b0.value = sd->status.sp;
break;
case SP::ASPD:
- WFIFOL(s, 4) = static_cast<uint16_t>(sd->aspd.count());
+ fixed_b0.value = sd->aspd.count();
break;
case SP::ATK1:
- WFIFOL(s, 4) = sd->base_atk + sd->watk;
+ fixed_b0.value = sd->base_atk + sd->watk;
break;
case SP::DEF1:
- WFIFOL(s, 4) = sd->def;
+ fixed_b0.value = sd->def;
break;
case SP::MDEF1:
- WFIFOL(s, 4) = sd->mdef;
+ fixed_b0.value = sd->mdef;
break;
case SP::ATK2:
- WFIFOL(s, 4) = sd->watk2;
+ fixed_b0.value = sd->watk2;
break;
case SP::DEF2:
- WFIFOL(s, 4) = sd->def2;
+ fixed_b0.value = sd->def2;
break;
case SP::MDEF2:
- WFIFOL(s, 4) = sd->mdef2;
+ fixed_b0.value = sd->mdef2;
break;
case SP::CRITICAL:
- WFIFOL(s, 4) = sd->critical / 10;
+ fixed_b0.value = sd->critical / 10;
break;
case SP::MATK1:
- WFIFOL(s, 4) = sd->matk1;
+ fixed_b0.value = sd->matk1;
break;
case SP::MATK2:
- WFIFOL(s, 4) = sd->matk2;
+ fixed_b0.value = sd->matk2;
+ break;
+ case SP::GM:
+ fixed_b0.value = pc_isGM(sd).get_all_bits();
break;
+ default:
+ goto not_b0;
+ }
+
+ send_fpacket<0x00b0, 8>(s, fixed_b0);
+ return 0;
+ }
+not_b0:
+
+ {
+ Packet_Fixed<0x00b1> fixed_b1;
+ fixed_b1.sp_type = type;
+ switch (type)
+ {
case SP::ZENY:
trade_verifyzeny(sd);
- WFIFOW(s, 0) = 0xb1;
if (sd->status.zeny < 0)
sd->status.zeny = 0;
- WFIFOL(s, 4) = sd->status.zeny;
+ fixed_b1.value = sd->status.zeny;
break;
+
case SP::BASEEXP:
- WFIFOW(s, 0) = 0xb1;
- WFIFOL(s, 4) = sd->status.base_exp;
+ fixed_b1.value = sd->status.base_exp;
break;
case SP::JOBEXP:
- WFIFOW(s, 0) = 0xb1;
- WFIFOL(s, 4) = sd->status.job_exp;
+ fixed_b1.value = sd->status.job_exp;
break;
case SP::NEXTBASEEXP:
- WFIFOW(s, 0) = 0xb1;
- WFIFOL(s, 4) = pc_nextbaseexp(sd);
+ fixed_b1.value = pc_nextbaseexp(sd);
break;
case SP::NEXTJOBEXP:
- WFIFOW(s, 0) = 0xb1;
- WFIFOL(s, 4) = pc_nextjobexp(sd);
+ fixed_b1.value = pc_nextjobexp(sd);
break;
- // 00be 終了
+ default:
+ goto not_b1;
+ }
+
+ send_fpacket<0x00b1, 8>(s, fixed_b1);
+ return 0;
+ }
+not_b1:
+
+ {
+ Packet_Fixed<0x00be> fixed_be;
+ fixed_be.sp_type = type;
+ switch (type)
+ {
case SP::USTR:
case SP::UAGI:
case SP::UVIT:
case SP::UINT:
case SP::UDEX:
case SP::ULUK:
- WFIFOW(s, 0) = 0xbe;
- WFIFOB(s, 4) = pc_need_status_point(sd, usp_to_sp(type));
- len = 5;
+ fixed_be.value = pc_need_status_point(sd, usp_to_sp(type));
break;
- // 013a 終了
+ default:
+ goto not_be;
+ }
+
+ send_fpacket<0x00be, 5>(s, fixed_be);
+ return 0;
+ }
+not_be:
+
+ {
+ Packet_Fixed<0x013a> fixed_13a;
+ switch (type)
+ {
case SP::ATTACKRANGE:
- WFIFOW(s, 0) = 0x13a;
- WFIFOW(s, 2) = (sd->attack_spell_override)
- ? sd->attack_spell_range : sd->attackrange;
- len = 4;
+ fixed_13a.attack_range = (sd->attack_spell_override
+ ? sd->attack_spell_range
+ : sd->attackrange);
break;
- // 0141 終了
+ default:
+ goto not_13a;
+ }
+
+ send_fpacket<0x013a, 4>(s, fixed_13a);
+ return 0;
+ }
+not_13a:
+
+ {
+ Packet_Fixed<0x00141> fixed_141;
+ fixed_141.sp_type = type;
+ switch (type)
+ {
case SP::STR:
case SP::AGI:
case SP::VIT:
@@ -1777,27 +1786,28 @@ int clif_updatestatus(dumb_ptr<map_session_data> sd, SP type)
case SP::LUK:
{
ATTR attr = sp_to_attr(type);
- WFIFOW(s, 0) = 0x141;
- WFIFOL(s, 2) = uint16_t(type);
- WFIFOL(s, 6) = sd->status.attrs[attr];
- WFIFOL(s, 10) = sd->paramb[attr] + sd->parame[attr];
- len = 14;
+ fixed_141.value_status = sd->status.attrs[attr];
+ fixed_141.value_b_e = sd->paramb[attr] + sd->parame[attr];
}
break;
- case SP::GM:
- WFIFOL(s, 4) = pc_isGM(sd);
- break;
-
default:
+ goto not_141;
+ }
+
+ send_fpacket<0x0141, 14>(s, fixed_141);
+ return 0;
+ }
+
+not_141:
+ {
+ {
if (battle_config.error_log)
- PRINTF("clif_updatestatus : make %d routine\n",
+ PRINTF("clif_updatestatus : make %d routine\n"_fmt,
type);
return 1;
+ }
}
- WFIFOSET(s, len);
-
- return 0;
}
/*==========================================
@@ -1806,16 +1816,15 @@ int clif_updatestatus(dumb_ptr<map_session_data> sd, SP type)
*/
int clif_changelook(dumb_ptr<block_list> bl, LOOK type, int val)
{
- return clif_changelook_towards(bl, type, val, NULL);
+ return clif_changelook_towards(bl, type, val, nullptr);
}
int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
dumb_ptr<map_session_data> dstsd)
{
- unsigned char buf[32];
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::PC)
sd = bl->is_player();
@@ -1826,61 +1835,65 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
if (sd
&& (type == LOOK::WEAPON || type == LOOK::SHIELD || type >= LOOK::SHOES))
{
- WBUFW(buf, 0) = 0x1d7;
- WBUFL(buf, 2) = bl->bl_id;
+ Packet_Fixed<0x01d7> fixed_1d7;
+ fixed_1d7.block_id = bl->bl_id;
if (type >= LOOK::SHOES)
{
EQUIP equip_point = equip_points[type];
- WBUFB(buf, 6) = uint16_t(type);
- int idx = sd->equip_index_maybe[equip_point];
- if (idx >= 0 && sd->inventory_data[idx])
+ fixed_1d7.look_type = type;
+ IOff0 idx = sd->equip_index_maybe[equip_point];
+ if (idx.ok() && sd->inventory_data[idx])
{
- WBUFW(buf, 7) = sd->status.inventory[idx].nameid;
+ fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->status.inventory[idx].nameid);
}
else
- WBUFW(buf, 7) = 0;
- WBUFW(buf, 9) = 0;
+ fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(ItemNameId());
+ fixed_1d7.shield = ItemNameId();
}
else
{
- WBUFB(buf, 6) = 2;
- int widx = sd->equip_index_maybe[EQUIP::WEAPON];
- int sidx = sd->equip_index_maybe[EQUIP::SHIELD];
+ fixed_1d7.look_type = LOOK::WEAPON;
+ IOff0 widx = sd->equip_index_maybe[EQUIP::WEAPON];
+ IOff0 sidx = sd->equip_index_maybe[EQUIP::SHIELD];
if (sd->attack_spell_override)
- WBUFW(buf, 7) = sd->attack_spell_look_override;
+ fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->attack_spell_look_override);
else
{
- if (widx >= 0 && sd->inventory_data[widx])
+ if (widx.ok() && sd->inventory_data[widx])
{
- WBUFW(buf, 7) = sd->status.inventory[widx].nameid;
+ fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(sd->status.inventory[widx].nameid);
}
else
- WBUFW(buf, 7) = 0;
+ fixed_1d7.weapon_or_name_id_or_value = unwrap<ItemNameId>(ItemNameId());
}
- if (sidx >= 0 && sidx != widx && sd->inventory_data[sidx])
+ if (sidx.ok() && sidx != widx && sd->inventory_data[sidx])
{
- WBUFW(buf, 9) = sd->status.inventory[sidx].nameid;
+ fixed_1d7.shield = sd->status.inventory[sidx].nameid;
}
else
- WBUFW(buf, 9) = 0;
+ fixed_1d7.shield = ItemNameId();
}
+
+ Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7);
if (dstsd)
- clif_send(buf, clif_parse_func_table[0x1d7].len, dstsd, SendWho::SELF);
+ clif_send(buf, dstsd, SendWho::SELF);
else
- clif_send(buf, clif_parse_func_table[0x1d7].len, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA);
}
else
{
- WBUFW(buf, 0) = 0x1d7;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFB(buf, 6) = uint8_t(type);
- WBUFW(buf, 7) = val;
- WBUFW(buf, 9) = 0;
+ Packet_Fixed<0x01d7> fixed_1d7;
+ fixed_1d7.block_id = bl->bl_id;
+ fixed_1d7.look_type = type;
+ fixed_1d7.weapon_or_name_id_or_value = val;
+ fixed_1d7.shield = ItemNameId();
+
+ Buffer buf = create_fpacket<0x01d7, 11>(fixed_1d7);
if (dstsd)
- clif_send(buf, clif_parse_func_table[0x1d7].len, dstsd, SendWho::SELF);
+ clif_send(buf, dstsd, SendWho::SELF);
else
- clif_send(buf, clif_parse_func_table[0x1d7].len, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA);
}
return 0;
}
@@ -1892,42 +1905,42 @@ int clif_changelook_towards(dumb_ptr<block_list> bl, LOOK type, int val,
static
int clif_initialstatus(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xbd;
- WFIFOW(s, 2) = sd->status.status_point;
-
- WFIFOB(s, 4) = min(sd->status.attrs[ATTR::STR], 255);
- WFIFOB(s, 5) = pc_need_status_point(sd, SP::STR);
- WFIFOB(s, 6) = min(sd->status.attrs[ATTR::AGI], 255);
- WFIFOB(s, 7) = pc_need_status_point(sd, SP::AGI);
- WFIFOB(s, 8) = min(sd->status.attrs[ATTR::VIT], 255);
- WFIFOB(s, 9) = pc_need_status_point(sd, SP::VIT);
- WFIFOB(s, 10) = min(sd->status.attrs[ATTR::INT], 255);
- WFIFOB(s, 11) = pc_need_status_point(sd, SP::INT);
- WFIFOB(s, 12) = min(sd->status.attrs[ATTR::DEX], 255);
- WFIFOB(s, 13) = pc_need_status_point(sd, SP::DEX);
- WFIFOB(s, 14) = min(sd->status.attrs[ATTR::LUK], 255);
- WFIFOB(s, 15) = pc_need_status_point(sd, SP::LUK);
-
- WFIFOW(s, 16) = sd->base_atk + sd->watk;
- WFIFOW(s, 18) = sd->watk2; //atk bonus
- WFIFOW(s, 20) = sd->matk1;
- WFIFOW(s, 22) = sd->matk2;
- WFIFOW(s, 24) = sd->def; // def
- WFIFOW(s, 26) = sd->def2;
- WFIFOW(s, 28) = sd->mdef; // mdef
- WFIFOW(s, 30) = sd->mdef2;
- WFIFOW(s, 32) = sd->hit;
- WFIFOW(s, 34) = sd->flee;
- WFIFOW(s, 36) = sd->flee2 / 10;
- WFIFOW(s, 38) = sd->critical / 10;
- WFIFOW(s, 40) = sd->status.karma;
- WFIFOW(s, 42) = sd->status.manner;
-
- WFIFOSET(s, clif_parse_func_table[0xbd].len);
+ Packet_Fixed<0x00bd> fixed_bd;
+ fixed_bd.status_point = sd->status.status_point;
+
+ fixed_bd.str_attr = saturate<uint8_t>(sd->status.attrs[ATTR::STR]);
+ fixed_bd.str_upd = pc_need_status_point(sd, SP::STR);
+ fixed_bd.agi_attr = saturate<uint8_t>(sd->status.attrs[ATTR::AGI]);
+ fixed_bd.agi_upd = pc_need_status_point(sd, SP::AGI);
+ fixed_bd.vit_attr = saturate<uint8_t>(sd->status.attrs[ATTR::VIT]);
+ fixed_bd.vit_upd = pc_need_status_point(sd, SP::VIT);
+ fixed_bd.int_attr = saturate<uint8_t>(sd->status.attrs[ATTR::INT]);
+ fixed_bd.int_upd = pc_need_status_point(sd, SP::INT);
+ fixed_bd.dex_attr = saturate<uint8_t>(sd->status.attrs[ATTR::DEX]);
+ fixed_bd.dex_upd = pc_need_status_point(sd, SP::DEX);
+ fixed_bd.luk_attr = saturate<uint8_t>(sd->status.attrs[ATTR::LUK]);
+ fixed_bd.luk_upd = pc_need_status_point(sd, SP::LUK);
+
+ fixed_bd.atk_sum = sd->base_atk + sd->watk;
+ fixed_bd.watk2 = sd->watk2; //atk bonus
+ fixed_bd.matk1 = sd->matk1;
+ fixed_bd.matk2 = sd->matk2;
+ fixed_bd.def = sd->def;
+ fixed_bd.def2 = sd->def2;
+ fixed_bd.mdef = sd->mdef;
+ fixed_bd.mdef2 = sd->mdef2;
+ fixed_bd.hit = sd->hit;
+ fixed_bd.flee = sd->flee;
+ fixed_bd.flee2 = sd->flee2 / 10;
+ fixed_bd.critical = sd->critical / 10;
+ fixed_bd.karma = sd->status.karma;
+ fixed_bd.manner = sd->status.manner;
+
+ send_fpacket<0x00bd, 44>(s, fixed_bd);
clif_updatestatus(sd, SP::STR);
clif_updatestatus(sd, SP::AGI);
@@ -1946,18 +1959,16 @@ int clif_initialstatus(dumb_ptr<map_session_data> sd)
*矢装備
*------------------------------------------
*/
-int clif_arrowequip(dumb_ptr<map_session_data> sd, int val)
+int clif_arrowequip(dumb_ptr<map_session_data> sd, IOff0 val)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if (sd->attacktarget && sd->attacktarget > 0) // [Valaris]
- sd->attacktarget = 0;
+ sd->attacktarget = BlockId();
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x013c;
- WFIFOW(s, 2) = val + 2; //矢のアイテムID
-
- WFIFOSET(s, clif_parse_func_table[0x013c].len);
+ Packet_Fixed<0x013c> fixed_13c;
+ fixed_13c.ioff2 = val.shift();
+ send_fpacket<0x013c, 4>(s, fixed_13c);
return 0;
}
@@ -1968,14 +1979,13 @@ int clif_arrowequip(dumb_ptr<map_session_data> sd, int val)
*/
int clif_arrow_fail(dumb_ptr<map_session_data> sd, int type)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x013b;
- WFIFOW(s, 2) = type;
-
- WFIFOSET(s, clif_parse_func_table[0x013b].len);
+ Packet_Fixed<0x013b> fixed_13b;
+ fixed_13b.type = type;
+ send_fpacket<0x013b, 4>(s, fixed_13b);
return 0;
}
@@ -1986,14 +1996,14 @@ int clif_arrow_fail(dumb_ptr<map_session_data> sd, int type)
*/
int clif_statusupack(dumb_ptr<map_session_data> sd, SP type, int ok, int val)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xbc;
- WFIFOW(s, 2) = uint16_t(type);
- WFIFOB(s, 4) = ok;
- WFIFOB(s, 5) = val;
- WFIFOSET(s, clif_parse_func_table[0xbc].len);
+ Packet_Fixed<0x00bc> fixed_bc;
+ fixed_bc.sp_type = type;
+ fixed_bc.ok = ok;
+ fixed_bc.val = val;
+ send_fpacket<0x00bc, 6>(s, fixed_bc);
return 0;
}
@@ -2002,16 +2012,16 @@ int clif_statusupack(dumb_ptr<map_session_data> sd, SP type, int ok, int val)
*
*------------------------------------------
*/
-int clif_equipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok)
+int clif_equipitemack(dumb_ptr<map_session_data> sd, IOff0 n, EPOS pos, int ok)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xaa;
- WFIFOW(s, 2) = n + 2;
- WFIFOW(s, 4) = uint16_t(pos);
- WFIFOB(s, 6) = ok;
- WFIFOSET(s, clif_parse_func_table[0xaa].len);
+ Packet_Fixed<0x00aa> fixed_aa;
+ fixed_aa.ioff2 = n.shift();
+ fixed_aa.epos = pos;
+ fixed_aa.ok = ok;
+ send_fpacket<0x00aa, 7>(s, fixed_aa);
return 0;
}
@@ -2020,16 +2030,16 @@ int clif_equipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok)
*
*------------------------------------------
*/
-int clif_unequipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok)
+int clif_unequipitemack(dumb_ptr<map_session_data> sd, IOff0 n, EPOS pos, int ok)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xac;
- WFIFOW(s, 2) = n + 2;
- WFIFOW(s, 4) = uint16_t(pos);
- WFIFOB(s, 6) = ok;
- WFIFOSET(s, clif_parse_func_table[0xac].len);
+ Packet_Fixed<0x00ac> fixed_ac;
+ fixed_ac.ioff2 = n.shift();
+ fixed_ac.epos = pos;
+ fixed_ac.ok = ok;
+ send_fpacket<0x00ac, 7>(s, fixed_ac);
return 0;
}
@@ -2040,15 +2050,14 @@ int clif_unequipitemack(dumb_ptr<map_session_data> sd, int n, EPOS pos, int ok)
*/
int clif_misceffect(dumb_ptr<block_list> bl, int type)
{
- uint8_t buf[32];
+ nullpo_retz(bl);
- nullpo_ret(bl);
+ Packet_Fixed<0x019b> fixed_19b;
+ fixed_19b.block_id = bl->bl_id;
+ fixed_19b.type = type;
+ Buffer buf = create_fpacket<0x019b, 10>(fixed_19b);
- WBUFW(buf, 0) = 0x19b;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFL(buf, 6) = type;
-
- clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA);
return 0;
}
@@ -2059,22 +2068,22 @@ int clif_misceffect(dumb_ptr<block_list> bl, int type)
*/
int clif_changeoption(dumb_ptr<block_list> bl)
{
- uint8_t buf[32];
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
Option option = *battle_get_option(bl);
sc_data = battle_get_sc_data(bl);
- WBUFW(buf, 0) = 0x119;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFW(buf, 6) = uint16_t(*battle_get_opt1(bl));
- WBUFW(buf, 8) = uint16_t(*battle_get_opt2(bl));
- WBUFW(buf, 10) = uint16_t(option);
- WBUFB(buf, 12) = 0; // ??
+ Packet_Fixed<0x0119> fixed_119;
+ fixed_119.block_id = bl->bl_id;
+ fixed_119.opt1 = *battle_get_opt1(bl);
+ fixed_119.opt2 = *battle_get_opt2(bl);
+ fixed_119.option = option;
+ fixed_119.zero = 0;
+ Buffer buf = create_fpacket<0x0119, 13>(fixed_119);
- clif_send(buf, clif_parse_func_table[0x119].len, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA);
return 0;
}
@@ -2083,31 +2092,30 @@ int clif_changeoption(dumb_ptr<block_list> bl)
*
*------------------------------------------
*/
-int clif_useitemack(dumb_ptr<map_session_data> sd, int index, int amount,
+int clif_useitemack(dumb_ptr<map_session_data> sd, IOff0 index, int amount,
int ok)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (!ok)
{
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xa8;
- WFIFOW(s, 2) = index + 2;
- WFIFOW(s, 4) = amount;
- WFIFOB(s, 6) = ok;
- WFIFOSET(s, clif_parse_func_table[0xa8].len);
+ Packet_Fixed<0x00a8> fixed_a8;
+ fixed_a8.ioff2 = index.shift();
+ fixed_a8.amount = amount;
+ fixed_a8.ok = ok;
+ send_fpacket<0x00a8, 7>(s, fixed_a8);
}
else
{
- uint8_t buf[32];
-
- 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, 10) = amount;
- WBUFB(buf, 12) = ok;
- clif_send(buf, clif_parse_func_table[0x1c8].len, sd, SendWho::SELF);
+ Packet_Fixed<0x01c8> fixed_1c8;
+ fixed_1c8.ioff2 = index.shift();
+ fixed_1c8.name_id = sd->status.inventory[index].nameid;
+ fixed_1c8.block_id = sd->bl_id;
+ fixed_1c8.amount = amount;
+ fixed_1c8.ok = ok;
+ Buffer buf = create_fpacket<0x01c8, 13>(fixed_1c8);
+ clif_send(buf, sd, SendWho::SELF);
}
return 0;
@@ -2122,9 +2130,9 @@ void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name)
nullpo_retv(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xe5;
- WFIFO_STRING(s, 2, name.to__actual(), 24);
- WFIFOSET(s, clif_parse_func_table[0xe5].len);
+ Packet_Fixed<0x00e5> fixed_e5;
+ fixed_e5.char_name = name;
+ send_fpacket<0x00e5, 26>(s, fixed_e5);
}
/*==========================================
@@ -2136,9 +2144,9 @@ void clif_tradestart(dumb_ptr<map_session_data> sd, int type)
nullpo_retv(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xe7;
- WFIFOB(s, 2) = type;
- WFIFOSET(s, clif_parse_func_table[0xe7].len);
+ Packet_Fixed<0x00e7> fixed_e7;
+ fixed_e7.type = type;
+ send_fpacket<0x00e7, 3>(s, fixed_e7);
}
/*==========================================
@@ -2146,57 +2154,57 @@ void clif_tradestart(dumb_ptr<map_session_data> sd, int type)
*------------------------------------------
*/
void clif_tradeadditem(dumb_ptr<map_session_data> sd,
- dumb_ptr<map_session_data> tsd, int index, int amount)
+ dumb_ptr<map_session_data> tsd, IOff2 index2, int amount)
{
nullpo_retv(sd);
nullpo_retv(tsd);
Session *s = tsd->sess;
- WFIFOW(s, 0) = 0xe9;
- WFIFOL(s, 2) = amount;
- if (index == 0)
+ Packet_Fixed<0x00e9> fixed_e9;
+ fixed_e9.amount = amount;
+ if (!index2.ok())
{
- WFIFOW(s, 6) = 0; // type id
- WFIFOB(s, 8) = 0; //identify flag
- WFIFOB(s, 9) = 0; // attribute
- WFIFOB(s, 10) = 0; //refine
- WFIFOW(s, 11) = 0; //card (4w)
- WFIFOW(s, 13) = 0; //card (4w)
- WFIFOW(s, 15) = 0; //card (4w)
- WFIFOW(s, 17) = 0; //card (4w)
+ fixed_e9.name_id = ItemNameId();
+ fixed_e9.identify = 0;
+ fixed_e9.broken_or_attribute = 0;
+ fixed_e9.refine = 0;
+ fixed_e9.card0 = 0;
+ fixed_e9.card1 = 0;
+ fixed_e9.card2 = 0;
+ fixed_e9.card3 = 0;
}
else
{
- index -= 2;
- WFIFOW(s, 6) = sd->status.inventory[index].nameid; // type id
- WFIFOB(s, 8) = 0; //identify;
- WFIFOB(s, 9) = 0; //broken or attribute;
- WFIFOB(s, 10) = 0; //refine;
+ IOff0 index0 = index2.unshift();
+ fixed_e9.name_id = sd->status.inventory[index0].nameid;
+ fixed_e9.identify = 0;
+ fixed_e9.broken_or_attribute = 0;
+ fixed_e9.refine = 0;
{
- WFIFOW(s, 11) = 0; //card[0];
- WFIFOW(s, 13) = 0; //card[1];
- WFIFOW(s, 15) = 0; //card[2];
- WFIFOW(s, 17) = 0; //card[3];
+ fixed_e9.card0 = 0;
+ fixed_e9.card1 = 0;
+ fixed_e9.card2 = 0;
+ fixed_e9.card3 = 0;
}
}
- WFIFOSET(s, clif_parse_func_table[0xe9].len);
+ send_fpacket<0x00e9, 19>(s, fixed_e9);
}
/*==========================================
* アイテム追加成功/失敗
*------------------------------------------
*/
-int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount,
+int clif_tradeitemok(dumb_ptr<map_session_data> sd, IOff2 index2, int amount,
int fail)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x1b1;
- WFIFOW(s, 2) = index;
- WFIFOW(s, 4) = amount;
- WFIFOB(s, 6) = fail;
- WFIFOSET(s, clif_parse_func_table[0x1b1].len);
+ Packet_Fixed<0x01b1> fixed_1b1;
+ fixed_1b1.ioff2 = index2;
+ fixed_1b1.amount = amount;
+ fixed_1b1.fail = fail;
+ send_fpacket<0x01b1, 7>(s, fixed_1b1);
return 0;
}
@@ -2207,12 +2215,12 @@ int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount,
*/
int clif_tradedeal_lock(dumb_ptr<map_session_data> sd, int fail)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xec;
- WFIFOB(s, 2) = fail; // 0=you 1=the other person
- WFIFOSET(s, clif_parse_func_table[0xec].len);
+ Packet_Fixed<0x00ec> fixed_ec;
+ fixed_ec.fail = fail; // 0=you 1=the other person
+ send_fpacket<0x00ec, 3>(s, fixed_ec);
return 0;
}
@@ -2223,11 +2231,11 @@ int clif_tradedeal_lock(dumb_ptr<map_session_data> sd, int fail)
*/
int clif_tradecancelled(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xee;
- WFIFOSET(s, clif_parse_func_table[0xee].len);
+ Packet_Fixed<0x00ee> fixed_ee;
+ send_fpacket<0x00ee, 2>(s, fixed_ee);
return 0;
}
@@ -2238,12 +2246,12 @@ int clif_tradecancelled(dumb_ptr<map_session_data> sd)
*/
int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xf0;
- WFIFOB(s, 2) = fail;
- WFIFOSET(s, clif_parse_func_table[0xf0].len);
+ Packet_Fixed<0x00f0> fixed_f0;
+ fixed_f0.fail = fail;
+ send_fpacket<0x00f0, 3>(s, fixed_f0);
return 0;
}
@@ -2253,16 +2261,16 @@ int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail)
*------------------------------------------
*/
int clif_updatestorageamount(dumb_ptr<map_session_data> sd,
- struct storage *stor)
+ Storage *stor)
{
- nullpo_ret(sd);
- nullpo_ret(stor);
+ nullpo_retz(sd);
+ nullpo_retz(stor);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xf2; // update storage amount
- WFIFOW(s, 2) = stor->storage_amount; //items
- WFIFOW(s, 4) = MAX_STORAGE; //items max
- WFIFOSET(s, clif_parse_func_table[0xf2].len);
+ Packet_Fixed<0x00f2> fixed_f2;
+ fixed_f2.current_slots = stor->storage_amount; //items
+ fixed_f2.max_slots = MAX_STORAGE; //items max
+ send_fpacket<0x00f2, 6>(s, fixed_f2);
return 0;
}
@@ -2271,30 +2279,27 @@ int clif_updatestorageamount(dumb_ptr<map_session_data> sd,
* カプラ倉庫にアイテムを追加する
*------------------------------------------
*/
-int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor,
- int index, int amount)
+int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor,
+ SOff0 index, int amount)
{
- nullpo_ret(sd);
- nullpo_ret(stor);
+ nullpo_retz(sd);
+ nullpo_retz(stor);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xf4; // Storage item added
- WFIFOW(s, 2) = index + 1; // index
- WFIFOL(s, 4) = amount; // amount
-/* if ((view = itemdb_viewid(stor->storage_[index].nameid)) > 0)
- WFIFOW(fd,8) =view;
- else*/
- WFIFOW(s, 8) = stor->storage_[index].nameid;
- WFIFOB(s, 10) = 0; //identify;
- WFIFOB(s, 11) = 0; //broken or attribute;
- WFIFOB(s, 12) = 0; //refine;
+ Packet_Fixed<0x00f4> fixed_f4;
+ fixed_f4.soff1 = index.shift();
+ fixed_f4.amount = amount;
+ fixed_f4.name_id = stor->storage_[index].nameid;
+ fixed_f4.identify = 0;
+ fixed_f4.broken_or_attribute = 0;
+ fixed_f4.refine = 0;
{
- WFIFOW(s, 13) = 0; //card[0];
- WFIFOW(s, 15) = 0; //card[1];
- WFIFOW(s, 17) = 0; //card[2];
- WFIFOW(s, 19) = 0; //card[3];
+ fixed_f4.card0 = 0;
+ fixed_f4.card1 = 0;
+ fixed_f4.card2 = 0;
+ fixed_f4.card3 = 0;
}
- WFIFOSET(s, clif_parse_func_table[0xf4].len);
+ send_fpacket<0x00f4, 21>(s, fixed_f4);
return 0;
}
@@ -2303,16 +2308,16 @@ int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor,
* カプラ倉庫からアイテムを取り去る
*------------------------------------------
*/
-int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index,
+int clif_storageitemremoved(dumb_ptr<map_session_data> sd, SOff0 index,
int amount)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xf6; // Storage item removed
- WFIFOW(s, 2) = index + 1;
- WFIFOL(s, 4) = amount;
- WFIFOSET(s, clif_parse_func_table[0xf6].len);
+ Packet_Fixed<0x00f6> fixed_f6;
+ fixed_f6.soff1 = index.shift();
+ fixed_f6.amount = amount;
+ send_fpacket<0x00f6, 8>(s, fixed_f6);
return 0;
}
@@ -2323,11 +2328,11 @@ int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index,
*/
int clif_storageclose(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xf8; // Storage Closed
- WFIFOSET(s, clif_parse_func_table[0xf8].len);
+ Packet_Fixed<0x00f8> fixed_f8;
+ send_fpacket<0x00f8, 2>(s, fixed_f8);
return 0;
}
@@ -2335,7 +2340,7 @@ int clif_storageclose(dumb_ptr<map_session_data> sd)
void clif_changelook_accessories(dumb_ptr<block_list> bl,
dumb_ptr<map_session_data> dest)
{
- for (LOOK i = LOOK::SHOES; i < LOOK::COUNT; i = LOOK(uint8_t(i) + 1))
+ for (LOOK i = LOOK::SHOES; i < LOOK::COUNT; i = LOOK(static_cast<uint8_t>(i) + 1))
clif_changelook_towards(bl, i, 0, dest);
}
@@ -2350,25 +2355,22 @@ static
void clif_getareachar_pc(dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> dstsd)
{
- int len;
-
if (bool(dstsd->status.option & Option::INVISIBILITY))
return;
nullpo_retv(sd);
nullpo_retv(dstsd);
- uint8_t buf[256];
+ Buffer buf;
if (dstsd->walktimer)
{
- len = clif_set007b(dstsd, buf);
+ clif_set007b(dstsd, buf);
}
else
{
- len = clif_set0078(dstsd, buf);
+ clif_set0078_main_1d8(dstsd, buf);
}
- WFIFO_BUF_CLONE(sd->sess, buf, len);
- WFIFOSET(sd->sess, len);
+ send_buffer(sd->sess, buf);
if (battle_config.save_clothcolor == 1 && dstsd->status.clothes_color > 0)
clif_changelook(dstsd, LOOK::CLOTHES_COLOR,
@@ -2385,16 +2387,15 @@ void clif_getareachar_pc(dumb_ptr<map_session_data> sd,
static
void clif_getareachar_npc(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd)
{
- int len;
-
nullpo_retv(sd);
nullpo_retv(nd);
- if (nd->npc_class < 0 || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS)
+ if (nd->npc_class == NEGATIVE_SPECIES || nd->flag & 1 || nd->npc_class == INVISIBLE_CLASS)
return;
- len = clif_npc0078(nd, static_cast<uint8_t *>(WFIFOP(sd->sess, 0)));
- WFIFOSET(sd->sess, len);
+ Buffer buf;
+ clif_npc0078(nd, buf);
+ send_buffer(sd->sess, buf);
}
/*==========================================
@@ -2403,13 +2404,11 @@ void clif_getareachar_npc(dumb_ptr<map_session_data> sd, dumb_ptr<npc_data> nd)
*/
int clif_movemob(dumb_ptr<mob_data> md)
{
- unsigned char buf[256];
- int len;
+ nullpo_retz(md);
- nullpo_ret(md);
-
- len = clif_mob007b(md, buf);
- clif_send(buf, len, md, SendWho::AREA);
+ Buffer buf;
+ clif_mob007b(md, buf);
+ clif_send(buf, md, SendWho::AREA);
return 0;
}
@@ -2420,20 +2419,19 @@ int clif_movemob(dumb_ptr<mob_data> md)
*/
int clif_fixmobpos(dumb_ptr<mob_data> md)
{
- unsigned char buf[256];
- int len;
-
- nullpo_ret(md);
+ nullpo_retz(md);
if (md->state.state == MS::WALK)
{
- len = clif_mob007b(md, buf);
- clif_send(buf, len, md, SendWho::AREA);
+ Buffer buf;
+ clif_mob007b(md, buf);
+ clif_send(buf, md, SendWho::AREA);
}
else
{
- len = clif_mob0078(md, buf);
- clif_send(buf, len, md, SendWho::AREA);
+ Buffer buf;
+ clif_mob0078(md, buf);
+ clif_send(buf, md, SendWho::AREA);
}
return 0;
@@ -2445,22 +2443,21 @@ int clif_fixmobpos(dumb_ptr<mob_data> md)
*/
int clif_fixpcpos(dumb_ptr<map_session_data> sd)
{
- unsigned char buf[256];
- int len;
-
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->walktimer)
{
- len = clif_set007b(sd, buf);
- clif_send(buf, len, sd, SendWho::AREA);
+ Buffer buf;
+ clif_set007b(sd, buf);
+ clif_send(buf, sd, SendWho::AREA);
}
else
{
- len = clif_set0078(sd, buf);
- clif_send(buf, len, sd, SendWho::AREA);
+ Buffer buf;
+ clif_set0078_main_1d8(sd, buf);
+ clif_send(buf, sd, SendWho::AREA);
}
- clif_changelook_accessories(sd, NULL);
+ clif_changelook_accessories(sd, nullptr);
return 0;
}
@@ -2473,25 +2470,25 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
tick_t tick, interval_t sdelay, interval_t ddelay, int damage,
int div, DamageType type, int damage2)
{
- unsigned char buf[256];
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(src);
- nullpo_ret(dst);
+ nullpo_retz(src);
+ nullpo_retz(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, 10) = tick.time_since_epoch().count();
- WBUFL(buf, 14) = sdelay.count();
- WBUFL(buf, 18) = ddelay.count();
- WBUFW(buf, 22) = (damage > 0x7fff) ? 0x7fff : damage;
- WBUFW(buf, 24) = div;
- WBUFB(buf, 26) = static_cast<uint8_t>(type);
- WBUFW(buf, 27) = damage2;
- clif_send(buf, clif_parse_func_table[0x8a].len, src, SendWho::AREA);
+ Packet_Fixed<0x008a> fixed_8a;
+ fixed_8a.src_id = src->bl_id;
+ fixed_8a.dst_id = dst->bl_id;
+ fixed_8a.tick = tick;
+ fixed_8a.sdelay = sdelay;
+ fixed_8a.ddelay = ddelay;
+ fixed_8a.damage = (damage > 0x7fff) ? 0x7fff : damage;
+ fixed_8a.div = div;
+ fixed_8a.damage_type = type;
+ fixed_8a.damage2 = damage2;
+ Buffer buf = create_fpacket<0x008a, 29>(fixed_8a);
+ clif_send(buf, src, SendWho::AREA);
return 0;
}
@@ -2503,19 +2500,20 @@ int clif_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
static
void clif_getareachar_mob(dumb_ptr<map_session_data> sd, dumb_ptr<mob_data> md)
{
- int len;
nullpo_retv(sd);
nullpo_retv(md);
if (md->state.state == MS::WALK)
{
- len = clif_mob007b(md, static_cast<uint8_t *>(WFIFOP(sd->sess, 0)));
- WFIFOSET(sd->sess, len);
+ Buffer buf;
+ clif_mob007b(md, buf);
+ send_buffer(sd->sess, buf);
}
else
{
- len = clif_mob0078(md, static_cast<uint8_t *>(WFIFOP(sd->sess, 0)));
- WFIFOSET(sd->sess, len);
+ Buffer buf;
+ clif_mob0078(md, buf);
+ send_buffer(sd->sess, buf);
}
}
@@ -2531,18 +2529,16 @@ void clif_getareachar_item(dumb_ptr<map_session_data> sd,
nullpo_retv(fitem);
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;
- WFIFOB(s, 8) = 0; //identify;
- WFIFOW(s, 9) = fitem->bl_x;
- WFIFOW(s, 11) = fitem->bl_y;
- WFIFOW(s, 13) = fitem->item_data.amount;
- WFIFOB(s, 15) = fitem->subx;
- WFIFOB(s, 16) = fitem->suby;
-
- WFIFOSET(s, clif_parse_func_table[0x9d].len);
+ Packet_Fixed<0x009d> fixed_9d;
+ fixed_9d.block_id = fitem->bl_id;
+ fixed_9d.name_id = fitem->item_data.nameid;
+ fixed_9d.identify = 0;
+ fixed_9d.x = fitem->bl_x;
+ fixed_9d.y = fitem->bl_y;
+ fixed_9d.amount = fitem->item_data.amount;
+ fixed_9d.subx = fitem->subx;
+ fixed_9d.suby = fitem->suby;
+ send_fpacket<0x009d, 17>(s, fixed_9d);
}
/*==========================================
@@ -2578,7 +2574,7 @@ void clif_getareachar(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> sd)
break;
default:
if (battle_config.error_log)
- PRINTF("get area char ??? %d\n",
+ PRINTF("get area char ??? %d\n"_fmt,
bl->bl_type);
break;
}
@@ -2694,32 +2690,32 @@ void clif_mobinsight(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md)
int clif_skillinfo(dumb_ptr<map_session_data> sd, SkillID skillid, int type,
int range)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
if (!sd->status.skill[skillid].lv)
return 0;
- WFIFOW(s, 0) = 0x147;
- WFIFOW(s, 2) = static_cast<uint16_t>(skillid);
+ Packet_Fixed<0x0147> fixed_147;
+ fixed_147.info.skill_id = skillid;
if (type < 0)
- WFIFOW(s, 4) = skill_get_inf(skillid);
+ fixed_147.info.type_or_inf = skill_get_inf(skillid);
else
- WFIFOW(s, 4) = type;
- WFIFOW(s, 6) = 0;
- WFIFOW(s, 8) = sd->status.skill[skillid].lv;
- WFIFOW(s, 10) = skill_get_sp(skillid, sd->status.skill[skillid].lv);
+ fixed_147.info.type_or_inf = type;
+ fixed_147.info.flags = SkillFlags::ZERO;
+ fixed_147.info.level = sd->status.skill[skillid].lv;
+ fixed_147.info.sp = skill_get_sp(skillid, sd->status.skill[skillid].lv);
if (range < 0)
{
range = skill_get_range(skillid, sd->status.skill[skillid].lv);
if (range < 0)
range = battle_get_range(sd) - (range + 1);
- WFIFOW(s, 12) = range;
+ fixed_147.info.range = range;
}
else
- WFIFOW(s, 12) = range;
- WFIFO_ZERO(s, 14, 24);
- WFIFOB(s, 38) = sd->status.skill[skillid].lv < skill_get_max_raise(skillid);
- WFIFOSET(s, clif_parse_func_table[0x147].len);
+ fixed_147.info.range = range;
+ fixed_147.info.unused = ""_s;
+ fixed_147.info.can_raise = sd->status.skill[skillid].lv < skill_get_max_raise(skillid);
+ send_fpacket<0x0147, 39>(s, fixed_147);
return 0;
}
@@ -2730,35 +2726,34 @@ int clif_skillinfo(dumb_ptr<map_session_data> sd, SkillID skillid, int type,
*/
void clif_skillinfoblock(dumb_ptr<map_session_data> sd)
{
- int len = 4, range;
-
nullpo_retv(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x10f;
+ std::vector<Packet_Repeat<0x010f>> repeat_10f;
for (SkillID i : erange(SkillID(), MAX_SKILL))
{
if (sd->status.skill[i].lv && sd->tmw_version >= 1)
{
+ Packet_Repeat<0x010f> info;
// [Fate] Version 1 and later don't crash because of bad skill IDs anymore
- WFIFOW(s, len) = static_cast<uint16_t>(i);
- WFIFOW(s, len + 2) = skill_get_inf(i);
- WFIFOW(s, len + 4) = static_cast<uint16_t>(
+ info.info.skill_id = i;
+ info.info.type_or_inf = skill_get_inf(i);
+ info.info.flags = (
skill_db[i].poolflags
| (sd->status.skill[i].flags & SkillFlags::POOL_ACTIVATED));
- WFIFOW(s, len + 6) = sd->status.skill[i].lv;
- WFIFOW(s, len + 8) = skill_get_sp(i, sd->status.skill[i].lv);
- range = skill_get_range(i, sd->status.skill[i].lv);
+ info.info.level = sd->status.skill[i].lv;
+ info.info.sp = skill_get_sp(i, sd->status.skill[i].lv);
+ int range = skill_get_range(i, sd->status.skill[i].lv);
if (range < 0)
range = battle_get_range(sd) - (range + 1);
- WFIFOW(s, len + 10) = range;
- WFIFO_ZERO(s, len + 12, 24);
- WFIFOB(s, len + 36) = sd->status.skill[i].lv < skill_get_max_raise(i);
- len += 37;
+ info.info.range = range;
+ info.info.unused = ""_s;
+ info.info.can_raise = sd->status.skill[i].lv < skill_get_max_raise(i);
+
+ repeat_10f.push_back(info);
}
}
- WFIFOW(s, 2) = len;
- WFIFOSET(s, len);
+ send_packet_repeatonly<0x010f, 4, 37>(s, repeat_10f);
}
/*==========================================
@@ -2767,21 +2762,19 @@ void clif_skillinfoblock(dumb_ptr<map_session_data> sd)
*/
int clif_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num)
{
- int range;
-
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x10e;
- WFIFOW(s, 2) = uint16_t(skill_num);
- WFIFOW(s, 4) = sd->status.skill[skill_num].lv;
- WFIFOW(s, 6) = skill_get_sp(skill_num, sd->status.skill[skill_num].lv);
- range = skill_get_range(skill_num, sd->status.skill[skill_num].lv);
+ Packet_Fixed<0x010e> fixed_10e;
+ fixed_10e.skill_id = skill_num;
+ fixed_10e.level = sd->status.skill[skill_num].lv;
+ fixed_10e.sp = skill_get_sp(skill_num, sd->status.skill[skill_num].lv);
+ int range = skill_get_range(skill_num, sd->status.skill[skill_num].lv);
if (range < 0)
range = battle_get_range(sd) - (range + 1);
- WFIFOW(s, 8) = range;
- WFIFOB(s, 10) = sd->status.skill[skill_num].lv < skill_get_max_raise(skill_num);
- WFIFOSET(s, clif_parse_func_table[0x10e].len);
+ fixed_10e.range = range;
+ fixed_10e.can_raise = sd->status.skill[skill_num].lv < skill_get_max_raise(skill_num);
+ send_fpacket<0x010e, 11>(s, fixed_10e);
return 0;
}
@@ -2792,14 +2785,11 @@ int clif_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num)
*/
int clif_skillcastcancel(dumb_ptr<block_list> bl)
{
- unsigned char buf[16];
-
- nullpo_ret(bl);
-
- WBUFW(buf, 0) = 0x1b9;
- WBUFL(buf, 2) = bl->bl_id;
- clif_send(buf, clif_parse_func_table[0x1b9].len, bl, SendWho::AREA);
+ // packet 0x01b9 was being sent with length 0,
+ // even though there were 6 bytes involved
+ // and the client ignores it anyway
+ (void)bl;
return 0;
}
@@ -2810,7 +2800,7 @@ int clif_skillcastcancel(dumb_ptr<block_list> bl)
int clif_skill_fail(dumb_ptr<map_session_data> sd, SkillID skill_id, int type,
int btype)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
@@ -2819,13 +2809,13 @@ int clif_skill_fail(dumb_ptr<map_session_data> sd, SkillID skill_id, int type,
return 0;
}
- WFIFOW(s, 0) = 0x110;
- WFIFOW(s, 2) = uint16_t(skill_id);
- WFIFOW(s, 4) = btype;
- WFIFOW(s, 6) = 0;
- WFIFOB(s, 8) = 0;
- WFIFOB(s, 9) = type;
- WFIFOSET(s, clif_parse_func_table[0x110].len);
+ Packet_Fixed<0x0110> fixed_110;
+ fixed_110.skill_id = skill_id;
+ fixed_110.btype = btype;
+ fixed_110.zero1 = 0;
+ fixed_110.zero2 = 0;
+ fixed_110.type = type;
+ send_fpacket<0x0110, 10>(s, fixed_110);
return 0;
}
@@ -2838,26 +2828,26 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
tick_t tick, interval_t sdelay, interval_t ddelay, int damage,
int div, SkillID skill_id, int skill_lv, int type)
{
- unsigned char buf[64];
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(src);
- nullpo_ret(dst);
+ nullpo_retz(src);
+ nullpo_retz(dst);
sc_data = battle_get_sc_data(dst);
- WBUFW(buf, 0) = 0x1de;
- WBUFW(buf, 2) = uint16_t(skill_id);
- WBUFL(buf, 4) = src->bl_id;
- WBUFL(buf, 8) = 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());
- WBUFL(buf, 24) = damage;
- WBUFW(buf, 28) = skill_lv;
- WBUFW(buf, 30) = div;
- WBUFB(buf, 32) = (type > 0) ? type : skill_get_hit(skill_id);
- clif_send(buf, clif_parse_func_table[0x1de].len, src, SendWho::AREA);
+ Packet_Fixed<0x01de> fixed_1de;
+ fixed_1de.skill_id = skill_id;
+ fixed_1de.src_id = src->bl_id;
+ fixed_1de.dst_id = dst->bl_id;
+ fixed_1de.tick = tick;
+ fixed_1de.sdelay = sdelay;
+ fixed_1de.ddelay = ddelay;
+ fixed_1de.damage = damage;
+ fixed_1de.skill_level = skill_lv;
+ fixed_1de.div = div;
+ fixed_1de.type_or_hit = (type > 0) ? type : skill_get_hit(skill_id);
+ Buffer buf = create_fpacket<0x01de, 33>(fixed_1de);
+ clif_send(buf, src, SendWho::AREA);
return 0;
}
@@ -2868,15 +2858,14 @@ int clif_skill_damage(dumb_ptr<block_list> src, dumb_ptr<block_list> dst,
*/
int clif_status_change(dumb_ptr<block_list> bl, StatusChange type, int flag)
{
- unsigned char buf[16];
-
- nullpo_ret(bl);
+ nullpo_retz(bl);
- WBUFW(buf, 0) = 0x0196;
- WBUFW(buf, 2) = uint16_t(type);
- WBUFL(buf, 4) = bl->bl_id;
- WBUFB(buf, 8) = flag;
- clif_send(buf, clif_parse_func_table[0x196].len, bl, SendWho::AREA);
+ Packet_Fixed<0x0196> fixed_196;
+ fixed_196.sc_type = type;
+ fixed_196.block_id = bl->bl_id;
+ fixed_196.flag = flag;
+ Buffer buf = create_fpacket<0x0196, 9>(fixed_196);
+ clif_send(buf, bl, SendWho::AREA);
return 0;
}
@@ -2889,11 +2878,8 @@ void clif_displaymessage(Session *s, XString mes)
if (mes)
{
// don't send a void message (it's not displaying on the client chat). @help can send void line.
- WFIFOW(s, 0) = 0x8e;
- size_t str_len = mes.size() + 1; // NUL (might not be NUL yet)
- WFIFOW(s, 2) = 4 + str_len;
- WFIFO_STRING(s, 4, mes, str_len);
- WFIFOSET(s, 4 + str_len);
+ // This is untrue now ^
+ send_packet_repeatonly<0x008e, 4, 1>(s, mes);
}
}
@@ -2903,14 +2889,9 @@ void clif_displaymessage(Session *s, XString mes)
*/
void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag)
{
- size_t str_len = mes.size() + 1;
- unsigned char buf[str_len + 4];
-
- WBUFW(buf, 0) = 0x9a;
- WBUFW(buf, 2) = str_len + 4;
- WBUF_STRING(buf, 4, mes, str_len);
+ Buffer buf = create_packet_repeatonly<0x009a, 4, 1>(mes);
flag &= 0x07;
- clif_send(buf, WBUFW(buf, 2), bl,
+ clif_send(buf, bl,
(flag == 1) ? SendWho::ALL_SAMEMAP :
(flag == 2) ? SendWho::AREA :
(flag == 3) ? SendWho::SELF :
@@ -2923,15 +2904,14 @@ void clif_GMmessage(dumb_ptr<block_list> bl, XString mes, int flag)
*/
void clif_resurrection(dumb_ptr<block_list> bl, int type)
{
- uint8_t buf[16];
-
nullpo_retv(bl);
- WBUFW(buf, 0) = 0x148;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFW(buf, 6) = type;
+ Packet_Fixed<0x0148> fixed_148;
+ fixed_148.block_id = bl->bl_id;
+ fixed_148.type = type;
+ Buffer buf = create_fpacket<0x0148, 8>(fixed_148);
- clif_send(buf, clif_parse_func_table[0x148].len, bl,
+ clif_send(buf, bl,
type == 1 ? SendWho::AREA : SendWho::AREA_WOS);
}
@@ -2941,12 +2921,9 @@ void clif_resurrection(dumb_ptr<block_list> bl, int type)
*/
void clif_wis_message(Session *s, CharName nick, XString mes) // R 0097 <len>.w <nick>.24B <message>.?B
{
- size_t mes_len = mes.size() + 1;
- WFIFOW(s, 0) = 0x97;
- WFIFOW(s, 2) = mes_len + 24 + 4;
- WFIFO_STRING(s, 4, nick.to__actual(), 24);
- WFIFO_STRING(s, 28, mes, mes_len);
- WFIFOSET(s, WFIFOW(s, 2));
+ Packet_Head<0x0097> head_97;
+ head_97.char_name = nick;
+ send_vpacket<0x0097, 28, 1>(s, head_97, mes);
}
/*==========================================
@@ -2955,9 +2932,9 @@ void clif_wis_message(Session *s, CharName nick, XString mes) // R 0097 <len>.
*/
void clif_wis_end(Session *s, int flag) // R 0098 <type>.B: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
{
- WFIFOW(s, 0) = 0x98;
- WFIFOW(s, 2) = flag;
- WFIFOSET(s, clif_parse_func_table[0x98].len);
+ Packet_Fixed<0x0098> fixed_98;
+ fixed_98.flag = flag;
+ send_fpacket<0x0098, 3>(s, fixed_98);
}
/*==========================================
@@ -2974,12 +2951,12 @@ void clif_wis_end(Session *s, int flag) // R 0098 <type>.B: 0: success to send w
*/
int clif_party_created(dumb_ptr<map_session_data> sd, int flag)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xfa;
- WFIFOB(s, 2) = flag;
- WFIFOSET(s, clif_parse_func_table[0xfa].len);
+ Packet_Fixed<0x00fa> fixed_fa;
+ fixed_fa.flag = flag;
+ send_fpacket<0x00fa, 3>(s, fixed_fa);
return 0;
}
@@ -2987,43 +2964,45 @@ int clif_party_created(dumb_ptr<map_session_data> sd, int flag)
* パーティ情報送信
*------------------------------------------
*/
-int clif_party_info(struct party *p, Session *s)
+int clif_party_info(PartyPair p, Session *s)
{
- unsigned char buf[1024];
- int i, c;
- dumb_ptr<map_session_data> sd = NULL;
+ int i;
+ dumb_ptr<map_session_data> sd = nullptr;
- nullpo_ret(p);
+ nullpo_retz(p);
- WBUFW(buf, 0) = 0xfb;
- WBUF_STRING(buf, 4, p->name, 24);
- for (i = c = 0; i < MAX_PARTY; i++)
+ Packet_Head<0x00fb> head_fb;
+ std::vector<Packet_Repeat<0x00fb>> repeat_fb;
+ head_fb.party_name = p->name;
+ for (i = 0; i < MAX_PARTY; i++)
{
- struct party_member *m = &p->member[i];
- if (m->account_id > 0)
+ PartyMember *m = &p->member[i];
+ if (m->account_id)
{
- if (sd == NULL)
+ Packet_Repeat<0x00fb> info;
+ if (sd == nullptr)
sd = dumb_ptr<map_session_data>(m->sd);
- WBUFL(buf, 28 + c * 46) = 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;
- WBUFB(buf, 28 + c * 46 + 45) = (m->online) ? 0 : 1;
- c++;
+
+ info.account_id = m->account_id;
+ info.char_name = m->name;
+ info.map_name = m->map;
+ info.leader = (m->leader) ? 0 : 1;
+ info.online = (m->online) ? 0 : 1;
+ repeat_fb.push_back(info);
}
}
- size_t len = 28 + c * 46;
- WBUFW(buf, 2) = len;
if (s)
{
// If set, send only to fd.
- WFIFO_BUF_CLONE(s, buf, len);
- WFIFOSET(s, len);
+ send_vpacket<0x00fb, 28, 46>(s, head_fb, repeat_fb);
return 9;
}
// else, send it to all the party, if they exist.
- if (sd != NULL)
- clif_send(buf, len, sd, SendWho::PARTY);
+ if (sd != nullptr)
+ {
+ Buffer buf = create_vpacket<0x00fb, 28, 46>(head_fb, repeat_fb);
+ clif_send(buf, sd, SendWho::PARTY);
+ }
return 0;
}
@@ -3037,7 +3016,7 @@ int clif_party_info(struct party *p, Session *s)
void clif_party_invite(dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> tsd)
{
- struct party *p;
+ PartyPair p;
nullpo_retv(sd);
nullpo_retv(tsd);
@@ -3047,10 +3026,10 @@ void clif_party_invite(dumb_ptr<map_session_data> sd,
if (!(p = party_search(sd->status.party_id)))
return;
- WFIFOW(s, 0) = 0xfe;
- WFIFOL(s, 2) = sd->status_key.account_id;
- WFIFO_STRING(s, 6, p->name, 24);
- WFIFOSET(s, clif_parse_func_table[0xfe].len);
+ Packet_Fixed<0x00fe> fixed_fe;
+ fixed_fe.account_id = sd->status_key.account_id;
+ fixed_fe.party_name = p->name;
+ send_fpacket<0x00fe, 30>(s, fixed_fe);
}
/*==========================================
@@ -3072,10 +3051,10 @@ void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag
nullpo_retv(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xfd;
- WFIFO_STRING(s, 2, nick.to__actual(), 24);
- WFIFOB(s, 26) = flag;
- WFIFOSET(s, clif_parse_func_table[0xfd].len);
+ Packet_Fixed<0x00fd> fixed_fd;
+ fixed_fd.char_name = nick;
+ fixed_fd.flag = flag;
+ send_fpacket<0x00fd, 27>(s, fixed_fd);
}
/*==========================================
@@ -3085,32 +3064,30 @@ void clif_party_inviteack(dumb_ptr<map_session_data> sd, CharName nick, int flag
* 0x100=一人にのみ送信
*------------------------------------------
*/
-void clif_party_option(struct party *p, dumb_ptr<map_session_data> sd, int flag)
+void clif_party_option(PartyPair p, dumb_ptr<map_session_data> sd, int flag)
{
- unsigned char buf[16];
-
nullpo_retv(p);
-// if(battle_config.etc_log)
-// PRINTF("clif_party_option: %d %d %d\n",p->exp,p->item,flag);
- if (sd == NULL && flag == 0)
+ if (sd == nullptr && flag == 0)
{
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))) != nullptr)
break;
}
- if (sd == NULL)
+ if (sd == nullptr)
return;
- WBUFW(buf, 0) = 0x101;
- WBUFW(buf, 2) = ((flag & 0x01) ? 2 : p->exp);
- WBUFW(buf, 4) = ((flag & 0x10) ? 2 : p->item);
+ Packet_Fixed<0x0101> fixed_101;
+ fixed_101.exp = ((flag & 0x01) ? 2 : p->exp);
+ fixed_101.item = ((flag & 0x10) ? 2 : p->item);
if (flag == 0)
- clif_send(buf, clif_parse_func_table[0x101].len, sd, SendWho::PARTY);
+ {
+ Buffer buf = create_fpacket<0x0101, 6>(fixed_101);
+ clif_send(buf, sd, SendWho::PARTY);
+ }
else
{
- WFIFO_BUF_CLONE(sd->sess, buf, clif_parse_func_table[0x101].len);
- WFIFOSET(sd->sess, clif_parse_func_table[0x101].len);
+ send_fpacket<0x0101, 6>(sd->sess, fixed_101);
}
}
@@ -3118,35 +3095,36 @@ 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_leaved(PartyPair p, dumb_ptr<map_session_data> sd,
+ AccountId account_id, CharName name, int flag)
{
- unsigned char buf[64];
int i;
nullpo_retv(p);
- WBUFW(buf, 0) = 0x105;
- WBUFL(buf, 2) = account_id;
- WBUF_STRING(buf, 6, name.to__actual(), 24);
- WBUFB(buf, 30) = flag & 0x0f;
+ Packet_Fixed<0x0105> fixed_105;
+ fixed_105.account_id = account_id;
+ fixed_105.char_name = name;
+ fixed_105.flag = flag & 0x0f;
if ((flag & 0xf0) == 0)
{
- if (sd == NULL)
+ if (sd == nullptr)
for (i = 0; i < MAX_PARTY; i++)
{
sd = dumb_ptr<map_session_data>(p->member[i].sd);
- if (sd != NULL)
+ if (sd != nullptr)
break;
}
- if (sd != NULL)
- clif_send(buf, clif_parse_func_table[0x105].len, sd, SendWho::PARTY);
+ if (sd != nullptr)
+ {
+ Buffer buf = create_fpacket<0x0105, 31>(fixed_105);
+ clif_send(buf, sd, SendWho::PARTY);
+ }
}
- else if (sd != NULL)
+ else if (sd != nullptr)
{
- WFIFO_BUF_CLONE(sd->sess, buf, clif_parse_func_table[0x105].len);
- WFIFOSET(sd->sess, clif_parse_func_table[0x105].len);
+ send_fpacket<0x0105, 31>(sd->sess, fixed_105);
}
}
@@ -3154,7 +3132,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(PartyPair p, AccountId account_id, XString mes)
{
// always set, but clang is not smart enough
dumb_ptr<map_session_data> sd = nullptr;
@@ -3165,18 +3143,15 @@ void clif_party_message(struct party *p, int account_id, XString mes)
for (i = 0; i < MAX_PARTY; i++)
{
sd = dumb_ptr<map_session_data>(p->member[i].sd);
- if (sd != NULL)
+ if (sd != nullptr)
break;
}
- if (sd != NULL)
+ if (sd != nullptr)
{
- size_t len = mes.size() + 1;
- unsigned char buf[len + 8];
- WBUFW(buf, 0) = 0x109;
- WBUFW(buf, 2) = len + 8;
- WBUFL(buf, 4) = account_id;
- WBUF_STRING(buf, 8, mes, len);
- clif_send(buf, len + 8, sd, SendWho::PARTY);
+ Packet_Head<0x0109> head_109;
+ head_109.account_id = account_id;
+ Buffer buf = create_vpacket<0x0109, 8, 1>(head_109, mes);
+ clif_send(buf, sd, SendWho::PARTY);
}
}
@@ -3184,19 +3159,16 @@ void clif_party_message(struct party *p, int account_id, XString mes)
* パーティ座標通知
*------------------------------------------
*/
-int clif_party_xy(struct party *, dumb_ptr<map_session_data> sd)
+int clif_party_xy(PartyPair , dumb_ptr<map_session_data> sd)
{
- unsigned char buf[16];
-
- nullpo_ret(sd);
+ nullpo_retz(sd);
- WBUFW(buf, 0) = 0x107;
- WBUFL(buf, 2) = 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);
-// if(battle_config.etc_log)
-// PRINTF("clif_party_xy %d\n",sd->status_key.account_id);
+ Packet_Fixed<0x0107> fixed_107;
+ fixed_107.account_id = sd->status_key.account_id;
+ fixed_107.x = sd->bl_x;
+ fixed_107.y = sd->bl_y;
+ Buffer buf = create_fpacket<0x0107, 10>(fixed_107);
+ clif_send(buf, sd, SendWho::PARTY_SAMEMAP_WOS);
return 0;
}
@@ -3204,20 +3176,17 @@ int clif_party_xy(struct party *, dumb_ptr<map_session_data> sd)
* パーティHP通知
*------------------------------------------
*/
-int clif_party_hp(struct party *, dumb_ptr<map_session_data> sd)
+int clif_party_hp(PartyPair , dumb_ptr<map_session_data> sd)
{
- unsigned char buf[16];
-
- nullpo_ret(sd);
+ nullpo_retz(sd);
- WBUFW(buf, 0) = 0x106;
- WBUFL(buf, 2) = sd->status_key.account_id;
- WBUFW(buf, 6) = (sd->status.hp > 0x7fff) ? 0x7fff : sd->status.hp;
- WBUFW(buf, 8) =
+ Packet_Fixed<0x0106> fixed_106;
+ fixed_106.account_id = sd->status_key.account_id;
+ fixed_106.hp = (sd->status.hp > 0x7fff) ? 0x7fff : sd->status.hp;
+ fixed_106.max_hp =
(sd->status.max_hp > 0x7fff) ? 0x7fff : sd->status.max_hp;
- clif_send(buf, clif_parse_func_table[0x106].len, sd, SendWho::PARTY_AREA_WOS);
-// if(battle_config.etc_log)
-// PRINTF("clif_party_hp %d\n",sd->status_key.account_id);
+ Buffer buf = create_fpacket<0x0106, 10>(fixed_106);
+ clif_send(buf, sd, SendWho::PARTY_AREA_WOS);
return 0;
}
@@ -3227,18 +3196,18 @@ int clif_party_hp(struct party *, dumb_ptr<map_session_data> sd)
*/
int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl)
{
- nullpo_ret(sd);
- nullpo_ret(bl);
+ nullpo_retz(sd);
+ nullpo_retz(bl);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0x139;
- WFIFOL(s, 2) = bl->bl_id;
- WFIFOW(s, 6) = bl->bl_x;
- WFIFOW(s, 8) = bl->bl_y;
- WFIFOW(s, 10) = sd->bl_x;
- WFIFOW(s, 12) = sd->bl_y;
- WFIFOW(s, 14) = sd->attackrange;
- WFIFOSET(s, clif_parse_func_table[0x139].len);
+ Packet_Fixed<0x0139> fixed_139;
+ fixed_139.block_id = bl->bl_id;
+ fixed_139.bl_x = bl->bl_x;
+ fixed_139.bl_y = bl->bl_y;
+ fixed_139.sd_x = sd->bl_x;
+ fixed_139.sd_y = sd->bl_y;
+ fixed_139.range = sd->attackrange;
+ send_fpacket<0x0139, 16>(s, fixed_139);
return 0;
}
@@ -3248,13 +3217,12 @@ int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl)
*/
int clif_mvp_effect(dumb_ptr<map_session_data> sd)
{
- unsigned char buf[16];
+ nullpo_retz(sd);
- nullpo_ret(sd);
-
- WBUFW(buf, 0) = 0x10c;
- WBUFL(buf, 2) = sd->bl_id;
- clif_send(buf, clif_parse_func_table[0x10c].len, sd, SendWho::AREA);
+ Packet_Fixed<0x010c> fixed_10c;
+ fixed_10c.block_id = sd->bl_id;
+ Buffer buf = create_fpacket<0x010c, 6>(fixed_10c);
+ clif_send(buf, sd, SendWho::AREA);
return 0;
}
@@ -3264,22 +3232,19 @@ int clif_mvp_effect(dumb_ptr<map_session_data> sd)
*/
void clif_emotion(dumb_ptr<block_list> bl, int type)
{
- unsigned char buf[8];
-
nullpo_retv(bl);
- WBUFW(buf, 0) = 0xc0;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFB(buf, 6) = type;
- clif_send(buf, clif_parse_func_table[0xc0].len, bl, SendWho::AREA);
+ Packet_Fixed<0x00c0> fixed_c0;
+ fixed_c0.block_id = bl->bl_id;
+ fixed_c0.type = type;
+ Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0);
+ clif_send(buf, bl, SendWho::AREA);
}
static
void clif_emotion_towards(dumb_ptr<block_list> bl,
dumb_ptr<block_list> target, int type)
{
- unsigned char buf[8];
- int len = clif_parse_func_table[0xc0].len;
dumb_ptr<map_session_data> sd = target->is_player();
nullpo_retv(bl);
@@ -3288,12 +3253,11 @@ void clif_emotion_towards(dumb_ptr<block_list> bl,
if (target->bl_type != BL::PC)
return;
- WBUFW(buf, 0) = 0xc0;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFB(buf, 6) = type;
+ Packet_Fixed<0x00c0> fixed_c0;
+ fixed_c0.block_id = bl->bl_id;
+ fixed_c0.type = type;
- WFIFO_BUF_CLONE(sd->sess, buf, len);
- WFIFOSET(sd->sess, len);
+ send_fpacket<0x00c0, 7>(sd->sess, fixed_c0);
}
/*==========================================
@@ -3302,14 +3266,13 @@ void clif_emotion_towards(dumb_ptr<block_list> bl,
*/
void clif_sitting(Session *, dumb_ptr<map_session_data> sd)
{
- unsigned char buf[64];
-
nullpo_retv(sd);
- WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = sd->bl_id;
- WBUFB(buf, 26) = 2;
- clif_send(buf, clif_parse_func_table[0x8a].len, sd, SendWho::AREA);
+ Packet_Fixed<0x008a> fixed_8a;
+ fixed_8a.src_id = sd->bl_id;
+ fixed_8a.damage_type = DamageType::SIT;
+ Buffer buf = create_fpacket<0x008a, 29>(fixed_8a);
+ clif_send(buf, sd, SendWho::AREA);
}
/*==========================================
@@ -3317,30 +3280,30 @@ 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);
+ nullpo_retz(sd);
Session *s = sd->sess;
- WFIFOW(s, 0) = 0xcd;
- WFIFOL(s, 2) = id;
- WFIFOSET(s, clif_parse_func_table[0xcd].len);
+ Packet_Fixed<0x00cd> fixed_cd;
+ fixed_cd.account_id = id;
+ send_fpacket<0x00cd, 6>(s, fixed_cd);
return 0;
}
static
-void clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd);
+void clif_do_quit_game(Session *s, dumb_ptr<map_session_data> sd);
int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd,
int type)
{
- nullpo_ret(tsd);
+ nullpo_retz(tsd);
if (type)
clif_GM_kickack(sd, tsd->status_key.account_id);
tsd->opt1 = Opt1::ZERO;
tsd->opt2 = Opt2::ZERO;
- clif_parse_QuitGame(tsd->sess, tsd);
+ clif_do_quit_game(tsd->sess, tsd);
return 0;
}
@@ -3348,15 +3311,12 @@ int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd,
// displaying special effects (npcs, weather, etc) [Valaris]
int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag)
{
- unsigned char buf[24];
-
- nullpo_ret(bl);
+ nullpo_retz(bl);
- WBUF_ZERO(buf, 0, clif_parse_func_table[0x19b].len);
-
- WBUFW(buf, 0) = 0x19b;
- WBUFL(buf, 2) = bl->bl_id;
- WBUFL(buf, 6) = type;
+ Packet_Fixed<0x019b> fixed_19b;
+ fixed_19b.block_id = bl->bl_id;
+ fixed_19b.type = type;
+ Buffer buf = create_fpacket<0x019b, 10>(fixed_19b);
if (flag == 2)
{
@@ -3371,9 +3331,9 @@ int clif_specialeffect(dumb_ptr<block_list> bl, int type, int flag)
}
}
else if (flag == 1)
- clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::SELF);
+ clif_send(buf, bl, SendWho::SELF);
else if (!flag)
- clif_send(buf, clif_parse_func_table[0x19b].len, bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA);
return 0;
@@ -3388,35 +3348,39 @@ 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)
+RecvResult 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)
{
if (battle_config.error_log)
- PRINTF("clif_parse_WantToConnection : invalid request?\n");
- return;
+ PRINTF("clif_parse_WantToConnection : invalid request?\n"_fmt);
+ return RecvResult::Error;
}
- if (RFIFOW(s, 0) == 0x72)
+ Packet_Fixed<0x0072> fixed;
+ RecvResult rv = recv_fpacket<0x0072, 19>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
{
- account_id = RFIFOL(s, 2);
+ account_id = fixed.account_id;
}
- else
- return; // Not the auth packet
- WFIFOL(s, 0) = account_id;
- WFIFOSET(s, 4);
+ // formerly: account id
+ Packet_Payload<0x8000> special;
+ special.magic_packet_length = 4;
+ send_ppacket<0x8000>(s, special);
// 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
clif_authfail_fd(old_sd->sess, 2); // same id
- PRINTF("clif_parse_WantToConnection: Double connection for account %d (sessions: #%d (new) and #%d (old)).\n",
- account_id, s, old_sd->sess);
+ PRINTF("clif_parse_WantToConnection: Double connection for account %d (sessions: #%d (new) and #%d (old)).\n"_fmt,
+ account_id, s, old_sd->sess);
}
else
{
@@ -3424,16 +3388,16 @@ 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),
- tick_t(static_cast<interval_t>(RFIFOL(s, 14))),
- static_cast<SEX>(RFIFOB(s, 18)));
+ pc_setnewpc(sd, account_id, fixed.char_id, fixed.login_id1,
+ fixed.client_tick,
+ fixed.sex);
map_addiddb(sd);
chrif_authreq(sd);
}
- return;
+ return RecvResult::Complete;
}
/*==========================================
@@ -3442,12 +3406,15 @@ void clif_parse_WantToConnection(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_LoadEndAck(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ if (sd->bl_prev != nullptr)
+ return RecvResult::Error;
- if (sd->bl_prev != NULL)
- return;
+ Packet_Fixed<0x007d> fixed;
+ RecvResult rv = recv_fpacket<0x007d, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
// 接続ok時
//clif_authok();
@@ -3494,7 +3461,7 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd)
if (!battle_config.pk_mode)
{
// remove pvp stuff for pk_mode [Valaris]
- sd->pvp_timer = Timer(gettick() + std::chrono::milliseconds(200),
+ sd->pvp_timer = Timer(gettick() + 200_ms,
std::bind(pc_calc_pvprank_timer, ph::_1, ph::_2,
sd->bl_id));
sd->pvp_rank = 0;
@@ -3519,7 +3486,7 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd)
clif_changeoption(sd);
// broken equipment
-// clif_changelook_accessories(sd, NULL);
+// clif_changelook_accessories(sd, nullptr);
map_foreachinarea(std::bind(clif_getareachar, ph::_1, sd),
sd->bl_m,
@@ -3529,6 +3496,8 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd)
if (!sd->state.seen_motd)
pc_show_motd(sd);
+
+ return rv;
}
/*==========================================
@@ -3536,13 +3505,18 @@ void clif_parse_LoadEndAck(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TickSend(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TickSend(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x007e> fixed;
+ RecvResult rv = recv_fpacket<0x007e, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- sd->client_tick = tick_t(static_cast<interval_t>(RFIFOL(s, 2)));
- sd->server_tick = gettick();
+ uint32_t client_tick = fixed.client_tick;
+ (void)client_tick;
clif_servertick(sd);
+
+ return rv;
}
/*==========================================
@@ -3550,71 +3524,83 @@ void clif_parse_TickSend(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_WalkToXY(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_WalkToXY(Session *s, dumb_ptr<map_session_data> sd)
{
- int x, y;
-
- nullpo_retv(sd);
+ Packet_Fixed<0x0085> fixed;
+ RecvResult rv = recv_fpacket<0x0085, 5>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
- if (sd->npc_id != 0 || sd->state.storage_open)
- return;
+ if (sd->npc_id || sd->state.storage_open)
+ return rv;
if (sd->canmove_tick > gettick())
- return;
+ return rv;
// ステータス異常やハイディング中(トンネルドライブ無)で動けない
if (bool(sd->opt1) && sd->opt1 != (Opt1::_stone6))
- return;
+ return rv;
if (sd->invincible_timer)
pc_delinvincibletimer(sd);
pc_stopattack(sd);
- x = RFIFOB(s, 2) * 4 + (RFIFOB(s, 3) >> 6);
- y = ((RFIFOB(s, 3) & 0x3f) << 4) + (RFIFOB(s, 4) >> 4);
+ int x = fixed.pos.x;
+ int y = fixed.pos.y;
pc_walktoxy(sd, x, y);
+ return rv;
}
/*==========================================
*
*------------------------------------------
*/
-void clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd)
+static
+RecvResult clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd)
{
- tick_t tick = gettick();
+ Packet_Fixed<0x018a> fixed;
+ RecvResult rv = recv_fpacket<0x018a, 4>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- nullpo_retv(sd);
+ clif_do_quit_game(s, sd);
+ return rv;
+}
+
+void clif_do_quit_game(Session *s, dumb_ptr<map_session_data> sd)
+{
+
+ tick_t tick = gettick();
- WFIFOW(s, 0) = 0x18b;
+ Packet_Fixed<0x018b> fixed_18b;
if ((!pc_isdead(sd) && (sd->opt1 != Opt1::ZERO || sd->opt2 != Opt2::ZERO))
|| (tick < sd->canact_tick))
{
- WFIFOW(s, 2) = 1;
- WFIFOSET(s, clif_parse_func_table[0x18b].len);
+ fixed_18b.okay = 1;
+ send_fpacket<0x018b, 4>(s, fixed_18b);
return;
}
/* Rovert's prevent logout option fixed [Valaris] */
if (!battle_config.prevent_logout
- || tick >= sd->canlog_tick + std::chrono::seconds(10))
+ || tick >= sd->canlog_tick + 10_s)
{
clif_setwaitclose(s);
- WFIFOW(s, 2) = 0;
+ fixed_18b.okay = 0;
}
else
{
- WFIFOW(s, 2) = 1;
+ fixed_18b.okay = 1;
}
- WFIFOSET(s, clif_parse_func_table[0x18b].len);
-
+ send_fpacket<0x018b, 4>(s, fixed_18b);
}
/*==========================================
@@ -3622,18 +3608,23 @@ void clif_parse_QuitGame(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x0094> fixed;
+ RecvResult rv = recv_fpacket<0x0094, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
dumb_ptr<block_list> bl;
- int account_id;
+ BlockId account_id;
- account_id = RFIFOL(s, 2);
+ account_id = fixed.block_id;
bl = map_id2bl(account_id);
- if (bl == NULL)
- return;
+ if (bl == nullptr)
+ return rv;
- WFIFOW(s, 0) = 0x95;
- WFIFOL(s, 2) = account_id;
+ Packet_Fixed<0x0095> fixed_95;
+ fixed_95.block_id = account_id;
switch (bl->bl_type)
{
@@ -3641,21 +3632,21 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
{
dumb_ptr<map_session_data> ssd = bl->is_player();
- nullpo_retv(ssd);
+ nullpo_retr(rv, ssd);
if (ssd->state.shroud_active)
- WFIFO_STRING(s, 6, "", 24);
+ fixed_95.char_name = CharName();
else
- WFIFO_STRING(s, 6, ssd->status_key.name.to__actual(), 24);
- WFIFOSET(s, clif_parse_func_table[0x95].len);
+ fixed_95.char_name = ssd->status_key.name;
+ send_fpacket<0x0095, 30>(s, fixed_95);
- struct party *p = NULL;
+ PartyPair p;
PartyName party_name;
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)))
{
party_name = p->name;
send = 1;
@@ -3663,30 +3654,28 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
if (send)
{
- WFIFOW(s, 0) = 0x195;
- WFIFOL(s, 2) = account_id;
- WFIFO_STRING(s, 6, party_name, 24);
- WFIFO_STRING(s, 30, "", 24);
- WFIFO_STRING(s, 54, "", 24);
- WFIFO_STRING(s, 78, "", 24); // We send this value twice because the client expects it
- WFIFOSET(s, clif_parse_func_table[0x195].len);
-
+ Packet_Fixed<0x0195> fixed_195;
+ fixed_195.block_id = account_id;
+ fixed_195.party_name = party_name;
+ fixed_195.guild_name = ""_s;
+ fixed_195.guild_pos = ""_s;
+ fixed_195.guild_pos = ""_s; // We send this value twice because the client expects it
+ send_fpacket<0x0195, 102>(s, fixed_195);
}
- 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;
+ Packet_Fixed<0x020c> fixed_20c;
// Mask the IP using the char-server password
if (battle_config.mask_ip_gms)
ip = MD5_ip(ip);
- WFIFOL(s, 2) = account_id;
- WFIFOIP(s, 6) = ip;
- WFIFOSET(s, clif_parse_func_table[0x20C].len);
+ fixed_20c.block_id = account_id;
+ fixed_20c.ip = ip;
+ send_fpacket<0x020c, 10>(s, fixed_20c);
}
-
}
break;
case BL::NPC:
@@ -3694,26 +3683,28 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
NpcName name = bl->is_npc()->name;
// [fate] elim hashed out/invisible names for the client
auto it = std::find(name.begin(), name.end(), '#');
- WFIFO_STRING(s, 6, name.xislice_h(it), 24);
- WFIFOSET(s, clif_parse_func_table[0x95].len);
+ fixed_95.char_name = stringish<CharName>(name.xislice_h(it));
+ send_fpacket<0x0095, 30>(s, fixed_95);
}
break;
case BL::MOB:
{
dumb_ptr<mob_data> md = bl->is_mob();
- nullpo_retv(md);
+ nullpo_retr(rv, md);
- WFIFO_STRING(s, 6, md->name, 24);
- WFIFOSET(s, clif_parse_func_table[0x95].len);
+ fixed_95.char_name = stringish<CharName>(md->name);
+ send_fpacket<0x0095, 30>(s, fixed_95);
}
break;
default:
if (battle_config.error_log)
- PRINTF("clif_parse_GetCharNameRequest : bad type %d (%d)\n",
+ PRINTF("clif_parse_GetCharNameRequest : bad type %d (%d)\n"_fmt,
bl->bl_type, account_id);
break;
}
+
+ return rv;
}
/*==========================================
@@ -3724,63 +3715,60 @@ void clif_parse_GetCharNameRequest(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_GlobalMessage(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ AString repeat;
+ RecvResult rv = recv_packet_repeatonly<0x008c, 4, 1>(s, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
- AString mbuf = clif_validate_chat(sd, ChatType::Global);
+ AString mbuf = clif_validate_chat(sd, ChatType::Global, repeat);
if (!mbuf)
{
- clif_displaymessage(s, "Your message could not be sent.");
- return;
+ clif_displaymessage(s, "Your message could not be sent."_s);
+ return rv;
}
- if (is_atcommand(s, sd, mbuf, 0))
- return;
+ if (is_atcommand(s, sd, mbuf, GmLevel()))
+ return rv;
- if (!magic_message(sd, mbuf))
+ if (!magic::magic_message(sd, mbuf))
{
/* Don't send chat that results in an automatic ban. */
if (tmw_CheckChatSpam(sd, mbuf))
{
- clif_displaymessage(s, "Your message could not be sent.");
- return;
+ clif_displaymessage(s, "Your message could not be sent."_s);
+ return rv;
}
/* It's not a spell/magic message, so send the message to others. */
- size_t mbuf_size = mbuf.size() + 1;
- 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;
- WBUF_STRING(sendbuf, 8, mbuf, mbuf_size);
-
- clif_send(sendbuf, mbuf_size + 8, sd, SendWho::AREA_CHAT_WOC);
+ Packet_Head<0x008d> head_8d;
+ head_8d.block_id = sd->bl_id;
+ XString repeat_8d = mbuf;
+ Buffer sendbuf = create_vpacket<0x008d, 8, 1>(head_8d, repeat_8d);
+
+ clif_send(sendbuf, sd, SendWho::AREA_CHAT_WOC);
}
/* Send the message back to the speaker. */
- size_t len = RFIFOW(s, 2);
- RFIFO_WFIFO_CLONE(s, s, len);
- WFIFOW(s, 0) = 0x8e;
- WFIFOSET(s, len);
+ send_packet_repeatonly<0x008e, 4, 1>(s, repeat);
+
+ return rv;
}
void clif_message(dumb_ptr<block_list> bl, XString msg)
{
size_t msg_len = msg.size() + 1;
- uint8_t buf[512];
-
if (msg_len + 16 > 512)
return;
nullpo_retv(bl);
- WBUFW(buf, 0) = 0x8d;
- WBUFW(buf, 2) = msg_len + 8;
- WBUFL(buf, 4) = bl->bl_id;
- WBUF_STRING(buf, 8, msg, msg_len);
+ Packet_Head<0x008d> head_8d;
+ head_8d.block_id = bl->bl_id;
+ Buffer buf = create_vpacket<0x008d, 8, 1>(head_8d, msg);
- clif_send(buf, WBUFW(buf, 2), bl, SendWho::AREA);
+ clif_send(buf, bl, SendWho::AREA);
}
/*==========================================
@@ -3788,16 +3776,17 @@ void clif_message(dumb_ptr<block_list> bl, XString msg)
*------------------------------------------
*/
static
-void clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd)
{
- unsigned char buf[64];
+ Packet_Fixed<0x009b> fixed;
+ RecvResult rv = recv_fpacket<0x009b, 5>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- nullpo_retv(sd);
-
- // RFIFOW(fd, 2) and WBUFW(buf, 6) are always 0
+ // RFIFOW(fd,2) and WBUFW(buf,6) are always 0
// TODO perhaps we could use that to remove this hack?
DIR dir;
- uint8_t client_dir = RFIFOB(s, 4);
+ uint8_t client_dir = fixed.client_dir;
// the client uses a diffenent direction enum ... ugh
switch (client_dir)
{
@@ -3810,21 +3799,22 @@ void clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd)
case 0 | 8: dir = DIR::E; break; // right
case 1 | 8: dir = DIR::SE; break;
default:
- return;
+ return rv;
}
if (dir == sd->dir)
- return;
+ return rv;
pc_setdir(sd, dir);
- WBUFW(buf, 0) = 0x9c;
- WBUFL(buf, 2) = sd->bl_id;
- WBUFW(buf, 6) = 0;
- WBUFB(buf, 8) = client_dir;
+ Packet_Fixed<0x009c> fixed_9c;
+ fixed_9c.block_id = sd->bl_id;
+ fixed_9c.client_dir = client_dir;
+ Buffer buf = create_fpacket<0x009c, 9>(fixed_9c);
- clif_send(buf, clif_parse_func_table[0x9c].len, sd, SendWho::AREA_WOS);
+ clif_send(buf, sd, SendWho::AREA_WOS);
+ return rv;
}
/*==========================================
@@ -3832,23 +3822,27 @@ void clif_parse_ChangeDir(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd)
{
- unsigned char buf[64];
-
- nullpo_retv(sd);
+ Packet_Fixed<0x00bf> fixed;
+ RecvResult rv = recv_fpacket<0x00bf, 3>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (battle_config.basic_skill_check == 0
|| pc_checkskill(sd, SkillID::NV_EMOTE) >= 1)
{
- uint8_t emote = RFIFOB(s, 2);
- WBUFW(buf, 0) = 0xc0;
- WBUFL(buf, 2) = sd->bl_id;
- WBUFB(buf, 6) = emote;
- clif_send(buf, clif_parse_func_table[0xc0].len, sd, SendWho::AREA);
+ uint8_t emote = fixed.emote;
+ Packet_Fixed<0x00c0> fixed_c0;
+ fixed_c0.block_id = sd->bl_id;
+ fixed_c0.type = emote;
+ Buffer buf = create_fpacket<0x00c0, 7>(fixed_c0);
+ clif_send(buf, sd, SendWho::AREA);
}
else
clif_skill_fail(sd, SkillID::ONE, 0, 1);
+
+ return rv;
}
/*==========================================
@@ -3856,11 +3850,18 @@ void clif_parse_Emotion(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_HowManyConnections(Session *s, dumb_ptr<map_session_data>)
+RecvResult clif_parse_HowManyConnections(Session *s, dumb_ptr<map_session_data>)
{
- WFIFOW(s, 0) = 0xc2;
- WFIFOL(s, 2) = map_getusers();
- WFIFOSET(s, clif_parse_func_table[0xc2].len);
+ Packet_Fixed<0x00c1> fixed;
+ RecvResult rv = recv_fpacket<0x00c1, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ Packet_Fixed<0x00c2> fixed_c2;
+ fixed_c2.users = map_getusers();
+ send_fpacket<0x00c2, 6>(s, fixed_c2);
+
+ return rv;
}
/*==========================================
@@ -3868,64 +3869,69 @@ void clif_parse_HowManyConnections(Session *s, dumb_ptr<map_session_data>)
*------------------------------------------
*/
static
-void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
{
- unsigned char buf[64];
- int action_type, target_id;
+ Packet_Fixed<0x0089> fixed;
+ RecvResult rv = recv_fpacket<0x0089, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- nullpo_retv(sd);
+ DamageType action_type;
+ BlockId target_id;
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| bool(sd->opt1)
|| sd->state.storage_open)
- return;
+ return rv;
tick_t tick = gettick();
pc_stop_walking(sd, 0);
pc_stopattack(sd);
- target_id = RFIFOL(s, 2);
- action_type = RFIFOB(s, 6);
+ target_id = fixed.target_id;
+ action_type = fixed.action;
switch (action_type)
{
- case 0x00: // once attack
- case 0x07: // continuous attack
+ case DamageType::NORMAL:
+ case DamageType::CONTINUOUS:
if (bool(sd->status.option & Option::HIDE))
- return;
+ return rv;
if (!battle_config.skill_delay_attack_enable)
{
if (tick < sd->canact_tick)
{
clif_skill_fail(sd, SkillID::ONE, 4, 0);
- return;
+ return rv;
}
}
if (sd->invincible_timer)
pc_delinvincibletimer(sd);
- if (sd->attacktarget > 0) // [Valaris]
- sd->attacktarget = 0;
- pc_attack(sd, target_id, action_type != 0);
+ sd->attacktarget = BlockId();
+ pc_attack(sd, target_id, action_type != DamageType::NORMAL);
break;
- case 0x02: // sitdown
+ case DamageType::SIT:
pc_stop_walking(sd, 1);
pc_setsit(sd);
clif_sitting(s, sd);
break;
- case 0x03: // standup
+ case DamageType::STAND:
pc_setstand(sd);
- WBUFW(buf, 0) = 0x8a;
- WBUFL(buf, 2) = sd->bl_id;
- WBUFB(buf, 26) = 3;
- clif_send(buf, clif_parse_func_table[0x8a].len, sd, SendWho::AREA);
+ Packet_Fixed<0x008a> fixed_8a;
+ fixed_8a.src_id = sd->bl_id;
+ fixed_8a.damage_type = DamageType::STAND;
+ Buffer buf = create_fpacket<0x008a, 29>(fixed_8a);
+ clif_send(buf, sd, SendWho::AREA);
break;
}
+
+ return rv;
}
/*==========================================
@@ -3933,11 +3939,14 @@ void clif_parse_ActionRequest(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x00b2> fixed;
+ RecvResult rv = recv_fpacket<0x00b2, 3>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- switch (RFIFOB(s, 2))
+ switch (fixed.flag)
{
case 0x00:
if (pc_isdead(sd))
@@ -3961,19 +3970,21 @@ void clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd)
case 0x01:
/* Rovert's Prevent logout option - Fixed [Valaris] */
if (!battle_config.prevent_logout
- || gettick() >= sd->canlog_tick + std::chrono::seconds(10))
+ || gettick() >= sd->canlog_tick + 10_s)
{
chrif_charselectreq(sd);
}
else
{
- WFIFOW(s, 0) = 0x18b;
- WFIFOW(s, 2) = 1;
+ Packet_Fixed<0x018b> fixed_18b;
+ fixed_18b.okay = 1;
- WFIFOSET(s, clif_parse_func_table[0x018b].len);
+ send_fpacket<0x018b, 4>(s, fixed_18b);
}
break;
}
+
+ return rv;
}
/*==========================================
@@ -3987,29 +3998,33 @@ void clif_parse_Restart(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd)
{
- dumb_ptr<map_session_data> dstsd = NULL;
+ Packet_Head<0x0096> head;
+ AString repeat;
+ RecvResult rv = recv_vpacket<0x0096, 28, 1>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
- nullpo_retv(sd);
+ dumb_ptr<map_session_data> dstsd = nullptr;
- AString mbuf = clif_validate_chat(sd, ChatType::Whisper);
+ AString mbuf = clif_validate_chat(sd, ChatType::Whisper, repeat);
if (!mbuf)
{
- clif_displaymessage(s, "Your message could not be sent.");
- return;
+ clif_displaymessage(s, "Your message could not be sent."_s);
+ return rv;
}
- if (is_atcommand(s, sd, mbuf, 0))
+ if (is_atcommand(s, sd, mbuf, GmLevel()))
{
- return;
+ return rv;
}
/* Don't send chat that results in an automatic ban. */
if (tmw_CheckChatSpam(sd, mbuf))
{
- clif_displaymessage(s, "Your message could not be sent.");
- return;
+ clif_displaymessage(s, "Your message could not be sent."_s);
+ return rv;
}
/*
@@ -4018,7 +4033,7 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd)
* conflict (for instance, "Test" versus "test"), the char-server must
* settle the discrepancy.
*/
- CharName tname = stringish<CharName>(RFIFO_STRING<24>(s, 4));
+ CharName tname = head.target_name;
if (!(dstsd = map_nick2sd(tname))
|| dstsd->status_key.name != tname)
intif_wis_message(sd, tname, mbuf);
@@ -4027,7 +4042,7 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd)
/* Refuse messages addressed to self. */
if (dstsd->sess == s)
{
- ZString mes = "You cannot page yourself.";
+ ZString mes = "You cannot page yourself."_s;
clif_wis_message(s, wisp_server_name, mes);
}
else
@@ -4042,6 +4057,8 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd)
}
}
}
+
+ return rv;
}
/*==========================================
@@ -4049,37 +4066,41 @@ void clif_parse_Wis(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd)
{
- dumb_ptr<flooritem_data> fitem;
- int map_object_id;
+ Packet_Fixed<0x009f> fixed;
+ RecvResult rv = recv_fpacket<0x009f, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- nullpo_retv(sd);
+ dumb_ptr<flooritem_data> fitem;
- map_object_id = RFIFOL(s, 2);
+ BlockId map_object_id = fixed.object_id;
fitem = map_id_is_item(map_object_id);
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO) //会話禁止
- return;
+ return rv;
- if (fitem == NULL || fitem->bl_m != sd->bl_m)
- return;
+ if (fitem == nullptr || fitem->bl_m != sd->bl_m)
+ return rv;
if (abs(sd->bl_x - fitem->bl_x) >= 2
|| abs(sd->bl_y - fitem->bl_y) >= 2)
- return; // too far away to pick up
+ return rv; // too far away to pick up
if (sd->state.shroud_active && sd->state.shroud_disappears_on_pickup)
- magic_unshroud(sd);
+ magic::magic_unshroud(sd);
pc_takeitem(sd, fitem);
+
+ return rv;
}
/*==========================================
@@ -4087,33 +4108,38 @@ void clif_parse_TakeItem(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd)
{
- int item_index, item_amount;
-
- nullpo_retv(sd);
+ Packet_Fixed<0x00a2> fixed;
+ RecvResult rv = recv_fpacket<0x00a2, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
if (sd->bl_m->flag.get(MapFlag::NO_PLAYER_DROPS))
{
- clif_displaymessage(sd->sess, "Can't drop items here.");
- return;
+ clif_displaymessage(sd->sess, "Can't drop items here."_s);
+ return rv;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO)
{
- clif_displaymessage(sd->sess, "Can't drop items right now.");
- return;
+ clif_displaymessage(sd->sess, "Can't drop items right now."_s);
+ return rv;
}
- item_index = RFIFOW(s, 2) - 2;
- item_amount = RFIFOW(s, 4);
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 item_index = fixed.ioff2.unshift();
+ int item_amount = fixed.amount;
pc_dropitem(sd, item_index, item_amount);
+
+ return rv;
}
/*==========================================
@@ -4121,23 +4147,30 @@ void clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x00a7> fixed;
+ RecvResult rv = recv_fpacket<0x00a7, 8>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO) //会話禁止
- return;
+ return rv;
if (sd->invincible_timer)
pc_delinvincibletimer(sd);
- pc_useitem(sd, RFIFOW(s, 2) - 2);
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ pc_useitem(sd, fixed.ioff2.unshift());
+
+ return rv;
}
/*==========================================
@@ -4145,30 +4178,35 @@ void clif_parse_UseItem(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd)
{
- int index;
-
- nullpo_retv(sd);
+ Packet_Fixed<0x00a9> fixed;
+ RecvResult rv = recv_fpacket<0x00a9, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
- index = RFIFOW(s, 2) - 2;
- if (sd->npc_id != 0)
- return;
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 index = fixed.ioff2.unshift();
+ if (sd->npc_id)
+ return rv;
if (sd->inventory_data[index])
{
- EPOS epos = EPOS(RFIFOW(s, 4));
+ EPOS epos = fixed.epos_ignored;
if (sd->inventory_data[index]->type == ItemType::ARROW)
epos = EPOS::ARROW;
// Note: the EPOS argument to pc_equipitem is actually ignored
pc_equipitem(sd, index, epos);
}
+
+ return rv;
}
/*==========================================
@@ -4176,23 +4214,28 @@ void clif_parse_EquipItem(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd)
{
- int index;
-
- nullpo_retv(sd);
+ Packet_Fixed<0x00ab> fixed;
+ RecvResult rv = recv_fpacket<0x00ab, 4>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
- index = RFIFOW(s, 2) - 2;
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 index = fixed.ioff2.unshift();
- if (sd->npc_id != 0
+ if (sd->npc_id
|| sd->opt1 != Opt1::ZERO)
- return;
+ return rv;
pc_unequipitem(sd, index, CalcStatus::NOW);
+
+ return rv;
}
/*==========================================
@@ -4200,18 +4243,23 @@ void clif_parse_UnequipItem(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_NpcClicked(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x0090> fixed;
+ RecvResult rv = recv_fpacket<0x0090, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (pc_isdead(sd))
{
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- return;
+ return rv;
}
- if (sd->npc_id != 0)
- return;
- npc_click(sd, RFIFOL(s, 2));
+ if (sd->npc_id)
+ return rv;
+ npc_click(sd, fixed.block_id);
+
+ return rv;
}
/*==========================================
@@ -4219,9 +4267,16 @@ 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)
+RecvResult clif_parse_NpcBuySellSelected(Session *s, dumb_ptr<map_session_data> sd)
{
- npc_buysellsel(sd, RFIFOL(s, 2), RFIFOB(s, 6));
+ Packet_Fixed<0x00c5> fixed;
+ RecvResult rv = recv_fpacket<0x00c5, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ npc_buysellsel(sd, fixed.block_id, fixed.type);
+
+ return rv;
}
/*==========================================
@@ -4229,17 +4284,20 @@ void clif_parse_NpcBuySellSelected(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_NpcBuyListSend(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_NpcBuyListSend(Session *s, dumb_ptr<map_session_data> sd)
{
- int n = (RFIFOW(s, 2) - 4) / 4;
- // really an array of pairs of uint16_t
- const uint16_t *item_list = static_cast<const uint16_t *>(RFIFOP(s, 4));
+ std::vector<Packet_Repeat<0x00c8>> repeat;
+ RecvResult rv = recv_packet_repeatonly<0x00c8, 4, 4>(s, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
- int fail = npc_buylist(sd, n, item_list);
+ int fail = npc_buylist(sd, repeat);
- WFIFOW(s, 0) = 0xca;
- WFIFOB(s, 2) = fail;
- WFIFOSET(s, clif_parse_func_table[0xca].len);
+ Packet_Fixed<0x00ca> fixed_ca;
+ fixed_ca.fail = fail;
+ send_fpacket<0x00ca, 3>(s, fixed_ca);
+
+ return rv;
}
/*==========================================
@@ -4247,17 +4305,20 @@ void clif_parse_NpcBuyListSend(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_NpcSellListSend(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_NpcSellListSend(Session *s, dumb_ptr<map_session_data> sd)
{
- int n = (RFIFOW(s, 2) - 4) / 4;
- // really an array of pairs of uint16_t
- const uint16_t *item_list = static_cast<const uint16_t *>(RFIFOP(s, 4));
+ std::vector<Packet_Repeat<0x00c9>> repeat;
+ RecvResult rv = recv_packet_repeatonly<0x00c9, 4, 4>(s, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ int fail = npc_selllist(sd, repeat);
- int fail = npc_selllist(sd, n, item_list);
+ Packet_Fixed<0x00cb> fixed_cb;
+ fixed_cb.fail = fail;
+ send_fpacket<0x00cb, 3>(s, fixed_cb);
- WFIFOW(s, 0) = 0xcb;
- WFIFOB(s, 2) = fail;
- WFIFOSET(s, clif_parse_func_table[0xcb].len);
+ return rv;
}
/*==========================================
@@ -4265,17 +4326,22 @@ void clif_parse_NpcSellListSend(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TradeRequest(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TradeRequest(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x00e4> fixed;
+ RecvResult rv = recv_fpacket<0x00e4, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (battle_config.basic_skill_check == 0
|| pc_checkskill(sd, SkillID::NV_TRADE) >= 1)
{
- trade_traderequest(sd, RFIFOL(sd->sess, 2));
+ trade_traderequest(sd, fixed.block_id);
}
else
clif_skill_fail(sd, SkillID::ONE, 0, 0);
+
+ return rv;
}
/*==========================================
@@ -4283,11 +4349,16 @@ void clif_parse_TradeRequest(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TradeAck(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TradeAck(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x00e6> fixed;
+ RecvResult rv = recv_fpacket<0x00e6, 3>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- trade_tradeack(sd, RFIFOB(sd->sess, 2));
+ trade_tradeack(sd, fixed.type);
+
+ return rv;
}
/*==========================================
@@ -4295,11 +4366,18 @@ void clif_parse_TradeAck(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TradeAddItem(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TradeAddItem(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x00e8> fixed;
+ RecvResult rv = recv_fpacket<0x00e8, 8>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- trade_tradeadditem(sd, RFIFOW(sd->sess, 2), RFIFOL(sd->sess, 4));
+ if (fixed.zeny_or_ioff2.index != 0 && !fixed.zeny_or_ioff2.ok())
+ return RecvResult::Error;
+ trade_tradeadditem(sd, fixed.zeny_or_ioff2, fixed.amount);
+
+ return rv;
}
/*==========================================
@@ -4307,9 +4385,16 @@ void clif_parse_TradeAddItem(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TradeOk(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TradeOk(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x00eb> fixed;
+ RecvResult rv = recv_fpacket<0x00eb, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
trade_tradeok(sd);
+
+ return rv;
}
/*==========================================
@@ -4317,9 +4402,16 @@ void clif_parse_TradeOk(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TradeCansel(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TradeCansel(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x00ed> fixed;
+ RecvResult rv = recv_fpacket<0x00ed, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
trade_tradecancel(sd);
+
+ return rv;
}
/*==========================================
@@ -4327,9 +4419,16 @@ void clif_parse_TradeCansel(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_TradeCommit(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_TradeCommit(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x00ef> fixed;
+ RecvResult rv = recv_fpacket<0x00ef, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
trade_tradecommit(sd);
+
+ return rv;
}
/*==========================================
@@ -4337,9 +4436,16 @@ void clif_parse_TradeCommit(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_StopAttack(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_StopAttack(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x0118> fixed;
+ RecvResult rv = recv_fpacket<0x0118, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
pc_stopattack(sd);
+
+ return rv;
}
/*==========================================
@@ -4347,9 +4453,16 @@ void clif_parse_StopAttack(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_StatusUp(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_StatusUp(Session *s, dumb_ptr<map_session_data> sd)
{
- pc_statusup(sd, SP(RFIFOW(s, 2)));
+ Packet_Fixed<0x00bb> fixed;
+ RecvResult rv = recv_fpacket<0x00bb, 5>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ pc_statusup(sd, fixed.asp);
+
+ return rv;
}
/*==========================================
@@ -4357,9 +4470,16 @@ void clif_parse_StatusUp(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_SkillUp(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_SkillUp(Session *s, dumb_ptr<map_session_data> sd)
{
- pc_skillup(sd, SkillID(RFIFOW(s, 2)));
+ Packet_Fixed<0x0112> fixed;
+ RecvResult rv = recv_fpacket<0x0112, 4>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ pc_skillup(sd, fixed.skill_id);
+
+ return rv;
}
/*==========================================
@@ -4367,12 +4487,17 @@ void clif_parse_SkillUp(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_NpcSelectMenu(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_NpcSelectMenu(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x00b8> fixed;
+ RecvResult rv = recv_fpacket<0x00b8, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ sd->npc_menu = fixed.menu_entry;
+ map_scriptcont(sd, fixed.npc_id);
- sd->npc_menu = RFIFOB(s, 6);
- map_scriptcont(sd, RFIFOL(s, 2));
+ return rv;
}
/*==========================================
@@ -4380,9 +4505,16 @@ 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)
+RecvResult clif_parse_NpcNextClicked(Session *s, dumb_ptr<map_session_data> sd)
{
- map_scriptcont(sd, RFIFOL(s, 2));
+ Packet_Fixed<0x00b9> fixed;
+ RecvResult rv = recv_fpacket<0x00b9, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ map_scriptcont(sd, fixed.npc_id);
+
+ return rv;
}
/*==========================================
@@ -4390,12 +4522,17 @@ void clif_parse_NpcNextClicked(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_NpcAmountInput(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_NpcAmountInput(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x0143> fixed;
+ RecvResult rv = recv_fpacket<0x0143, 10>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- sd->npc_amount = RFIFOL(s, 6);
- map_scriptcont(sd, RFIFOL(s, 2));
+ sd->npc_amount = fixed.input_int_value;
+ map_scriptcont(sd, fixed.block_id);
+
+ return rv;
}
/*==========================================
@@ -4405,22 +4542,19 @@ void clif_parse_NpcAmountInput(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_NpcStringInput(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_NpcStringInput(Session *s, dumb_ptr<map_session_data> sd)
{
- int len;
- nullpo_retv(sd);
+ Packet_Head<0x01d5> head;
+ AString repeat;
+ RecvResult rv = recv_vpacket<0x01d5, 8, 1>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
- len = RFIFOW(s, 2) - 8;
+ sd->npc_str = repeat;
- /*
- * If we check for equal to 0, too, we'll freeze clients that send (or
- * claim to have sent) an "empty" message.
- */
- if (len < 0)
- return;
- sd->npc_str = RFIFO_STRING(s, 8, len);
+ map_scriptcont(sd, head.block_id);
- map_scriptcont(sd, RFIFOL(s, 4));
+ return rv;
}
/*==========================================
@@ -4428,9 +4562,16 @@ 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)
+RecvResult clif_parse_NpcCloseClicked(Session *s, dumb_ptr<map_session_data> sd)
{
- map_scriptcont(sd, RFIFOL(s, 2));
+ Packet_Fixed<0x0146> fixed;
+ RecvResult rv = recv_fpacket<0x0146, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ map_scriptcont(sd, fixed.block_id);
+
+ return rv;
}
/*==========================================
@@ -4438,21 +4579,26 @@ void clif_parse_NpcCloseClicked(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd)
{
- int item_index, item_amount;
+ Packet_Fixed<0x00f3> fixed;
+ RecvResult rv = recv_fpacket<0x00f3, 8>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- nullpo_retv(sd);
-
- item_index = RFIFOW(s, 2) - 2;
- item_amount = RFIFOL(s, 4);
+ if (!fixed.ioff2.ok())
+ return RecvResult::Error;
+ IOff0 item_index = fixed.ioff2.unshift();
+ int item_amount = fixed.amount;
- 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;
+ return rv;
if (sd->state.storage_open)
storage_storageadd(sd, item_index, item_amount);
+
+ return rv;
}
/*==========================================
@@ -4460,21 +4606,26 @@ void clif_parse_MoveToKafra(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd)
{
- int item_index, item_amount;
-
- nullpo_retv(sd);
+ Packet_Fixed<0x00f5> fixed;
+ RecvResult rv = recv_fpacket<0x00f5, 8>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
- item_index = RFIFOW(s, 2) - 1;
- item_amount = RFIFOL(s, 4);
+ if (!fixed.soff1.ok())
+ return RecvResult::Error;
+ SOff0 item_index = fixed.soff1.unshift();
+ int item_amount = fixed.amount;
- 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;
+ return rv;
if (sd->state.storage_open)
storage_storageget(sd, item_index, item_amount);
+
+ return rv;
}
/*==========================================
@@ -4482,12 +4633,17 @@ void clif_parse_MoveFromKafra(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_CloseKafra(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_CloseKafra(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ Packet_Fixed<0x00f7> fixed;
+ RecvResult rv = recv_fpacket<0x00f7, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
if (sd->state.storage_open)
storage_storageclose(sd);
+
+ return rv;
}
/*==========================================
@@ -4498,16 +4654,23 @@ void clif_parse_CloseKafra(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_CreateParty(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_CreateParty(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x00f9> fixed;
+ RecvResult rv = recv_fpacket<0x00f9, 26>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
if (battle_config.basic_skill_check == 0
|| pc_checkskill(sd, SkillID::NV_PARTY) >= 2)
{
- PartyName name = stringish<PartyName>(RFIFO_STRING<24>(s, 2));
+ PartyName name = fixed.party_name;
party_create(sd, name);
}
else
clif_skill_fail(sd, SkillID::ONE, 0, 4);
+
+ return rv;
}
/*==========================================
@@ -4518,9 +4681,16 @@ 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)
+RecvResult clif_parse_PartyInvite(Session *s, dumb_ptr<map_session_data> sd)
{
- party_invite(sd, RFIFOL(s, 2));
+ Packet_Fixed<0x00fc> fixed;
+ RecvResult rv = recv_fpacket<0x00fc, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ party_invite(sd, fixed.account_id);
+
+ return rv;
}
/*==========================================
@@ -4531,18 +4701,25 @@ void clif_parse_PartyInvite(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_ReplyPartyInvite(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_ReplyPartyInvite(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x00ff> fixed;
+ RecvResult rv = recv_fpacket<0x00ff, 10>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
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, fixed.account_id, fixed.flag);
}
else
{
- party_reply_invite(sd, RFIFOL(s, 2), 0);
+ party_reply_invite(sd, fixed.account_id, 0);
clif_skill_fail(sd, SkillID::ONE, 0, 4);
}
+
+ return rv;
}
/*==========================================
@@ -4550,9 +4727,16 @@ void clif_parse_ReplyPartyInvite(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_LeaveParty(Session *, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_LeaveParty(Session *s, dumb_ptr<map_session_data> sd)
{
+ Packet_Fixed<0x0100> fixed;
+ RecvResult rv = recv_fpacket<0x0100, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
party_leave(sd);
+
+ return rv;
}
/*==========================================
@@ -4560,11 +4744,18 @@ void clif_parse_LeaveParty(Session *, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_RemovePartyMember(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_RemovePartyMember(Session *s, dumb_ptr<map_session_data> sd)
{
- int account_id = RFIFOL(s, 2);
- // unused RFIFO_STRING<24>(fd, 6);
+ Packet_Fixed<0x0103> fixed;
+ RecvResult rv = recv_fpacket<0x0103, 30>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ AccountId account_id = fixed.account_id;
+ // unused fixed.unusedchar_name;
party_removemember(sd, account_id);
+
+ return rv;
}
/*==========================================
@@ -4572,9 +4763,16 @@ void clif_parse_RemovePartyMember(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_PartyChangeOption(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_PartyChangeOption(Session *s, dumb_ptr<map_session_data> sd)
{
- party_changeoption(sd, RFIFOW(s, 2), RFIFOW(s, 4));
+ Packet_Fixed<0x0102> fixed;
+ RecvResult rv = recv_fpacket<0x0102, 6>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ party_changeoption(sd, fixed.exp, fixed.item);
+
+ return rv;
}
/*==========================================
@@ -4586,582 +4784,604 @@ void clif_parse_PartyChangeOption(Session *s, dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-void clif_parse_PartyMessage(Session *s, dumb_ptr<map_session_data> sd)
+RecvResult clif_parse_PartyMessage(Session *s, dumb_ptr<map_session_data> sd)
{
- nullpo_retv(sd);
+ AString repeat;
+ RecvResult rv = recv_packet_repeatonly<0x0108, 4, 1>(s, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
- AString mbuf = clif_validate_chat(sd, ChatType::Party);
+ AString mbuf = clif_validate_chat(sd, ChatType::Party, repeat);
if (!mbuf)
{
- clif_displaymessage(s, "Your message could not be sent.");
- return;
+ clif_displaymessage(s, "Your message could not be sent."_s);
+ return rv;
}
- if (is_atcommand(s, sd, mbuf, 0))
- return;
+ if (is_atcommand(s, sd, mbuf, GmLevel()))
+ return rv;
/* Don't send chat that results in an automatic ban. */
if (tmw_CheckChatSpam(sd, mbuf))
{
- clif_displaymessage(s, "Your message could not be sent.");
- return;
+ clif_displaymessage(s, "Your message could not be sent."_s);
+ return rv;
}
party_send_message(sd, mbuf);
+
+ return rv;
}
func_table clif_parse_func_table[0x0220] =
{
- {0, 10, NULL, }, // 0x0000
- {0, 0, NULL, }, // 0x0001
- {0, 0, NULL, }, // 0x0002
- {0, 0, NULL, }, // 0x0003
- {0, 0, NULL, }, // 0x0004
- {0, 0, NULL, }, // 0x0005
- {0, 0, NULL, }, // 0x0006
- {0, 0, NULL, }, // 0x0007
- {0, 0, NULL, }, // 0x0008
- {0, 0, NULL, }, // 0x0009
- {0, 0, NULL, }, // 0x000a
- {0, 0, NULL, }, // 0x000b
- {0, 0, NULL, }, // 0x000c
- {0, 0, NULL, }, // 0x000d
- {0, 0, NULL, }, // 0x000e
- {0, 0, NULL, }, // 0x000f
- {0, 0, NULL, }, // 0x0010
- {0, 0, NULL, }, // 0x0011
- {0, 0, NULL, }, // 0x0012
- {0, 0, NULL, }, // 0x0013
- {0, 0, NULL, }, // 0x0014
- {0, 0, NULL, }, // 0x0015
- {0, 0, NULL, }, // 0x0016
- {0, 0, NULL, }, // 0x0017
- {0, 0, NULL, }, // 0x0018
- {0, 0, NULL, }, // 0x0019
- {0, 0, NULL, }, // 0x001a
- {0, 0, NULL, }, // 0x001b
- {0, 0, NULL, }, // 0x001c
- {0, 0, NULL, }, // 0x001d
- {0, 0, NULL, }, // 0x001e
- {0, 0, NULL, }, // 0x001f
- {0, 0, NULL, }, // 0x0020
- {0, 0, NULL, }, // 0x0021
- {0, 0, NULL, }, // 0x0022
- {0, 0, NULL, }, // 0x0023
- {0, 0, NULL, }, // 0x0024
- {0, 0, NULL, }, // 0x0025
- {0, 0, NULL, }, // 0x0026
- {0, 0, NULL, }, // 0x0027
- {0, 0, NULL, }, // 0x0028
- {0, 0, NULL, }, // 0x0029
- {0, 0, NULL, }, // 0x002a
- {0, 0, NULL, }, // 0x002b
- {0, 0, NULL, }, // 0x002c
- {0, 0, NULL, }, // 0x002d
- {0, 0, NULL, }, // 0x002e
- {0, 0, NULL, }, // 0x002f
- {0, 0, NULL, }, // 0x0030
- {0, 0, NULL, }, // 0x0031
- {0, 0, NULL, }, // 0x0032
- {0, 0, NULL, }, // 0x0033
- {0, 0, NULL, }, // 0x0034
- {0, 0, NULL, }, // 0x0035
- {0, 0, NULL, }, // 0x0036
- {0, 0, NULL, }, // 0x0037
- {0, 0, NULL, }, // 0x0038
- {0, 0, NULL, }, // 0x0039
- {0, 0, NULL, }, // 0x003a
- {0, 0, NULL, }, // 0x003b
- {0, 0, NULL, }, // 0x003c
- {0, 0, NULL, }, // 0x003d
- {0, 0, NULL, }, // 0x003e
- {0, 0, NULL, }, // 0x003f
- {0, 0, NULL, }, // 0x0040
- {0, 0, NULL, }, // 0x0041
- {0, 0, NULL, }, // 0x0042
- {0, 0, NULL, }, // 0x0043
- {0, 0, NULL, }, // 0x0044
- {0, 0, NULL, }, // 0x0045
- {0, 0, NULL, }, // 0x0046
- {0, 0, NULL, }, // 0x0047
- {0, 0, NULL, }, // 0x0048
- {0, 0, NULL, }, // 0x0049
- {0, 0, NULL, }, // 0x004a
- {0, 0, NULL, }, // 0x004b
- {0, 0, NULL, }, // 0x004c
- {0, 0, NULL, }, // 0x004d
- {0, 0, NULL, }, // 0x004e
- {0, 0, NULL, }, // 0x004f
- {0, 0, NULL, }, // 0x0050
- {0, 0, NULL, }, // 0x0051
- {0, 0, NULL, }, // 0x0052
- {0, 0, NULL, }, // 0x0053
- {0, 0, NULL, }, // 0x0054
- {0, 0, NULL, }, // 0x0055
- {0, 0, NULL, }, // 0x0056
- {0, 0, NULL, }, // 0x0057
- {0, 0, NULL, }, // 0x0058
- {0, 0, NULL, }, // 0x0059
- {0, 0, NULL, }, // 0x005a
- {0, 0, NULL, }, // 0x005b
- {0, 0, NULL, }, // 0x005c
- {0, 0, NULL, }, // 0x005d
- {0, 0, NULL, }, // 0x005e
- {0, 0, NULL, }, // 0x005f
- {0, 0, NULL, }, // 0x0060
- {0, 0, NULL, }, // 0x0061
- {0, 0, NULL, }, // 0x0062
- {0, VAR,NULL, }, // 0x0063
- {0, 55, NULL, }, // 0x0064
- {0, 17, NULL, }, // 0x0065
- {0, 3, NULL, }, // 0x0066
- {0, 37, NULL, }, // 0x0067
- {0, 46, NULL, }, // 0x0068
- {0, VAR,NULL, }, // 0x0069
- {0, 23, NULL, }, // 0x006a
- {0, VAR,NULL, }, // 0x006b
- {0, 3, NULL, }, // 0x006c
- {0, 108,NULL, }, // 0x006d
- {0, 3, NULL, }, // 0x006e
- {0, 2, NULL, }, // 0x006f
- {0, 3, NULL, }, // 0x0070
- {0, 28, NULL, }, // 0x0071
+ {0, 10, nullptr, }, // 0x0000
+ {0, 0, nullptr, }, // 0x0001
+ {0, 0, nullptr, }, // 0x0002
+ {0, 0, nullptr, }, // 0x0003
+ {0, 0, nullptr, }, // 0x0004
+ {0, 0, nullptr, }, // 0x0005
+ {0, 0, nullptr, }, // 0x0006
+ {0, 0, nullptr, }, // 0x0007
+ {0, 0, nullptr, }, // 0x0008
+ {0, 0, nullptr, }, // 0x0009
+ {0, 0, nullptr, }, // 0x000a
+ {0, 0, nullptr, }, // 0x000b
+ {0, 0, nullptr, }, // 0x000c
+ {0, 0, nullptr, }, // 0x000d
+ {0, 0, nullptr, }, // 0x000e
+ {0, 0, nullptr, }, // 0x000f
+ {0, 0, nullptr, }, // 0x0010
+ {0, 0, nullptr, }, // 0x0011
+ {0, 0, nullptr, }, // 0x0012
+ {0, 0, nullptr, }, // 0x0013
+ {0, 0, nullptr, }, // 0x0014
+ {0, 0, nullptr, }, // 0x0015
+ {0, 0, nullptr, }, // 0x0016
+ {0, 0, nullptr, }, // 0x0017
+ {0, 0, nullptr, }, // 0x0018
+ {0, 0, nullptr, }, // 0x0019
+ {0, 0, nullptr, }, // 0x001a
+ {0, 0, nullptr, }, // 0x001b
+ {0, 0, nullptr, }, // 0x001c
+ {0, 0, nullptr, }, // 0x001d
+ {0, 0, nullptr, }, // 0x001e
+ {0, 0, nullptr, }, // 0x001f
+ {0, 0, nullptr, }, // 0x0020
+ {0, 0, nullptr, }, // 0x0021
+ {0, 0, nullptr, }, // 0x0022
+ {0, 0, nullptr, }, // 0x0023
+ {0, 0, nullptr, }, // 0x0024
+ {0, 0, nullptr, }, // 0x0025
+ {0, 0, nullptr, }, // 0x0026
+ {0, 0, nullptr, }, // 0x0027
+ {0, 0, nullptr, }, // 0x0028
+ {0, 0, nullptr, }, // 0x0029
+ {0, 0, nullptr, }, // 0x002a
+ {0, 0, nullptr, }, // 0x002b
+ {0, 0, nullptr, }, // 0x002c
+ {0, 0, nullptr, }, // 0x002d
+ {0, 0, nullptr, }, // 0x002e
+ {0, 0, nullptr, }, // 0x002f
+ {0, 0, nullptr, }, // 0x0030
+ {0, 0, nullptr, }, // 0x0031
+ {0, 0, nullptr, }, // 0x0032
+ {0, 0, nullptr, }, // 0x0033
+ {0, 0, nullptr, }, // 0x0034
+ {0, 0, nullptr, }, // 0x0035
+ {0, 0, nullptr, }, // 0x0036
+ {0, 0, nullptr, }, // 0x0037
+ {0, 0, nullptr, }, // 0x0038
+ {0, 0, nullptr, }, // 0x0039
+ {0, 0, nullptr, }, // 0x003a
+ {0, 0, nullptr, }, // 0x003b
+ {0, 0, nullptr, }, // 0x003c
+ {0, 0, nullptr, }, // 0x003d
+ {0, 0, nullptr, }, // 0x003e
+ {0, 0, nullptr, }, // 0x003f
+ {0, 0, nullptr, }, // 0x0040
+ {0, 0, nullptr, }, // 0x0041
+ {0, 0, nullptr, }, // 0x0042
+ {0, 0, nullptr, }, // 0x0043
+ {0, 0, nullptr, }, // 0x0044
+ {0, 0, nullptr, }, // 0x0045
+ {0, 0, nullptr, }, // 0x0046
+ {0, 0, nullptr, }, // 0x0047
+ {0, 0, nullptr, }, // 0x0048
+ {0, 0, nullptr, }, // 0x0049
+ {0, 0, nullptr, }, // 0x004a
+ {0, 0, nullptr, }, // 0x004b
+ {0, 0, nullptr, }, // 0x004c
+ {0, 0, nullptr, }, // 0x004d
+ {0, 0, nullptr, }, // 0x004e
+ {0, 0, nullptr, }, // 0x004f
+ {0, 0, nullptr, }, // 0x0050
+ {0, 0, nullptr, }, // 0x0051
+ {0, 0, nullptr, }, // 0x0052
+ {0, 0, nullptr, }, // 0x0053
+ {0, 0, nullptr, }, // 0x0054
+ {0, 0, nullptr, }, // 0x0055
+ {0, 0, nullptr, }, // 0x0056
+ {0, 0, nullptr, }, // 0x0057
+ {0, 0, nullptr, }, // 0x0058
+ {0, 0, nullptr, }, // 0x0059
+ {0, 0, nullptr, }, // 0x005a
+ {0, 0, nullptr, }, // 0x005b
+ {0, 0, nullptr, }, // 0x005c
+ {0, 0, nullptr, }, // 0x005d
+ {0, 0, nullptr, }, // 0x005e
+ {0, 0, nullptr, }, // 0x005f
+ {0, 0, nullptr, }, // 0x0060
+ {0, 0, nullptr, }, // 0x0061
+ {0, 0, nullptr, }, // 0x0062
+ {0, VAR,nullptr, }, // 0x0063
+ {0, 55, nullptr, }, // 0x0064
+ {0, 17, nullptr, }, // 0x0065
+ {0, 3, nullptr, }, // 0x0066
+ {0, 37, nullptr, }, // 0x0067
+ {0, 46, nullptr, }, // 0x0068
+ {0, VAR,nullptr, }, // 0x0069
+ {0, 23, nullptr, }, // 0x006a
+ {0, VAR,nullptr, }, // 0x006b
+ {0, 3, nullptr, }, // 0x006c
+ {0, 108,nullptr, }, // 0x006d
+ {0, 3, nullptr, }, // 0x006e
+ {0, 2, nullptr, }, // 0x006f
+ {0, 3, nullptr, }, // 0x0070
+ {0, 28, nullptr, }, // 0x0071
{0, 19, clif_parse_WantToConnection, }, // 0x0072
- {0, 11, NULL, }, // 0x0073
- {0, 3, NULL, }, // 0x0074
- {0, VAR,NULL, }, // 0x0075
- {0, 9, NULL, }, // 0x0076
- {0, 5, NULL, }, // 0x0077
- {0, 54, NULL, }, // 0x0078
- {0, 53, NULL, }, // 0x0079
- {0, 58, NULL, }, // 0x007a
- {0, 60, NULL, }, // 0x007b
- {0, 41, NULL, }, // 0x007c
+ {0, 11, nullptr, }, // 0x0073
+ {0, 3, nullptr, }, // 0x0074
+ {0, VAR,nullptr, }, // 0x0075
+ {0, 9, nullptr, }, // 0x0076
+ {0, 5, nullptr, }, // 0x0077
+ {0, 54, nullptr, }, // 0x0078
+ {0, 53, nullptr, }, // 0x0079
+ {0, 58, nullptr, }, // 0x007a
+ {0, 60, nullptr, }, // 0x007b
+ {0, 41, nullptr, }, // 0x007c
{-1, 2, clif_parse_LoadEndAck, }, // 0x007d
{0, 6, clif_parse_TickSend, }, // 0x007e
- {0, 6, NULL, }, // 0x007f
- {0, 7, NULL, }, // 0x0080
- {0, 3, NULL, }, // 0x0081
- {0, 2, NULL, }, // 0x0082
- {0, 2, NULL, }, // 0x0083
- {0, 2, NULL, }, // 0x0084
+ {0, 6, nullptr, }, // 0x007f
+ {0, 7, nullptr, }, // 0x0080
+ {0, 3, nullptr, }, // 0x0081
+ {0, 2, nullptr, }, // 0x0082
+ {0, 2, nullptr, }, // 0x0083
+ {0, 2, nullptr, }, // 0x0084
{-1, 5, clif_parse_WalkToXY, }, // 0x0085 Walk code limits this on it's own
- {0, 16, NULL, }, // 0x0086
- {0, 12, NULL, }, // 0x0087
- {0, 10, NULL, }, // 0x0088
+ {0, 16, nullptr, }, // 0x0086
+ {0, 12, nullptr, }, // 0x0087
+ {0, 10, nullptr, }, // 0x0088
{1000, 7, clif_parse_ActionRequest, }, // 0x0089 Special case - see below
- {0, 29, NULL, }, // 0x008a
- {0, 23, NULL, }, // 0x008b unknown... size 2 or 23?
+ {0, 29, nullptr, }, // 0x008a
+ {0, 23, nullptr, }, // 0x008b unknown... size 2 or 23?
{300, VAR,clif_parse_GlobalMessage, }, // 0x008c
- {0, VAR,NULL, }, // 0x008d
- {0, VAR,NULL, }, // 0x008e
- {0, 0, NULL, }, // 0x008f
+ {0, VAR,nullptr, }, // 0x008d
+ {0, VAR,nullptr, }, // 0x008e
+ {0, 0, nullptr, }, // 0x008f
{500, 7, clif_parse_NpcClicked, }, // 0x0090
- {0, 22, NULL, }, // 0x0091
- {0, 28, NULL, }, // 0x0092
- {0, 2, NULL, }, // 0x0093
+ {0, 22, nullptr, }, // 0x0091
+ {0, 28, nullptr, }, // 0x0092
+ {0, 2, nullptr, }, // 0x0093
{-1, 6, clif_parse_GetCharNameRequest, }, // 0x0094
- {0, 30, NULL, }, // 0x0095
+ {0, 30, nullptr, }, // 0x0095
{300, VAR,clif_parse_Wis, }, // 0x0096
- {0, VAR,NULL, }, // 0x0097
- {0, 3, NULL, }, // 0x0098
- {300, VAR,NULL, }, // 0x0099
- {0, VAR,NULL, }, // 0x009a
+ {0, VAR,nullptr, }, // 0x0097
+ {0, 3, nullptr, }, // 0x0098
+ {300, VAR,nullptr, }, // 0x0099
+ {0, VAR,nullptr, }, // 0x009a
{-1, 5, clif_parse_ChangeDir, }, // 0x009b
- {0, 9, NULL, }, // 0x009c
- {0, 17, NULL, }, // 0x009d
- {0, 17, NULL, }, // 0x009e
+ {0, 9, nullptr, }, // 0x009c
+ {0, 17, nullptr, }, // 0x009d
+ {0, 17, nullptr, }, // 0x009e
{400, 6, clif_parse_TakeItem, }, // 0x009f
- {0, 23, NULL, }, // 0x00a0
- {0, 6, NULL, }, // 0x00a1
+ {0, 23, nullptr, }, // 0x00a0
+ {0, 6, nullptr, }, // 0x00a1
{50, 6, clif_parse_DropItem, }, // 0x00a2
- {0, VAR,NULL, }, // 0x00a3
- {0, VAR,NULL, }, // 0x00a4
- {0, VAR,NULL, }, // 0x00a5
- {0, VAR,NULL, }, // 0x00a6
+ {0, VAR,nullptr, }, // 0x00a3
+ {0, VAR,nullptr, }, // 0x00a4
+ {0, VAR,nullptr, }, // 0x00a5
+ {0, VAR,nullptr, }, // 0x00a6
{0, 8, clif_parse_UseItem, }, // 0x00a7
- {0, 7, NULL, }, // 0x00a8
+ {0, 7, nullptr, }, // 0x00a8
{-1, 6, clif_parse_EquipItem, }, // 0x00a9 Special case - outfit window (not implemented yet - needs to allow bursts)
- {0, 7, NULL, }, // 0x00aa
+ {0, 7, nullptr, }, // 0x00aa
{-1, 4, clif_parse_UnequipItem, }, // 0x00ab Special case - outfit window (not implemented yet - needs to allow bursts)
- {0, 7, NULL, }, // 0x00ac
- {0, 0, NULL, }, // 0x00ad
- {0, VAR,NULL, }, // 0x00ae
- {0, 6, NULL, }, // 0x00af
- {0, 8, NULL, }, // 0x00b0
- {0, 8, NULL, }, // 0x00b1
+ {0, 7, nullptr, }, // 0x00ac
+ {0, 0, nullptr, }, // 0x00ad
+ {0, VAR,nullptr, }, // 0x00ae
+ {0, 6, nullptr, }, // 0x00af
+ {0, 8, nullptr, }, // 0x00b0
+ {0, 8, nullptr, }, // 0x00b1
{0, 3, clif_parse_Restart, }, // 0x00b2
- {0, 3, NULL, }, // 0x00b3
- {0, VAR,NULL, }, // 0x00b4
- {0, 6, NULL, }, // 0x00b5
- {0, 6, NULL, }, // 0x00b6
- {0, VAR,NULL, }, // 0x00b7
+ {0, 3, nullptr, }, // 0x00b3
+ {0, VAR,nullptr, }, // 0x00b4
+ {0, 6, nullptr, }, // 0x00b5
+ {0, 6, nullptr, }, // 0x00b6
+ {0, VAR,nullptr, }, // 0x00b7
{0, 7, clif_parse_NpcSelectMenu, }, // 0x00b8
{-1, 6, clif_parse_NpcNextClicked, }, // 0x00b9
- {0, 2, NULL, }, // 0x00ba
+ {0, 2, nullptr, }, // 0x00ba
{-1, 5, clif_parse_StatusUp, }, // 0x00bb People click this very quickly
- {0, 6, NULL, }, // 0x00bc
- {0, 44, NULL, }, // 0x00bd
- {0, 5, NULL, }, // 0x00be
+ {0, 6, nullptr, }, // 0x00bc
+ {0, 44, nullptr, }, // 0x00bd
+ {0, 5, nullptr, }, // 0x00be
{1000, 3, clif_parse_Emotion, }, // 0x00bf
- {0, 7, NULL, }, // 0x00c0
+ {0, 7, nullptr, }, // 0x00c0
{0, 2, clif_parse_HowManyConnections, }, // 0x00c1
- {0, 6, NULL, }, // 0x00c2
- {0, 8, NULL, }, // 0x00c3
- {0, 6, NULL, }, // 0x00c4
+ {0, 6, nullptr, }, // 0x00c2
+ {0, 8, nullptr, }, // 0x00c3
+ {0, 6, nullptr, }, // 0x00c4
{0, 7, clif_parse_NpcBuySellSelected, }, // 0x00c5
- {0, VAR,NULL, }, // 0x00c6
- {0, VAR,NULL, }, // 0x00c7
+ {0, VAR,nullptr, }, // 0x00c6
+ {0, VAR,nullptr, }, // 0x00c7
{-1, VAR,clif_parse_NpcBuyListSend, }, // 0x00c8
{-1, VAR,clif_parse_NpcSellListSend, }, // 0x00c9 Selling multiple 1-slot items
- {0, 3, NULL, }, // 0x00ca
- {0, 3, NULL, }, // 0x00cb
- {0, 6, NULL, }, // 0x00cc
- {0, 6, NULL, }, // 0x00cd
- {0, 2, NULL, }, // 0x00ce
- {0, 27, NULL, }, // 0x00cf
- {0, 3, NULL, }, // 0x00d0
- {0, 4, NULL, }, // 0x00d1
- {0, 4, NULL, }, // 0x00d2
- {0, 2, NULL, }, // 0x00d3
- {0, VAR,NULL, }, // 0x00d4
- {0, VAR,NULL, }, // 0x00d5
- {0, 3, NULL, }, // 0x00d6
- {0, VAR,NULL, }, // 0x00d7
- {0, 6, NULL, }, // 0x00d8
- {0, 14, NULL, }, // 0x00d9
- {0, 3, NULL, }, // 0x00da
- {0, VAR,NULL, }, // 0x00db
- {0, 28, NULL, }, // 0x00dc
- {0, 29, NULL, }, // 0x00dd
- {0, VAR,NULL, }, // 0x00de
- {0, VAR,NULL, }, // 0x00df
- {0, 30, NULL, }, // 0x00e0
- {0, 30, NULL, }, // 0x00e1
- {0, 26, NULL, }, // 0x00e2
- {0, 2, NULL, }, // 0x00e3
+ {0, 3, nullptr, }, // 0x00ca
+ {0, 3, nullptr, }, // 0x00cb
+ {0, 6, nullptr, }, // 0x00cc
+ {0, 6, nullptr, }, // 0x00cd
+ {0, 2, nullptr, }, // 0x00ce
+ {0, 27, nullptr, }, // 0x00cf
+ {0, 3, nullptr, }, // 0x00d0
+ {0, 4, nullptr, }, // 0x00d1
+ {0, 4, nullptr, }, // 0x00d2
+ {0, 2, nullptr, }, // 0x00d3
+ {0, VAR,nullptr, }, // 0x00d4
+ {0, VAR,nullptr, }, // 0x00d5
+ {0, 3, nullptr, }, // 0x00d6
+ {0, VAR,nullptr, }, // 0x00d7
+ {0, 6, nullptr, }, // 0x00d8
+ {0, 14, nullptr, }, // 0x00d9
+ {0, 3, nullptr, }, // 0x00da
+ {0, VAR,nullptr, }, // 0x00db
+ {0, 28, nullptr, }, // 0x00dc
+ {0, 29, nullptr, }, // 0x00dd
+ {0, VAR,nullptr, }, // 0x00de
+ {0, VAR,nullptr, }, // 0x00df
+ {0, 30, nullptr, }, // 0x00e0
+ {0, 30, nullptr, }, // 0x00e1
+ {0, 26, nullptr, }, // 0x00e2
+ {0, 2, nullptr, }, // 0x00e3
{2000, 6, clif_parse_TradeRequest, }, // 0x00e4
- {0, 26, NULL, }, // 0x00e5
+ {0, 26, nullptr, }, // 0x00e5
{0, 3, clif_parse_TradeAck, }, // 0x00e6
- {0, 3, NULL, }, // 0x00e7
+ {0, 3, nullptr, }, // 0x00e7
{0, 8, clif_parse_TradeAddItem, }, // 0x00e8
- {0, 19, NULL, }, // 0x00e9
- {0, 5, NULL, }, // 0x00ea
+ {0, 19, nullptr, }, // 0x00e9
+ {0, 5, nullptr, }, // 0x00ea
{0, 2, clif_parse_TradeOk, }, // 0x00eb
- {0, 3, NULL, }, // 0x00ec
+ {0, 3, nullptr, }, // 0x00ec
{0, 2, clif_parse_TradeCansel, }, // 0x00ed
- {0, 2, NULL, }, // 0x00ee
+ {0, 2, nullptr, }, // 0x00ee
{0, 2, clif_parse_TradeCommit, }, // 0x00ef
- {0, 3, NULL, }, // 0x00f0
- {0, 2, NULL, }, // 0x00f1
- {0, 6, NULL, }, // 0x00f2
+ {0, 3, nullptr, }, // 0x00f0
+ {0, 2, nullptr, }, // 0x00f1
+ {0, 6, nullptr, }, // 0x00f2
{-1, 8, clif_parse_MoveToKafra, }, // 0x00f3
- {0, 21, NULL, }, // 0x00f4
+ {0, 21, nullptr, }, // 0x00f4
{-1, 8, clif_parse_MoveFromKafra, }, // 0x00f5
- {0, 8, NULL, }, // 0x00f6
+ {0, 8, nullptr, }, // 0x00f6
{0, 2, clif_parse_CloseKafra, }, // 0x00f7
- {0, 2, NULL, }, // 0x00f8
+ {0, 2, nullptr, }, // 0x00f8
{2000, 26, clif_parse_CreateParty, }, // 0x00f9
- {0, 3, NULL, }, // 0x00fa
- {0, VAR,NULL, }, // 0x00fb
+ {0, 3, nullptr, }, // 0x00fa
+ {0, VAR,nullptr, }, // 0x00fb
{2000, 6, clif_parse_PartyInvite, }, // 0x00fc
- {0, 27, NULL, }, // 0x00fd
- {0, 30, NULL, }, // 0x00fe
+ {0, 27, nullptr, }, // 0x00fd
+ {0, 30, nullptr, }, // 0x00fe
{0, 10, clif_parse_ReplyPartyInvite, }, // 0x00ff
{0, 2, clif_parse_LeaveParty, }, // 0x0100
- {0, 6, NULL, }, // 0x0101
+ {0, 6, nullptr, }, // 0x0101
{0, 6, clif_parse_PartyChangeOption, }, // 0x0102
{0, 30, clif_parse_RemovePartyMember, }, // 0x0103
- {0, 79, NULL, }, // 0x0104
- {0, 31, NULL, }, // 0x0105
- {0, 10, NULL, }, // 0x0106
- {0, 10, NULL, }, // 0x0107
+ {0, 79, nullptr, }, // 0x0104
+ {0, 31, nullptr, }, // 0x0105
+ {0, 10, nullptr, }, // 0x0106
+ {0, 10, nullptr, }, // 0x0107
{300, VAR,clif_parse_PartyMessage, }, // 0x0108
- {0, VAR,NULL, }, // 0x0109
- {0, 4, NULL, }, // 0x010a
- {0, 6, NULL, }, // 0x010b
- {0, 6, NULL, }, // 0x010c
- {0, 2, NULL, }, // 0x010d
- {0, 11, NULL, }, // 0x010e
- {0, VAR,NULL, }, // 0x010f
- {0, 10, NULL, }, // 0x0110
- {0, 39, NULL, }, // 0x0111
+ {0, VAR,nullptr, }, // 0x0109
+ {0, 4, nullptr, }, // 0x010a
+ {0, 6, nullptr, }, // 0x010b
+ {0, 6, nullptr, }, // 0x010c
+ {0, 2, nullptr, }, // 0x010d
+ {0, 11, nullptr, }, // 0x010e
+ {0, VAR,nullptr, }, // 0x010f
+ {0, 10, nullptr, }, // 0x0110
+ {0, 39, nullptr, }, // 0x0111
{-1, 4, clif_parse_SkillUp, }, // 0x0112
- {0, 10, NULL, }, // 0x0113
- {0, 31, NULL, }, // 0x0114
- {0, 35, NULL, }, // 0x0115
- {0, 10, NULL, }, // 0x0116
- {0, 18, NULL, }, // 0x0117
+ {0, 10, nullptr, }, // 0x0113
+ {0, 31, nullptr, }, // 0x0114
+ {0, 35, nullptr, }, // 0x0115
+ {0, 10, nullptr, }, // 0x0116
+ {0, 18, nullptr, }, // 0x0117
{0, 2, clif_parse_StopAttack, }, // 0x0118
- {0, 13, NULL, }, // 0x0119
- {0, 15, NULL, }, // 0x011a
- {0, 20, NULL, }, // 0x011b
- {0, 68, NULL, }, // 0x011c
- {0, 2, NULL, }, // 0x011d
- {0, 3, NULL, }, // 0x011e
- {0, 16, NULL, }, // 0x011f
- {0, 6, NULL, }, // 0x0120
- {0, 14, NULL, }, // 0x0121
- {0, VAR,NULL, }, // 0x0122
- {0, VAR,NULL, }, // 0x0123
- {0, 21, NULL, }, // 0x0124
- {0, 8, NULL, }, // 0x0125
- {0, 8, NULL, }, // 0x0126
- {0, 8, NULL, }, // 0x0127
- {0, 8, NULL, }, // 0x0128
- {0, 8, NULL, }, // 0x0129
- {0, 2, NULL, }, // 0x012a
- {0, 2, NULL, }, // 0x012b
- {0, 3, NULL, }, // 0x012c
- {0, 4, NULL, }, // 0x012d
- {0, 2, NULL, }, // 0x012e
- {0, VAR,NULL, }, // 0x012f
- {0, 6, NULL, }, // 0x0130
- {0, 86, NULL, }, // 0x0131
- {0, 6, NULL, }, // 0x0132
- {0, VAR,NULL, }, // 0x0133
- {0, VAR,NULL, }, // 0x0134
- {0, 7, NULL, }, // 0x0135
- {0, VAR,NULL, }, // 0x0136
- {0, 6, NULL, }, // 0x0137
- {0, 3, NULL, }, // 0x0138
- {0, 16, NULL, }, // 0x0139
- {0, 4, NULL, }, // 0x013a
- {0, 4, NULL, }, // 0x013b
- {0, 4, NULL, }, // 0x013c
- {0, 6, NULL, }, // 0x013d
- {0, 24, NULL, }, // 0x013e
- {0, 26, NULL, }, // 0x013f
- {0, 22, NULL, }, // 0x0140
- {0, 14, NULL, }, // 0x0141
- {0, 6, NULL, }, // 0x0142
+ {0, 13, nullptr, }, // 0x0119
+ {0, 15, nullptr, }, // 0x011a
+ {0, 20, nullptr, }, // 0x011b
+ {0, 68, nullptr, }, // 0x011c
+ {0, 2, nullptr, }, // 0x011d
+ {0, 3, nullptr, }, // 0x011e
+ {0, 16, nullptr, }, // 0x011f
+ {0, 6, nullptr, }, // 0x0120
+ {0, 14, nullptr, }, // 0x0121
+ {0, VAR,nullptr, }, // 0x0122
+ {0, VAR,nullptr, }, // 0x0123
+ {0, 21, nullptr, }, // 0x0124
+ {0, 8, nullptr, }, // 0x0125
+ {0, 8, nullptr, }, // 0x0126
+ {0, 8, nullptr, }, // 0x0127
+ {0, 8, nullptr, }, // 0x0128
+ {0, 8, nullptr, }, // 0x0129
+ {0, 2, nullptr, }, // 0x012a
+ {0, 2, nullptr, }, // 0x012b
+ {0, 3, nullptr, }, // 0x012c
+ {0, 4, nullptr, }, // 0x012d
+ {0, 2, nullptr, }, // 0x012e
+ {0, VAR,nullptr, }, // 0x012f
+ {0, 6, nullptr, }, // 0x0130
+ {0, 86, nullptr, }, // 0x0131
+ {0, 6, nullptr, }, // 0x0132
+ {0, VAR,nullptr, }, // 0x0133
+ {0, VAR,nullptr, }, // 0x0134
+ {0, 7, nullptr, }, // 0x0135
+ {0, VAR,nullptr, }, // 0x0136
+ {0, 6, nullptr, }, // 0x0137
+ {0, 3, nullptr, }, // 0x0138
+ {0, 16, nullptr, }, // 0x0139
+ {0, 4, nullptr, }, // 0x013a
+ {0, 4, nullptr, }, // 0x013b
+ {0, 4, nullptr, }, // 0x013c
+ {0, 6, nullptr, }, // 0x013d
+ {0, 24, nullptr, }, // 0x013e
+ {0, 26, nullptr, }, // 0x013f
+ {0, 22, nullptr, }, // 0x0140
+ {0, 14, nullptr, }, // 0x0141
+ {0, 6, nullptr, }, // 0x0142
{300, 10, clif_parse_NpcAmountInput, }, // 0x0143
- {0, 23, NULL, }, // 0x0144
- {0, 19, NULL, }, // 0x0145
+ {0, 23, nullptr, }, // 0x0144
+ {0, 19, nullptr, }, // 0x0145
{300, 6, clif_parse_NpcCloseClicked, }, // 0x0146
- {0, 39, NULL, }, // 0x0147
- {0, 8, NULL, }, // 0x0148
- {0, 9, NULL, }, // 0x0149
- {0, 6, NULL, }, // 0x014a
- {0, 27, NULL, }, // 0x014b
- {0, VAR,NULL, }, // 0x014c
- {0, 2, NULL, }, // 0x014d
- {0, 6, NULL, }, // 0x014e
- {0, 6, NULL, }, // 0x014f
- {0, 110,NULL, }, // 0x0150
- {0, 6, NULL, }, // 0x0151
- {0, VAR,NULL, }, // 0x0152
- {0, VAR,NULL, }, // 0x0153
- {0, VAR,NULL, }, // 0x0154
- {0, VAR,NULL, }, // 0x0155
- {0, VAR,NULL, }, // 0x0156
- {0, 6, NULL, }, // 0x0157
- {0, VAR,NULL, }, // 0x0158
- {0, 54, NULL, }, // 0x0159
- {0, 66, NULL, }, // 0x015a
- {0, 54, NULL, }, // 0x015b
- {0, 90, NULL, }, // 0x015c
- {0, 42, NULL, }, // 0x015d
- {0, 6, NULL, }, // 0x015e
- {0, 42, NULL, }, // 0x015f
- {0, VAR,NULL, }, // 0x0160
- {0, VAR,NULL, }, // 0x0161
- {0, VAR,NULL, }, // 0x0162
- {0, VAR,NULL, }, // 0x0163
- {0, VAR,NULL, }, // 0x0164
- {0, 30, NULL, }, // 0x0165
- {0, VAR,NULL, }, // 0x0166
- {0, 3, NULL, }, // 0x0167
- {0, 14, NULL, }, // 0x0168
- {0, 3, NULL, }, // 0x0169
- {0, 30, NULL, }, // 0x016a
- {0, 10, NULL, }, // 0x016b
- {0, 43, NULL, }, // 0x016c
- {0, 14, NULL, }, // 0x016d
- {0, 186,NULL, }, // 0x016e
- {0, 182,NULL, }, // 0x016f
- {0, 14, NULL, }, // 0x0170
- {0, 30, NULL, }, // 0x0171
- {0, 10, NULL, }, // 0x0172
- {0, 3, NULL, }, // 0x0173
- {0, VAR,NULL, }, // 0x0174
- {0, 6, NULL, }, // 0x0175
- {0, 106,NULL, }, // 0x0176
- {0, VAR,NULL, }, // 0x0177
- {0, 4, NULL, }, // 0x0178
- {0, 5, NULL, }, // 0x0179
- {0, 4, NULL, }, // 0x017a
- {0, VAR,NULL, }, // 0x017b
- {0, 6, NULL, }, // 0x017c
- {0, 7, NULL, }, // 0x017d
- {0, VAR,NULL, }, // 0x017e
- {0, VAR,NULL, }, // 0x017f
- {0, 6, NULL, }, // 0x0180
- {0, 3, NULL, }, // 0x0181
- {0, 106,NULL, }, // 0x0182
- {0, 10, NULL, }, // 0x0183
- {0, 10, NULL, }, // 0x0184
- {0, 34, NULL, }, // 0x0185
- {0, 0, NULL, }, // 0x0186
- {0, 6, NULL, }, // 0x0187
- {0, 8, NULL, }, // 0x0188
- {0, 4, NULL, }, // 0x0189
+ {0, 39, nullptr, }, // 0x0147
+ {0, 8, nullptr, }, // 0x0148
+ {0, 9, nullptr, }, // 0x0149
+ {0, 6, nullptr, }, // 0x014a
+ {0, 27, nullptr, }, // 0x014b
+ {0, VAR,nullptr, }, // 0x014c
+ {0, 2, nullptr, }, // 0x014d
+ {0, 6, nullptr, }, // 0x014e
+ {0, 6, nullptr, }, // 0x014f
+ {0, 110,nullptr, }, // 0x0150
+ {0, 6, nullptr, }, // 0x0151
+ {0, VAR,nullptr, }, // 0x0152
+ {0, VAR,nullptr, }, // 0x0153
+ {0, VAR,nullptr, }, // 0x0154
+ {0, VAR,nullptr, }, // 0x0155
+ {0, VAR,nullptr, }, // 0x0156
+ {0, 6, nullptr, }, // 0x0157
+ {0, VAR,nullptr, }, // 0x0158
+ {0, 54, nullptr, }, // 0x0159
+ {0, 66, nullptr, }, // 0x015a
+ {0, 54, nullptr, }, // 0x015b
+ {0, 90, nullptr, }, // 0x015c
+ {0, 42, nullptr, }, // 0x015d
+ {0, 6, nullptr, }, // 0x015e
+ {0, 42, nullptr, }, // 0x015f
+ {0, VAR,nullptr, }, // 0x0160
+ {0, VAR,nullptr, }, // 0x0161
+ {0, VAR,nullptr, }, // 0x0162
+ {0, VAR,nullptr, }, // 0x0163
+ {0, VAR,nullptr, }, // 0x0164
+ {0, 30, nullptr, }, // 0x0165
+ {0, VAR,nullptr, }, // 0x0166
+ {0, 3, nullptr, }, // 0x0167
+ {0, 14, nullptr, }, // 0x0168
+ {0, 3, nullptr, }, // 0x0169
+ {0, 30, nullptr, }, // 0x016a
+ {0, 10, nullptr, }, // 0x016b
+ {0, 43, nullptr, }, // 0x016c
+ {0, 14, nullptr, }, // 0x016d
+ {0, 186,nullptr, }, // 0x016e
+ {0, 182,nullptr, }, // 0x016f
+ {0, 14, nullptr, }, // 0x0170
+ {0, 30, nullptr, }, // 0x0171
+ {0, 10, nullptr, }, // 0x0172
+ {0, 3, nullptr, }, // 0x0173
+ {0, VAR,nullptr, }, // 0x0174
+ {0, 6, nullptr, }, // 0x0175
+ {0, 106,nullptr, }, // 0x0176
+ {0, VAR,nullptr, }, // 0x0177
+ {0, 4, nullptr, }, // 0x0178
+ {0, 5, nullptr, }, // 0x0179
+ {0, 4, nullptr, }, // 0x017a
+ {0, VAR,nullptr, }, // 0x017b
+ {0, 6, nullptr, }, // 0x017c
+ {0, 7, nullptr, }, // 0x017d
+ {0, VAR,nullptr, }, // 0x017e
+ {0, VAR,nullptr, }, // 0x017f
+ {0, 6, nullptr, }, // 0x0180
+ {0, 3, nullptr, }, // 0x0181
+ {0, 106,nullptr, }, // 0x0182
+ {0, 10, nullptr, }, // 0x0183
+ {0, 10, nullptr, }, // 0x0184
+ {0, 34, nullptr, }, // 0x0185
+ {0, 0, nullptr, }, // 0x0186
+ {0, 6, nullptr, }, // 0x0187
+ {0, 8, nullptr, }, // 0x0188
+ {0, 4, nullptr, }, // 0x0189
{0, 4, clif_parse_QuitGame, }, // 0x018a
- {0, 4, NULL, }, // 0x018b
- {0, 29, NULL, }, // 0x018c
- {0, VAR,NULL, }, // 0x018d
- {0, 10, NULL, }, // 0x018e
- {0, 6, NULL, }, // 0x018f
- {0, 90, NULL, }, // 0x0190
- {0, 86, NULL, }, // 0x0191
- {0, 24, NULL, }, // 0x0192
- {0, 6, NULL, }, // 0x0193
- {0, 30, NULL, }, // 0x0194
- {0, 102,NULL, }, // 0x0195
- {0, 9, NULL, }, // 0x0196
- {0, 4, NULL, }, // 0x0197
- {0, 8, NULL, }, // 0x0198
- {0, 4, NULL, }, // 0x0199
- {0, 14, NULL, }, // 0x019a
- {0, 10, NULL, }, // 0x019b
- {0, VAR,NULL, }, // 0x019c
- {300, 6, NULL, }, // 0x019d
- {0, 2, NULL, }, // 0x019e
- {0, 6, NULL, }, // 0x019f
- {0, 3, NULL, }, // 0x01a0
- {0, 3, NULL, }, // 0x01a1
- {0, 35, NULL, }, // 0x01a2
- {0, 5, NULL, }, // 0x01a3
- {0, 11, NULL, }, // 0x01a4
- {0, 26, NULL, }, // 0x01a5
- {0, VAR,NULL, }, // 0x01a6
- {0, 4, NULL, }, // 0x01a7
- {0, 4, NULL, }, // 0x01a8
- {0, 6, NULL, }, // 0x01a9
- {0, 10, NULL, }, // 0x01aa
- {0, 12, NULL, }, // 0x01ab
- {0, 6, NULL, }, // 0x01ac
- {0, VAR,NULL, }, // 0x01ad
- {0, 4, NULL, }, // 0x01ae
- {0, 4, NULL, }, // 0x01af
- {0, 11, NULL, }, // 0x01b0
- {0, 7, NULL, }, // 0x01b1
- {0, VAR,NULL, }, // 0x01b2
- {0, 67, NULL, }, // 0x01b3
- {0, 12, NULL, }, // 0x01b4
- {0, 18, NULL, }, // 0x01b5
- {0, 114,NULL, }, // 0x01b6
- {0, 6, NULL, }, // 0x01b7
- {0, 3, NULL, }, // 0x01b8
- {0, 6, NULL, }, // 0x01b9
- {0, 26, NULL, }, // 0x01ba
- {0, 26, NULL, }, // 0x01bb
- {0, 26, NULL, }, // 0x01bc
- {0, 26, NULL, }, // 0x01bd
- {0, 2, NULL, }, // 0x01be
- {0, 3, NULL, }, // 0x01bf
- {0, 2, NULL, }, // 0x01c0
- {0, 14, NULL, }, // 0x01c1
- {0, 10, NULL, }, // 0x01c2
- {0, VAR,NULL, }, // 0x01c3
- {0, 22, NULL, }, // 0x01c4
- {0, 22, NULL, }, // 0x01c5
- {0, 4, NULL, }, // 0x01c6
- {0, 2, NULL, }, // 0x01c7
- {0, 13, NULL, }, // 0x01c8
- {0, 97, NULL, }, // 0x01c9
- {0, 0, NULL, }, // 0x01ca
- {0, 9, NULL, }, // 0x01cb
- {0, 9, NULL, }, // 0x01cc
- {0, 30, NULL, }, // 0x01cd
- {0, 6, NULL, }, // 0x01ce
- {0, 28, NULL, }, // 0x01cf
- {0, 8, NULL, }, // 0x01d0
- {0, 14, NULL, }, // 0x01d1
- {0, 10, NULL, }, // 0x01d2
- {0, 35, NULL, }, // 0x01d3
- {0, 6, NULL, }, // 0x01d4
+ {0, 4, nullptr, }, // 0x018b
+ {0, 29, nullptr, }, // 0x018c
+ {0, VAR,nullptr, }, // 0x018d
+ {0, 10, nullptr, }, // 0x018e
+ {0, 6, nullptr, }, // 0x018f
+ {0, 90, nullptr, }, // 0x0190
+ {0, 86, nullptr, }, // 0x0191
+ {0, 24, nullptr, }, // 0x0192
+ {0, 6, nullptr, }, // 0x0193
+ {0, 30, nullptr, }, // 0x0194
+ {0, 102,nullptr, }, // 0x0195
+ {0, 9, nullptr, }, // 0x0196
+ {0, 4, nullptr, }, // 0x0197
+ {0, 8, nullptr, }, // 0x0198
+ {0, 4, nullptr, }, // 0x0199
+ {0, 14, nullptr, }, // 0x019a
+ {0, 10, nullptr, }, // 0x019b
+ {0, VAR,nullptr, }, // 0x019c
+ {300, 6, nullptr, }, // 0x019d
+ {0, 2, nullptr, }, // 0x019e
+ {0, 6, nullptr, }, // 0x019f
+ {0, 3, nullptr, }, // 0x01a0
+ {0, 3, nullptr, }, // 0x01a1
+ {0, 35, nullptr, }, // 0x01a2
+ {0, 5, nullptr, }, // 0x01a3
+ {0, 11, nullptr, }, // 0x01a4
+ {0, 26, nullptr, }, // 0x01a5
+ {0, VAR,nullptr, }, // 0x01a6
+ {0, 4, nullptr, }, // 0x01a7
+ {0, 4, nullptr, }, // 0x01a8
+ {0, 6, nullptr, }, // 0x01a9
+ {0, 10, nullptr, }, // 0x01aa
+ {0, 12, nullptr, }, // 0x01ab
+ {0, 6, nullptr, }, // 0x01ac
+ {0, VAR,nullptr, }, // 0x01ad
+ {0, 4, nullptr, }, // 0x01ae
+ {0, 4, nullptr, }, // 0x01af
+ {0, 11, nullptr, }, // 0x01b0
+ {0, 7, nullptr, }, // 0x01b1
+ {0, VAR,nullptr, }, // 0x01b2
+ {0, 67, nullptr, }, // 0x01b3
+ {0, 12, nullptr, }, // 0x01b4
+ {0, 18, nullptr, }, // 0x01b5
+ {0, 114,nullptr, }, // 0x01b6
+ {0, 6, nullptr, }, // 0x01b7
+ {0, 3, nullptr, }, // 0x01b8
+ {0, 6, nullptr, }, // 0x01b9
+ {0, 26, nullptr, }, // 0x01ba
+ {0, 26, nullptr, }, // 0x01bb
+ {0, 26, nullptr, }, // 0x01bc
+ {0, 26, nullptr, }, // 0x01bd
+ {0, 2, nullptr, }, // 0x01be
+ {0, 3, nullptr, }, // 0x01bf
+ {0, 2, nullptr, }, // 0x01c0
+ {0, 14, nullptr, }, // 0x01c1
+ {0, 10, nullptr, }, // 0x01c2
+ {0, VAR,nullptr, }, // 0x01c3
+ {0, 22, nullptr, }, // 0x01c4
+ {0, 22, nullptr, }, // 0x01c5
+ {0, 4, nullptr, }, // 0x01c6
+ {0, 2, nullptr, }, // 0x01c7
+ {0, 13, nullptr, }, // 0x01c8
+ {0, 97, nullptr, }, // 0x01c9
+ {0, 0, nullptr, }, // 0x01ca
+ {0, 9, nullptr, }, // 0x01cb
+ {0, 9, nullptr, }, // 0x01cc
+ {0, 30, nullptr, }, // 0x01cd
+ {0, 6, nullptr, }, // 0x01ce
+ {0, 28, nullptr, }, // 0x01cf
+ {0, 8, nullptr, }, // 0x01d0
+ {0, 14, nullptr, }, // 0x01d1
+ {0, 10, nullptr, }, // 0x01d2
+ {0, 35, nullptr, }, // 0x01d3
+ {0, 6, nullptr, }, // 0x01d4
{300, VAR,clif_parse_NpcStringInput, }, // 0x01d5 - set to -1
- {0, 4, NULL, }, // 0x01d6
- {0, 11, NULL, }, // 0x01d7
- {0, 54, NULL, }, // 0x01d8
- {0, 53, NULL, }, // 0x01d9
- {0, 60, NULL, }, // 0x01da
- {0, 2, NULL, }, // 0x01db
- {0, VAR,NULL, }, // 0x01dc
- {0, 47, NULL, }, // 0x01dd
- {0, 33, NULL, }, // 0x01de
- {0, 6, NULL, }, // 0x01df
- {0, 30, NULL, }, // 0x01e0
- {0, 8, NULL, }, // 0x01e1
- {0, 34, NULL, }, // 0x01e2
- {0, 14, NULL, }, // 0x01e3
- {0, 2, NULL, }, // 0x01e4
- {0, 6, NULL, }, // 0x01e5
- {0, 26, NULL, }, // 0x01e6
- {0, 2, NULL, }, // 0x01e7
- {0, 28, NULL, }, // 0x01e8
- {0, 81, NULL, }, // 0x01e9
- {0, 6, NULL, }, // 0x01ea
- {0, 10, NULL, }, // 0x01eb
- {0, 26, NULL, }, // 0x01ec
- {0, 2, NULL, }, // 0x01ed
- {0, VAR,NULL, }, // 0x01ee
- {0, VAR,NULL, }, // 0x01ef
- {0, VAR,NULL, }, // 0x01f0
- {0, VAR,NULL, }, // 0x01f1
- {0, 20, NULL, }, // 0x01f2
- {0, 10, NULL, }, // 0x01f3
- {0, 32, NULL, }, // 0x01f4
- {0, 9, NULL, }, // 0x01f5
- {0, 34, NULL, }, // 0x01f6
- {0, 14, NULL, }, // 0x01f7
- {0, 2, NULL, }, // 0x01f8
- {0, 6, NULL, }, // 0x01f9
- {0, 48, NULL, }, // 0x01fa
- {0, 56, NULL, }, // 0x01fb
- {0, VAR,NULL, }, // 0x01fc
- {0, 4, NULL, }, // 0x01fd
- {0, 5, NULL, }, // 0x01fe
- {0, 10, NULL, }, // 0x01ff
- {0, 26, NULL, }, // 0x0200
- {0, VAR,NULL, }, // 0x0201
- {0, 26, NULL, }, // 0x0202
- {0, 10, NULL, }, // 0x0203
- {0, 18, NULL, }, // 0x0204
- {0, 26, NULL, }, // 0x0205
- {0, 11, NULL, }, // 0x0206
- {0, 34, NULL, }, // 0x0207
- {0, 14, NULL, }, // 0x0208
- {0, 36, NULL, }, // 0x0209
- {0, 10, NULL, }, // 0x020a
- {0, 19, NULL, }, // 0x020b
- {0, 10, NULL, }, // 0x020c
- {0, VAR,NULL, }, // 0x020d
- {0, 24, NULL, }, // 0x020e
- {0, 0, NULL, }, // 0x020f
- {0, 0, NULL, }, // 0x0210
- {0, 0, NULL, }, // 0x0211
- {0, 0, NULL, }, // 0x0212
- {0, 0, NULL, }, // 0x0213
- {0, 0, NULL, }, // 0x0214
- {0, 0, NULL, }, // 0x0215
- {0, 0, NULL, }, // 0x0216
- {0, 0, NULL, }, // 0x0217
- {0, 0, NULL, }, // 0x0218
- {0, 0, NULL, }, // 0x0219
- {0, 0, NULL, }, // 0x021a
- {0, 0, NULL, }, // 0x021b
- {0, 0, NULL, }, // 0x021c
- {0, 0, NULL, }, // 0x021d
- {0, 0, NULL, }, // 0x021e
- {0, 0, NULL, }, // 0x021f
+ {0, 4, nullptr, }, // 0x01d6
+ {0, 11, nullptr, }, // 0x01d7
+ {0, 54, nullptr, }, // 0x01d8
+ {0, 53, nullptr, }, // 0x01d9
+ {0, 60, nullptr, }, // 0x01da
+ {0, 2, nullptr, }, // 0x01db
+ {0, VAR,nullptr, }, // 0x01dc
+ {0, 47, nullptr, }, // 0x01dd
+ {0, 33, nullptr, }, // 0x01de
+ {0, 6, nullptr, }, // 0x01df
+ {0, 30, nullptr, }, // 0x01e0
+ {0, 8, nullptr, }, // 0x01e1
+ {0, 34, nullptr, }, // 0x01e2
+ {0, 14, nullptr, }, // 0x01e3
+ {0, 2, nullptr, }, // 0x01e4
+ {0, 6, nullptr, }, // 0x01e5
+ {0, 26, nullptr, }, // 0x01e6
+ {0, 2, nullptr, }, // 0x01e7
+ {0, 28, nullptr, }, // 0x01e8
+ {0, 81, nullptr, }, // 0x01e9
+ {0, 6, nullptr, }, // 0x01ea
+ {0, 10, nullptr, }, // 0x01eb
+ {0, 26, nullptr, }, // 0x01ec
+ {0, 2, nullptr, }, // 0x01ed
+ {0, VAR,nullptr, }, // 0x01ee
+ {0, VAR,nullptr, }, // 0x01ef
+ {0, VAR,nullptr, }, // 0x01f0
+ {0, VAR,nullptr, }, // 0x01f1
+ {0, 20, nullptr, }, // 0x01f2
+ {0, 10, nullptr, }, // 0x01f3
+ {0, 32, nullptr, }, // 0x01f4
+ {0, 9, nullptr, }, // 0x01f5
+ {0, 34, nullptr, }, // 0x01f6
+ {0, 14, nullptr, }, // 0x01f7
+ {0, 2, nullptr, }, // 0x01f8
+ {0, 6, nullptr, }, // 0x01f9
+ {0, 48, nullptr, }, // 0x01fa
+ {0, 56, nullptr, }, // 0x01fb
+ {0, VAR,nullptr, }, // 0x01fc
+ {0, 4, nullptr, }, // 0x01fd
+ {0, 5, nullptr, }, // 0x01fe
+ {0, 10, nullptr, }, // 0x01ff
+ {0, 26, nullptr, }, // 0x0200
+ {0, VAR,nullptr, }, // 0x0201
+ {0, 26, nullptr, }, // 0x0202
+ {0, 10, nullptr, }, // 0x0203
+ {0, 18, nullptr, }, // 0x0204
+ {0, 26, nullptr, }, // 0x0205
+ {0, 11, nullptr, }, // 0x0206
+ {0, 34, nullptr, }, // 0x0207
+ {0, 14, nullptr, }, // 0x0208
+ {0, 36, nullptr, }, // 0x0209
+ {0, 10, nullptr, }, // 0x020a
+ {0, 19, nullptr, }, // 0x020b
+ {0, 10, nullptr, }, // 0x020c
+ {0, VAR,nullptr, }, // 0x020d
+ {0, 24, nullptr, }, // 0x020e
+ {0, 0, nullptr, }, // 0x020f
+ {0, 0, nullptr, }, // 0x0210
+ {0, 0, nullptr, }, // 0x0211
+ {0, 0, nullptr, }, // 0x0212
+ {0, 0, nullptr, }, // 0x0213
+ {0, 0, nullptr, }, // 0x0214
+ {0, 0, nullptr, }, // 0x0215
+ {0, 0, nullptr, }, // 0x0216
+ {0, 0, nullptr, }, // 0x0217
+ {0, 0, nullptr, }, // 0x0218
+ {0, 0, nullptr, }, // 0x0219
+ {0, 0, nullptr, }, // 0x021a
+ {0, 0, nullptr, }, // 0x021b
+ {0, 0, nullptr, }, // 0x021c
+ {0, 0, nullptr, }, // 0x021d
+ {0, 0, nullptr, }, // 0x021e
+ {0, 0, nullptr, }, // 0x021f
};
// Checks for packet flooding
static
-int clif_check_packet_flood(Session *s, int cmd)
+uint16_t clif_check_packet_flood(Session *s, int cmd)
{
+ uint16_t len = clif_parse_func_table[cmd].len_unused;
+ if (len == VAR)
+ {
+ Little16 netlen;
+ if (!packet_fetch(s, 2, reinterpret_cast<Byte *>(&netlen), 2))
+ {
+ return 0;
+ }
+ if (!network_to_native(&len, netlen))
+ {
+ s->set_eof();
+ return 0;
+ }
+ }
+ if (packet_avail(s) < len)
+ return 0;
+
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get()));
tick_t tick = gettick();
@@ -5182,30 +5402,28 @@ int clif_check_packet_flood(Session *s, int cmd)
// Default rate is 100ms
interval_t rate = clif_parse_func_table[cmd].rate;
if (rate == interval_t::zero())
- rate = std::chrono::milliseconds(100);
+ rate = 100_ms;
// ActionRequest - attacks are allowed a faster rate than sit/stand
if (cmd == 0x89)
{
- int action_type = RFIFOB(s, 6);
- if (action_type == 0x00 || action_type == 0x07)
- rate = std::chrono::milliseconds(20);
+ DamageType damage_type;
+ Byte action_type;
+ if (!packet_fetch(s, 6, &action_type, 1))
+ return 0;
+ if (!network_to_native(&damage_type, action_type))
+ {
+ s->set_eof();
+ return 0;
+ }
+ if (damage_type == DamageType::NORMAL || damage_type == DamageType::CONTINUOUS)
+ rate = 20_ms;
else
- rate = std::chrono::seconds(1);
+ rate = 1_s;
}
-// Restore this code when mana1.0 is released
-#if 0
- // ChangeDir - only apply limit if not walking
- if (cmd == 0x9b)
- {
- // .29 clients spam this packet when walking into a blocked tile
- if (RFIFOB(fd, 4) == sd->dir || sd->walktimer != -1)
- return 0;
-
- rate = 500;
- }
-#endif
+ // Restore this code when mana1.0 is released
+ // nope, nuh-uh
// They are flooding
if (tick < sd->flood_rates[cmd] + rate)
@@ -5223,16 +5441,16 @@ int clif_check_packet_flood(Session *s, int cmd)
if (sd->packet_flood_in >= battle_config.packet_spam_flood)
{
- PRINTF("packet flood detected from %s [0x%x]\n", sd->status_key.name, cmd);
+ PRINTF("packet flood detected from %s [0x%x]\n"_fmt, sd->status_key.name, cmd);
if (battle_config.packet_spam_kick)
{
s->set_eof();
- return 1;
+ return len;
}
sd->packet_flood_in = 0;
}
- return 1;
+ return len;
}
sd->flood_rates[cmd] = tick;
@@ -5240,9 +5458,9 @@ int clif_check_packet_flood(Session *s, int cmd)
}
inline
-void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, const char *msg)
+void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, ZString msg)
{
- PRINTF("clif_validate_chat(): %s (ID %d) sent a malformed message: %s.\n",
+ PRINTF("clif_validate_chat(): %s (ID %d) sent a malformed message: %s.\n"_fmt,
sd->status_key.name, sd->status_key.account_id, msg);
}
/**
@@ -5256,7 +5474,7 @@ void WARN_MALFORMED_MSG(dumb_ptr<map_session_data> sd, const char *msg)
* @return a dynamically allocated copy of the message, or empty string upon failure
*/
static
-AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type)
+AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type, XString buf)
{
nullpo_retr(AString(), sd);
/*
@@ -5267,54 +5485,8 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type)
return AString();
Session *s = sd->sess;
- size_t msg_len = RFIFOW(s, 2) - 4;
size_t name_len = sd->status_key.name.to__actual().size();
- /*
- * At least one character is required in all instances.
- * Notes for length checks:
- *
- * For all types, header (2) + length (2) is considered empty.
- * For type 1, the message must be longer than the maximum name length (24)
- * to be valid.
- * For type 2, the message must be longer than the sender's name length
- * plus the length of the separator (" : ").
- */
- size_t min_len =
- (type == ChatType::Whisper) ? 24
- : (type == ChatType::Global) ? name_len + 3
- : 0;
-
- /* The player just sent the header (2) and length (2) words. */
- if (!msg_len)
- {
- WARN_MALFORMED_MSG(sd, "no message sent");
- return AString();
- }
-
- /* The client sent (or claims to have sent) an empty message. */
- if (msg_len == min_len)
- {
- WARN_MALFORMED_MSG(sd, "empty message");
- return AString();
- }
-
- /* The protocol specifies that the target must be 24 bytes long. */
- if (type == ChatType::Whisper && msg_len < min_len)
- {
- /* Disallow malformed messages. */
- clif_setwaitclose(s);
- WARN_MALFORMED_MSG(sd, "illegal target name");
- return AString();
- }
-
- size_t pstart = 4;
- size_t buf_len = msg_len;
- if (type == ChatType::Whisper)
- {
- pstart += 24;
- buf_len -= 24;
- }
- AString pbuf = RFIFO_STRING(s, pstart, buf_len);
+ XString pbuf = buf;
/*
* The client attempted to exceed the maximum message length.
@@ -5323,20 +5495,21 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type)
* is truncated. But the previous behavior was to drop the message, so
* we'll do that, too.
*/
- if (buf_len >= battle_config.chat_maxline)
+ // TODO this cuts global chat short by (name_length + 3)
+ if (buf.size() >= battle_config.chat_maxline)
{
- WARN_MALFORMED_MSG(sd, "exceeded maximum message length");
+ WARN_MALFORMED_MSG(sd, "exceeded maximum message length"_s);
return AString();
}
if (type == ChatType::Global)
{
XString p = pbuf;
- if (!(p.startswith(sd->status_key.name.to__actual()) && p.xslice_t(name_len).startswith(" : ")))
+ if (!(p.startswith(sd->status_key.name.to__actual()) && p.xslice_t(name_len).startswith(" : "_s)))
{
/* Disallow malformed/spoofed messages. */
clif_setwaitclose(s);
- WARN_MALFORMED_MSG(sd, "spoofed name/invalid format");
+ WARN_MALFORMED_MSG(sd, "spoofed name/invalid format"_s);
return AString();
}
/* Step beyond the separator. */
@@ -5354,19 +5527,39 @@ AString clif_validate_chat(dumb_ptr<map_session_data> sd, ChatType type)
static
void clif_parse(Session *s)
{
- int packet_len = 0, cmd = 0;
+ // old code:
+ // no while loop (can hang if more than one packet)
+ // handles 0x7530 and 0x7532 specially, also 0x0072
+ // checks packet length table
+ // checks rate limiter
+ // dispatches to actual function, unchecked
+ // interstitial code:
+ // introduces while loop
+ // checks rate limiter
+ // dispatches to actual function
+ // if incomplete, unchecks rate limiter
+ // if error, close socket
+ // future code:
+ // hoists while loop
+ // treats all packets as variable-length, except a hard-coded list
+ // reads packet of that length unconditionally into a buffer
+ // does rate-limit check (hoisted?)
+ // dispatches to actual function
+ // if error, close socket
+
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(static_cast<map_session_data *>(s->session_data.get()));
if (!sd || (sd && !sd->state.auth))
{
- if (RFIFOREST(s) < 2)
- { // too small a packet disconnect
- s->set_eof();
- }
- if (RFIFOW(s, 0) != 0x72 && RFIFOW(s, 0) != 0x7530)
+ uint16_t packet_id;
+ if (!packet_peek_id(s, &packet_id))
+ return;
+
+ if (packet_id != 0x0072 && packet_id != 0x7530)
{
// first packet must be auth or finger
s->set_eof();
+ return;
}
}
@@ -5375,100 +5568,89 @@ void clif_parse(Session *s)
s->set_eof();
return;
}
-
- if (RFIFOREST(s) < 2)
- return; // Too small (no packet number)
-
- cmd = RFIFOW(s, 0);
-
- // 管理用パケット処理
- if (cmd >= 30000)
+ if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1)
{
- switch (cmd)
- {
- case 0x7530: // Athena情報所得
- WFIFOW(s, 0) = 0x7531;
- WFIFO_STRUCT(s, 2, CURRENT_MAP_SERVER_VERSION);
- WFIFOSET(s, 10);
- RFIFOSKIP(s, 2);
- break;
- case 0x7532: // 接続の切断
- s->set_eof();
- break;
- }
+ packet_discard(s, packet_avail(s));
return;
}
- else if (cmd >= 0x200)
- return;
- // パケット長を計算
- packet_len = clif_parse_func_table[cmd].len;
- if (packet_len == VAR)
+ uint16_t packet_id;
+ RecvResult rv = RecvResult::Complete;
+ while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id))
{
- if (RFIFOREST(s) < 4)
+ switch (packet_id)
{
- return; // Runt packet (variable length without a length sent)
+ case 0x7530:
+ {
+ Packet_Fixed<0x7530> fixed;
+ rv = recv_fpacket<0x7530, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ Packet_Fixed<0x7531> fixed_31;
+ fixed_31.version = CURRENT_MAP_SERVER_VERSION;
+ send_fpacket<0x7531, 10>(s, fixed_31);
+ break;
+ }
+ case 0x7532:
+ {
+ Packet_Fixed<0x7532> fixed;
+ rv = recv_fpacket<0x7532, 2>(s, fixed);
+ if (rv != RecvResult::Complete)
+ break;
+
+ s->set_eof();
+ break;
+ }
}
- packet_len = RFIFOW(s, 2);
- if (packet_len < 4 || packet_len > 32768)
+ if (packet_id < 0x0220)
{
- s->set_eof();
- return; // Runt packet (variable out of bounds)
+ if (uint16_t len = clif_check_packet_flood(s, packet_id))
+ {
+ // Packet flood: skip packet
+ packet_discard(s, len);
+ rv = RecvResult::Complete;
+ }
+ else
+ {
+ clif_func func = clif_parse_func_table[packet_id].func;
+ if (!func)
+ goto unknown_packet;
+ rv = func(s, sd);
+ }
}
+ else
+ goto unknown_packet;
}
- if (RFIFOREST(s) < packet_len)
- {
- return; // Runt packet (sent legnth is too small)
- }
-
- if (sd && sd->state.auth == 1 && sd->state.waitingdisconnect == 1)
- { // 切断待ちの場合パケットを処理しない
-
- }
- else if (clif_parse_func_table[cmd].func)
- {
- if (clif_check_packet_flood(s, cmd))
- {
- // Flood triggered. Skip packet.
- RFIFOSKIP(sd->sess, packet_len);
- return;
- }
+ if (rv == RecvResult::Error)
+ s->set_eof();
+ return;
- clif_parse_func_table[cmd].func(s, sd);
- }
- else
+unknown_packet:
{
- // 不明なパケット
if (battle_config.error_log)
{
if (s)
- PRINTF("\nclif_parse: session #%d, packet 0x%x, lenght %d\n",
- s, cmd, packet_len);
-#ifdef DUMP_UNKNOWN_PACKET
+ PRINTF("\nclif_parse: session #%d, packet 0x%x, lenght %zu\n"_fmt,
+ s, packet_id, packet_avail(s));
{
- int i;
- ZString packet_txt = "save/packet.txt";
- PRINTF("---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
- for (i = 0; i < packet_len; i++)
- {
- if ((i & 15) == 0)
- PRINTF("\n%04X ", i);
- PRINTF("%02X ", RFIFOB(s, i));
- }
+ ZString packet_txt = "save/packet.txt"_s;
if (sd && sd->state.auth)
{
- PRINTF("\nAccount ID %d, character ID %d, player name %s.\n",
+ PRINTF("Unknown packet: Account ID %d, character ID %d, player name %s.\n"_fmt,
sd->status_key.account_id, sd->status_key.char_id,
sd->status_key.name);
}
else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified)
- PRINTF("\nAccount ID %d.\n", sd->bl_id);
+ PRINTF("Unkonwn packet (unauthenticated): Account ID %d.\n"_fmt, sd->bl_id);
+ else
+ PRINTF("Unknown packet (unknown)\n"_fmt);
io::AppendFile fp(packet_txt);
if (!fp.is_open())
{
- PRINTF("clif.c: cant write [%s] !!! data is lost !!!\n",
+ PRINTF("clif.c: cant write [%s] !!! data is lost !!!\n"_fmt,
packet_txt);
return;
}
@@ -5479,34 +5661,29 @@ void clif_parse(Session *s)
if (sd && sd->state.auth)
{
FPRINTF(fp,
- "%s\nPlayer with account ID %d (character ID %d, player name %s) sent wrong packet:\n",
+ "%s\nPlayer with account ID %d (character ID %d, player name %s) sent wrong packet:\n"_fmt,
now,
sd->status_key.account_id,
sd->status_key.char_id, sd->status_key.name);
}
else if (sd) // not authentified! (refused by char-server or disconnect before to be authentified)
FPRINTF(fp,
- "%s\nPlayer with account ID %d sent wrong packet:\n",
+ "%s\nUnauthenticated player with account ID %d sent wrong packet:\n"_fmt,
now, sd->bl_id);
+ else
+ FPRINTF(fp,
+ "%s\nUnknown connection sent wrong packet:\n"_fmt,
+ now);
- FPRINTF(fp,
- "\t---- 00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F");
- for (i = 0; i < packet_len; i++)
- {
- if ((i & 15) == 0)
- FPRINTF(fp, "\n\t%04X ", i);
- FPRINTF(fp, "%02X ", RFIFOB(s, i));
- }
- FPRINTF(fp, "\n\n");
+ packet_dump(fp, s);
}
}
-#endif
}
}
- RFIFOSKIP(s, packet_len);
}
void do_init_clif(void)
{
- make_listen_port(map_port, SessionParsers{func_parse: clif_parse, func_delete: clif_delete});
+ make_listen_port(map_port, SessionParsers{.func_parse= clif_parse, .func_delete= clif_delete});
}
+} // namespace tmwa
diff --git a/src/map/clif.hpp b/src/map/clif.hpp
index 1fdd67c..adb4889 100644
--- a/src/map/clif.hpp
+++ b/src/map/clif.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_CLIF_HPP
-#define TMWA_MAP_CLIF_HPP
+#pragma once
// clif.hpp - Network interface to the client.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,22 +20,29 @@
// 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"
+#include "clif.t.hpp"
-# include <functional>
+#include <functional>
-# include "../strings/fwd.hpp"
+#include "../strings/fwd.hpp"
-# include "../mmo/ip.hpp"
-# include "../mmo/timer.t.hpp"
+#include "../generic/fwd.hpp"
-# include "battle.t.hpp"
-# include "map.hpp"
-# include "pc.t.hpp"
-# include "skill.t.hpp"
+#include "../net/timer.t.hpp"
+#include "../mmo/fwd.hpp"
+#include "../mmo/mmo.hpp"
+
+#include "battle.t.hpp"
+#include "map.t.hpp"
+#include "pc.t.hpp"
+#include "skill.t.hpp"
+
+
+namespace tmwa
+{
void clif_setip(IP4Address);
void clif_setport(int);
@@ -47,16 +53,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,18 +72,18 @@ 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
-int clif_additem(dumb_ptr<map_session_data>, int, int, PickupFail); //self
-void clif_delitem(dumb_ptr<map_session_data>, 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>, IOff0, int, PickupFail); //self
+void clif_delitem(dumb_ptr<map_session_data>, IOff0, int); //self
int clif_updatestatus(dumb_ptr<map_session_data>, SP); //self
int clif_damage(dumb_ptr<block_list>, dumb_ptr<block_list>,
tick_t, interval_t, interval_t,
@@ -89,14 +95,14 @@ int clif_takeitem(dumb_ptr<block_list> src, dumb_ptr<block_list> dst)
}
int clif_changelook(dumb_ptr<block_list>, LOOK, int); // area
void clif_changelook_accessories(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> dst); // area or target; list gloves, boots etc.
-int clif_arrowequip(dumb_ptr<map_session_data> sd, int val); //self
+int clif_arrowequip(dumb_ptr<map_session_data> sd, IOff0 val); //self
int clif_arrow_fail(dumb_ptr<map_session_data> sd, int type); //self
int clif_statusupack(dumb_ptr<map_session_data>, SP, int, int); // self
-int clif_equipitemack(dumb_ptr<map_session_data>, int, EPOS, int); // self
-int clif_unequipitemack(dumb_ptr<map_session_data>, int, EPOS, int); // self
+int clif_equipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self
+int clif_unequipitemack(dumb_ptr<map_session_data>, IOff0, EPOS, int); // self
int clif_misceffect(dumb_ptr<block_list>, int); // area
int clif_changeoption(dumb_ptr<block_list>); // area
-int clif_useitemack(dumb_ptr<map_session_data>, int, int, int); // self
+int clif_useitemack(dumb_ptr<map_session_data>, IOff0, int, int); // self
void clif_emotion(dumb_ptr<block_list> bl, int type);
void clif_sitting(Session *, dumb_ptr<map_session_data> sd);
@@ -105,22 +111,22 @@ void clif_sitting(Session *, dumb_ptr<map_session_data> sd);
void clif_traderequest(dumb_ptr<map_session_data> sd, CharName name);
void clif_tradestart(dumb_ptr<map_session_data> sd, int type);
void clif_tradeadditem(dumb_ptr<map_session_data> sd,
- dumb_ptr<map_session_data> tsd, int index, int amount);
-int clif_tradeitemok(dumb_ptr<map_session_data> sd, int index, int amount,
+ dumb_ptr<map_session_data> tsd, IOff2 index2, int amount);
+int clif_tradeitemok(dumb_ptr<map_session_data> sd, IOff2 index, int amount,
int fail);
int clif_tradedeal_lock(dumb_ptr<map_session_data> sd, int fail);
int clif_tradecancelled(dumb_ptr<map_session_data> sd);
int clif_tradecompleted(dumb_ptr<map_session_data> sd, int fail);
// storage
-int clif_storageitemlist(dumb_ptr<map_session_data> sd, struct storage *stor);
+int clif_storageitemlist(dumb_ptr<map_session_data> sd, Storage *stor);
int clif_storageequiplist(dumb_ptr<map_session_data> sd,
- struct storage *stor);
+ Storage *stor);
int clif_updatestorageamount(dumb_ptr<map_session_data> sd,
- struct storage *stor);
-int clif_storageitemadded(dumb_ptr<map_session_data> sd, struct storage *stor,
- int index, int amount);
-int clif_storageitemremoved(dumb_ptr<map_session_data> sd, int index,
+ Storage *stor);
+int clif_storageitemadded(dumb_ptr<map_session_data> sd, Storage *stor,
+ SOff0 index, int amount);
+int clif_storageitemremoved(dumb_ptr<map_session_data> sd, SOff0 index,
int amount);
int clif_storageclose(dumb_ptr<map_session_data> sd);
@@ -157,17 +163,17 @@ int clif_movetoattack(dumb_ptr<map_session_data> sd, dumb_ptr<block_list> bl);
// party
int clif_party_created(dumb_ptr<map_session_data> sd, int flag);
-int clif_party_info(struct party *p, Session *s);
+int clif_party_info(PartyPair p, Session *s);
void clif_party_invite(dumb_ptr<map_session_data> sd,
dumb_ptr<map_session_data> tsd);
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,
+void clif_party_option(PartyPair 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);
-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);
+void clif_party_leaved(PartyPair p, dumb_ptr<map_session_data> sd,
+ AccountId account_id, CharName name, int flag);
+void clif_party_message(PartyPair p, AccountId account_id, XString mes);
+int clif_party_xy(PartyPair p, dumb_ptr<map_session_data> sd);
+int clif_party_hp(PartyPair p, dumb_ptr<map_session_data> sd);
// atcommand
void clif_displaymessage(Session *s, XString mes);
@@ -183,5 +189,4 @@ int clif_GM_kick(dumb_ptr<map_session_data> sd, dumb_ptr<map_session_data> tsd,
int clif_foreachclient(std::function<void(dumb_ptr<map_session_data>)>);
void do_init_clif(void);
-
-#endif // TMWA_MAP_CLIF_HPP
+} // namespace tmwa
diff --git a/src/map/clif.t.hpp b/src/map/clif.t.hpp
index 5cb06ad..1789ee8 100644
--- a/src/map/clif.t.hpp
+++ b/src/map/clif.t.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_CLIF_T_HPP
-#define TMWA_MAP_CLIF_T_HPP
+#pragma once
// clif.t.hpp - Network interface to the client.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,9 +20,99 @@
// 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 <cstdint>
+
+#include "../ints/little.hpp"
+
+#include "../compat/iter.hpp"
+
+#include "../generic/enum.hpp"
+
+#include "../mmo/consts.hpp"
+#include "../mmo/enums.hpp"
+
+
+namespace tmwa
+{
+namespace e
+{
+// [Fate] status.option properties. These are persistent status changes.
+// IDs that are not listed are not used in the code (to the best of my knowledge)
+enum class Option : uint16_t
+{
+ ZERO = 0x0000,
+
+ // [Fate] This is the GM `@hide' flag
+ HIDE = 0x0040,
+ // [Fate] Complete invisibility to other clients
+ INVISIBILITY = 0x1000,
+
+ // ?
+ REAL_ANY_HIDE = HIDE,
+};
+enum class Opt1 : uint16_t
+{
+ ZERO = 0,
+ _stone1 = 1,
+ _freeze = 2,
+ _stan = 3,
+ _sleep = 4,
+ _stone6 = 6,
+};
+enum class Opt2 : uint16_t
+{
+ ZERO = 0x0000,
+ _poison = 0x0001,
+ _curse = 0x0002,
+ _silence = 0x0004,
+ BLIND = 0x0010,
+ _speedpotion0 = 0x0020,
+ _signumcrucis = 0x0040,
+ _atkpot = 0x0080,
+ _heal = 0x0100,
+ _slowpoison = 0x0200,
+};
+enum class Opt3 : uint16_t
+{
+ ZERO = 0x0000,
+ _concentration = 0x0001,
+ _overthrust = 0x0002,
+ _energycoat = 0x0004,
+ _explosionspirits = 0x0008,
+ _steelbody = 0x0010,
+ _berserk = 0x0080,
+
+ _marionette = 0x0400,
+ _assumptio = 0x0800,
+};
+
+ENUM_BITWISE_OPERATORS(Option)
+ENUM_BITWISE_OPERATORS(Opt2)
+ENUM_BITWISE_OPERATORS(Opt3)
+}
+using e::Option;
+using e::Opt1;
+using e::Opt2;
+using e::Opt3;
+
+
+enum class ItemType : uint8_t
+{
+ USE = 0, // in eA, healing only
+ _1 = 1, // unused
+ _2 = 2, // in eA, other usable items
+ JUNK = 3, // "useless" items (e.g. quests)
+ WEAPON = 4, // all weapons
+ ARMOR = 5, // all other equipment
+ _6 = 6, // in eA, card
+ _7 = 7, // in eA, pet egg
+ _8 = 8, // in eA, pet equipment
+ _9 = 9, // unused
+ ARROW = 10, // ammo
+ _11 = 11, // in eA, delayed use (special script)
+};
enum class BeingRemoveWhy : uint8_t
{
@@ -40,4 +129,589 @@ enum class BeingRemoveWhy : uint8_t
NEGATIVE1 = 0xff,
};
-#endif // TMWA_MAP_CLIF_T_HPP
+enum class PickupFail : uint8_t
+{
+ OKAY = 0,
+ BAD_ITEM = 1,
+ TOO_HEAVY = 2,
+ TOO_FAR = 3,
+ INV_FULL = 4,
+ STACK_FULL = 5,
+ DROP_STEAL = 6,
+};
+
+// this is used for both input and output
+// different values are valid in 0x0089 vs 0x008a
+enum class DamageType : uint8_t
+{
+ NORMAL = 0x00,
+ TAKEITEM = 0x01,
+ SIT = 0x02,
+ STAND = 0x03,
+ RETURNED = 0x04,
+ CONTINUOUS = 0x07,
+ DOUBLED = 0x08,
+ CRITICAL = 0x0a,
+ FLEE2 = 0x0b,
+};
+
+enum class LOOK : uint8_t
+{
+ BASE = 0,
+ HAIR = 1,
+ WEAPON = 2,
+ HEAD_BOTTOM = 3,
+ HEAD_TOP = 4,
+ HEAD_MID = 5,
+ HAIR_COLOR = 6,
+ CLOTHES_COLOR = 7,
+ SHIELD = 8,
+ SHOES = 9,
+ GLOVES = 10,
+ CAPE = 11,
+ MISC1 = 12,
+ MISC2 = 13,
+
+ COUNT,
+};
+
+// Note: there is also a typedef by this name in <dirent.h>
+// but we should be fine since we never include it.
+// (in the long term we should still rename this though)
+enum class DIR : uint8_t
+{
+ S = 0,
+ SW = 1,
+ W = 2,
+ NW = 3,
+ N = 4,
+ NE = 5,
+ E = 6,
+ SE = 7,
+
+ COUNT,
+};
+
+constexpr
+earray<int, DIR, DIR::COUNT> dirx //=
+{{
+ 0, -1, -1, -1, 0, 1, 1, 1,
+}}, diry //=
+{{
+ 1, 1, 0, -1, -1, -1, 0, 1,
+}};
+
+constexpr
+bool dir_is_diagonal(DIR d)
+{
+ return static_cast<uint8_t>(d) & 1;
+}
+
+
+enum class SP : uint16_t
+{
+ // sent to client
+ SPEED = 0,
+
+ // when used as "no stat"
+ ZERO = 0,
+
+ // sent to client
+ BASEEXP = 1,
+ // sent to client
+ JOBEXP = 2,
+#if 0
+ KARMA = 3,
+#endif
+
+ // sent to client
+ HP = 5,
+ // sent to client
+ MAXHP = 6,
+ // sent to client
+ SP = 7,
+ // sent to client
+ MAXSP = 8,
+ // sent to client
+ STATUSPOINT = 9,
+
+ // sent to client
+ BASELEVEL = 11,
+ // sent to client
+ SKILLPOINT = 12,
+ // sent to client
+ STR = 13,
+ // sent to client
+ AGI = 14,
+ // sent to client
+ VIT = 15,
+ // sent to client
+ INT = 16,
+ // sent to client
+ DEX = 17,
+ // sent to client
+ LUK = 18,
+ CLASS = 19,
+ // sent to client
+ ZENY = 20,
+ SEX = 21,
+ // sent to client
+ NEXTBASEEXP = 22,
+ // sent to client
+ NEXTJOBEXP = 23,
+ // sent to client
+ WEIGHT = 24,
+ // sent to client
+ MAXWEIGHT = 25,
+
+ // sent to client
+ USTR = 32,
+ // sent to client
+ UAGI = 33,
+ // sent to client
+ UVIT = 34,
+ // sent to client
+ UINT = 35,
+ // sent to client
+ UDEX = 36,
+ // sent to client
+ ULUK = 37,
+
+ // sent to client
+ ATK1 = 41,
+ // sent to client
+ ATK2 = 42,
+ // sent to client
+ MATK1 = 43,
+ // sent to client
+ MATK2 = 44,
+ // sent to client
+ DEF1 = 45,
+ // sent to client
+ DEF2 = 46,
+ // sent to client
+ MDEF1 = 47,
+ // sent to client
+ MDEF2 = 48,
+ // sent to client
+ HIT = 49,
+ // sent to client
+ FLEE1 = 50,
+ // sent to client
+ FLEE2 = 51,
+ // sent to client
+ CRITICAL = 52,
+ // sent to client
+ ASPD = 53,
+
+ // sent to client
+ JOBLEVEL = 55,
+
+#if 0
+ PARTNER = 57,
+ CART = 58,
+ FAME = 59,
+ UNBREAKABLE = 60,
+#endif
+
+ DEAF = 70,
+
+ // sent to client
+ GM = 500,
+
+ // sent to client
+ ATTACKRANGE = 1000,
+#if 0
+ ATKELE = 1001,
+#endif
+#if 0
+ DEFELE = 1002,
+#endif
+#if 0
+ CASTRATE = 1003,
+#endif
+ MAXHPRATE = 1004,
+#if 0
+ MAXSPRATE = 1005,
+#endif
+#if 0
+ SPRATE = 1006,
+#endif
+
+#if 0
+ ADDEFF = 1012,
+#endif
+#if 0
+ RESEFF = 1013,
+#endif
+ BASE_ATK = 1014,
+ ASPD_RATE = 1015,
+ HP_RECOV_RATE = 1016,
+#if 0
+ SP_RECOV_RATE = 1017,
+#endif
+#if 0
+ SPEED_RATE = 1018,
+#endif
+ CRITICAL_DEF = 1019,
+#if 0
+ NEAR_ATK_DEF = 1020,
+#endif
+#if 0
+ LONG_ATK_DEF = 1021,
+#endif
+#if 0
+ DOUBLE_RATE = 1022,
+#endif
+ DOUBLE_ADD_RATE = 1023,
+#if 0
+ MATK = 1024,
+#endif
+#if 0
+ MATK_RATE = 1025,
+#endif
+#if 0
+ IGNORE_DEF_ELE = 1026,
+#endif
+#if 0
+ IGNORE_DEF_RACE = 1027,
+#endif
+#if 0
+ ATK_RATE = 1028,
+#endif
+ SPEED_ADDRATE = 1029,
+#if 0
+ ASPD_ADDRATE = 1030,
+#endif
+#if 0
+ MAGIC_ATK_DEF = 1031,
+#endif
+#if 0
+ MISC_ATK_DEF = 1032,
+#endif
+#if 0
+ IGNORE_MDEF_ELE = 1033,
+#endif
+#if 0
+ IGNORE_MDEF_RACE = 1034,
+#endif
+
+#if 0
+ PERFECT_HIT_RATE = 1038,
+#endif
+#if 0
+ PERFECT_HIT_ADD_RATE = 1039,
+#endif
+#if 0
+ CRITICAL_RATE = 1040,
+#endif
+#if 0
+ GET_ZENY_NUM = 1041,
+#endif
+#if 0
+ ADD_GET_ZENY_NUM = 1042,
+#endif
+
+#if 0
+ ADD_MONSTER_DROP_ITEM = 1047,
+#endif
+#if 0
+ DEF_RATIO_ATK_ELE = 1048,
+#endif
+#if 0
+ DEF_RATIO_ATK_RACE = 1049,
+#endif
+#if 0
+ ADD_SPEED = 1050,
+#endif
+#if 0
+ HIT_RATE = 1051,
+#endif
+#if 0
+ FLEE_RATE = 1052,
+#endif
+#if 0
+ FLEE2_RATE = 1053,
+#endif
+ DEF_RATE = 1054,
+ DEF2_RATE = 1055,
+#if 0
+ MDEF_RATE = 1056,
+#endif
+#if 0
+ MDEF2_RATE = 1057,
+#endif
+#if 0
+ SPLASH_RANGE = 1058,
+#endif
+#if 0
+ SPLASH_ADD_RANGE = 1059,
+#endif
+
+ HP_DRAIN_RATE = 1061,
+#if 0
+ SP_DRAIN_RATE = 1062,
+#endif
+#if 0
+ SHORT_WEAPON_DAMAGE_RETURN = 1063,
+#endif
+#if 0
+ LONG_WEAPON_DAMAGE_RETURN = 1064,
+#endif
+
+#if 0
+ ADDEFF2 = 1067,
+#endif
+ BREAK_WEAPON_RATE = 1068,
+ BREAK_ARMOR_RATE = 1069,
+ ADD_STEAL_RATE = 1070,
+ MAGIC_DAMAGE_RETURN = 1071,
+#if 0
+ RANDOM_ATTACK_INCREASE = 1072,
+#endif
+};
+
+constexpr
+SP attr_to_sp(ATTR attr)
+{
+ return static_cast<SP>(static_cast<uint16_t>(attr) + static_cast<uint16_t>(SP::STR));
+}
+
+constexpr
+ATTR sp_to_attr(SP sp)
+{
+ return static_cast<ATTR>(static_cast<uint16_t>(sp) - static_cast<uint16_t>(SP::STR));
+}
+
+constexpr
+SP attr_to_usp(ATTR attr)
+{
+ return static_cast<SP>(static_cast<uint16_t>(attr) + static_cast<uint16_t>(SP::USTR));
+}
+
+constexpr
+ATTR usp_to_attr(SP sp)
+{
+ return static_cast<ATTR>(static_cast<uint16_t>(sp) - static_cast<uint16_t>(SP::USTR));
+}
+
+constexpr
+SP sp_to_usp(SP sp)
+{
+ return attr_to_usp(sp_to_attr(sp));
+}
+
+constexpr
+SP usp_to_sp(SP sp)
+{
+ return attr_to_sp(usp_to_attr(sp));
+}
+
+
+// xxxx xxxx xxyy yyyy yyyy dddd
+struct NetPosition1
+{
+ Byte data[3];
+};
+
+struct Position1
+{
+ uint16_t x, y;
+ DIR dir;
+};
+
+inline
+bool native_to_network(NetPosition1 *network, Position1 native)
+{
+ uint16_t x = native.x;
+ uint16_t y = native.y;
+ uint8_t d = static_cast<uint8_t>(native.dir);
+
+ uint8_t *p = reinterpret_cast<uint8_t *>(network);
+ p[0] = x >> 2;
+ p[1] = (x << 6) | ((y >> 4) & 0x3f);
+ p[2] = y << 4 | d;
+
+ return x < 1024 && y < 1024 && d < 16;
+}
+
+inline
+bool network_to_native(Position1 *native, NetPosition1 network)
+{
+ const uint8_t *p = reinterpret_cast<const uint8_t *>(&network);
+ native->x = (p[0] & (0x3ff >> 2)) << 2 | p[1] >> (8 - 2);
+ native->y = (p[1] & (0x3ff >> 4)) << 4 | p[2] >> (8 - 4);
+ uint8_t d = p[2] & 0x0f;
+ native->dir = static_cast<DIR>(d);
+ return d < 8;
+}
+
+// x0xx xxxx xxy0 yyyy yyyy x1xx xxxx xxy1 yyyy yyyy
+struct NetPosition2
+{
+ Byte data[5];
+};
+
+struct Position2
+{
+ uint16_t x0, y0;
+ uint16_t x1, y1;
+};
+
+inline
+bool native_to_network(NetPosition2 *network, Position2 native)
+{
+ uint16_t x0 = native.x0;
+ uint16_t y0 = native.y0;
+ uint16_t x1 = native.x1;
+ uint16_t y1 = native.y1;
+
+ uint8_t *p = reinterpret_cast<uint8_t *>(network);
+ p[0] = x0 >> 2;
+ p[1] = (x0 << 6) | ((y0 >> 4) & 0x3f);
+ p[2] = (y0 << 4) | ((x1 >> 6) & 0x0f);
+ p[3] = (x1 << 2) | ((y1 >> 8) & 0x03);
+ p[4] = y1;
+
+ return x0 < 1024 && y0 < 1024 && x1 < 1024 && y1 < 1024;
+}
+
+inline
+bool network_to_native(Position2 *native, NetPosition2 network)
+{
+ const uint8_t *p = reinterpret_cast<const uint8_t *>(&network);
+ native->x0 = (p[0] & (0x3ff >> 2)) << 2 | p[1] >> (8 - 2);
+ native->y0 = (p[1] & (0x3ff >> 4)) << 4 | p[2] >> (8 - 4);
+ native->x1 = (p[2] & (0x3ff >> 6)) << 6 | p[3] >> (8 - 6);
+ native->y1 = (p[3] & (0x3ff >> 8)) << 8 | p[4] >> (8 - 8);
+ return true;
+}
+
+struct IOff2;
+struct SOff1;
+
+struct IOff0
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get0() < MAX_INVENTORY; }
+ uint16_t get0() const
+ { return index; }
+ static IOff0 from(uint16_t i)
+ { return IOff0{i}; }
+ static IteratorPair<ValueIterator<IOff0>> iter()
+ { return {IOff0::from(0), IOff0::from(MAX_INVENTORY)}; }
+ friend uint16_t convert_for_printf(IOff0 i0) { return i0.index; }
+
+ IOff0& operator ++() { ++index; return *this; }
+ friend bool operator == (IOff0 l, IOff0 r) { return l.index == r.index; }
+ friend bool operator != (IOff0 l, IOff0 r) { return !(l == r); }
+ IOff2 shift() const;
+
+ IOff0() : index(0) {}
+private:
+ explicit IOff0(uint16_t i) : index(i) {}
+};
+
+struct SOff0
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get0() < MAX_STORAGE; }
+ uint16_t get0() const
+ { return index; }
+ static SOff0 from(uint16_t i)
+ { return SOff0{i}; }
+ static IteratorPair<ValueIterator<SOff0>> iter()
+ { return {SOff0::from(0), SOff0::from(MAX_STORAGE)}; }
+ friend uint16_t convert_for_printf(SOff0 s0) { return s0.index; }
+
+ SOff0& operator ++() { ++index; return *this; }
+ friend bool operator == (SOff0 l, SOff0 r) { return l.index == r.index; }
+ friend bool operator != (SOff0 l, SOff0 r) { return !(l == r); }
+ SOff1 shift() const;
+
+ SOff0() : index(0) {}
+private:
+ explicit SOff0(uint16_t i) : index(i) {}
+};
+
+struct IOff2
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get2() < MAX_INVENTORY; }
+ uint16_t get2() const
+ { return index - 2; }
+ static IOff2 from(uint16_t i)
+ { return IOff2{static_cast<uint16_t>(i + 2)}; }
+ static IteratorPair<ValueIterator<IOff2>> iter()
+ { return {IOff2::from(0), IOff2::from(MAX_INVENTORY)}; }
+
+ IOff2& operator ++() { ++index; return *this; }
+ friend bool operator == (IOff2 l, IOff2 r) { return l.index == r.index; }
+ friend bool operator != (IOff2 l, IOff2 r) { return !(l == r); }
+ IOff0 unshift() const
+ { return IOff0::from(get2()); }
+
+ IOff2() : index(0) {}
+private:
+ explicit IOff2(uint16_t i) : index(i) {}
+};
+
+struct SOff1
+{
+ uint16_t index;
+
+ bool ok() const
+ { return get1() < MAX_STORAGE; }
+ uint16_t get1() const
+ { return index - 1; }
+ static SOff1 from(uint16_t i)
+ { return SOff1{static_cast<uint16_t>(i + 1)}; }
+ static IteratorPair<ValueIterator<SOff1>> iter()
+ { return {SOff1::from(0), SOff1::from(MAX_STORAGE)}; }
+
+ SOff1& operator ++() { ++index; return *this; }
+ friend bool operator == (SOff1 l, SOff1 r) { return l.index == r.index; }
+ friend bool operator != (SOff1 l, SOff1 r) { return !(l == r); }
+ SOff0 unshift() const
+ { return SOff0::from(get1()); }
+
+ SOff1() : index(0) {}
+private:
+ explicit SOff1(uint16_t i) : index(i) {}
+};
+
+inline IOff2 IOff0::shift() const
+{ return IOff2::from(get0()); }
+inline SOff1 SOff0::shift() const
+{ return SOff1::from(get0()); }
+
+inline
+bool native_to_network(Little16 *network, IOff2 native)
+{
+ return native_to_network(network, native.index);
+}
+
+inline
+bool network_to_native(IOff2 *native, Little16 network)
+{
+ return network_to_native(&native->index, network);
+}
+
+inline
+bool native_to_network(Little16 *network, SOff1 native)
+{
+ return native_to_network(network, native.index);
+}
+
+inline
+bool network_to_native(SOff1 *native, Little16 network)
+{
+ return network_to_native(&native->index, network);
+}
+} // namespace tmwa
diff --git a/src/map/magic-interpreter-aux.cpp b/src/map/fwd.hpp
index 10a376b..79bbbcd 100644
--- a/src/map/magic-interpreter-aux.cpp
+++ b/src/map/fwd.hpp
@@ -1,5 +1,5 @@
-#include "magic-interpreter-aux.hpp"
-// magic-interpreter-aux.cpp - Edge of the magic system.
+#pragma once
+// map/fwd.hpp - list of type names for map server
//
// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -18,4 +18,42 @@
// 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"
+#include "../sanity.hpp"
+
+
+namespace tmwa
+{
+// meh, add more when I feel like it
+class BlockId;
+struct block_list;
+struct map_session_data;
+struct npc_data;
+struct mob_data;
+struct flooritem_data;
+//struct magic::invocation;
+struct map_local;
+class npc_data_script;
+class npc_data_shop;
+class npc_data_warp;
+class npc_data_message;
+struct NpcEvent;
+
+struct item_data;
+
+namespace magic
+{
+struct fun_t;
+struct op_t;
+struct expr_t;
+struct val_t;
+struct location_t;
+struct area_t;
+struct spell_t;
+struct invocation;
+struct teleport_anchor_t;
+struct env_t;
+struct magic_conf_t;
+struct component_t;
+struct effect_set_t;
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/grfio.cpp b/src/map/grfio.cpp
index c3d1e40..4a1656b 100644
--- a/src/map/grfio.cpp
+++ b/src/map/grfio.cpp
@@ -20,28 +20,29 @@
// 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 <sys/stat.h>
-
#include <fcntl.h>
#include <unistd.h>
#include <cassert>
-#include <cstdio>
-#include <cstring>
#include <map>
#include "../strings/mstring.hpp"
#include "../strings/rstring.hpp"
#include "../strings/astring.hpp"
+#include "../strings/zstring.hpp"
#include "../io/cxxstdio.hpp"
#include "../io/read.hpp"
#include "../mmo/extract.hpp"
+#include "../mmo/mmo.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
static
std::map<MapName, RString> resnametable;
@@ -50,7 +51,7 @@ bool load_resnametable(ZString filename)
io::ReadFile in(filename);
if (!in.is_open())
{
- FPRINTF(stderr, "Missing %s\n", filename);
+ FPRINTF(stderr, "Missing %s\n"_fmt, filename);
return false;
}
@@ -63,7 +64,7 @@ bool load_resnametable(ZString filename)
if (!extract(line,
record<'#'>(&key, &value)))
{
- PRINTF("Bad resnametable line: %s\n", line);
+ PRINTF("Bad resnametable line: %s\n"_fmt, line);
rv = false;
continue;
}
@@ -85,7 +86,7 @@ std::vector<uint8_t> grfio_reads(MapName rname)
{
MString lfname_;
// TODO ... instead of here
- lfname_ += "data/";
+ lfname_ += "data/"_s;
lfname_ += grfio_resnametable(rname);
AString lfname = AString(lfname_);
@@ -93,7 +94,7 @@ std::vector<uint8_t> grfio_reads(MapName rname)
int fd = open(lfname.c_str(), O_RDONLY);
if (fd == -1)
{
- FPRINTF(stderr, "Resource %s (file %s) not found\n",
+ FPRINTF(stderr, "Resource %s (file %s) not found\n"_fmt,
rname, lfname);
return {};
}
@@ -105,3 +106,4 @@ std::vector<uint8_t> grfio_reads(MapName rname)
close(fd);
return buffer;
}
+} // namespace tmwa
diff --git a/src/map/grfio.hpp b/src/map/grfio.hpp
index 9b6d5e2..d2ab058 100644
--- a/src/map/grfio.hpp
+++ b/src/map/grfio.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_GRFIO_HPP
-#define TMWA_MAP_GRFIO_HPP
+#pragma once
// grfio.hpp - Don't read GRF files, just name-map .wlk files.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,19 +20,23 @@
// 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 <cstdint>
-# include <vector>
+#include <vector>
-# include "../mmo/mmo.hpp"
+#include "../strings/fwd.hpp"
+#include "../mmo/fwd.hpp"
+
+
+namespace tmwa
+{
bool load_resnametable(ZString filename);
/// Load a resource into memory, subject to data/resnametable.txt.
/// Normally, resourcename is xxx-y.gat and the file is xxx-y.wlk.
/// Currently there is exactly one .wlk per .gat, but multiples are fine.
std::vector<uint8_t> grfio_reads(MapName resourcename);
-
-#endif // TMWA_MAP_GRFIO_HPP
+} // namespace tmwa
diff --git a/src/map/intif.cpp b/src/map/intif.cpp
index 2cae2ad..314db24 100644
--- a/src/map/intif.cpp
+++ b/src/map/intif.cpp
@@ -20,18 +20,21 @@
// 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 <cstdlib>
-#include <cstring>
-
#include "../compat/nullpo.hpp"
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
+#include "../strings/literal.hpp"
#include "../io/cxxstdio.hpp"
-#include "../mmo/socket.hpp"
+#include "../net/packets.hpp"
+#include "../net/socket.hpp"
+
+#include "../mmo/mmo.hpp"
+
+#include "../proto2/char-map.hpp"
#include "battle.hpp"
#include "chrif.hpp"
@@ -43,32 +46,19 @@
#include "../poison.hpp"
-static
-const int packet_len_table[] =
-{
- -1, -1, 27, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -1, 7, 0, 0, 0, 0, 0, 0, -1, 11, 0, 0, 0, 0, 0, 0,
- 35, -1, 11, 15, 34, 29, 7, -1, 0, 0, 0, 0, 0, 0, 0, 0,
- 10, -1, 15, 0, 79, 19, 7, -1, 0, -1, -1, -1, 14, 67, 186, -1,
- 9, 9, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 11, -1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
+namespace tmwa
+{
//-----------------------------------------------------------------
// inter serverへの送信
// Message for all GMs on all map servers
void intif_GMmessage(XString mes)
{
- WFIFOW(char_session, 0) = 0x3000;
- size_t len = mes.size() + 1;
- WFIFOW(char_session, 2) = 4 + len;
- WFIFO_STRING(char_session, 4, mes, len);
- WFIFOSET(char_session, WFIFOW(char_session, 2));
+ if (!char_session)
+ return;
+
+ send_packet_repeatonly<0x3000, 4, 1>(char_session, mes);
}
// The transmission of Wisp/Page to inter-server (player not found on this server)
@@ -76,65 +66,69 @@ void intif_wis_message(dumb_ptr<map_session_data> sd, CharName nick, ZString mes
{
nullpo_retv(sd);
- size_t mes_len = mes.size() + 1;
- WFIFOW(char_session, 0) = 0x3001;
- WFIFOW(char_session, 2) = mes_len + 52;
- WFIFO_STRING(char_session, 4, sd->status_key.name.to__actual(), 24);
- WFIFO_STRING(char_session, 28, nick.to__actual(), 24);
- WFIFO_STRING(char_session, 52, mes, mes_len);
- WFIFOSET(char_session, WFIFOW(char_session, 2));
+ if (!char_session)
+ return;
+
+ Packet_Head<0x3001> head_01;
+ head_01.from_char_name = sd->status_key.name;
+ head_01.to_char_name = nick;
+ send_vpacket<0x3001, 52, 1>(char_session, head_01, mes);
if (battle_config.etc_log)
- PRINTF("intif_wis_message from %s to %s)\n",
+ PRINTF("intif_wis_message from %s to %s)\n"_fmt,
sd->status_key.name, nick);
}
// The reply of Wisp/page
static
-void intif_wis_replay(int id, int flag)
+void intif_wis_replay(CharId id, int flag)
{
- WFIFOW(char_session, 0) = 0x3002;
- WFIFOL(char_session, 2) = id;
- WFIFOB(char_session, 6) = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
- WFIFOSET(char_session, 7);
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3002> fixed_02;
+ fixed_02.char_id = id;
+ fixed_02.flag = flag; // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+ send_fpacket<0x3002, 7>(char_session, fixed_02);
if (battle_config.etc_log)
- PRINTF("intif_wis_replay: id: %d, flag:%d\n", id, flag);
+ PRINTF("intif_wis_replay: id: %d, flag:%d\n"_fmt, id, 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;
- WFIFO_STRING(char_session, 30, mes, mes_len);
- WFIFOSET(char_session, WFIFOW(char_session, 2));
+ if (!char_session)
+ return;
+
+ Packet_Head<0x3003> head_03;
+ head_03.char_name = Wisp_name;
+ head_03.min_gm_level = min_gm_level;
+ send_vpacket<0x3003, 30, 1>(char_session, head_03, mes);
if (battle_config.etc_log)
- PRINTF("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n",
+ PRINTF("intif_wis_message_to_gm: from: '%s', min level: %d, message: '%s'.\n"_fmt,
Wisp_name, min_gm_level, mes);
}
// アカウント変数送信
void intif_saveaccountreg(dumb_ptr<map_session_data> sd)
{
- int j, p;
-
nullpo_retv(sd);
+ if (!char_session)
+ return;
+
assert (sd->status.account_reg_num < ACCOUNT_REG_NUM);
- WFIFOW(char_session, 0) = 0x3004;
- WFIFOL(char_session, 4) = sd->bl_id;
- for (j = 0, p = 8; j < sd->status.account_reg_num; j++, p += 36)
+ Packet_Head<0x3004> head_04;
+ head_04.account_id = block_to_account(sd->bl_id);
+ std::vector<Packet_Repeat<0x3004>> repeat_04(sd->status.account_reg_num);
+ for (size_t j = 0; j < sd->status.account_reg_num; j++)
{
- WFIFO_STRING(char_session, p, sd->status.account_reg[j].str, 32);
- WFIFOL(char_session, p + 32) = sd->status.account_reg[j].value;
+ repeat_04[j].name = sd->status.account_reg[j].str;
+ repeat_04[j].value = sd->status.account_reg[j].value;
}
- WFIFOW(char_session, 2) = p;
- WFIFOSET(char_session, p);
+ send_vpacket<0x3004, 8, 36>(char_session, head_04, repeat_04);
}
// アカウント変数要求
@@ -142,28 +136,36 @@ 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;
- WFIFOSET(char_session, 6);
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3005> fixed_05;
+ fixed_05.account_id = block_to_account(sd->bl_id);
+ send_fpacket<0x3005, 6>(char_session, fixed_05);
}
// 倉庫データ要求
-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;
- WFIFOSET(char_session, 6);
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3010> fixed_10;
+ fixed_10.account_id = account_id;
+ send_fpacket<0x3010, 6>(char_session, fixed_10);
}
// 倉庫データ送信
-void intif_send_storage(struct storage *stor)
+void intif_send_storage(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;
- WFIFO_STRUCT(char_session, 8, *stor);
- WFIFOSET(char_session, WFIFOW(char_session, 2));
+ if (!char_session)
+ return;
+
+ Packet_Payload<0x3011> payload_11;
+ payload_11.account_id = stor->account_id;
+ payload_11.storage = *stor;
+ send_ppacket<0x3011>(char_session, payload_11);
}
// パーティ作成要求
@@ -171,95 +173,116 @@ 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;
- 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);
- WFIFOW(char_session, 70) = sd->status.base_level;
- WFIFOSET(char_session, 72);
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3020> fixed_20;
+ fixed_20.account_id = sd->status_key.account_id;
+ fixed_20.party_name = name;
+ fixed_20.char_name = sd->status_key.name;
+ fixed_20.map_name = sd->bl_m->name_;
+ fixed_20.level = sd->status.base_level;
+ send_fpacket<0x3020, 72>(char_session, fixed_20);
}
// パーティ情報要求
-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;
- WFIFOSET(char_session, 6);
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3021> fixed_21;
+ fixed_21.party_id = party_id;
+ send_fpacket<0x3021, 6>(char_session, fixed_21);
}
// パーティ追加要求
-void intif_party_addmember(int party_id, int account_id)
+void intif_party_addmember(PartyId party_id, AccountId account_id)
{
+ if (!char_session)
+ return;
+
dumb_ptr<map_session_data> sd;
- sd = map_id2sd(account_id);
- if (sd != NULL)
+ sd = map_id2sd(account_to_block(account_id));
+ if (sd != nullptr)
{
- WFIFOW(char_session, 0) = 0x3022;
- WFIFOL(char_session, 2) = party_id;
- WFIFOL(char_session, 6) = 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;
- WFIFOSET(char_session, 52);
+ Packet_Fixed<0x3022> fixed_22;
+ fixed_22.party_id = party_id;
+ fixed_22.account_id = account_id;
+ fixed_22.char_name = sd->status_key.name;
+ fixed_22.map_name = sd->bl_m->name_;
+ fixed_22.level = sd->status.base_level;
+ send_fpacket<0x3022, 52>(char_session, fixed_22);
}
}
// パーティ設定変更
-void intif_party_changeoption(int party_id, int account_id, int exp, int item)
-{
- WFIFOW(char_session, 0) = 0x3023;
- WFIFOL(char_session, 2) = party_id;
- WFIFOL(char_session, 6) = account_id;
- WFIFOW(char_session, 10) = exp;
- WFIFOW(char_session, 12) = item;
- WFIFOSET(char_session, 14);
+void intif_party_changeoption(PartyId party_id, AccountId account_id, int exp, int item)
+{
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3023> fixed_23;
+ fixed_23.party_id = party_id;
+ fixed_23.account_id = account_id;
+ fixed_23.exp = exp;
+ fixed_23.item = item;
+ send_fpacket<0x3023, 14>(char_session, fixed_23);
}
// パーティ脱退要求
-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;
- WFIFOSET(char_session, 10);
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3024> fixed_24;
+ fixed_24.party_id = party_id;
+ fixed_24.account_id = account_id;
+ send_fpacket<0x3024, 10>(char_session, fixed_24);
}
// パーティ移動要求
void intif_party_changemap(dumb_ptr<map_session_data> sd, int online)
{
- if (sd != NULL)
+ if (!char_session)
+ return;
+
+ if (sd != nullptr)
{
- WFIFOW(char_session, 0) = 0x3025;
- WFIFOL(char_session, 2) = sd->status.party_id;
- WFIFOL(char_session, 6) = 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;
- WFIFOSET(char_session, 29);
+ Packet_Fixed<0x3025> fixed_25;
+ fixed_25.party_id = sd->status.party_id;
+ fixed_25.account_id = sd->status_key.account_id;
+ fixed_25.map_name = sd->bl_m->name_;
+ fixed_25.online = online;
+ fixed_25.level = sd->status.base_level;
+ send_fpacket<0x3025, 29>(char_session, fixed_25);
}
}
// パーティ会話送信
-void intif_party_message(int party_id, int 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;
- WFIFO_STRING(char_session, 12, mes, len);
- WFIFOSET(char_session, len + 12);
+void intif_party_message(PartyId party_id, AccountId account_id, XString mes)
+{
+ if (!char_session)
+ return;
+
+ Packet_Head<0x3027> head_27;
+ head_27.party_id = party_id;
+ head_27.account_id = account_id;
+ send_vpacket<0x3027, 12, 1>(char_session, head_27, mes);
}
// パーティ競合チェック要求
-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;
- WFIFO_STRING(char_session, 10, nick.to__actual(), 24);
- WFIFOSET(char_session, 34);
+ if (!char_session)
+ return;
+
+ Packet_Fixed<0x3028> fixed_28;
+ fixed_28.party_id = party_id;
+ fixed_28.account_id = account_id;
+ fixed_28.char_name = nick;
+ send_fpacket<0x3028, 34>(char_session, fixed_28);
}
//-----------------------------------------------------------------
@@ -267,55 +290,52 @@ void intif_party_checkconflict(int party_id, int account_id, CharName nick)
// Wisp/Page reception
static
-int intif_parse_WisMessage(Session *s)
+int intif_parse_WisMessage(Session *, const Packet_Head<0x3801>& head, AString& buf)
{
// rewritten by [Yor]
dumb_ptr<map_session_data> sd;
- CharName from = stringish<CharName>(RFIFO_STRING<24>(s, 8));
- CharName to = stringish<CharName>(RFIFO_STRING<24>(s, 32));
-
- size_t len = RFIFOW(s, 2) - 56;
- AString buf = RFIFO_STRING(s, 56, len);
+ CharName from = head.src_char_name;
+ CharName to = head.dst_char_name;
if (battle_config.etc_log)
{
- PRINTF("intif_parse_wismessage: id: %d, from: %s, to: %s\n",
- RFIFOL(s, 4),
- from,
- to);
+ PRINTF("intif_parse_wismessage: id: %d, from: %s, to: %s\n"_fmt,
+ head.whisper_id,
+ from,
+ to);
}
sd = map_nick2sd(to); // Searching destination player
- if (sd != NULL && sd->status_key.name == to)
+ if (sd != nullptr && sd->status_key.name == to)
{
// exactly same name (inter-server have checked the name before)
{
// if source player not found in ignore list
{
clif_wis_message(sd->sess, from, buf);
- intif_wis_replay(RFIFOL(s, 4), 0); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+ intif_wis_replay(head.whisper_id, 0); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
}
}
}
else
- intif_wis_replay(RFIFOL(s, 4), 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
+ intif_wis_replay(head.whisper_id, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
return 0;
}
// Wisp/page transmission result reception
static
-int intif_parse_WisEnd(Session *s)
+int intif_parse_WisEnd(Session *, const Packet_Fixed<0x3802>& fixed)
{
dumb_ptr<map_session_data> sd;
- CharName name = stringish<CharName>(RFIFO_STRING<24>(s, 2));
- uint8_t flag = RFIFOB(s, 26);
+ CharName name = fixed.sender_char_name;
+ uint8_t flag = fixed.flag;
if (battle_config.etc_log)
// flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
- PRINTF("intif_parse_wisend: player: %s, flag: %d\n",
+ PRINTF("intif_parse_wisend: player: %s, flag: %d\n"_fmt,
name, flag);
sd = map_nick2sd(name);
- if (sd != NULL)
+ if (sd != nullptr)
clif_wis_end(sd->sess, flag);
return 0;
@@ -323,19 +343,11 @@ int intif_parse_WisEnd(Session *s)
// Received wisp message from map-server via char-server for ALL gm
static
-void mapif_parse_WisToGM(Session *s)
+void mapif_parse_WisToGM(Session *, const Packet_Head<0x3803>& head, AString& message)
{
// 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;
-
- min_gm_level = RFIFOW(s, 28);
- CharName Wisp_name = stringish<CharName>(RFIFO_STRING<24>(s, 4));
- AString message = RFIFO_STRING(s, 30, len);
+ GmLevel min_gm_level = head.min_gm_level;
+ CharName Wisp_name = head.char_name;
// information is sended to all online GM
for (io::FD i : iter_fds())
{
@@ -345,7 +357,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);
}
}
@@ -353,65 +365,57 @@ void mapif_parse_WisToGM(Session *s)
// アカウント変数通知
static
-int intif_parse_AccountReg(Session *s)
+int intif_parse_AccountReg(Session *, const Packet_Head<0x3804>& head, const std::vector<Packet_Repeat<0x3804>>& repeat)
{
- int j, p;
- dumb_ptr<map_session_data> sd = map_id2sd(RFIFOL(s, 4));
- if (sd == NULL)
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(head.account_id));
+ if (sd == nullptr)
return 1;
- for (p = 8, j = 0; p < RFIFOW(s, 2) && j < ACCOUNT_REG_NUM;
- p += 36, j++)
+
+ size_t jlim = std::min(ACCOUNT_REG_NUM, repeat.size());
+ for (size_t j = 0; j < jlim; j++)
{
- sd->status.account_reg[j].str = stringish<VarName>(RFIFO_STRING<32>(s, p));
- sd->status.account_reg[j].value = RFIFOL(s, p + 32);
+ sd->status.account_reg[j].str = repeat[j].name;
+ sd->status.account_reg[j].value = repeat[j].value;
}
- sd->status.account_reg_num = j;
-// PRINTF("intif: accountreg\n");
+ sd->status.account_reg_num = jlim;
return 0;
}
// 倉庫データ受信
static
-int intif_parse_LoadStorage(Session *s)
+int intif_parse_LoadStorage(Session *, const Packet_Payload<0x3810>& payload)
{
- struct storage *stor;
+ Storage *stor;
dumb_ptr<map_session_data> sd;
- sd = map_id2sd(RFIFOL(s, 4));
- if (sd == NULL)
+ sd = map_id2sd(account_to_block(payload.account_id));
+ if (sd == nullptr)
{
if (battle_config.error_log)
- PRINTF("intif_parse_LoadStorage: user not found %d\n",
- RFIFOL(s, 4));
+ PRINTF("intif_parse_LoadStorage: user not found %d\n"_fmt,
+ payload.account_id);
return 1;
}
- stor = account2storage(RFIFOL(s, 4));
+ stor = account2storage(payload.account_id);
if (stor->storage_status == 1)
{ // Already open.. lets ignore this update
if (battle_config.error_log)
- PRINTF("intif_parse_LoadStorage: storage received for a client already open (User %d:%d)\n",
- sd->status_key.account_id, sd->status_key.char_id);
+ PRINTF("intif_parse_LoadStorage: storage received for a client already open (User %d:%d)\n"_fmt,
+ sd->status_key.account_id, sd->status_key.char_id);
return 1;
}
if (stor->dirty)
{ // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
if (battle_config.error_log)
- PRINTF("intif_parse_LoadStorage: received storage for an already modified non-saved storage! (User %d:%d)\n",
- sd->status_key.account_id, sd->status_key.char_id);
+ PRINTF("intif_parse_LoadStorage: received storage for an already modified non-saved storage! (User %d:%d)\n"_fmt,
+ sd->status_key.account_id, sd->status_key.char_id);
return 1;
}
- if (RFIFOW(s, 2) - 8 != sizeof(struct storage))
- {
- if (battle_config.error_log)
- PRINTF("intif_parse_LoadStorage: data size error %d %zu\n",
- RFIFOW(s, 2) - 8, sizeof(struct storage));
- return 1;
- }
if (battle_config.save_log)
- PRINTF("intif_openstorage: %d\n", RFIFOL(s, 4));
- RFIFO_STRUCT(s, 8, *stor);
+ PRINTF("intif_openstorage: %d\n"_fmt, payload.account_id);
+ *stor = payload.storage;
stor->dirty = 0;
stor->storage_status = 1;
sd->state.storage_open = 1;
@@ -424,199 +428,273 @@ int intif_parse_LoadStorage(Session *s)
// 倉庫データ送信成功
static
-void intif_parse_SaveStorage(Session *s)
+void intif_parse_SaveStorage(Session *, const Packet_Fixed<0x3811>& fixed)
{
if (battle_config.save_log)
- PRINTF("intif_savestorage: done %d %d\n", RFIFOL(s, 2),
- RFIFOB(s, 6));
- storage_storage_saved(RFIFOL(s, 2));
+ PRINTF("intif_savestorage: done %d %d\n"_fmt, fixed.account_id,
+ fixed.unknown);
+ storage_storage_saved(fixed.account_id);
}
// パーティ作成可否
static
-void intif_parse_PartyCreated(Session *s)
+void intif_parse_PartyCreated(Session *, const Packet_Fixed<0x3820>& fixed)
{
if (battle_config.etc_log)
- PRINTF("intif: party created\n");
- int account_id = RFIFOL(s, 2);
- int fail = RFIFOB(s, 6);
- int party_id = RFIFOL(s, 7);
- PartyName name = stringish<PartyName>(RFIFO_STRING<24>(s, 11));
+ PRINTF("intif: party created\n"_fmt);
+ AccountId account_id = fixed.account_id;
+ int fail = fixed.error;
+ PartyId party_id = fixed.party_id;
+ PartyName name = fixed.party_name;
party_created(account_id, fail, party_id, name);
}
// パーティ情報
static
-void intif_parse_PartyInfo(Session *s)
+void intif_parse_PartyInfo(Session *, const Packet_Head<0x3821>& head, bool has_opt, const Packet_Option<0x3821>& option)
{
- if (RFIFOW(s, 2) == 8)
+ if (!has_opt)
{
if (battle_config.error_log)
- PRINTF("intif: party noinfo %d\n", RFIFOL(s, 4));
- party_recv_noinfo(RFIFOL(s, 4));
+ PRINTF("intif: party noinfo %d\n"_fmt, head.party_id);
+ party_recv_noinfo(head.party_id);
return;
}
-// PRINTF("intif: party info %d\n",RFIFOL(fd,4));
- if (RFIFOW(s, 2) != sizeof(struct party) + 4)
- {
- if (battle_config.error_log)
- PRINTF("intif: party info : data size error %d %d %zu\n",
- RFIFOL(s, 4), RFIFOW(s, 2),
- sizeof(struct party) + 4);
- }
- party p {};
- RFIFO_STRUCT(s, 4, p);
- party_recv_info(&p);
+ PartyId pi = head.party_id;
+ PartyMost pm = option.party_most;
+ PartyPair pp;
+ pp.party_id = pi;
+ pp.party_most = &pm;
+ party_recv_info(pp);
}
// パーティ追加通知
static
-void intif_parse_PartyMemberAdded(Session *s)
+void intif_parse_PartyMemberAdded(Session *, const Packet_Fixed<0x3822>& fixed)
{
if (battle_config.etc_log)
- PRINTF("intif: party member added %d %d %d\n", RFIFOL(s, 2),
- RFIFOL(s, 6), RFIFOB(s, 10));
- party_member_added(RFIFOL(s, 2), RFIFOL(s, 6), RFIFOB(s, 10));
+ PRINTF("intif: party member added %d %d %d\n"_fmt, fixed.party_id,
+ fixed.account_id, fixed.flag);
+ party_member_added(fixed.party_id, fixed.account_id, fixed.flag);
}
// パーティ設定変更通知
static
-void intif_parse_PartyOptionChanged(Session *s)
+void intif_parse_PartyOptionChanged(Session *, const Packet_Fixed<0x3823>& fixed)
{
- party_optionchanged(RFIFOL(s, 2), RFIFOL(s, 6), RFIFOW(s, 10),
- RFIFOW(s, 12), RFIFOB(s, 14));
+ party_optionchanged(fixed.party_id, fixed.account_id, fixed.exp,
+ fixed.item, fixed.flag);
}
// パーティ脱退通知
static
-void intif_parse_PartyMemberLeaved(Session *s)
+void intif_parse_PartyMemberLeaved(Session *, const Packet_Fixed<0x3824>& fixed)
{
- int party_id = RFIFOL(s, 2);
- int account_id = RFIFOL(s, 6);
- CharName name = stringish<CharName>(RFIFO_STRING<24>(s, 10));
+ PartyId party_id = fixed.party_id;
+ AccountId account_id = fixed.account_id;
+ CharName name = fixed.char_name;
if (battle_config.etc_log)
- PRINTF("intif: party member leaved %d %d %s\n",
+ PRINTF("intif: party member leaved %d %d %s\n"_fmt,
party_id, account_id, name);
party_member_leaved(party_id, account_id, name);
}
// パーティ解散通知
static
-void intif_parse_PartyBroken(Session *s)
+void intif_parse_PartyBroken(Session *, const Packet_Fixed<0x3826>& fixed)
{
- party_broken(RFIFOL(s, 2));
+ party_broken(fixed.party_id);
}
// パーティ移動通知
static
-void intif_parse_PartyMove(Session *s)
+void intif_parse_PartyMove(Session *, const Packet_Fixed<0x3825>& fixed)
{
- int party_id = RFIFOL(s, 2);
- int account_id = RFIFOL(s, 6);
- MapName map = stringish<MapName>(RFIFO_STRING<16>(s, 10));
- uint8_t online = RFIFOB(s, 26);
- uint16_t lv = RFIFOW(s, 27);
+ PartyId party_id = fixed.party_id;
+ AccountId account_id = fixed.account_id;
+ MapName map = fixed.map_name;
+ uint8_t online = fixed.online;
+ uint16_t lv = fixed.level;
party_recv_movemap(party_id, account_id, map, online, lv);
}
// パーティメッセージ
static
-void intif_parse_PartyMessage(Session *s)
+void intif_parse_PartyMessage(Session *, const Packet_Head<0x3827>& head, AString& buf)
{
- 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(head.party_id, head.account_id, buf);
}
//-----------------------------------------------------------------
// inter serverからの通信
// エラーがあれば0(false)を返すこと
// パケットが処理できれば1,パケット長が足りなければ2を返すこと
-int intif_parse(Session *s)
-{
- int packet_len;
- int cmd = RFIFOW(s, 0);
- // パケットのID確認
- if (cmd < 0x3800
- || cmd >=
- 0x3800 + (sizeof(packet_len_table) / sizeof(packet_len_table[0]))
- || packet_len_table[cmd - 0x3800] == 0)
- {
- return 0;
- }
- // パケットの長さ確認
- packet_len = packet_len_table[cmd - 0x3800];
- if (packet_len == -1)
- {
- if (RFIFOREST(s) < 4)
- return 2;
- packet_len = RFIFOW(s, 2);
- }
-// if(battle_config.etc_log)
-// PRINTF("intif_parse %d %x %d %d\n",fd,cmd,packet_len,RFIFOREST(fd));
- if (RFIFOREST(s) < packet_len)
- {
- return 2;
- }
- // 処理分岐
- switch (cmd)
+RecvResult intif_parse(Session *s, uint16_t packet_id)
+{
+ RecvResult rv;
+
+ switch (packet_id)
{
case 0x3800:
{
- AString mes = RFIFO_STRING(s, 4, packet_len - 4);
- clif_GMmessage(NULL, mes, 0);
- }
+ AString mes;
+ rv = recv_packet_repeatonly<0x3800, 4, 1>(s, mes);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ clif_GMmessage(nullptr, mes, 0);
break;
+ }
case 0x3801:
- intif_parse_WisMessage(s);
+ {
+ Packet_Head<0x3801> head;
+ AString repeat;
+ rv = recv_vpacket<0x3801, 56, 1>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_WisMessage(s, head, repeat);
break;
+ }
case 0x3802:
- intif_parse_WisEnd(s);
+ {
+ Packet_Fixed<0x3802> fixed;
+ rv = recv_fpacket<0x3802, 27>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_WisEnd(s, fixed);
break;
+ }
case 0x3803:
- mapif_parse_WisToGM(s);
+ {
+ Packet_Head<0x3803> head;
+ AString repeat;
+ rv = recv_vpacket<0x3803, 30, 1>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ mapif_parse_WisToGM(s, head, repeat);
break;
+ }
case 0x3804:
- intif_parse_AccountReg(s);
+ {
+ Packet_Head<0x3804> head;
+ std::vector<Packet_Repeat<0x3804>> repeat;
+ rv = recv_vpacket<0x3804, 8, 36>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_AccountReg(s, head, repeat);
break;
+ }
case 0x3810:
- intif_parse_LoadStorage(s);
+ {
+ Packet_Payload<0x3810> payload;
+ rv = recv_ppacket<0x3810>(s, payload);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_LoadStorage(s, payload);
break;
+ }
case 0x3811:
- intif_parse_SaveStorage(s);
+ {
+ Packet_Fixed<0x3811> fixed;
+ rv = recv_fpacket<0x3811, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_SaveStorage(s, fixed);
break;
+ }
case 0x3820:
- intif_parse_PartyCreated(s);
+ {
+ Packet_Fixed<0x3820> fixed;
+ rv = recv_fpacket<0x3820, 35>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyCreated(s, fixed);
break;
+ }
case 0x3821:
- intif_parse_PartyInfo(s);
+ {
+ Packet_Head<0x3821> head;
+ bool has_opt;
+ Packet_Option<0x3821> option;
+ rv = recv_opacket<0x3821, 8, sizeof(NetPacket_Option<0x3821>)>(s, head, &has_opt, option);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyInfo(s, head, has_opt, option);
break;
+ }
case 0x3822:
- intif_parse_PartyMemberAdded(s);
+ {
+ Packet_Fixed<0x3822> fixed;
+ rv = recv_fpacket<0x3822, 11>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyMemberAdded(s, fixed);
break;
+ }
case 0x3823:
- intif_parse_PartyOptionChanged(s);
+ {
+ Packet_Fixed<0x3823> fixed;
+ rv = recv_fpacket<0x3823, 15>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyOptionChanged(s, fixed);
break;
+ }
case 0x3824:
- intif_parse_PartyMemberLeaved(s);
+ {
+ Packet_Fixed<0x3824> fixed;
+ rv = recv_fpacket<0x3824, 34>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyMemberLeaved(s, fixed);
break;
+ }
case 0x3825:
- intif_parse_PartyMove(s);
+ {
+ Packet_Fixed<0x3825> fixed;
+ rv = recv_fpacket<0x3825, 29>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyMove(s, fixed);
break;
+ }
case 0x3826:
- intif_parse_PartyBroken(s);
+ {
+ Packet_Fixed<0x3826> fixed;
+ rv = recv_fpacket<0x3826, 7>(s, fixed);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyBroken(s, fixed);
break;
+ }
case 0x3827:
- intif_parse_PartyMessage(s);
+ {
+ Packet_Head<0x3827> head;
+ AString repeat;
+ rv = recv_vpacket<0x3827, 12, 1>(s, head, repeat);
+ if (rv != RecvResult::Complete)
+ return rv;
+
+ intif_parse_PartyMessage(s, head, repeat);
break;
+ }
default:
- if (battle_config.error_log)
- PRINTF("intif_parse : unknown packet %d %x\n", s,
- RFIFOW(s, 0));
- return 0;
+ return RecvResult::Error;
}
- // パケット読み飛ばし
- RFIFOSKIP(s, packet_len);
- return 1;
+ return rv;
}
+} // namespace tmwa
diff --git a/src/map/intif.hpp b/src/map/intif.hpp
index 80de797..5be61a9 100644
--- a/src/map/intif.hpp
+++ b/src/map/intif.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_INTIF_HPP
-#define TMWA_MAP_INTIF_HPP
+#pragma once
// intif.hpp - Network interface to the internal server.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,33 +20,39 @@
// 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 "../strings/fwd.hpp"
-# include "map.hpp"
+#include "../generic/fwd.hpp"
-int intif_parse(Session *);
+#include "../net/fwd.hpp"
+
+#include "../mmo/fwd.hpp"
+
+
+namespace tmwa
+{
+RecvResult intif_parse(Session *, uint16_t packet_id);
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_send_storage(struct storage *stor);
+void intif_request_storage(AccountId account_id);
+void intif_send_storage(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);
-
-#endif // TMWA_MAP_INTIF_HPP
+void intif_party_message(PartyId party_id, AccountId account_id, XString mes);
+void intif_party_checkconflict(PartyId party_id, AccountId account_id, CharName nick);
+} // namespace tmwa
diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp
index 4ebb52c..50cc5c4 100644
--- a/src/map/itemdb.cpp
+++ b/src/map/itemdb.cpp
@@ -20,29 +20,28 @@
// 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 <cstdlib>
-#include <cstring>
-
-#include "../compat/nullpo.hpp"
+#include <algorithm>
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
#include "../generic/db.hpp"
-#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
#include "../io/read.hpp"
#include "../mmo/config_parse.hpp"
#include "../mmo/extract.hpp"
-#include "../mmo/socket.hpp"
+#include "../mmo/extract_enums.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
static
-Map<int, struct item_data> item_db;
+Map<ItemNameId, struct item_data> item_db;
// Function declarations
@@ -67,7 +66,7 @@ struct item_data *itemdb_searchname(XString str_)
ItemName str = stringish<ItemName>(str_);
if (XString(str) != str_)
return nullptr;
- struct item_data *item = NULL;
+ struct item_data *item = nullptr;
for (auto& pair : item_db)
itemdb_searchname_sub(&pair.second, str, &item);
return item;
@@ -77,7 +76,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 +85,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 +100,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 +109,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 +139,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
@@ -174,7 +158,7 @@ bool itemdb_readdb(ZString filename)
if (!in.is_open())
{
- PRINTF("can't read %s\n", filename);
+ PRINTF("can't read %s\n"_fmt, filename);
return false;
}
@@ -220,7 +204,7 @@ bool itemdb_readdb(ZString filename)
)
)
{
- PRINTF("%s:%d: error: bad item line: %s\n",
+ PRINTF("%s:%d: error: bad item line: %s\n"_fmt,
filename, lines, line);
rv = false;
continue;
@@ -242,8 +226,8 @@ bool itemdb_readdb(ZString filename)
id->value_sell = id->value_buy / 2;
}
- id->use_script = NULL;
- id->equip_script = NULL;
+ id->use_script = nullptr;
+ id->equip_script = nullptr;
if (!tail_part)
continue;
@@ -254,7 +238,7 @@ bool itemdb_readdb(ZString filename)
continue;
id->equip_script = parse_script(tail_part, lines, true);
}
- PRINTF("read %s done (count=%d)\n", filename, ln);
+ PRINTF("read %s done (count=%d)\n"_fmt, filename, ln);
}
return rv;
@@ -281,3 +265,4 @@ void do_final_itemdb(void)
itemdb_final(&pair.second);
item_db.clear();
}
+} // namespace tmwa
diff --git a/src/map/itemdb.hpp b/src/map/itemdb.hpp
index 16802da..25b4dad 100644
--- a/src/map/itemdb.hpp
+++ b/src/map/itemdb.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_ITEMDB_HPP
-#define TMWA_MAP_ITEMDB_HPP
+#pragma once
// itemdb.hpp - Item definitions.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,16 +20,20 @@
// 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"
+#include "../mmo/ids.hpp"
+#include "../mmo/mmo.hpp"
-# include "map.t.hpp"
-# include "script.hpp"
+#include "map.t.hpp"
+#include "script.hpp"
+
+namespace tmwa
+{
struct item_data
{
- int nameid;
+ ItemNameId nameid;
ItemName name, jname;
int value_buy;
int value_sell;
@@ -58,47 +61,47 @@ 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);
void do_final_itemdb(void);
bool itemdb_readdb(ZString filename);
-
-#endif // TMWA_MAP_ITEMDB_HPP
+} // namespace tmwa
diff --git a/src/map/magic-expr-eval.cpp b/src/map/magic-expr-eval.cpp
index 36b69f5..9903600 100644
--- a/src/map/magic-expr-eval.cpp
+++ b/src/map/magic-expr-eval.cpp
@@ -19,3 +19,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../poison.hpp"
+
+
+namespace tmwa
+{
+namespace magic
+{
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-expr-eval.hpp b/src/map/magic-expr-eval.hpp
index 9b9f5f8..4529c04 100644
--- a/src/map/magic-expr-eval.hpp
+++ b/src/map/magic-expr-eval.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAGIC_EXPR_EVAL_HPP
-#define TMWA_MAP_MAGIC_EXPR_EVAL_HPP
+#pragma once
// magic-expr-eval.hpp - Utilities for evaluating magic.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -20,47 +19,33 @@
// 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 "../range/slice.hpp"
+#include "../strings/zstring.hpp"
-# include "../strings/zstring.hpp"
+#include "magic-interpreter.t.hpp"
-# include "magic-interpreter.hpp"
-/* Helper definitions for dealing with functions and operations */
+namespace tmwa
+{
+namespace magic
+{
+// TODO soon kill this unlike I killed VAR
+#define ARGINT(x) args[x].get_if<ValInt>()->v_int
+#define ARGDIR(x) args[x].get_if<ValDir>()->v_dir
+#define ARGSTR(x) ZString(args[x].get_if<ValString>()->v_string)
+#define ARGENTITY(x) args[x].get_if<ValEntityPtr>()->v_entity
+#define ARGLOCATION(x) args[x].get_if<ValLocation>()->v_location
+#define ARGAREA(x) args[x].get_if<ValArea>()->v_area
+#define ARGSPELL(x) args[x].get_if<ValSpell>()->v_spell
+#define ARGINVOCATION(x) args[x].get_if<ValInvocationPtr>()->v_invocation
-int magic_signature_check(ZString opname, ZString funname, ZString signature,
- Slice<val_t> args, int line, int column);
+#define ENTITY_TYPE(x) ARGENTITY(x)->bl_type
-void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height,
- area_t& area);
+#define ARGPC(x) (ARGENTITY(x)->is_player())
+#define ARGNPC(x) (ARGENTITY(x)->is_npc())
+#define ARGMOB(x) (ARGENTITY(x)->is_mob())
-# define ARGINT(x) args[x].v.v_int
-# define ARGDIR(x) args[x].v.v_dir
-# define ARGSTR(x) ZString(args[x].v.v_string)
-# define ARGENTITY(x) args[x].v.v_entity
-# define ARGLOCATION(x) args[x].v.v_location
-# define ARGAREA(x) args[x].v.v_area
-# define ARGSPELL(x) args[x].v.v_spell
-# define ARGINVOCATION(x) args[x].v.v_invocation
-
-# define RESULTINT result->v.v_int
-# define RESULTDIR result->v.v_dir
-# define RESULTSTR result->v.v_string
-# define RESULTENTITY result->v.v_entity
-# define RESULTLOCATION result->v.v_location
-# define RESULTAREA result->v.v_area
-# define RESULTSPELL result->v.v_spell
-# define RESULTINVOCATION result->v.v_invocation
-
-# define ARG_TYPE(x) args[x].ty
-# define ENTITY_TYPE(x) ARGENTITY(x)->bl_type
-
-# define ARGPC(x) (ARGENTITY(x)->is_player())
-# define ARGNPC(x) (ARGENTITY(x)->is_npc())
-# define ARGMOB(x) (ARGENTITY(x)->is_mob())
-
-# define ARG_MAY_BE_AREA(x) (ARG_TYPE(x) == TYPE::AREA || ARG_TYPE(x) == TYPE::LOCATION)
-
-#endif // TMWA_MAP_MAGIC_EXPR_EVAL_HPP
+#define ARG_MAY_BE_AREA(x) (args[x].is<ValArea>() || args[x].is<ValArea>())
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index 42ff3a7..306126e 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -1,6 +1,4 @@
-#include "magic-expr-eval.hpp"
#include "magic-expr.hpp"
-#include "magic-interpreter-aux.hpp"
// magic-expr.cpp - Pure functions for the old magic backend.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -22,40 +20,49 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cassert>
-#include <cmath>
-#include "../compat/alg.hpp"
+#include <algorithm>
#include "../strings/mstring.hpp"
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/vstring.hpp"
+#include "../strings/literal.hpp"
+#include "../generic/dumb_ptr.hpp"
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "battle.hpp"
+#include "itemdb.hpp"
+#include "magic-expr-eval.hpp"
+#include "magic-interpreter.hpp"
+#include "magic-interpreter-base.hpp"
#include "npc.hpp"
#include "pc.hpp"
-#include "itemdb.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
+namespace magic
+{
static
void free_area(dumb_ptr<area_t> area)
{
if (!area)
return;
- switch (area->ty)
+ MATCH (*area)
{
- case AREA::UNION:
- free_area(area->a.a_union[0]);
- free_area(area->a.a_union[1]);
- break;
- default:
- break;
+ CASE (const AreaUnion&, a)
+ {
+ free_area(a.a_union[0]);
+ free_area(a.a_union[1]);
+ }
}
area.delete_();
@@ -64,52 +71,108 @@ void free_area(dumb_ptr<area_t> area)
static
dumb_ptr<area_t> dup_area(dumb_ptr<area_t> area)
{
- dumb_ptr<area_t> retval = dumb_ptr<area_t>::make();
- *retval = *area;
-
- switch (area->ty)
+ MATCH (*area)
{
- case AREA::UNION:
- retval->a.a_union[0] = dup_area(retval->a.a_union[0]);
- retval->a.a_union[1] = dup_area(retval->a.a_union[1]);
- break;
- default:
- break;
+ CASE (const location_t&, loc)
+ {
+ return dumb_ptr<area_t>::make(loc, area->size);
+ }
+ CASE (const AreaUnion&, a)
+ {
+ AreaUnion u;
+ u.a_union[0] = dup_area(a.a_union[0]);
+ u.a_union[1] = dup_area(a.a_union[1]);
+ return dumb_ptr<area_t>::make(u, area->size);
+ }
+ CASE (const AreaRect&, rect)
+ {
+ return dumb_ptr<area_t>::make(rect, area->size);
+ }
+ CASE (const AreaBar&, bar)
+ {
+ return dumb_ptr<area_t>::make(bar, area->size);
+ }
}
- return retval;
+ abort();
}
-void magic_copy_var(val_t *dest, val_t *src)
+void magic_copy_var(val_t *dest, const val_t *src)
{
- *dest = *src;
-
- switch (dest->ty)
+ MATCH (*src)
{
- case TYPE::STRING:
- dest->v.v_string = dest->v.v_string.dup();
- break;
- case TYPE::AREA:
- dest->v.v_area = dup_area(dest->v.v_area);
- break;
+ // mumble mumble not a public API ...
default:
- break;
+ {
+ abort();
+ }
+ CASE (const ValUndef&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValInt&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValDir&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValString&, s)
+ {
+ *dest = ValString{s.v_string.dup()};
+ }
+ CASE (const ValEntityInt&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValEntityPtr&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValLocation&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValArea&, s)
+ {
+ *dest = ValArea{dup_area(s.v_area)};
+ }
+ CASE (const ValSpell&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValInvocationInt&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValInvocationPtr&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValFail&, s)
+ {
+ *dest = s;
+ }
+ CASE (const ValNegative1&, s)
+ {
+ *dest = s;
+ }
}
-
}
void magic_clear_var(val_t *v)
{
- switch (v->ty)
+ MATCH (*v)
{
- case TYPE::STRING:
- v->v.v_string.delete_();
- break;
- case TYPE::AREA:
- free_area(v->v.v_area);
- break;
- default:
- break;
+ CASE (ValString&, s)
+ {
+ s.v_string.delete_();
+ }
+ CASE (const ValArea&, a)
+ {
+ free_area(a.v_area);
+ }
}
}
@@ -125,113 +188,110 @@ AString show_entity(dumb_ptr<block_list> entity)
case BL::MOB:
return entity->is_mob()->name;
case BL::ITEM:
- assert (0 && "There is no way this code did what it was supposed to do!");
+ assert (0 && "There is no way this code did what it was supposed to do!"_s);
/* Sorry about this one... */
- // WTF? item_data is a struct item, not a struct item_data
+ // WTF? item_data is a Item, not a struct item_data
// return ((struct item_data *) (&entity->is_item()->item_data))->name;
abort();
case BL::SPELL:
- return {"%invocation(ERROR:this-should-not-be-an-entity)"};
+ return "%invocation(ERROR:this-should-not-be-an-entity)"_s;
default:
- return {"%unknown-entity"};
+ return "%unknown-entity"_s;
}
}
static
-void stringify(val_t *v, int within_op)
+void stringify(val_t *v)
{
- static earray<ZString, DIR, DIR::COUNT> dirs //=
+ static earray<LString, DIR, DIR::COUNT> dirs //=
{{
- {"south"}, {"south-west"},
- {"west"}, {"north-west"},
- {"north"}, {"north-east"},
- {"east"}, {"south-east"},
+ "south"_s, "south-west"_s,
+ "west"_s, "north-west"_s,
+ "north"_s, "north-east"_s,
+ "east"_s, "south-east"_s,
}};
AString buf;
- switch (v->ty)
+ MATCH (*v)
{
- case TYPE::UNDEF:
- buf = "UNDEF";
- break;
-
- case TYPE::INT:
- buf = STRPRINTF("%i", v->v.v_int);
- break;
-
- case TYPE::STRING:
+ default:
+ {
+ abort();
+ }
+ CASE (const ValUndef&, x)
+ {
+ (void)x;
+ buf = "UNDEF"_s;
+ }
+ CASE (const ValInt&, x)
+ {
+ buf = STRPRINTF("%i"_fmt, x.v_int);
+ }
+ CASE (const ValString&, x)
+ {
+ (void)x;
return;
-
- case TYPE::DIR:
- buf = dirs[v->v.v_dir];
- break;
-
- case TYPE::ENTITY:
- buf = show_entity(v->v.v_entity);
- break;
-
- case TYPE::LOCATION:
- buf = STRPRINTF("<\"%s\", %d, %d>",
- v->v.v_location.m->name_,
- v->v.v_location.x,
- v->v.v_location.y);
- break;
-
- case TYPE::AREA:
- buf = "%area";
- free_area(v->v.v_area);
- break;
-
- case TYPE::SPELL:
- buf = v->v.v_spell->name;
+ }
+ CASE (const ValDir&, x)
+ {
+ buf = dirs[x.v_dir];
+ }
+ CASE (const ValEntityPtr&, x)
+ {
+ buf = show_entity(x.v_entity);
+ }
+ CASE (const ValLocation&, x)
+ {
+ buf = STRPRINTF("<\"%s\", %d, %d>"_fmt,
+ x.v_location.m->name_,
+ x.v_location.x,
+ x.v_location.y);
+ }
+ CASE (const ValArea&, x)
+ {
+ buf = "%area"_s;
+ free_area(x.v_area);
+ }
+ CASE (const ValSpell&, x)
+ {
+ buf = x.v_spell->name;
break;
-
- case TYPE::INVOCATION:
+ }
+ CASE (const ValInvocationInt&, x)
{
- dumb_ptr<invocation> invocation_ = within_op
- ? v->v.v_invocation
- : map_id2bl(v->v.v_int)->is_spell();
+ dumb_ptr<invocation> invocation_ =
+ map_id2bl(x.v_iid)->is_spell();
+ buf = invocation_->spell->name;
+ }
+ CASE (const ValInvocationPtr&, x)
+ {
+ dumb_ptr<invocation> invocation_ =
+ x.v_invocation;
buf = invocation_->spell->name;
}
- break;
-
- default:
- FPRINTF(stderr, "[magic] INTERNAL ERROR: Cannot stringify %d\n",
- v->ty);
- return;
}
- v->v.v_string = dumb_string::copys(buf);
- v->ty = TYPE::STRING;
+ *v = ValString{dumb_string::copys(buf)};
}
static
void intify(val_t *v)
{
- if (v->ty == TYPE::INT)
+ if (v->is<ValInt>())
return;
magic_clear_var(v);
- v->ty = TYPE::INT;
- v->v.v_int = 1;
-}
-
-static
-dumb_ptr<area_t> area_new(AREA ty)
-{
- auto retval = dumb_ptr<area_t>::make();
- retval->ty = ty;
- return retval;
+ *v = ValInt{1};
}
static
dumb_ptr<area_t> area_union(dumb_ptr<area_t> area, dumb_ptr<area_t> other_area)
{
- dumb_ptr<area_t> retval = area_new(AREA::UNION);
- retval->a.a_union[0] = area;
- retval->a.a_union[1] = other_area;
- retval->size = area->size + other_area->size; /* Assume no overlap */
- return retval;
+ AreaUnion a;
+ a.a_union[0] = area;
+ a.a_union[1] = other_area;
+ int size = area->size + other_area->size; /* Assume no overlap */
+ return dumb_ptr<area_t>::make(a, size);
}
/**
@@ -240,41 +300,43 @@ dumb_ptr<area_t> area_union(dumb_ptr<area_t> area, dumb_ptr<area_t> other_area)
static
void make_area(val_t *v)
{
- if (v->ty == TYPE::LOCATION)
+ if (ValLocation *l = v->get_if<ValLocation>())
{
- auto a = dumb_ptr<area_t>::make();
- v->ty = TYPE::AREA;
- a->ty = AREA::LOCATION;
- a->a.a_loc = v->v.v_location;
- v->v.v_area = a;
+ auto a = dumb_ptr<area_t>::make(l->v_location, 1);
+ *v = ValArea{a};
}
}
static
void make_location(val_t *v)
{
- if (v->ty == TYPE::AREA && v->v.v_area->ty == AREA::LOCATION)
+ if (ValArea *a = v->get_if<ValArea>())
{
- location_t location = v->v.v_area->a.a_loc;
- free_area(v->v.v_area);
- v->ty = TYPE::LOCATION;
- v->v.v_location = location;
+ MATCH (*a->v_area)
+ {
+ CASE (const location_t&, location)
+ {
+ free_area(a->v_area);
+ *v = ValLocation{location};
+ }
+ }
}
}
static
void make_spell(val_t *v)
{
- if (v->ty == TYPE::INVOCATION)
+ assert(!v->is<ValInvocationInt>());
+ if (ValInvocationPtr *p = v->get_if<ValInvocationPtr>())
{
- dumb_ptr<invocation> invoc = v->v.v_invocation;
- //invoc = (dumb_ptr<invocation>) map_id2bl(v->v.v_int);
+ dumb_ptr<invocation> invoc = p->v_invocation;
if (!invoc)
- v->ty = TYPE::FAIL;
+ {
+ *v = ValFail{};
+ }
else
{
- v->ty = TYPE::SPELL;
- v->v.v_spell = invoc->spell;
+ *v = ValSpell{invoc->spell};
}
}
}
@@ -282,34 +344,31 @@ void make_spell(val_t *v)
static
int fun_add(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- if (ARG_TYPE(0) == TYPE::INT && ARG_TYPE(1) == TYPE::INT)
+ if (args[0].is<ValInt>() && args[1].is<ValInt>())
{
/* Integer addition */
- RESULTINT = ARGINT(0) + ARGINT(1);
- result->ty = TYPE::INT;
+ *result = ValInt{ARGINT(0) + ARGINT(1)};
}
else if (ARG_MAY_BE_AREA(0) && ARG_MAY_BE_AREA(1))
{
/* Area union */
make_area(&args[0]);
make_area(&args[1]);
- RESULTAREA = area_union(ARGAREA(0), ARGAREA(1));
- ARGAREA(0) = NULL;
- ARGAREA(1) = NULL;
- result->ty = TYPE::AREA;
+ *result = ValArea{area_union(ARGAREA(0), ARGAREA(1))};
+ ARGAREA(0) = nullptr; args[0] = ValUndef{};
+ ARGAREA(1) = nullptr; args[1] = ValUndef{};
}
else
{
/* Anything else -> string concatenation */
- stringify(&args[0], 1);
- stringify(&args[1], 1);
+ stringify(&args[0]);
+ stringify(&args[1]);
/* Yes, we could speed this up. */
// ugh
MString m;
m += ARGSTR(0);
m += ARGSTR(1);
- RESULTSTR = dumb_string::copys(AString(m));
- result->ty = TYPE::STRING;
+ *result = ValString{dumb_string::copys(AString(m))};
}
return 0;
}
@@ -317,14 +376,14 @@ int fun_add(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
static
int fun_sub(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) - ARGINT(1);
+ *result = ValInt{ARGINT(0) - ARGINT(1)};
return 0;
}
static
int fun_mul(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) * ARGINT(1);
+ *result = ValInt{ARGINT(0) * ARGINT(1)};
return 0;
}
@@ -333,7 +392,7 @@ int fun_div(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (!ARGINT(1))
return 1; /* division by zero */
- RESULTINT = ARGINT(0) / ARGINT(1);
+ *result = ValInt{ARGINT(0) / ARGINT(1)};
return 0;
}
@@ -342,52 +401,52 @@ int fun_mod(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (!ARGINT(1))
return 1; /* division by zero */
- RESULTINT = ARGINT(0) % ARGINT(1);
+ *result = ValInt{ARGINT(0) % ARGINT(1)};
return 0;
}
static
int fun_or(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) || ARGINT(1);
+ *result = ValInt{ARGINT(0) || ARGINT(1)};
return 0;
}
static
int fun_and(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) && ARGINT(1);
+ *result = ValInt{ARGINT(0) && ARGINT(1)};
return 0;
}
static
int fun_not(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = !ARGINT(0);
+ *result = ValInt{!ARGINT(0)};
return 0;
}
static
int fun_neg(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ~ARGINT(0);
+ *result = ValInt{~ARGINT(0)};
return 0;
}
static
int fun_gte(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- if (ARG_TYPE(0) == TYPE::STRING || ARG_TYPE(1) == TYPE::STRING)
+ if (args[0].is<ValString>() || args[1].is<ValString>())
{
- stringify(&args[0], 1);
- stringify(&args[1], 1);
- RESULTINT = ARGSTR(0) >= ARGSTR(1);
+ stringify(&args[0]);
+ stringify(&args[1]);
+ *result = ValInt{ARGSTR(0) >= ARGSTR(1)};
}
else
{
intify(&args[0]);
intify(&args[1]);
- RESULTINT = ARGINT(0) >= ARGINT(1);
+ *result = ValInt{ARGINT(0) >= ARGINT(1)};
}
return 0;
}
@@ -396,24 +455,24 @@ static
int fun_lt(dumb_ptr<env_t> env, val_t *result, Slice<val_t> args)
{
fun_gte(env, result, args);
- RESULTINT = !RESULTINT;
+ result->get_if<ValInt>()->v_int ^= 1;
return 0;
}
static
int fun_gt(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- if (ARG_TYPE(0) == TYPE::STRING || ARG_TYPE(1) == TYPE::STRING)
+ if (args[0].is<ValString>() || args[1].is<ValString>())
{
- stringify(&args[0], 1);
- stringify(&args[1], 1);
- RESULTINT = ARGSTR(0) > ARGSTR(1);
+ stringify(&args[0]);
+ stringify(&args[1]);
+ *result = ValInt{ARGSTR(0) > ARGSTR(1)};
}
else
{
intify(&args[0]);
intify(&args[1]);
- RESULTINT = ARGINT(0) > ARGINT(1);
+ *result = ValInt{ARGINT(0) > ARGINT(1)};
}
return 0;
}
@@ -422,38 +481,38 @@ static
int fun_lte(dumb_ptr<env_t> env, val_t *result, Slice<val_t> args)
{
fun_gt(env, result, args);
- RESULTINT = !RESULTINT;
+ result->get_if<ValInt>()->v_int ^= 1;
return 0;
}
static
int fun_eq(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- if (ARG_TYPE(0) == TYPE::STRING || ARG_TYPE(1) == TYPE::STRING)
+ if (args[0].is<ValString>() || args[1].is<ValString>())
{
- stringify(&args[0], 1);
- stringify(&args[1], 1);
- RESULTINT = ARGSTR(0) == ARGSTR(1);
+ stringify(&args[0]);
+ stringify(&args[1]);
+ *result = ValInt{ARGSTR(0) == ARGSTR(1)};
}
- else if (ARG_TYPE(0) == TYPE::DIR && ARG_TYPE(1) == TYPE::DIR)
- RESULTINT = ARGDIR(0) == ARGDIR(1);
- else if (ARG_TYPE(0) == TYPE::ENTITY && ARG_TYPE(1) == TYPE::ENTITY)
- RESULTINT = ARGENTITY(0) == ARGENTITY(1);
- else if (ARG_TYPE(0) == TYPE::LOCATION && ARG_TYPE(1) == TYPE::LOCATION)
- RESULTINT = (ARGLOCATION(0).x == ARGLOCATION(1).x
+ else if (args[0].is<ValDir>() && args[1].is<ValDir>())
+ *result = ValInt{ARGDIR(0) == ARGDIR(1)};
+ else if (args[0].is<ValEntityPtr>() && args[1].is<ValEntityPtr>())
+ *result = ValInt{ARGENTITY(0) == ARGENTITY(1)};
+ else if (args[0].is<ValLocation>() && args[1].is<ValLocation>())
+ *result = ValInt{(ARGLOCATION(0).x == ARGLOCATION(1).x
&& ARGLOCATION(0).y == ARGLOCATION(1).y
- && ARGLOCATION(0).m == ARGLOCATION(1).m);
- else if (ARG_TYPE(0) == TYPE::AREA && ARG_TYPE(1) == TYPE::AREA)
- RESULTINT = ARGAREA(0) == ARGAREA(1); /* Probably not that great an idea... */
- else if (ARG_TYPE(0) == TYPE::SPELL && ARG_TYPE(1) == TYPE::SPELL)
- RESULTINT = ARGSPELL(0) == ARGSPELL(1);
- else if (ARG_TYPE(0) == TYPE::INVOCATION && ARG_TYPE(1) == TYPE::INVOCATION)
- RESULTINT = ARGINVOCATION(0) == ARGINVOCATION(1);
+ && ARGLOCATION(0).m == ARGLOCATION(1).m)};
+ else if (args[0].is<ValArea>() && args[1].is<ValArea>())
+ *result = ValInt{ARGAREA(0) == ARGAREA(1)}; /* Probably not that great an idea... */
+ else if (args[0].is<ValSpell>() && args[1].is<ValSpell>())
+ *result = ValInt{ARGSPELL(0) == ARGSPELL(1)};
+ else if (args[0].is<ValInvocationPtr>() && args[1].is<ValInvocationPtr>())
+ *result = ValInt{ARGINVOCATION(0) == ARGINVOCATION(1)};
else
{
intify(&args[0]);
intify(&args[1]);
- RESULTINT = ARGINT(0) == ARGINT(1);
+ *result = ValInt{ARGINT(0) == ARGINT(1)};
}
return 0;
}
@@ -462,56 +521,56 @@ static
int fun_ne(dumb_ptr<env_t> env, val_t *result, Slice<val_t> args)
{
fun_eq(env, result, args);
- RESULTINT = !RESULTINT;
+ result->get_if<ValInt>()->v_int ^= 1;
return 0;
}
static
int fun_bitand(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) & ARGINT(1);
+ *result = ValInt{ARGINT(0) & ARGINT(1)};
return 0;
}
static
int fun_bitor(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) | ARGINT(1);
+ *result = ValInt{ARGINT(0) | ARGINT(1)};
return 0;
}
static
int fun_bitxor(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) ^ ARGINT(1);
+ *result = ValInt{ARGINT(0) ^ ARGINT(1)};
return 0;
}
static
int fun_bitshl(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) << ARGINT(1);
+ *result = ValInt{ARGINT(0) << ARGINT(1)};
return 0;
}
static
int fun_bitshr(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGINT(0) >> ARGINT(1);
+ *result = ValInt{ARGINT(0) >> ARGINT(1)};
return 0;
}
static
int fun_max(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = max(ARGINT(0), ARGINT(1));
+ *result = ValInt{std::max(ARGINT(0), ARGINT(1))};
return 0;
}
static
int fun_min(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = min(ARGINT(0), ARGINT(1));
+ *result = ValInt{std::min(ARGINT(0), ARGINT(1))};
return 0;
}
@@ -528,37 +587,38 @@ int fun_if_then_else(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height,
area_t& area_)
{
- area_t *area = &area_; // diff hack
- switch (area->ty)
+ MATCH (area_)
{
- case AREA::UNION:
- break;
-
- case AREA::LOCATION:
- *m = area->a.a_loc.m;
- *x = area->a.a_loc.x;
- *y = area->a.a_loc.y;
+ CASE (const AreaUnion&, a)
+ {
+ (void)a;
+ abort();
+ }
+ CASE (const location_t&, a_loc)
+ {
+ *m = a_loc.m;
+ *x = a_loc.x;
+ *y = a_loc.y;
*width = 1;
*height = 1;
- break;
-
- case AREA::RECT:
- *m = area->a.a_rect.loc.m;
- *x = area->a.a_rect.loc.x;
- *y = area->a.a_rect.loc.y;
- *width = area->a.a_rect.width;
- *height = area->a.a_rect.height;
- break;
-
- case AREA::BAR:
+ }
+ CASE (const AreaRect&, a_rect)
+ {
+ *m = a_rect.loc.m;
+ *x = a_rect.loc.x;
+ *y = a_rect.loc.y;
+ *width = a_rect.width;
+ *height = a_rect.height;
+ }
+ CASE (const AreaBar&, a_bar)
{
- int tx = area->a.a_bar.loc.x;
- int ty = area->a.a_bar.loc.y;
- int twidth = area->a.a_bar.width;
- int tdepth = area->a.a_bar.width;
- *m = area->a.a_bar.loc.m;
+ int tx = a_bar.loc.x;
+ int ty = a_bar.loc.y;
+ int twidth = a_bar.width;
+ int tdepth = a_bar.width;
+ *m = a_bar.loc.m;
- switch (area->a.a_bar.dir)
+ switch (a_bar.dir)
{
case DIR::S:
*x = tx - twidth;
@@ -590,27 +650,50 @@ void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height,
default:
FPRINTF(stderr,
- "Error: Trying to compute area of NE/SE/NW/SW-facing bar");
+ "Error: Trying to compute area of NE/SE/NW/SW-facing bar"_fmt);
*x = tx;
*y = ty;
*width = *height = 1;
}
- break;
}
}
}
int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area)
{
- switch (area->ty)
+ MATCH (*area)
{
- case AREA::UNION:
- return magic_location_in_area(m, x, y, area->a.a_union[0])
- || magic_location_in_area(m, x, y, area->a.a_union[1]);
- case AREA::LOCATION:
- case AREA::RECT:
- case AREA::BAR:
+ CASE (const AreaUnion&, a)
+ {
+ return magic_location_in_area(m, x, y, a.a_union[0])
+ || magic_location_in_area(m, x, y, a.a_union[1]);
+ }
+ CASE (const location_t&, a_loc)
{
+ (void)a_loc;
+ // TODO this can be simplified
+ map_local *am;
+ int ax, ay, awidth, aheight;
+ magic_area_rect(&am, &ax, &ay, &awidth, &aheight, *area);
+ return (am == m
+ && (x >= ax) && (y >= ay)
+ && (x < ax + awidth) && (y < ay + aheight));
+ }
+ CASE (const AreaRect&, a_rect)
+ {
+ (void)a_rect;
+ // TODO this is too complicated
+ map_local *am;
+ int ax, ay, awidth, aheight;
+ magic_area_rect(&am, &ax, &ay, &awidth, &aheight, *area);
+ return (am == m
+ && (x >= ax) && (y >= ay)
+ && (x < ax + awidth) && (y < ay + aheight));
+ }
+ CASE (const AreaBar&, a_bar)
+ {
+ (void)a_bar;
+ // TODO this is wrong
map_local *am;
int ax, ay, awidth, aheight;
magic_area_rect(&am, &ax, &ay, &awidth, &aheight, *area);
@@ -618,18 +701,16 @@ int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area)
&& (x >= ax) && (y >= ay)
&& (x < ax + awidth) && (y < ay + aheight));
}
- default:
- FPRINTF(stderr, "INTERNAL ERROR: Invalid area\n");
- return 0;
}
+ abort();
}
static
int fun_is_in(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = magic_location_in_area(ARGLOCATION(0).m,
+ *result = ValInt{magic_location_in_area(ARGLOCATION(0).m,
ARGLOCATION(0).x,
- ARGLOCATION(0).y, ARGAREA(1));
+ ARGLOCATION(0).y, ARGAREA(1))};
return 0;
}
@@ -638,15 +719,16 @@ int fun_skill(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (ENTITY_TYPE(0) != BL::PC
// don't convert to enum until after the range check
+ // (actually it would be okay, I checked)
|| ARGINT(1) < 0
- || ARGINT(1) >= uint16_t(MAX_SKILL))
+ || ARGINT(1) >= static_cast<uint16_t>(MAX_SKILL))
{
- RESULTINT = 0;
+ *result = ValInt{0};
}
else
{
SkillID id = static_cast<SkillID>(ARGINT(1));
- RESULTINT = ARGPC(0)->status.skill[id].lv;
+ *result = ValInt{ARGPC(0)->status.skill[id].lv};
}
return 0;
}
@@ -654,7 +736,7 @@ int fun_skill(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
static
int fun_his_shroud(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = (ENTITY_TYPE(0) == BL::PC && ARGPC(0)->state.shroud_active);
+ *result = ValInt{(ENTITY_TYPE(0) == BL::PC && ARGPC(0)->state.shroud_active)};
return 0;
}
@@ -662,7 +744,7 @@ int fun_his_shroud(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
static \
int fun_get_##name(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) \
{ \
- RESULTINT = battle_get_##name(ARGENTITY(0)); \
+ *result = ValInt{battle_get_##name(ARGENTITY(0))}; \
return 0; \
}
@@ -680,7 +762,7 @@ BATTLE_GETTER(max_hp)
static
int fun_get_dir(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTDIR = battle_get_dir(ARGENTITY(0));
+ *result = ValDir{battle_get_dir(ARGENTITY(0))};
return 0;
}
@@ -689,9 +771,9 @@ static \
int fun_get_##name(dumb_ptr<env_t>, val_t *result, Slice<val_t> args) \
{ \
if (ENTITY_TYPE(0) == BL::PC) \
- RESULTINT = ARGPC(0)->status.name; \
+ *result = ValInt{ARGPC(0)->status.name}; \
else \
- RESULTINT = 0; \
+ *result = ValInt{0}; \
return 0; \
}
@@ -701,19 +783,19 @@ MMO_GETTER(max_sp)
static
int fun_name_of(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- if (ARG_TYPE(0) == TYPE::ENTITY)
+ if (args[0].is<ValEntityPtr>())
{
- RESULTSTR = dumb_string::copys(show_entity(ARGENTITY(0)));
+ *result = ValString{dumb_string::copys(show_entity(ARGENTITY(0)))};
return 0;
}
- else if (ARG_TYPE(0) == TYPE::SPELL)
+ else if (args[0].is<ValSpell>())
{
- RESULTSTR = dumb_string::copys(ARGSPELL(0)->name);
+ *result = ValString{dumb_string::copys(ARGSPELL(0)->name)};
return 0;
}
- else if (ARG_TYPE(0) == TYPE::INVOCATION)
+ else if (args[0].is<ValInvocationPtr>())
{
- RESULTSTR = dumb_string::copys(ARGINVOCATION(0)->spell->name);
+ *result = ValString{dumb_string::copys(ARGINVOCATION(0)->spell->name)};
return 0;
}
return 1;
@@ -725,7 +807,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;
+ *result = ValInt{unwrap<Species>(ARGMOB(0)->mob_class)};
return 0;
}
@@ -748,7 +830,9 @@ void COPY_LOCATION(location_t& dest, block_list& src)
static
int fun_location(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- COPY_LOCATION(RESULTLOCATION, *(ARGENTITY(0)));
+ location_t loc;
+ COPY_LOCATION(loc, *(ARGENTITY(0)));
+ *result = ValLocation{loc};
return 0;
}
@@ -760,13 +844,13 @@ int fun_random(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
delta = -delta;
if (delta == 0)
{
- RESULTINT = 0;
+ *result = ValInt{0};
return 0;
}
- RESULTINT = random_::to(delta);
+ *result = ValInt{random_::to(delta)};
if (ARGINT(0) < 0)
- RESULTINT = -RESULTINT;
+ result->get_if<ValInt>()->v_int *= -1;
return 0;
}
@@ -774,28 +858,28 @@ static
int fun_random_dir(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (ARGINT(0))
- RESULTDIR = random_::choice({DIR::S, DIR::SW, DIR::W, DIR::NW, DIR::N, DIR::NE, DIR::E, DIR::SE});
+ *result = ValDir{random_::choice({DIR::S, DIR::SW, DIR::W, DIR::NW, DIR::N, DIR::NE, DIR::E, DIR::SE})};
else
- RESULTDIR = random_::choice({DIR::S, DIR::W, DIR::N, DIR::E});
+ *result = ValDir{random_::choice({DIR::S, DIR::W, DIR::N, DIR::E})};
return 0;
}
static
int fun_hash_entity(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARGENTITY(0)->bl_id;
+ *result = ValInt{static_cast<int32_t>(unwrap<BlockId>(ARGENTITY(0)->bl_id))};
return 0;
}
-int // ret -1: not a string, ret 1: no such item, ret 0: OK
-magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable)
+// ret -1: not a string, ret 1: no such item, ret 0: OK
+int magic_find_item(Slice<val_t> args, int index, Item *item_, int *stackable)
{
struct item_data *item_data;
int must_add_sequentially;
- if (ARG_TYPE(index) == TYPE::INT)
- item_data = itemdb_exists(ARGINT(index));
- else if (ARG_TYPE(index) == TYPE::STRING)
+ if (args[index].is<ValInt>())
+ item_data = itemdb_exists(wrap<ItemNameId>(static_cast<uint16_t>(ARGINT(index))));
+ else if (args[index].is<ValString>())
item_data = itemdb_searchname(ARGSTR(index));
else
return -1;
@@ -813,7 +897,7 @@ magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable
if (stackable)
*stackable = !must_add_sequentially;
- *item_ = item();
+ *item_ = Item();
item_->nameid = item_data->nameid;
return 0;
@@ -822,25 +906,25 @@ magic_find_item(Slice<val_t> args, int index, struct item *item_, int *stackable
static
int fun_count_item(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
int stackable;
- struct item item;
+ Item item;
GET_ARG_ITEM(1, item, stackable);
if (!chr)
return 1;
- RESULTINT = pc_count_all_items(chr, item.nameid);
+ *result = ValInt{pc_count_all_items(chr, item.nameid)};
return 0;
}
static
int fun_is_equipped(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> chr = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
int stackable;
- struct item item;
+ Item item;
bool retval = false;
GET_ARG_ITEM(1, item, stackable);
@@ -850,36 +934,36 @@ int fun_is_equipped(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
for (EQUIP i : EQUIPs)
{
- int idx = chr->equip_index_maybe[i];
- if (idx >= 0 && chr->status.inventory[idx].nameid == item.nameid)
+ IOff0 idx = chr->equip_index_maybe[i];
+ if (idx.ok() && chr->status.inventory[idx].nameid == item.nameid)
{
retval = true;
break;
}
}
- RESULTINT = retval;
+ *result = ValInt{retval};
return 0;
}
static
int fun_is_married(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = (ENTITY_TYPE(0) == BL::PC && ARGPC(0)->status.partner_id);
+ *result = ValInt{(ENTITY_TYPE(0) == BL::PC && ARGPC(0)->status.partner_id)};
return 0;
}
static
int fun_is_dead(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = (ENTITY_TYPE(0) == BL::PC && pc_isdead(ARGPC(0)));
+ *result = ValInt{(ENTITY_TYPE(0) == BL::PC && pc_isdead(ARGPC(0)))};
return 0;
}
static
int fun_is_pc(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = (ENTITY_TYPE(0) == BL::PC);
+ *result = ValInt{(ENTITY_TYPE(0) == BL::PC)};
return 0;
}
@@ -888,8 +972,8 @@ int fun_partner(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (ENTITY_TYPE(0) == BL::PC && ARGPC(0)->status.partner_id)
{
- RESULTENTITY =
- map_nick2sd(map_charid2nick(ARGPC(0)->status.partner_id));
+ *result =
+ ValEntityPtr{map_nick2sd(map_charid2nick(ARGPC(0)->status.partner_id))};
return 0;
}
else
@@ -911,14 +995,14 @@ int fun_awayfrom(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
loc->y += dy;
}
- RESULTLOCATION = *loc;
+ *result = ValLocation{*loc};
return 0;
}
static
int fun_failed(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = ARG_TYPE(0) == TYPE::FAIL;
+ *result = ValInt{args[0].is<ValFail>()};
return 0;
}
@@ -926,26 +1010,28 @@ static
int fun_npc(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
NpcName name = stringish<NpcName>(ARGSTR(0));
- RESULTENTITY = npc_name2id(name);
- return RESULTENTITY == NULL;
+ dumb_ptr<npc_data> npc = npc_name2id(name);
+ *result = ValEntityPtr{npc};
+ return npc == nullptr;
}
static
int fun_pc(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
CharName name = stringish<CharName>(ARGSTR(0));
- RESULTENTITY = map_nick2sd(name);
- return RESULTENTITY == NULL;
+ dumb_ptr<map_session_data> chr = map_nick2sd(name);
+ *result = ValEntityPtr{chr};
+ return chr == nullptr;
}
static
int fun_distance(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (ARGLOCATION(0).m != ARGLOCATION(1).m)
- RESULTINT = 0x7fffffff;
+ *result = ValInt{0x7fffffff};
else
- RESULTINT = max(abs(ARGLOCATION(0).x - ARGLOCATION(1).x),
- abs(ARGLOCATION(0).y - ARGLOCATION(1).y));
+ *result = ValInt{std::max(abs(ARGLOCATION(0).x - ARGLOCATION(1).x),
+ abs(ARGLOCATION(0).y - ARGLOCATION(1).y))};
return 0;
}
@@ -953,12 +1039,12 @@ static
int fun_rdistance(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
if (ARGLOCATION(0).m != ARGLOCATION(1).m)
- RESULTINT = 0x7fffffff;
+ *result = ValInt{0x7fffffff};
else
{
int dx = ARGLOCATION(0).x - ARGLOCATION(1).x;
int dy = ARGLOCATION(0).y - ARGLOCATION(1).y;
- RESULTINT = static_cast<int>(sqrt((dx * dx) + (dy * dy)));
+ *result = ValInt{static_cast<int>(sqrt((dx * dx) + (dy * dy)))};
}
return 0;
}
@@ -974,7 +1060,7 @@ int fun_anchor(dumb_ptr<env_t> env, val_t *result, Slice<val_t> args)
magic_eval(env, result, anchor->location);
make_area(result);
- if (result->ty != TYPE::AREA)
+ if (!result->is<ValArea>())
{
magic_clear_var(result);
return 1;
@@ -991,28 +1077,48 @@ int fun_line_of_sight(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
COPY_LOCATION(e1, ARGLOCATION(0));
COPY_LOCATION(e2, ARGLOCATION(1));
- RESULTINT = battle_check_range(dumb_ptr<block_list>(&e1), dumb_ptr<block_list>(&e2), 0);
+ *result = ValInt{battle_check_range(dumb_ptr<block_list>(&e1), dumb_ptr<block_list>(&e2), 0)};
return 0;
}
void magic_random_location(location_t *dest, dumb_ptr<area_t> area)
{
- switch (area->ty)
+ MATCH (*area)
{
- case AREA::UNION:
+ CASE (const AreaUnion&, a)
{
- if (random_::chance({area->a.a_union[0]->size, area->size}))
- magic_random_location(dest, area->a.a_union[0]);
+ if (random_::chance({a.a_union[0]->size, area->size}))
+ magic_random_location(dest, a.a_union[0]);
else
- magic_random_location(dest, area->a.a_union[1]);
- break;
+ magic_random_location(dest, a.a_union[1]);
}
+ CASE (const location_t&, a_loc)
+ {
+ (void)a_loc;
+ // TODO this can be simplified
+ map_local *m;
+ int x, y, w, h;
+ magic_area_rect(&m, &x, &y, &w, &h, *area);
+
+ if (w <= 1)
+ w = 1;
- case AREA::LOCATION:
- case AREA::RECT:
- case AREA::BAR:
+ if (h <= 1)
+ h = 1;
+
+ // This is not exactly the same as the old logic,
+ // but it's better.
+ auto pair = map_randfreecell(m, x, y, w, h);
+
+ dest->m = m;
+ dest->x = pair.first;
+ dest->y = pair.second;
+ }
+ CASE (const AreaRect&, a_rect)
{
+ (void)a_rect;
+ // TODO this can be simplified
map_local *m;
int x, y, w, h;
magic_area_rect(&m, &x, &y, &w, &h, *area);
@@ -1030,19 +1136,38 @@ void magic_random_location(location_t *dest, dumb_ptr<area_t> area)
dest->m = m;
dest->x = pair.first;
dest->y = pair.second;
- break;
}
+ CASE (const AreaBar&, a_bar)
+ {
+ (void)a_bar;
+ // TODO this is wrong
+ map_local *m;
+ int x, y, w, h;
+ magic_area_rect(&m, &x, &y, &w, &h, *area);
- default:
- FPRINTF(stderr, "Unknown area type %d\n",
- area->ty);
+ if (w <= 1)
+ w = 1;
+
+ if (h <= 1)
+ h = 1;
+
+ // This is not exactly the same as the old logic,
+ // but it's better.
+ auto pair = map_randfreecell(m, x, y, w, h);
+
+ dest->m = m;
+ dest->x = pair.first;
+ dest->y = pair.second;
+ }
}
}
static
int fun_pick_location(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- magic_random_location(&result->v.v_location, ARGAREA(0));
+ location_t loc;
+ magic_random_location(&loc, ARGAREA(0));
+ *result = ValLocation{loc};
return 0;
}
@@ -1056,7 +1181,7 @@ int fun_read_script_int(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
if (subject_p->bl_type != BL::PC)
return 1;
- RESULTINT = get_script_var_i(subject_p->is_player(), var_name, array_index);
+ *result = ValInt{get_script_var_i(subject_p->is_player(), var_name, array_index)};
return 0;
}
@@ -1070,7 +1195,7 @@ int fun_read_script_str(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
if (subject_p->bl_type != BL::PC)
return 1;
- RESULTSTR = dumb_string::copys(get_script_var_s(subject_p->is_player(), var_name, array_index));
+ *result = ValString{dumb_string::copys(get_script_var_s(subject_p->is_player(), var_name, array_index))};
return 0;
}
@@ -1080,12 +1205,13 @@ int fun_rbox(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
location_t loc = ARGLOCATION(0);
int radius = ARGINT(1);
- RESULTAREA = area_new(AREA::RECT);
- RESULTAREA->a.a_rect.loc.m = loc.m;
- RESULTAREA->a.a_rect.loc.x = loc.x - radius;
- RESULTAREA->a.a_rect.loc.y = loc.y - radius;
- RESULTAREA->a.a_rect.width = radius * 2 + 1;
- RESULTAREA->a.a_rect.height = radius * 2 + 1;
+ AreaRect a_rect;
+ a_rect.loc.m = loc.m;
+ a_rect.loc.x = loc.x - radius;
+ a_rect.loc.y = loc.y - radius;
+ a_rect.width = radius * 2 + 1;
+ a_rect.height = radius * 2 + 1;
+ *result = ValArea{dumb_ptr<area_t>::make(a_rect, a_rect.width * a_rect.height)};
return 0;
}
@@ -1097,28 +1223,28 @@ int fun_running_status_update(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
return 1;
StatusChange sc = static_cast<StatusChange>(ARGINT(1));
- RESULTINT = bool(battle_get_sc_data(ARGENTITY(0))[sc].timer);
+ *result = ValInt{bool(battle_get_sc_data(ARGENTITY(0))[sc].timer)};
return 0;
}
static
int fun_status_option(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = (bool((ARGPC(0))->status.option & static_cast<Option>(ARGINT(1))));
+ *result = ValInt{(bool((ARGPC(0))->status.option & static_cast<Option>(ARGINT(1))))};
return 0;
}
static
int fun_element(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = static_cast<int>(battle_get_element(ARGENTITY(0)).element);
+ *result = ValInt{static_cast<int>(battle_get_element(ARGENTITY(0)).element)};
return 0;
}
static
int fun_element_level(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = battle_get_element(ARGENTITY(0)).level;
+ *result = ValInt{battle_get_element(ARGENTITY(0)).level};
return 0;
}
@@ -1126,14 +1252,14 @@ static
int fun_is_exterior(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
#warning "Evil assumptions!"
- RESULTINT = ARGLOCATION(0).m->name_[4] == '1';
+ *result = ValInt{ARGLOCATION(0).m->name_[4] == '1'};
return 0;
}
static
int fun_contains_string(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = NULL != strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str());
+ *result = ValInt{nullptr != strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str())};
return 0;
}
@@ -1141,14 +1267,14 @@ static
int fun_strstr(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
const char *offset = strstr(ARGSTR(0).c_str(), ARGSTR(1).c_str());
- RESULTINT = offset - ARGSTR(0).c_str();
- return offset == NULL;
+ *result = ValInt{static_cast<int32_t>(offset - ARGSTR(0).c_str())};
+ return offset == nullptr;
}
static
int fun_strlen(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = strlen(ARGSTR(0).c_str());
+ *result = ValInt{static_cast<int32_t>(strlen(ARGSTR(0).c_str()))};
return 0;
}
@@ -1173,7 +1299,7 @@ int fun_substr(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
const char *begin = src + offset;
const char *end = begin + len;
- RESULTSTR = dumb_string::copy(begin, end);
+ *result = ValString{dumb_string::copy(begin, end)};
return 0;
}
@@ -1181,7 +1307,7 @@ int fun_substr(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
static
int fun_sqrt(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- RESULTINT = static_cast<int>(sqrt(ARGINT(0)));
+ *result = ValInt{static_cast<int>(sqrt(ARGINT(0)))};
return 0;
}
@@ -1189,7 +1315,7 @@ static
int fun_map_level(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
#warning "Evil assumptions!"
- RESULTINT = ARGLOCATION(0).m->name_[4] - '0';
+ *result = ValInt{ARGLOCATION(0).m->name_[4] - '0'};
return 0;
}
@@ -1199,8 +1325,8 @@ int fun_map_nr(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
#warning "Evil assumptions!"
MapName mapname = ARGLOCATION(0).m->name_;
- RESULTINT = ((mapname[0] - '0') * 100)
- + ((mapname[1] - '0') * 10) + ((mapname[2] - '0'));
+ *result = ValInt{((mapname[0] - '0') * 100)
+ + ((mapname[1] - '0') * 10) + ((mapname[2] - '0'))};
return 0;
}
@@ -1222,30 +1348,30 @@ int fun_dir_towards(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
if (abs(dx) > abs(dy) * 2)
{ /* east or west */
if (dx < 0)
- RESULTINT = 2 /* west */ ;
+ *result = ValDir{DIR::W};
else
- RESULTINT = 6 /* east */ ;
+ *result = ValDir{DIR::E};
}
else if (abs(dy) > abs(dx) * 2)
{ /* north or south */
if (dy > 0)
- RESULTINT = 0 /* south */ ;
+ *result = ValDir{DIR::S};
else
- RESULTINT = 4 /* north */ ;
+ *result = ValDir{DIR::N};
}
else if (dx < 0)
{ /* north-west or south-west */
if (dy < 0)
- RESULTINT = 3 /* north-west */ ;
+ *result = ValDir{DIR::NW};
else
- RESULTINT = 1 /* south-west */ ;
+ *result = ValDir{DIR::SW};
}
else
{ /* north-east or south-east */
if (dy < 0)
- RESULTINT = 5 /* north-east */ ;
+ *result = ValDir{DIR::NE};
else
- RESULTINT = 7 /* south-east */ ;
+ *result = ValDir{DIR::SE};
}
}
else
@@ -1254,16 +1380,16 @@ int fun_dir_towards(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
if (abs(dx) > abs(dy))
{ /* east or west */
if (dx < 0)
- RESULTINT = 2 /* west */ ;
+ *result = ValDir{DIR::W};
else
- RESULTINT = 6 /* east */ ;
+ *result = ValDir{DIR::E};
}
else
{ /* north or south */
if (dy > 0)
- RESULTINT = 0 /* south */ ;
+ *result = ValDir{DIR::S};
else
- RESULTINT = 4 /* north */ ;
+ *result = ValDir{DIR::N};
}
}
@@ -1273,98 +1399,98 @@ int fun_dir_towards(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
static
int fun_extract_healer_xp(dumb_ptr<env_t>, val_t *result, Slice<val_t> args)
{
- dumb_ptr<map_session_data> sd = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> sd = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
if (!sd)
- RESULTINT = 0;
+ *result = ValInt{0};
else
- RESULTINT = pc_extract_healer_exp(sd, ARGINT(1));
+ *result = ValInt{pc_extract_healer_exp(sd, ARGINT(1))};
return 0;
}
-#define MAGIC_FUNCTION(name, args, ret, impl) {{name}, {{name}, {args}, ret, impl}}
-#define MAGIC_FUNCTION1(name, args, ret) MAGIC_FUNCTION(#name, args, ret, fun_##name)
-static
+#define MAGIC_FUNCTION(name, args, ret, impl) {name, {name, args, ret, impl}}
+#define MAGIC_FUNCTION1(name, args, ret) MAGIC_FUNCTION(#name##_s, args, ret, fun_##name)
+static // should be LString, but no heterogenous lookup yet
std::map<ZString, fun_t> functions =
{
- MAGIC_FUNCTION("+", "..", '.', fun_add),
- MAGIC_FUNCTION("-", "ii", 'i', fun_sub),
- MAGIC_FUNCTION("*", "ii", 'i', fun_mul),
- MAGIC_FUNCTION("/", "ii", 'i', fun_div),
- MAGIC_FUNCTION("%", "ii", 'i', fun_mod),
- MAGIC_FUNCTION("||", "ii", 'i', fun_or),
- MAGIC_FUNCTION("&&", "ii", 'i', fun_and),
- MAGIC_FUNCTION("<", "..", 'i', fun_lt),
- MAGIC_FUNCTION(">", "..", 'i', fun_gt),
- MAGIC_FUNCTION("<=", "..", 'i', fun_lte),
- MAGIC_FUNCTION(">=", "..", 'i', fun_gte),
- MAGIC_FUNCTION("==", "..", 'i', fun_eq),
- MAGIC_FUNCTION("!=", "..", 'i', fun_ne),
- MAGIC_FUNCTION("|", "..", 'i', fun_bitor),
- MAGIC_FUNCTION("&", "ii", 'i', fun_bitand),
- MAGIC_FUNCTION("^", "ii", 'i', fun_bitxor),
- MAGIC_FUNCTION("<<", "ii", 'i', fun_bitshl),
- MAGIC_FUNCTION(">>", "ii", 'i', fun_bitshr),
- MAGIC_FUNCTION1(not, "i", 'i'),
- MAGIC_FUNCTION1(neg, "i", 'i'),
- MAGIC_FUNCTION1(max, "ii", 'i'),
- MAGIC_FUNCTION1(min, "ii", 'i'),
- MAGIC_FUNCTION1(is_in, "la", 'i'),
- MAGIC_FUNCTION1(if_then_else, "i__", '_'),
- MAGIC_FUNCTION1(skill, "ei", 'i'),
- MAGIC_FUNCTION("str", "e", 'i', fun_get_str),
- MAGIC_FUNCTION("agi", "e", 'i', fun_get_agi),
- MAGIC_FUNCTION("vit", "e", 'i', fun_get_vit),
- MAGIC_FUNCTION("dex", "e", 'i', fun_get_dex),
- MAGIC_FUNCTION("luk", "e", 'i', fun_get_luk),
- MAGIC_FUNCTION("int", "e", 'i', fun_get_int),
- MAGIC_FUNCTION("level", "e", 'i', fun_get_lv),
- MAGIC_FUNCTION("mdef", "e", 'i', fun_get_mdef),
- MAGIC_FUNCTION("def", "e", 'i', fun_get_def),
- MAGIC_FUNCTION("hp", "e", 'i', fun_get_hp),
- MAGIC_FUNCTION("max_hp", "e", 'i', fun_get_max_hp),
- MAGIC_FUNCTION("sp", "e", 'i', fun_get_sp),
- MAGIC_FUNCTION("max_sp", "e", 'i', fun_get_max_sp),
- MAGIC_FUNCTION("dir", "e", 'd', fun_get_dir),
- MAGIC_FUNCTION1(name_of, ".", 's'),
- MAGIC_FUNCTION1(mob_id, "e", 'i'),
- MAGIC_FUNCTION1(location, "e", 'l'),
- MAGIC_FUNCTION1(random, "i", 'i'),
- MAGIC_FUNCTION1(random_dir, "i", 'd'),
- MAGIC_FUNCTION1(hash_entity, "e", 'i'),
- MAGIC_FUNCTION1(is_married, "e", 'i'),
- MAGIC_FUNCTION1(partner, "e", 'e'),
- MAGIC_FUNCTION1(awayfrom, "ldi", 'l'),
- MAGIC_FUNCTION1(failed, "_", 'i'),
- MAGIC_FUNCTION1(pc, "s", 'e'),
- MAGIC_FUNCTION1(npc, "s", 'e'),
- MAGIC_FUNCTION1(distance, "ll", 'i'),
- MAGIC_FUNCTION1(rdistance, "ll", 'i'),
- MAGIC_FUNCTION1(anchor, "s", 'a'),
- MAGIC_FUNCTION("random_location", "a", 'l', fun_pick_location),
- MAGIC_FUNCTION("script_int", "es", 'i', fun_read_script_int),
- MAGIC_FUNCTION("script_str", "es", 's', fun_read_script_str),
- MAGIC_FUNCTION1(rbox, "li", 'a'),
- MAGIC_FUNCTION1(count_item, "e.", 'i'),
- MAGIC_FUNCTION1(line_of_sight, "ll", 'i'),
- MAGIC_FUNCTION1(running_status_update, "ei", 'i'),
- MAGIC_FUNCTION1(status_option, "ei", 'i'),
- MAGIC_FUNCTION1(element, "e", 'i'),
- MAGIC_FUNCTION1(element_level, "e", 'i'),
- MAGIC_FUNCTION1(his_shroud, "e", 'i'),
- MAGIC_FUNCTION1(is_equipped, "e.", 'i'),
- MAGIC_FUNCTION1(is_exterior, "l", 'i'),
- MAGIC_FUNCTION1(contains_string, "ss", 'i'),
- MAGIC_FUNCTION1(strstr, "ss", 'i'),
- MAGIC_FUNCTION1(strlen, "s", 'i'),
- MAGIC_FUNCTION1(substr, "sii", 's'),
- MAGIC_FUNCTION1(sqrt, "i", 'i'),
- MAGIC_FUNCTION1(map_level, "l", 'i'),
- MAGIC_FUNCTION1(map_nr, "l", 'i'),
- MAGIC_FUNCTION1(dir_towards, "lli", 'd'),
- MAGIC_FUNCTION1(is_dead, "e", 'i'),
- MAGIC_FUNCTION1(is_pc, "e", 'i'),
- MAGIC_FUNCTION("extract_healer_experience", "ei", 'i', fun_extract_healer_xp),
+ MAGIC_FUNCTION("+"_s, ".."_s, '.', fun_add),
+ MAGIC_FUNCTION("-"_s, "ii"_s, 'i', fun_sub),
+ MAGIC_FUNCTION("*"_s, "ii"_s, 'i', fun_mul),
+ MAGIC_FUNCTION("/"_s, "ii"_s, 'i', fun_div),
+ MAGIC_FUNCTION("%"_s, "ii"_s, 'i', fun_mod),
+ MAGIC_FUNCTION("||"_s, "ii"_s, 'i', fun_or),
+ MAGIC_FUNCTION("&&"_s, "ii"_s, 'i', fun_and),
+ MAGIC_FUNCTION("<"_s, ".."_s, 'i', fun_lt),
+ MAGIC_FUNCTION(">"_s, ".."_s, 'i', fun_gt),
+ MAGIC_FUNCTION("<="_s, ".."_s, 'i', fun_lte),
+ MAGIC_FUNCTION(">="_s, ".."_s, 'i', fun_gte),
+ MAGIC_FUNCTION("=="_s, ".."_s, 'i', fun_eq),
+ MAGIC_FUNCTION("!="_s, ".."_s, 'i', fun_ne),
+ MAGIC_FUNCTION("|"_s, ".."_s, 'i', fun_bitor),
+ MAGIC_FUNCTION("&"_s, "ii"_s, 'i', fun_bitand),
+ MAGIC_FUNCTION("^"_s, "ii"_s, 'i', fun_bitxor),
+ MAGIC_FUNCTION("<<"_s, "ii"_s, 'i', fun_bitshl),
+ MAGIC_FUNCTION(">>"_s, "ii"_s, 'i', fun_bitshr),
+ MAGIC_FUNCTION1(not, "i"_s, 'i'),
+ MAGIC_FUNCTION1(neg, "i"_s, 'i'),
+ MAGIC_FUNCTION1(max, "ii"_s, 'i'),
+ MAGIC_FUNCTION1(min, "ii"_s, 'i'),
+ MAGIC_FUNCTION1(is_in, "la"_s, 'i'),
+ MAGIC_FUNCTION1(if_then_else, "i__"_s, '_'),
+ MAGIC_FUNCTION1(skill, "ei"_s, 'i'),
+ MAGIC_FUNCTION("str"_s, "e"_s, 'i', fun_get_str),
+ MAGIC_FUNCTION("agi"_s, "e"_s, 'i', fun_get_agi),
+ MAGIC_FUNCTION("vit"_s, "e"_s, 'i', fun_get_vit),
+ MAGIC_FUNCTION("dex"_s, "e"_s, 'i', fun_get_dex),
+ MAGIC_FUNCTION("luk"_s, "e"_s, 'i', fun_get_luk),
+ MAGIC_FUNCTION("int"_s, "e"_s, 'i', fun_get_int),
+ MAGIC_FUNCTION("level"_s, "e"_s, 'i', fun_get_lv),
+ MAGIC_FUNCTION("mdef"_s, "e"_s, 'i', fun_get_mdef),
+ MAGIC_FUNCTION("def"_s, "e"_s, 'i', fun_get_def),
+ MAGIC_FUNCTION("hp"_s, "e"_s, 'i', fun_get_hp),
+ MAGIC_FUNCTION("max_hp"_s, "e"_s, 'i', fun_get_max_hp),
+ MAGIC_FUNCTION("sp"_s, "e"_s, 'i', fun_get_sp),
+ MAGIC_FUNCTION("max_sp"_s, "e"_s, 'i', fun_get_max_sp),
+ MAGIC_FUNCTION("dir"_s, "e"_s, 'd', fun_get_dir),
+ MAGIC_FUNCTION1(name_of, "."_s, 's'),
+ MAGIC_FUNCTION1(mob_id, "e"_s, 'i'),
+ MAGIC_FUNCTION1(location, "e"_s, 'l'),
+ MAGIC_FUNCTION1(random, "i"_s, 'i'),
+ MAGIC_FUNCTION1(random_dir, "i"_s, 'd'),
+ MAGIC_FUNCTION1(hash_entity, "e"_s, 'i'),
+ MAGIC_FUNCTION1(is_married, "e"_s, 'i'),
+ MAGIC_FUNCTION1(partner, "e"_s, 'e'),
+ MAGIC_FUNCTION1(awayfrom, "ldi"_s, 'l'),
+ MAGIC_FUNCTION1(failed, "_"_s, 'i'),
+ MAGIC_FUNCTION1(pc, "s"_s, 'e'),
+ MAGIC_FUNCTION1(npc, "s"_s, 'e'),
+ MAGIC_FUNCTION1(distance, "ll"_s, 'i'),
+ MAGIC_FUNCTION1(rdistance, "ll"_s, 'i'),
+ MAGIC_FUNCTION1(anchor, "s"_s, 'a'),
+ MAGIC_FUNCTION("random_location"_s, "a"_s, 'l', fun_pick_location),
+ MAGIC_FUNCTION("script_int"_s, "es"_s, 'i', fun_read_script_int),
+ MAGIC_FUNCTION("script_str"_s, "es"_s, 's', fun_read_script_str),
+ MAGIC_FUNCTION1(rbox, "li"_s, 'a'),
+ MAGIC_FUNCTION1(count_item, "e."_s, 'i'),
+ MAGIC_FUNCTION1(line_of_sight, "ll"_s, 'i'),
+ MAGIC_FUNCTION1(running_status_update, "ei"_s, 'i'),
+ MAGIC_FUNCTION1(status_option, "ei"_s, 'i'),
+ MAGIC_FUNCTION1(element, "e"_s, 'i'),
+ MAGIC_FUNCTION1(element_level, "e"_s, 'i'),
+ MAGIC_FUNCTION1(his_shroud, "e"_s, 'i'),
+ MAGIC_FUNCTION1(is_equipped, "e."_s, 'i'),
+ MAGIC_FUNCTION1(is_exterior, "l"_s, 'i'),
+ MAGIC_FUNCTION1(contains_string, "ss"_s, 'i'),
+ MAGIC_FUNCTION1(strstr, "ss"_s, 'i'),
+ MAGIC_FUNCTION1(strlen, "s"_s, 'i'),
+ MAGIC_FUNCTION1(substr, "sii"_s, 's'),
+ MAGIC_FUNCTION1(sqrt, "i"_s, 'i'),
+ MAGIC_FUNCTION1(map_level, "l"_s, 'i'),
+ MAGIC_FUNCTION1(map_nr, "l"_s, 'i'),
+ MAGIC_FUNCTION1(dir_towards, "lli"_s, 'd'),
+ MAGIC_FUNCTION1(is_dead, "e"_s, 'i'),
+ MAGIC_FUNCTION1(is_pc, "e"_s, 'i'),
+ MAGIC_FUNCTION("extract_healer_experience"_s, "ei"_s, 'i', fun_extract_healer_xp),
};
fun_t *magic_get_fun(ZString name)
@@ -1377,24 +1503,24 @@ fun_t *magic_get_fun(ZString name)
// 1 on failure
static
-int eval_location(dumb_ptr<env_t> env, location_t *dest, e_location_t *expr)
+int eval_location(dumb_ptr<env_t> env, location_t *dest, const e_location_t *expr)
{
val_t m, x, y;
magic_eval(env, &m, expr->m);
magic_eval(env, &x, expr->x);
magic_eval(env, &y, expr->y);
- if (CHECK_TYPE(&m, TYPE::STRING)
- && CHECK_TYPE(&x, TYPE::INT) && CHECK_TYPE(&y, TYPE::INT))
+ if (m.is<ValString>()
+ && x.is<ValInt>() && y.is<ValInt>())
{
- MapName name = VString<15>(ZString(m.v.v_string));
+ MapName name = VString<15>(ZString(m.get_if<ValString>()->v_string));
map_local *map_id = map_mapname2mapid(name);
magic_clear_var(&m);
if (!map_id)
return 1;
dest->m = map_id;
- dest->x = x.v.v_int;
- dest->y = y.v.v_int;
+ dest->x = x.get_if<ValInt>()->v_int;
+ dest->y = y.get_if<ValInt>()->v_int;
return 0;
}
else
@@ -1407,141 +1533,145 @@ int eval_location(dumb_ptr<env_t> env, location_t *dest, e_location_t *expr)
}
static
-dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, e_area_t& expr_)
+dumb_ptr<area_t> eval_area(dumb_ptr<env_t> env, const e_area_t& expr_)
{
- e_area_t *expr = &expr_; // temporary hack to reduce diff
- auto area = dumb_ptr<area_t>::make();
- area->ty = expr->ty;
-
- switch (expr->ty)
+ MATCH (expr_)
{
- case AREA::LOCATION:
- area->size = 1;
- if (eval_location(env, &area->a.a_loc, &expr->a.a_loc))
+ CASE (const e_location_t&, a_loc)
+ {
+ location_t loc;
+ int size = 1;
+ if (eval_location(env, &loc, &a_loc))
{
- area.delete_();
- return NULL;
+ return nullptr;
}
else
- return area;
-
- case AREA::UNION:
+ {
+ return dumb_ptr<area_t>::make(loc, size);
+ }
+ }
+ CASE (const ExprAreaUnion&, a)
{
- int i, fail = 0;
- for (i = 0; i < 2; i++)
+ AreaUnion u;
+ bool fail = false;
+ for (int i = 0; i < 2; i++)
{
- area->a.a_union[i] = eval_area(env, *expr->a.a_union[i]);
- if (!area->a.a_union[i])
- fail = 1;
+ u.a_union[i] = eval_area(env, *a.a_union[i]);
+ if (!u.a_union[i])
+ fail = true;
}
if (fail)
{
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
{
- if (area->a.a_union[i])
- free_area(area->a.a_union[i]);
+ if (u.a_union[i])
+ free_area(u.a_union[i]);
}
- area.delete_();
- return NULL;
+ return nullptr;
}
- area->size = area->a.a_union[0]->size + area->a.a_union[1]->size;
- return area;
+ int size = u.a_union[0]->size + u.a_union[1]->size;
+ return dumb_ptr<area_t>::make(u, size);
}
-
- case AREA::RECT:
+ CASE (const ExprAreaRect&, a_rect)
{
val_t width, height;
- magic_eval(env, &width, expr->a.a_rect.width);
- magic_eval(env, &height, expr->a.a_rect.height);
-
- area->a.a_rect.width = width.v.v_int;
- area->a.a_rect.height = height.v.v_int;
-
- if (CHECK_TYPE(&width, TYPE::INT)
- && CHECK_TYPE(&height, TYPE::INT)
- && !eval_location(env, &(area->a.a_rect.loc),
- &expr->a.a_rect.loc))
+ magic_eval(env, &width, a_rect.width);
+ magic_eval(env, &height, a_rect.height);
+
+ AreaRect a_rect_;
+ if (width.is<ValInt>()
+ && height.is<ValInt>()
+ && !eval_location(env, &(a_rect_.loc),
+ &a_rect.loc))
{
- area->size = area->a.a_rect.width * area->a.a_rect.height;
+ a_rect_.width = width.get_if<ValInt>()->v_int;
+ a_rect_.height = height.get_if<ValInt>()->v_int;
+
+ int size = a_rect_.width * a_rect_.height;
magic_clear_var(&width);
magic_clear_var(&height);
- return area;
+ return dumb_ptr<area_t>::make(a_rect_, size);
}
else
{
- area.delete_();
magic_clear_var(&width);
magic_clear_var(&height);
- return NULL;
+ return nullptr;
}
}
-
- case AREA::BAR:
+ CASE (const ExprAreaBar&, a_bar)
{
val_t width, depth, dir;
- magic_eval(env, &width, expr->a.a_bar.width);
- magic_eval(env, &depth, expr->a.a_bar.depth);
- magic_eval(env, &dir, expr->a.a_bar.dir);
-
- area->a.a_bar.width = width.v.v_int;
- area->a.a_bar.depth = depth.v.v_int;
- area->a.a_bar.dir = dir.v.v_dir;
-
- if (CHECK_TYPE(&width, TYPE::INT)
- && CHECK_TYPE(&depth, TYPE::INT)
- && CHECK_TYPE(&dir, TYPE::DIR)
- && !eval_location(env, &area->a.a_bar.loc,
- &expr->a.a_bar.loc))
+ magic_eval(env, &width, a_bar.width);
+ magic_eval(env, &depth, a_bar.depth);
+ magic_eval(env, &dir, a_bar.dir);
+
+ AreaBar a_bar_;
+ if (width.is<ValInt>()
+ && depth.is<ValInt>()
+ && dir.is<ValDir>()
+ && !eval_location(env, &a_bar_.loc,
+ &a_bar.loc))
{
- area->size =
- (area->a.a_bar.width * 2 + 1) * area->a.a_bar.depth;
+ a_bar_.width = width.get_if<ValInt>()->v_int;
+ a_bar_.depth = depth.get_if<ValInt>()->v_int;
+ a_bar_.dir = dir.get_if<ValDir>()->v_dir;
+
+ int size = (a_bar_.width * 2 + 1) * a_bar_.depth;
magic_clear_var(&width);
magic_clear_var(&depth);
magic_clear_var(&dir);
- return area;
+ return dumb_ptr<area_t>::make(a_bar_, size);
}
else
{
- area.delete_();
magic_clear_var(&width);
magic_clear_var(&depth);
magic_clear_var(&dir);
- return NULL;
+ return nullptr;
}
}
-
- default:
- FPRINTF(stderr, "INTERNAL ERROR: Unknown area type %d\n",
- area->ty);
- area.delete_();
- return NULL;
}
+ abort();
}
+// This is called on arguments with begin=true,
+// and on the return value with begin=false.
+// In both cases, the ambiguous types are in pointer mode.
static
-TYPE type_key(char ty_key)
+bool type_key_matches(char ty_key, val_t *arg, bool begin)
{
switch (ty_key)
{
case 'i':
- return TYPE::INT;
+ if (begin)
+ intify(arg);
+ return arg->is<ValInt>();
case 'd':
- return TYPE::DIR;
+ return arg->is<ValDir>();
case 's':
- return TYPE::STRING;
+ if (begin)
+ stringify(arg);
+ return arg->is<ValString>();
case 'e':
- return TYPE::ENTITY;
+ return arg->is<ValEntityPtr>();
case 'l':
- return TYPE::LOCATION;
+ if (begin)
+ make_location(arg);
+ return arg->is<ValLocation>();
case 'a':
- return TYPE::AREA;
+ if (begin)
+ make_area(arg);
+ return arg->is<ValArea>();
case 'S':
- return TYPE::SPELL;
+ if (begin)
+ make_spell(arg);
+ return arg->is<ValSpell>();
case 'I':
- return TYPE::INVOCATION;
+ return arg->is<ValInvocationPtr>();
default:
- return TYPE::NEGATIVE_1;
+ return true;
}
}
@@ -1552,76 +1682,66 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature,
for (i = 0; i < args.size(); i++)
{
val_t *arg = &args[i];
- char ty_key = signature[i];
- TYPE ty = arg->ty;
- TYPE desired_ty = type_key(ty_key);
- if (ty == TYPE::ENTITY)
+ // whoa, it turns out the second p *does* shadow this one
+ if (ValEntityInt *p1 = arg->get_if<ValEntityInt>())
{
/* Dereference entities in preparation for calling function */
- arg->v.v_entity = map_id2bl(arg->v.v_int);
- if (!arg->v.v_entity)
- ty = arg->ty = TYPE::FAIL;
+ dumb_ptr<block_list> ent = map_id2bl(p1->v_eid);
+ if (ent)
+ {
+ *arg = ValEntityPtr{ent};
+ }
+ else
+ {
+ *arg = ValFail{};
+ }
}
- else if (ty == TYPE::INVOCATION)
+ else if (ValInvocationInt *p2 = arg->get_if<ValInvocationInt>())
{
- arg->v.v_invocation = map_id2bl(arg->v.v_int)->is_spell();
- if (!arg->v.v_entity)
- ty = arg->ty = TYPE::FAIL;
+ dumb_ptr<invocation> invoc = map_id2bl(p2->v_iid)->is_spell();
+ if (invoc)
+ {
+ *arg = ValInvocationPtr{invoc};
+ }
+ else
+ {
+ *arg = ValFail();
+ }
}
+ char ty_key = signature[i];
if (!ty_key)
{
FPRINTF(stderr,
- "[magic-eval]: L%d:%d: Too many arguments (%zu) to %s `%s'\n",
- line, column, args.size(), opname, funname);
+ "[magic-eval]: L%d:%d: Too many arguments (%zu) to %s `%s'\n"_fmt,
+ line, column, args.size(), opname, funname);
return 1;
}
- if (ty == TYPE::FAIL && ty_key != '_')
+ if (arg->is<ValFail>() && ty_key != '_')
return 1; /* Fail `in a sane way': This is a perfectly permissible error */
- if (ty == desired_ty || desired_ty == TYPE::NEGATIVE_1)
+ // this also does conversions now
+ if (type_key_matches(ty_key, arg, true))
continue;
- if (ty == TYPE::UNDEF)
+ if (arg->is<ValUndef>())
{
FPRINTF(stderr,
- "[magic-eval]: L%d:%d: Argument #%d to %s `%s' undefined\n",
- line, column, i + 1, opname, funname);
+ "[magic-eval]: L%d:%d: Argument #%d to %s `%s' undefined\n"_fmt,
+ line, column, i + 1, opname, funname);
return 1;
}
- /* If we are here, we have a type mismatch but no failure _yet_. Try to coerce. */
- switch (desired_ty)
- {
- case TYPE::INT:
- intify(arg);
- break; /* 100% success rate */
- case TYPE::STRING:
- stringify(arg, 1);
- break; /* 100% success rate */
- case TYPE::AREA:
- make_area(arg);
- break; /* Only works for locations */
- case TYPE::LOCATION:
- make_location(arg);
- break; /* Only works for some areas */
- case TYPE::SPELL:
- make_spell(arg);
- break; /* Only works for still-active invocatoins */
- default:
- break; /* We'll fail right below */
- }
- ty = arg->ty;
- if (ty != desired_ty)
{ /* Coercion failed? */
- if (ty != TYPE::FAIL)
+ if (!arg->is<ValFail>())
+ {
FPRINTF(stderr,
- "[magic-eval]: L%d:%d: Argument #%d to %s `%s' of incorrect type (%d)\n",
- line, column, i + 1, opname, funname,
- ty);
+ "[magic-eval]: L%d:%d: Argument #%d to %s `%s' of incorrect type (sorry, types aren't integers anymore)\n"_fmt,
+ line, column, i + 1, opname, funname);
+ }
return 1;
}
}
@@ -1631,100 +1751,94 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature,
void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr)
{
- switch (expr->ty)
+ MATCH (*expr)
{
- case EXPR::VAL:
- magic_copy_var(dest, &expr->e.e_val);
- break;
+ CASE (const val_t&, e_val)
+ {
+ magic_copy_var(dest, &e_val);
+ }
- case EXPR::LOCATION:
- if (eval_location(env, &dest->v.v_location, &expr->e.e_location))
- dest->ty = TYPE::FAIL;
+ CASE (const e_location_t&, e_location)
+ {
+ location_t loc;
+ if (eval_location(env, &loc, &e_location))
+ *dest = ValFail();
else
- dest->ty = TYPE::LOCATION;
- break;
-
- case EXPR::AREA:
- if ((dest->v.v_area = eval_area(env, expr->e.e_area)))
- dest->ty = TYPE::AREA;
+ *dest = ValLocation{loc};
+ }
+ CASE (const e_area_t&, e_area)
+ {
+ if (dumb_ptr<area_t> area = eval_area(env, e_area))
+ *dest = ValArea{area};
else
- dest->ty = TYPE::FAIL;
- break;
-
- case EXPR::FUNAPP:
+ *dest = ValFail();
+ }
+ CASE (const ExprFunApp&, e_funapp)
{
val_t arguments[MAX_ARGS];
- int args_nr = expr->e.e_funapp.args_nr;
+ int args_nr = e_funapp.args_nr;
int i;
- fun_t *f = expr->e.e_funapp.funp;
+ fun_t *f = e_funapp.funp;
for (i = 0; i < args_nr; ++i)
- magic_eval(env, &arguments[i], expr->e.e_funapp.args[i]);
- if (magic_signature_check("function", f->name, f->signature, Slice<val_t>(arguments, args_nr),
- expr->e.e_funapp.line_nr, expr->e.e_funapp.column)
+ magic_eval(env, &arguments[i], e_funapp.args[i]);
+ if (magic_signature_check("function"_s, f->name, f->signature, Slice<val_t>(arguments, args_nr),
+ e_funapp.line_nr, e_funapp.column)
|| f->fun(env, dest, Slice<val_t>(arguments, args_nr)))
- dest->ty = TYPE::FAIL;
+ *dest = ValFail();
else
{
- TYPE dest_ty = type_key(f->ret_ty);
- if (dest_ty != TYPE::NEGATIVE_1)
- dest->ty = dest_ty;
+ assert (!dest->is<ValInvocationPtr>());
+ assert (!dest->is<ValInvocationInt>());
+ assert (!dest->is<ValEntityInt>());
+ assert (type_key_matches(f->ret_ty, dest, false));
/* translate entity back into persistent int */
- if (dest->ty == TYPE::ENTITY)
+ if (ValEntityPtr *ent = dest->get_if<ValEntityPtr>())
{
- if (dest->v.v_entity)
- dest->v.v_int = dest->v.v_entity->bl_id;
+ if (ent->v_entity)
+ *dest = ValEntityInt{ent->v_entity->bl_id};
else
- dest->ty = TYPE::FAIL;
+ *dest = ValFail();
}
+ // what about invocation?
}
for (i = 0; i < args_nr; ++i)
magic_clear_var(&arguments[i]);
- break;
}
-
- case EXPR::ID:
+ CASE (const ExprId&, e)
{
- val_t v = env->VAR(expr->e.e_id);
+ val_t& v = env->VAR(e.e_id);
magic_copy_var(dest, &v);
- break;
}
-
- case EXPR::SPELLFIELD:
+ CASE (const ExprField&, e_field)
{
val_t v;
- int id = expr->e.e_field.id;
- magic_eval(env, &v, expr->e.e_field.expr);
+ int id = e_field.id;
+ magic_eval(env, &v, e_field.expr);
- if (v.ty == TYPE::INVOCATION)
+ assert(!v.is<ValInvocationPtr>());
+ if (ValInvocationInt *ii = v.get_if<ValInvocationInt>())
{
- dumb_ptr<invocation> t = map_id2bl(v.v.v_int)->is_spell();
+ dumb_ptr<invocation> t = map_id2bl(ii->v_iid)->is_spell();
if (!t)
- dest->ty = TYPE::UNDEF;
+ *dest = ValUndef();
else
{
- val_t val = t->env->VAR(id);
+ val_t& val = t->env->VAR(id);
magic_copy_var(dest, &val);
}
}
else
{
FPRINTF(stderr,
- "[magic] Attempt to access field %s on non-spell\n",
- env->base_env->varv[id].name);
- dest->ty = TYPE::FAIL;
+ "[magic] Attempt to access field %s on non-spell\n"_fmt,
+ env->base_env->varv[id].name);
+ *dest = ValFail();
}
- break;
}
-
- default:
- FPRINTF(stderr,
- "[magic] INTERNAL ERROR: Unknown expression type %d\n",
- expr->ty);
- break;
}
}
@@ -1733,12 +1847,12 @@ int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr)
val_t result;
magic_eval(env, &result, expr);
- if (result.ty == TYPE::FAIL || result.ty == TYPE::UNDEF)
+ if (result.is<ValFail>() || result.is<ValUndef>())
return 0;
intify(&result);
- return result.v.v_int;
+ return result.get_if<ValInt>()->v_int;
}
AString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr)
@@ -1746,17 +1860,13 @@ AString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr)
val_t result;
magic_eval(env, &result, expr);
- if (result.ty == TYPE::FAIL || result.ty == TYPE::UNDEF)
- return {"?"};
+ if (result.is<ValFail>() || result.is<ValUndef>())
+ return "?"_s;
- stringify(&result, 0);
+ // is this a memory leak?
+ stringify(&result);
- return result.v.v_string.str();
-}
-
-dumb_ptr<expr_t> magic_new_expr(EXPR ty)
-{
- auto expr = dumb_ptr<expr_t>::make();
- expr->ty = ty;
- return expr;
+ return result.get_if<ValString>()->v_string.str();
}
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-expr.hpp b/src/map/magic-expr.hpp
index 58f6596..294e665 100644
--- a/src/map/magic-expr.hpp
+++ b/src/map/magic-expr.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAGIC_EXPR_HPP
-#define TMWA_MAP_MAGIC_EXPR_HPP
+#pragma once
// magic-expr.hpp - Pure functions for the old magic backend.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -20,15 +19,24 @@
// 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.hpp"
+#include "../generic/fwd.hpp"
-# include "../range/slice.hpp"
+#include "../range/fwd.hpp"
-# include "../strings/fwd.hpp"
-# include "../strings/zstring.hpp"
+#include "../strings/zstring.hpp"
+#include "../strings/literal.hpp"
+#include "../mmo/fwd.hpp"
+
+#include "magic-interpreter.t.hpp"
+
+
+namespace tmwa
+{
+namespace magic
+{
/*
* Argument types:
* i : int
@@ -44,34 +52,20 @@
*/
struct fun_t
{
- ZString name;
- ZString signature;
+ LString name;
+ LString signature;
char ret_ty;
int (*fun)(dumb_ptr<env_t> env, val_t *result, Slice<val_t> arga);
};
-struct op_t
-{
- ZString name;
- ZString signature;
- int (*op)(dumb_ptr<env_t> env, Slice<val_t> arga);
-};
-
/**
* Retrieves a function by name
* @param name The name to look up
- * @return A function of that name, or NULL.
+ * @return A function of that name, or nullptr.
*/
fun_t *magic_get_fun(ZString name);
/**
- * Retrieves an operation by name
- * @param name The name to look up
- * @return An operation of that name, or NULL, and a function index
- */
-op_t *magic_get_op(ZString name);
-
-/**
* Evaluates an expression and stores the result in `dest'
*/
void magic_eval(dumb_ptr<env_t> env, val_t *dest, dumb_ptr<expr_t> expr);
@@ -86,18 +80,16 @@ int magic_eval_int(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr);
*/
AString magic_eval_str(dumb_ptr<env_t> env, dumb_ptr<expr_t> expr);
-dumb_ptr<expr_t> magic_new_expr(EXPR ty);
-
void magic_clear_var(val_t *v);
-void magic_copy_var(val_t *dest, val_t *src);
+void magic_copy_var(val_t *dest, const val_t *src);
void magic_random_location(location_t *dest, dumb_ptr<area_t> area);
// ret -1: not a string, ret 1: no such item, ret 0: OK
-int magic_find_item(Slice<val_t> args, int index, struct item *item, int *stackable);
+int magic_find_item(Slice<val_t> args, int index, Item *item, int *stackable);
-# define GET_ARG_ITEM(index, dest, stackable) \
+#define GET_ARG_ITEM(index, dest, stackable) \
switch (magic_find_item(args, index, &dest, &stackable)) \
{ \
case -1: return 1; \
@@ -107,4 +99,12 @@ int magic_find_item(Slice<val_t> args, int index, struct item *item, int *stacka
int magic_location_in_area(map_local *m, int x, int y, dumb_ptr<area_t> area);
-#endif // TMWA_MAP_MAGIC_EXPR_HPP
+/* Helper definitions for dealing with functions and operations */
+
+int magic_signature_check(ZString opname, ZString funname, ZString signature,
+ Slice<val_t> args, int line, int column);
+
+void magic_area_rect(map_local **m, int *x, int *y, int *width, int *height,
+ area_t& area);
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-interpreter-aux.hpp b/src/map/magic-interpreter-aux.hpp
deleted file mode 100644
index 1369b38..0000000
--- a/src/map/magic-interpreter-aux.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#ifndef TMWA_MAP_MAGIC_INTERPRETER_AUX_HPP
-#define TMWA_MAP_MAGIC_INTERPRETER_AUX_HPP
-// magic-interpreter-aux.hpp - Edge of the magic system.
-//
-// Copyright © 2004-2011 The Mana World Development Team
-// Copyright © 2011-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"
-
-# include "magic-interpreter.t.hpp"
-
-template<class T>
-bool CHECK_TYPE(T *v, TYPE t)
-{
- return v->ty == t;
-}
-
-#endif // TMWA_MAP_MAGIC_INTERPRETER_AUX_HPP
diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp
index d86f595..1ac391a 100644
--- a/src/map/magic-interpreter-base.cpp
+++ b/src/map/magic-interpreter-base.cpp
@@ -19,73 +19,67 @@
// 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 "magic-interpreter-aux.hpp"
-#include "magic-interpreter.hpp"
+#include <algorithm>
#include "../strings/astring.hpp"
#include "../strings/xstring.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
-#include "../mmo/timer.hpp"
+#include "../net/timer.hpp"
+#include "magic.hpp"
#include "magic-expr.hpp"
-
+#include "magic-interpreter.hpp"
#include "pc.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
+namespace magic
+{
static
-void set_int_p(val_t *v, int i, TYPE t)
+void set_int(val_t *v, int i)
{
- v->ty = t;
- v->v.v_int = i;
+ *v = ValInt{i};
}
-#warning "This code should die"
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-macros"
-
-#define set_int(v, i) set_int_p(v, i, TYPE::INT)
-#define set_dir(v, i) set_int_p(v, i, TYPE::DIR)
+static __attribute__((unused))
+void set_dir(val_t *v, DIR d)
+{
+ *v = ValDir{d};
+}
-#define SETTER(tty, dyn_ty, field) (val_t *v, tty x) { v->ty = dyn_ty; v->v.field = x; }
static
-void set_string SETTER(dumb_string, TYPE::STRING, v_string)
+void set_string(val_t *v, dumb_string x)
+{
+ *v = ValString{x};
+}
static
void set_entity(val_t *v, dumb_ptr<block_list> e)
{
- v->ty = TYPE::ENTITY;
- v->v.v_int = e->bl_id;
+ *v = ValEntityInt{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 = ValInvocationInt{i->bl_id};
}
static
-void set_spell SETTER(dumb_ptr<spell_t>, TYPE::SPELL, v_spell)
-
-#define setenv(f, v, x) f(&(env->varu[v]), x)
-
-#define set_env_int(v, x) setenv(set_int, v, x)
-#define set_env_dir(v, x) setenv(set_dir, v, x)
-#define set_env_string(v, x) setenv(set_string, v, x)
-#define set_env_entity(v, x) setenv(set_entity, v, x)
-#define set_env_location(v, x) setenv(set_location, v, x)
-#define set_env_area(v, x) setenv(set_area, v, x)
-#define set_env_invocation(v, x) setenv(set_invocation, v, x)
-#define set_env_spell(v, x) setenv(set_spell, v, x)
-
-#pragma GCC diagnostic pop
+void set_spell(val_t *v, dumb_ptr<spell_t> x)
+{
+ *v = ValSpell{x};
+}
magic_conf_t magic_conf; /* Global magic conf */
-env_t magic_default_env = { &magic_conf, NULL };
+env_t magic_default_env = { &magic_conf, nullptr };
AString magic_find_invocation(XString spellname)
{
@@ -102,7 +96,7 @@ dumb_ptr<spell_t> magic_find_spell(XString invocation)
if (it != magic_conf.spells_by_invocation.end())
return it->second;
- return NULL;
+ return nullptr;
}
/* -------------------------------------------------------------------------------- */
@@ -125,7 +119,7 @@ dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name)
if (it != magic_conf.anchors_by_invocation.end())
return it->second;
- return NULL;
+ return nullptr;
}
/* -------------------------------------------------------------------------------- */
@@ -170,7 +164,7 @@ dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
{
case SPELLARG::STRING:
- set_env_string(spell->arg, dumb_string::copys(param));
+ set_string(&env->varu[spell->arg], dumb_string::copys(param));
break;
case SPELLARG::PC:
@@ -179,7 +173,7 @@ dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
dumb_ptr<map_session_data> subject = map_nick2sd(name);
if (!subject)
subject = caster;
- set_env_entity(spell->arg, subject);
+ set_entity(&env->varu[spell->arg], subject);
break;
}
@@ -187,13 +181,13 @@ dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
break;
default:
- FPRINTF(stderr, "Unexpected spellarg type %d\n",
- spell->spellarg_ty);
+ FPRINTF(stderr, "Unexpected spellarg type %d\n"_fmt,
+ spell->spellarg_ty);
}
- set_env_entity(VAR_CASTER, caster);
- set_env_int(VAR_SPELLPOWER, spellpower);
- set_env_spell(VAR_SPELL, spell);
+ set_entity(&env->varu[VAR_CASTER], caster);
+ set_int(&env->varu[VAR_SPELLPOWER], spellpower);
+ set_spell(&env->varu[VAR_SPELL], spell);
return env;
}
@@ -201,22 +195,22 @@ dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
static
void free_components(dumb_ptr<component_t> *component_holder)
{
- if (*component_holder == NULL)
+ if (*component_holder == nullptr)
return;
free_components(&(*component_holder)->next);
(*component_holder).delete_();
- *component_holder = NULL;
+ *component_holder = nullptr;
}
-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;
- if (*component_holder == NULL)
+ if (*component_holder == nullptr)
{
auto component = dumb_ptr<component_t>::make();
- component->next = NULL;
+ component->next = nullptr;
component->item_id = id;
component->count = count;
*component_holder = component;
@@ -238,7 +232,7 @@ void magic_add_component(dumb_ptr<component_t> *component_holder, int id, int co
static
void copy_components(dumb_ptr<component_t> *component_holder, dumb_ptr<component_t> component)
{
- if (component == NULL)
+ if (component == nullptr)
return;
magic_add_component(component_holder, component->item_id, component->count);
@@ -295,8 +289,10 @@ int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data>
{
interval_t casttime = check->casttime;
- if (env->VAR(VAR_MIN_CASTTIME).ty == TYPE::INT)
- casttime = max(casttime, static_cast<interval_t>(env->VAR(VAR_MIN_CASTTIME).v.v_int));
+ if (ValInt *v = env->VAR(VAR_MIN_CASTTIME).get_if<ValInt>())
+ {
+ casttime = std::max(casttime, static_cast<interval_t>(v->v_int));
+ }
caster->cast_tick = tick + casttime; /* Make sure not to cast too frequently */
@@ -308,37 +304,37 @@ int spellguard_can_satisfy(spellguard_check_t *check, dumb_ptr<map_session_data>
}
static
-effect_set_t *spellguard_check_sub(spellguard_check_t *check,
+const effect_set_t *spellguard_check_sub(spellguard_check_t *check,
dumb_ptr<spellguard_t> guard,
dumb_ptr<map_session_data> caster,
dumb_ptr<env_t> env,
int *near_miss)
{
- if (guard == NULL)
- return NULL;
+ if (guard == nullptr)
+ return nullptr;
- switch (guard->ty)
+ MATCH (*guard)
{
- case SPELLGUARD::CONDITION:
- if (!magic_eval_int(env, guard->s.s_condition))
- return NULL;
- break;
-
- case SPELLGUARD::COMPONENTS:
- copy_components(&check->components, guard->s.s_components);
- break;
-
- case SPELLGUARD::CATALYSTS:
- copy_components(&check->catalysts, guard->s.s_catalysts);
- break;
-
- case SPELLGUARD::CHOICE:
+ CASE (const GuardCondition&, s)
+ {
+ if (!magic_eval_int(env, s.s_condition))
+ return nullptr;
+ }
+ CASE (const GuardComponents&, s)
+ {
+ copy_components(&check->components, s.s_components);
+ }
+ CASE (const GuardCatalysts&, s)
+ {
+ copy_components(&check->catalysts, s.s_catalysts);
+ }
+ CASE (const GuardChoice&, s)
{
spellguard_check_t altcheck = *check;
- effect_set_t *retval;
+ const effect_set_t *retval;
- altcheck.components = NULL;
- altcheck.catalysts = NULL;
+ altcheck.components = nullptr;
+ altcheck.catalysts = nullptr;
copy_components(&altcheck.catalysts, check->catalysts);
copy_components(&altcheck.components, check->components);
@@ -351,42 +347,38 @@ effect_set_t *spellguard_check_sub(spellguard_check_t *check,
if (retval)
return retval;
else
- return spellguard_check_sub(check, guard->s.s_alt, caster,
+ return spellguard_check_sub(check, s.s_alt, caster,
env, near_miss);
}
-
- case SPELLGUARD::MANA:
- check->mana += magic_eval_int(env, guard->s.s_mana);
- break;
-
- case SPELLGUARD::CASTTIME:
- check->casttime += static_cast<interval_t>(magic_eval_int(env, guard->s.s_mana));
- break;
-
- case SPELLGUARD::EFFECT:
+ CASE (const GuardMana&, s)
+ {
+ check->mana += magic_eval_int(env, s.s_mana);
+ }
+ CASE (const GuardCastTime&, s)
+ {
+ check->casttime += static_cast<interval_t>(magic_eval_int(env, s.s_casttime));
+ }
+ CASE (const effect_set_t&, s_effect)
+ {
if (spellguard_can_satisfy(check, caster, env, near_miss))
- return &guard->s.s_effect;
+ return &s_effect;
else
- return NULL;
-
- default:
- FPRINTF(stderr, "Unexpected spellguard type %d\n",
- guard->ty);
- return NULL;
+ return nullptr;
+ }
}
return spellguard_check_sub(check, guard->next, caster, env, near_miss);
}
static
-effect_set_t *check_spellguard(dumb_ptr<spellguard_t> guard,
+const effect_set_t *check_spellguard(dumb_ptr<spellguard_t> guard,
dumb_ptr<map_session_data> caster, dumb_ptr<env_t> env,
int *near_miss)
{
spellguard_check_t check;
- effect_set_t *retval;
- check.catalysts = NULL;
- check.components = NULL;
+ const effect_set_t *retval;
+ check.catalysts = nullptr;
+ check.components = nullptr;
check.mana = 0;
check.casttime = interval_t::zero();
@@ -402,7 +394,7 @@ effect_set_t *check_spellguard(dumb_ptr<spellguard_t> guard,
/* Public API */
/* -------------------------------------------------------------------------------- */
-effect_set_t *spell_trigger(dumb_ptr<spell_t> spell, dumb_ptr<map_session_data> caster,
+const effect_set_t *spell_trigger(dumb_ptr<spell_t> spell, dumb_ptr<map_session_data> caster,
dumb_ptr<env_t> env, int *near_miss)
{
dumb_ptr<spellguard_t> guard = spell->spellguard;
@@ -420,10 +412,11 @@ static
void spell_set_location(dumb_ptr<invocation> invocation, dumb_ptr<block_list> entity)
{
magic_clear_var(&invocation->env->varu[VAR_LOCATION]);
- invocation->env->varu[VAR_LOCATION].ty = TYPE::LOCATION;
- invocation->env->varu[VAR_LOCATION].v.v_location.m = entity->bl_m;
- invocation->env->varu[VAR_LOCATION].v.v_location.x = entity->bl_x;
- invocation->env->varu[VAR_LOCATION].v.v_location.y = entity->bl_y;
+ ValLocation v;
+ v.v_location.m = entity->bl_m;
+ v.v_location.x = entity->bl_x;
+ v.v_location.y = entity->bl_y;
+ invocation->env->varu[VAR_LOCATION] = v;
}
void spell_update_location(dumb_ptr<invocation> invocation)
@@ -441,7 +434,7 @@ void spell_update_location(dumb_ptr<invocation> invocation)
}
}
-dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t> env)
+dumb_ptr<invocation> spell_instantiate(const effect_set_t *effect_set, dumb_ptr<env_t> env)
{
dumb_ptr<invocation> retval;
retval.new_();
@@ -449,9 +442,8 @@ 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->spell = env->VAR(VAR_SPELL).v.v_spell;
- retval->stack_size = 0;
+ retval->caster = env->VAR(VAR_CASTER).get_if<ValEntityInt>()->v_eid;
+ retval->spell = env->VAR(VAR_SPELL).get_if<ValSpell>()->v_spell;
retval->current_effect = effect_set->effect;
retval->trigger_effect = effect_set->at_trigger;
retval->end_effect = effect_set->at_end;
@@ -464,7 +456,7 @@ dumb_ptr<invocation> spell_instantiate(effect_set_t *effect_set, dumb_ptr<env_t>
retval->bl_y = caster->bl_y;
map_addblock(retval);
- set_env_invocation(VAR_INVOCATION, retval);
+ set_invocation(&env->varu[VAR_INVOCATION], retval);
return retval;
}
@@ -478,32 +470,31 @@ dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> base)
// since this is the only call site, it is expanded here
//*retval = *base;
- retval->next_invocation = NULL;
+ retval->next_invocation = nullptr;
retval->flags = INVOCATION_FLAG::ZERO;
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;
retval->script_pos = 0;
// huh?
retval->current_effect = base->trigger_effect;
retval->trigger_effect = base->trigger_effect;
- retval->end_effect = NULL;
- // retval->status_change_refs = NULL;
+ retval->end_effect = nullptr;
+ // retval->status_change_refs = nullptr;
- retval->bl_id = 0;
- retval->bl_prev = NULL;
- retval->bl_next = NULL;
+ retval->bl_id = BlockId();
+ retval->bl_prev = nullptr;
+ retval->bl_next = nullptr;
retval->bl_m = base->bl_m;
retval->bl_x = base->bl_x;
retval->bl_y = base->bl_y;
retval->bl_type = base->bl_type;
retval->bl_id = map_addobject(retval);
- set_env_invocation(VAR_INVOCATION, retval);
+ set_invocation(&env->varu[VAR_INVOCATION], retval);
return retval;
}
@@ -517,10 +508,10 @@ void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocat
if (bool(invocation->flags & INVOCATION_FLAG::BOUND)
|| invocation->subject || invocation->next_invocation)
{
- int *i = NULL;
+ int *i = nullptr;
FPRINTF(stderr,
- "[magic] INTERNAL ERROR: Attempt to re-bind spell invocation `%s'\n",
- invocation->spell->name);
+ "[magic] INTERNAL ERROR: Attempt to re-bind spell invocation `%s'\n"_fmt,
+ invocation->spell->name);
*i = 1;
return;
}
@@ -545,8 +536,8 @@ int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invoca
*seeker = invocation_->next_invocation;
invocation_->flags &= ~INVOCATION_FLAG::BOUND;
- invocation_->next_invocation = NULL;
- invocation_->subject = 0;
+ invocation_->next_invocation = nullptr;
+ invocation_->subject = BlockId();
return 0;
}
@@ -555,3 +546,5 @@ int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invoca
return 1;
}
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-interpreter-base.hpp b/src/map/magic-interpreter-base.hpp
index 9b1e08a..4bb41a0 100644
--- a/src/map/magic-interpreter-base.hpp
+++ b/src/map/magic-interpreter-base.hpp
@@ -1,8 +1,8 @@
-#ifndef TMWA_MAP_MAGIC_INTERPRETER_BASE_HPP
-#define TMWA_MAP_MAGIC_INTERPRETER_BASE_HPP
-// magic-interpreter-base.hpp - dummy header to make Make dependencies work.
+#pragma once
+// magic-interpreter-base.hpp - Core of the old magic system.
//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
+// Copyright © 2004-2011 The Mana World Development Team
+// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com>
//
// This file is part of The Mana World (Athena server)
//
@@ -19,6 +19,72 @@
// 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"
-#endif // TMWA_MAP_MAGIC_INTERPRETER_BASE_HPP
+#include "../strings/fwd.hpp"
+
+#include "../generic/fwd.hpp"
+
+#include "../mmo/fwd.hpp"
+
+
+namespace tmwa
+{
+namespace magic
+{
+extern magic_conf_t magic_conf; /* Global magic conf */
+extern env_t magic_default_env; /* Fake default environment */
+
+/**
+ * Adds a component selection to a component holder (which may initially be nullptr)
+ */
+void magic_add_component(dumb_ptr<component_t> *component_holder, ItemNameId id, int count);
+
+/**
+ * Identifies the invocation used to trigger a spell
+ *
+ * Returns empty string if not found
+ */
+AString magic_find_invocation(XString spellname);
+
+/**
+ * Identifies the invocation used to denote a teleport location
+ *
+ * Returns empty string if not found
+ */
+AString magic_find_anchor_invocation(XString teleport_location);
+
+dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name);
+
+dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
+ dumb_ptr<map_session_data> caster, int spellpower, XString param);
+
+void magic_free_env(dumb_ptr<env_t> env);
+
+/**
+ * near_miss is set to nonzero iff the spell only failed due to ephemereal issues (spell delay in effect, out of mana, out of components)
+ */
+const effect_set_t *spell_trigger(dumb_ptr<spell_t> spell,
+ dumb_ptr<map_session_data> caster,
+ dumb_ptr<env_t> env, int *near_miss);
+
+dumb_ptr<invocation> spell_instantiate(const effect_set_t *effect, dumb_ptr<env_t> env);
+
+/**
+ * Bind a spell to a subject (this is a no-op for `local' spells).
+ */
+void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation);
+
+// 1 on failure
+int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation);
+
+/**
+ * Clones a spell to run the at_effect field
+ */
+dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> source);
+
+dumb_ptr<spell_t> magic_find_spell(XString invocation);
+
+void spell_update_location(dumb_ptr<invocation> invocation);
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-interpreter.cpp b/src/map/magic-interpreter.cpp
index 4680971..389a821 100644
--- a/src/map/magic-interpreter.cpp
+++ b/src/map/magic-interpreter.cpp
@@ -1,5 +1,5 @@
#include "magic-interpreter.hpp"
-// magic-interpreter.hpp - Old magic.
+// magic-interpreter.cpp - Old magic.
//
// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
//
@@ -19,3 +19,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../poison.hpp"
+
+
+namespace tmwa
+{
+namespace magic
+{
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp
index 7d529ee..01775b3 100644
--- a/src/map/magic-interpreter.hpp
+++ b/src/map/magic-interpreter.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAGIC_INTERPRETER_HPP
-#define TMWA_MAP_MAGIC_INTERPRETER_HPP
+#pragma once
// magic-interpreter.hpp - Old magic.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -20,200 +19,356 @@
// 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"
+#include "magic-interpreter.t.hpp"
-# include <cassert>
+#include <cassert>
-# include "../strings/fwd.hpp"
-# include "../strings/rstring.hpp"
+#include <memory>
-# include "magic.hpp"
-# include "map.hpp"
-# include "script.hpp"
-# include "skill.t.hpp"
+#include "../strings/fwd.hpp"
+#include "../strings/rstring.hpp"
-struct fun_t;
-struct op_t;
-struct expr_t;
-struct val_t;
-struct location_t;
-struct area_t;
-struct spell_t;
-struct invocation;
+#include "../generic/fwd.hpp"
+#include "../sexpr/variant.hpp"
+
+#include "../net/timer.t.hpp"
+
+#include "../mmo/ids.hpp"
+#include "../mmo/utils.hpp"
+
+#include "map.hpp"
+#include "script.hpp"
+#include "skill.t.hpp"
+
+
+namespace tmwa
+{
+namespace magic
+{
struct location_t
{
map_local *m;
int x, y;
};
-struct area_t
+struct AreaUnion
+{
+ dumb_ptr<area_t> a_union[2];
+};
+struct AreaRect
+{
+ location_t loc;
+ int width, height;
+};
+struct AreaBar
+{
+ location_t loc;
+ int width, depth;
+ DIR dir;
+};
+
+using AreaVariantBase = Variant<
+ location_t,
+ AreaUnion,
+ AreaRect,
+ AreaBar
+>;
+
+struct area_t : AreaVariantBase
{
- union au
- {
- location_t a_loc;
- struct
- {
- location_t loc;
- int width, depth;
- DIR dir;
- } a_bar;
- struct
- {
- location_t loc;
- int width, height;
- } a_rect;
- dumb_ptr<area_t> a_union[2];
-
- au() { really_memzero_this(this); }
- ~au() = default;
- au(const au&) = default;
- au& operator = (const au&) = default;
- } a;
int size;
- AREA ty;
+
+ area_t() = delete;
+ area_t(area_t&&) = default;
+ area_t(const area_t&) = delete;
+ area_t& operator = (area_t&&) = default;
+ area_t& operator = (const area_t&) = delete;
+
+ area_t(location_t v, int sz) : AreaVariantBase(std::move(v)), size(sz) {}
+ area_t(AreaUnion v, int sz) : AreaVariantBase(std::move(v)), size(sz) {}
+ area_t(AreaRect v, int sz) : AreaVariantBase(std::move(v)), size(sz) {}
+ area_t(AreaBar v, int sz) : AreaVariantBase(std::move(v)), size(sz) {}
};
-struct val_t
+struct ValUndef
+{
+};
+struct ValInt
+{
+ int v_int;
+};
+struct ValDir
+{
+ DIR v_dir;
+};
+struct ValString
+{
+ dumb_string v_string;
+};
+struct ValEntityInt
+{
+ BlockId v_eid;
+};
+struct ValEntityPtr
+{
+ dumb_ptr<block_list> v_entity;
+};
+struct ValLocation
+{
+ location_t v_location;
+};
+struct ValArea
+{
+ dumb_ptr<area_t> v_area;
+};
+struct ValSpell
+{
+ dumb_ptr<spell_t> v_spell;
+};
+struct ValInvocationInt
+{
+ BlockId v_iid;
+};
+struct ValInvocationPtr
+{
+ dumb_ptr<invocation> v_invocation;
+};
+struct ValFail
+{
+};
+struct ValNegative1
{
- union vu
- {
- int v_int;
- DIR v_dir;
- dumb_string v_string;
- /* Used ONLY during operation/function invocation; otherwise we use v_int */
- dumb_ptr<block_list> v_entity;
- dumb_ptr<area_t> v_area;
- location_t v_location;
- /* Used ONLY during operation/function invocation; otherwise we use v_int */
- dumb_ptr<invocation> v_invocation;
- dumb_ptr<spell_t> v_spell;
-
- vu() { really_memzero_this(this); }
- ~vu() = default;
- vu(const vu&) = default;
- vu& operator = (const vu&) = default;
- } v;
- TYPE ty;
};
+using ValVariantBase = Variant<
+ ValUndef,
+ ValInt,
+ ValDir,
+ ValString,
+ ValEntityInt,
+ ValEntityPtr,
+ ValLocation,
+ ValArea,
+ ValSpell,
+ ValInvocationInt,
+ ValInvocationPtr,
+ ValFail,
+ ValNegative1
+>;
+struct val_t : ValVariantBase
+{
+ val_t() noexcept : ValVariantBase(ValUndef{}) {}
+ val_t(val_t&&) = default;
+ val_t(const val_t&) = delete;
+ val_t& operator = (val_t&&) = default;
+ val_t& operator = (const val_t&) = delete;
+
+ val_t(ValUndef v) : ValVariantBase(std::move(v)) {}
+ val_t(ValInt v) : ValVariantBase(std::move(v)) {}
+ val_t(ValDir v) : ValVariantBase(std::move(v)) {}
+ val_t(ValString v) : ValVariantBase(std::move(v)) {}
+ val_t(ValEntityInt v) : ValVariantBase(std::move(v)) {}
+ val_t(ValEntityPtr v) : ValVariantBase(std::move(v)) {}
+ val_t(ValLocation v) : ValVariantBase(std::move(v)) {}
+ val_t(ValArea v) : ValVariantBase(std::move(v)) {}
+ val_t(ValSpell v) : ValVariantBase(std::move(v)) {}
+ val_t(ValInvocationInt v) : ValVariantBase(std::move(v)) {}
+ val_t(ValInvocationPtr v) : ValVariantBase(std::move(v)) {}
+ val_t(ValFail v) : ValVariantBase(std::move(v)) {}
+ val_t(ValNegative1 v) : ValVariantBase(std::move(v)) {}
+};
+
+
/* ----------- */
/* Expressions */
/* ----------- */
-# define MAX_ARGS 7 /* Max. # of args used in builtin primitive functions */
+#define MAX_ARGS 7 /* Max. # of args used in builtin primitive functions */
+
+struct e_area_t;
struct e_location_t
{
dumb_ptr<expr_t> m, x, y;
+
+ e_location_t() noexcept : m(), x(), y() {}
+};
+struct ExprAreaUnion
+{
+ dumb_ptr<e_area_t> a_union[2];
+};
+struct ExprAreaRect
+{
+ e_location_t loc;
+ dumb_ptr<expr_t> width, height;
+};
+struct ExprAreaBar
+{
+ e_location_t loc;
+ dumb_ptr<expr_t> width, depth, dir;
};
-struct e_area_t
+using ExprAreaVariantBase = Variant<
+ e_location_t,
+ ExprAreaUnion,
+ ExprAreaRect,
+ ExprAreaBar
+>;
+
+struct e_area_t : ExprAreaVariantBase
{
- union a0
- {
- e_location_t a_loc;
- struct
- {
- e_location_t loc;
- dumb_ptr<expr_t> width, depth, dir;
- } a_bar;
- struct
- {
- e_location_t loc;
- dumb_ptr<expr_t> width, height;
- } a_rect;
- dumb_ptr<e_area_t> a_union[2];
-
- a0() { really_memzero_this(this); }
- ~a0() = default;
- a0(const a0&) = default;
- a0& operator = (const a0&) = default;
- } a;
- AREA ty;
-};
-
-struct expr_t
-{
- union eu
- {
- val_t e_val;
- e_location_t e_location;
- e_area_t e_area;
- struct
- {
- fun_t *funp;
- int line_nr, column;
- int args_nr;
- dumb_ptr<expr_t> args[MAX_ARGS];
- } e_funapp;
- int e_id;
- struct
- {
- dumb_ptr<expr_t> expr;
- int id;
- } e_field;
-
- eu() { really_memzero_this(this); }
- ~eu() = default;
- eu(const eu&) = default;
- eu& operator = (const eu&) = default;
- } e;
- EXPR ty;
-};
-
-struct effect_t
+ e_area_t() = delete;
+ e_area_t(e_area_t&&) = default;
+ e_area_t(const e_area_t&) = delete;
+ e_area_t& operator = (e_area_t&&) = default;
+ e_area_t& operator = (const e_area_t&) = delete;
+
+ e_area_t(e_location_t v) : ExprAreaVariantBase(std::move(v)) {}
+ e_area_t(ExprAreaUnion v) : ExprAreaVariantBase(std::move(v)) {}
+ e_area_t(ExprAreaRect v) : ExprAreaVariantBase(std::move(v)) {}
+ e_area_t(ExprAreaBar v) : ExprAreaVariantBase(std::move(v)) {}
+};
+
+struct ExprFunApp
+{
+ fun_t *funp;
+ int line_nr, column;
+ int args_nr;
+ dumb_ptr<expr_t> args[MAX_ARGS];
+};
+struct ExprId
+{
+ int e_id;
+};
+struct ExprField
+{
+ dumb_ptr<expr_t> expr;
+ int id;
+};
+
+using ExprVariantBase = Variant<
+ val_t,
+ e_location_t,
+ e_area_t,
+ ExprFunApp,
+ ExprId,
+ ExprField
+>;
+struct expr_t : ExprVariantBase
+{
+ expr_t() = delete;
+ expr_t(expr_t&&) = default;
+ expr_t(const expr_t&) = delete;
+ expr_t& operator = (expr_t&&) = default;
+ expr_t& operator = (const expr_t&) = delete;
+
+ expr_t(val_t v) : ExprVariantBase(std::move(v)) {}
+ expr_t(e_location_t v) : ExprVariantBase(std::move(v)) {}
+ expr_t(e_area_t v) : ExprVariantBase(std::move(v)) {}
+ expr_t(ExprFunApp v) : ExprVariantBase(std::move(v)) {}
+ expr_t(ExprId v) : ExprVariantBase(std::move(v)) {}
+ expr_t(ExprField v) : ExprVariantBase(std::move(v)) {}
+};
+
+
+struct effect_t;
+
+struct EffectSkip
+{
+};
+struct EffectAbort
+{
+};
+struct EffectAssign
+{
+ int id;
+ dumb_ptr<expr_t> expr;
+};
+struct EffectForEach
+{
+ int id;
+ dumb_ptr<expr_t> area;
+ dumb_ptr<effect_t> body;
+ FOREACH_FILTER filter;
+};
+struct EffectFor
+{
+ int id;
+ dumb_ptr<expr_t> start, stop;
+ dumb_ptr<effect_t> body;
+};
+struct EffectIf
+{
+ dumb_ptr<expr_t> cond;
+ dumb_ptr<effect_t> true_branch, false_branch;
+};
+struct EffectSleep
+{
+ dumb_ptr<expr_t> e_sleep; /* sleep time */
+};
+struct EffectScript
+{
+ dumb_ptr<const ScriptBuffer> e_script;
+};
+struct EffectBreak
+{
+};
+struct EffectOp
+{
+ op_t *opp;
+ int args_nr;
+ int line_nr, column;
+ dumb_ptr<expr_t> args[MAX_ARGS];
+};
+struct EffectEnd
+{
+};
+struct EffectCall
+{
+ std::vector<int> *formalv;
+ dumb_ptr<std::vector<dumb_ptr<expr_t>>> actualvp;
+ dumb_ptr<effect_t> body;
+};
+
+using EffectVariantBase = Variant<
+ EffectSkip,
+ EffectAbort,
+ EffectAssign,
+ EffectForEach,
+ EffectFor,
+ EffectIf,
+ EffectSleep,
+ EffectScript,
+ EffectBreak,
+ EffectOp,
+ EffectEnd,
+ EffectCall
+>;
+struct effect_t : EffectVariantBase
{
dumb_ptr<effect_t> next;
- union e0
- {
- struct
- {
- int id;
- dumb_ptr<expr_t> expr;
- } e_assign;
- struct
- {
- int id;
- dumb_ptr<expr_t> area;
- dumb_ptr<effect_t> body;
- FOREACH_FILTER filter;
- } e_foreach;
- struct
- {
- int id;
- dumb_ptr<expr_t> start, stop;
- dumb_ptr<effect_t> body;
- } e_for;
- struct
- {
- dumb_ptr<expr_t> cond;
- dumb_ptr<effect_t> true_branch, false_branch;
- } e_if;
- dumb_ptr<expr_t> e_sleep; /* sleep time */
- dumb_ptr<const ScriptBuffer> e_script;
- struct
- {
- op_t *opp;
- int args_nr;
- int line_nr, column;
- dumb_ptr<expr_t> args[MAX_ARGS];
- } e_op;
- struct
- {
- std::vector<int> *formalv;
- dumb_ptr<std::vector<dumb_ptr<expr_t>>> actualvp;
- dumb_ptr<effect_t> body;
- } e_call;
-
- e0() { really_memzero_this(this); }
- ~e0() = default;
- e0(const e0&) = default;
- e0& operator = (const e0&) = default;
- } e;
- EFFECT ty;
+
+ effect_t() = delete;
+ effect_t(effect_t&&) = default;
+ effect_t(const effect_t&) = delete;
+ effect_t& operator = (effect_t&&) = default;
+ effect_t& operator = (const effect_t&) = delete;
+
+ effect_t(EffectSkip v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectAbort v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectAssign v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectForEach v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectFor v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectIf v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectSleep v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectScript v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectBreak v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectOp v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectEnd v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
+ effect_t(EffectCall v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {}
};
/* ---------- */
@@ -223,34 +378,67 @@ struct effect_t
struct component_t
{
dumb_ptr<component_t> next;
- int item_id;
+ ItemNameId item_id;
int count;
};
+struct spellguard_t;
+struct GuardCondition
+{
+ dumb_ptr<expr_t> s_condition;
+};
+struct GuardMana
+{
+ dumb_ptr<expr_t> s_mana;
+};
+struct GuardCastTime
+{
+ dumb_ptr<expr_t> s_casttime;
+};
+struct GuardComponents
+{
+ dumb_ptr<component_t> s_components;
+};
+struct GuardCatalysts
+{
+ dumb_ptr<component_t> s_catalysts;
+};
+struct GuardChoice
+{
+ dumb_ptr<spellguard_t> s_alt; /* either `next' or `s.s_alt' */
+};
struct effect_set_t
{
dumb_ptr<effect_t> effect, at_trigger, at_end;
};
-struct spellguard_t
+using SpellGuardVariantBase = Variant<
+ GuardCondition,
+ GuardMana,
+ GuardCastTime,
+ GuardComponents,
+ GuardCatalysts,
+ GuardChoice,
+ effect_set_t
+>;
+struct spellguard_t : SpellGuardVariantBase
{
dumb_ptr<spellguard_t> next;
- union su
- {
- dumb_ptr<expr_t> s_condition;
- dumb_ptr<expr_t> s_mana;
- dumb_ptr<expr_t> s_casttime;
- dumb_ptr<component_t> s_components;
- dumb_ptr<component_t> s_catalysts;
- dumb_ptr<spellguard_t> s_alt; /* either `next' or `s.s_alt' */
- effect_set_t s_effect;
- su() { really_memzero_this(this); }
- ~su() = default;
- su(const su&) = default;
- su& operator = (const su&) = default;
- } s;
- SPELLGUARD ty;
+
+ spellguard_t() = delete;
+ spellguard_t(spellguard_t&&) = default;
+ spellguard_t(const spellguard_t&) = delete;
+ spellguard_t& operator = (spellguard_t&&) = default;
+ spellguard_t& operator = (const spellguard_t&) = delete;
+
+ spellguard_t(GuardCondition v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {}
+ spellguard_t(GuardMana v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {}
+ spellguard_t(GuardCastTime v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {}
+ spellguard_t(GuardComponents v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {}
+ spellguard_t(GuardCatalysts v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {}
+ spellguard_t(GuardChoice v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {}
+ spellguard_t(effect_set_t v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {}
};
/* ------ */
@@ -309,17 +497,15 @@ struct magic_conf_t
/* Execution environment */
// these are not an enum they're a nasty intern hack
-# define VAR_MIN_CASTTIME 0
-# define VAR_OBSCURE_CHANCE 1
-# define VAR_CASTER 2
-# define VAR_SPELLPOWER 3
-# define VAR_SPELL 4
-# define VAR_INVOCATION 5
-# define VAR_TARGET 6
-# define VAR_SCRIPTTARGET 7
-# define VAR_LOCATION 8
-
-struct magic_config;
+#define VAR_MIN_CASTTIME 0
+#define VAR_OBSCURE_CHANCE 1
+#define VAR_CASTER 2
+#define VAR_SPELLPOWER 3
+#define VAR_SPELL 4
+#define VAR_INVOCATION 5
+#define VAR_TARGET 6
+#define VAR_SCRIPTTARGET 7
+#define VAR_LOCATION 8
struct env_t
{
@@ -329,7 +515,7 @@ struct env_t
val_t& VAR(size_t i)
{
assert (varu);
- if (varu[i].ty == TYPE::UNDEF)
+ if (varu[i].is<ValUndef>())
return base_env->varv[i].val;
else
return varu[i];
@@ -337,47 +523,53 @@ struct env_t
};
-# define MAX_STACK_SIZE 32
+struct CarForEach
+{
+ int id;
+ bool ty_is_spell_not_entity;
+ dumb_ptr<effect_t> body;
+ dumb_ptr<std::vector<BlockId>> entities_vp;
+ int index;
+};
+struct CarFor
+{
+ int id;
+ dumb_ptr<effect_t> body;
+ int current;
+ int stop;
+};
+struct CarProc
+{
+ int args_nr;
+ int *formalap;
+ dumb_ptr<val_t[]> old_actualpa;
+};
-struct cont_activation_record_t
+using CarVariantBase = Variant<
+ CarForEach,
+ CarFor,
+ CarProc
+>;
+
+struct cont_activation_record_t : CarVariantBase
{
dumb_ptr<effect_t> return_location;
- union cu
- {
- struct
- {
- int id;
- TYPE ty;
- dumb_ptr<effect_t> body;
- dumb_ptr<std::vector<int>> entities_vp;
- int index;
- } c_foreach;
- struct
- {
- int id;
- dumb_ptr<effect_t> body;
- int current;
- int stop;
- } c_for;
- struct
- {
- int args_nr;
- int *formalap;
- dumb_ptr<val_t[]> old_actualpa;
- } c_proc;
-
- cu() { really_memzero_this(this); }
- ~cu() = default;
- cu(const cu&) = default;
- cu& operator = (const cu&) = default;
- } c;
- CONT_STACK ty;
+
+ cont_activation_record_t() = delete;
+ cont_activation_record_t(cont_activation_record_t&&) = default;
+ cont_activation_record_t(const cont_activation_record_t&) = delete;
+ cont_activation_record_t& operator = (cont_activation_record_t&&) = default;
+ cont_activation_record_t& operator = (const cont_activation_record_t&) = delete;
+
+ cont_activation_record_t(CarForEach v, dumb_ptr<effect_t> rl) : CarVariantBase(std::move(v)), return_location(rl) {}
+ cont_activation_record_t(CarFor v, dumb_ptr<effect_t> rl) : CarVariantBase(std::move(v)), return_location(rl) {}
+ cont_activation_record_t(CarProc v, dumb_ptr<effect_t> rl) : CarVariantBase(std::move(v)), return_location(rl) {}
};
struct status_change_ref_t
{
StatusChange sc_type;
- int bl_id;
+ BlockId bl_id;
};
struct invocation : block_list
@@ -387,66 +579,30 @@ 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 */
- int stack_size;
- cont_activation_record_t stack[MAX_STACK_SIZE];
+ std::vector<cont_activation_record_t> stack;
int script_pos; /* Script position; if nonzero, resume the script we were running. */
dumb_ptr<effect_t> current_effect;
- dumb_ptr<effect_t> trigger_effect; /* If non-NULL, this is used to spawn a cloned effect based on the same environment */
- dumb_ptr<effect_t> end_effect; /* If non-NULL, this is executed when the spell terminates naturally, e.g. when all status changes have run out or all delays are over. */
+ dumb_ptr<effect_t> trigger_effect; /* If non-nullptr, this is used to spawn a cloned effect based on the same environment */
+ dumb_ptr<effect_t> end_effect; /* If non-nullptr, this is executed when the spell terminates naturally, e.g. when all status changes have run out or all delays are over. */
/* Status change references: for status change updates, keep track of whom we updated where */
std::vector<status_change_ref_t> status_change_refv;
};
+} // namespace magic
-inline dumb_ptr<invocation> block_list::as_spell() { return dumb_ptr<invocation>(static_cast<invocation *>(this)); }
-inline dumb_ptr<invocation> block_list::is_spell() { return bl_type == BL::SPELL ? as_spell() : nullptr; }
-
-extern magic_conf_t magic_conf; /* Global magic conf */
-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);
-
-dumb_ptr<teleport_anchor_t> magic_find_anchor(XString name);
-
-dumb_ptr<env_t> spell_create_env(magic_conf_t *conf, dumb_ptr<spell_t> spell,
- dumb_ptr<map_session_data> caster, int spellpower, XString param);
-
-void magic_free_env(dumb_ptr<env_t> env);
-
-/**
- * near_miss is set to nonzero iff the spell only failed due to ephemereal issues (spell delay in effect, out of mana, out of components)
- */
-effect_set_t *spell_trigger(dumb_ptr<spell_t> spell,
- dumb_ptr<map_session_data> caster,
- dumb_ptr<env_t> env, int *near_miss);
-
-dumb_ptr<invocation> spell_instantiate(effect_set_t *effect, dumb_ptr<env_t> env);
-
-/**
- * Bind a spell to a subject (this is a no-op for `local' spells).
- */
-void spell_bind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation);
-
-// 1 on failure
-int spell_unbind(dumb_ptr<map_session_data> subject, dumb_ptr<invocation> invocation);
-
-/**
- * Clones a spell to run the at_effect field
- */
-dumb_ptr<invocation> spell_clone_effect(dumb_ptr<invocation> source);
-
-dumb_ptr<spell_t> magic_find_spell(XString invocation);
+// inlines for map.hpp
+inline dumb_ptr<magic::invocation> block_list::as_spell() { return dumb_ptr<magic::invocation>(static_cast<magic::invocation *>(this)); }
+inline dumb_ptr<magic::invocation> block_list::is_spell() { return bl_type == BL::SPELL ? as_spell() : nullptr; }
+namespace magic
+{
/* The following is used only by the parser: */
struct args_rec_t
{
@@ -465,7 +621,5 @@ struct proc_t
, body()
{}
};
-
-void spell_update_location(dumb_ptr<invocation> invocation);
-
-#endif // TMWA_MAP_MAGIC_INTERPRETER_HPP
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-interpreter.py b/src/map/magic-interpreter.py
index 8170f27..f6fa4c9 100644
--- a/src/map/magic-interpreter.py
+++ b/src/map/magic-interpreter.py
@@ -2,7 +2,7 @@ class area_t(object):
''' print an area_t
'''
__slots__ = ('_value')
- name = 'area_t'
+ name = 'tmwa::area_t'
enabled = True
def __init__(self, value):
@@ -31,7 +31,7 @@ class val_t(object):
''' print a val_t
'''
__slots__ = ('_value')
- name = 'val_t'
+ name = 'tmwa::val_t'
enabled = True
def __init__(self, value):
@@ -69,7 +69,7 @@ class e_area_t(object):
''' print an e_area_t
'''
__slots__ = ('_value')
- name = 'e_area_t'
+ name = 'tmwa::e_area_t'
enabled = True
def __init__(self, value):
@@ -97,7 +97,7 @@ class expr_t(object):
''' print an expr_t
'''
__slots__ = ('_value')
- name = 'expr_t'
+ name = 'tmwa::expr_t'
enabled = True
def __init__(self, value):
@@ -129,7 +129,7 @@ class effect_t(object):
''' print an effect_t
'''
__slots__ = ('_value')
- name = 'effect_t'
+ name = 'tmwa::effect_t'
enabled = True
def __init__(self, value):
@@ -166,7 +166,7 @@ class spellguard_t(object):
''' print a spellguard_t
'''
__slots__ = ('_value')
- name = 'spellguard_t'
+ name = 'tmwa::spellguard_t'
enabled = True
def __init__(self, value):
@@ -201,7 +201,7 @@ class cont_activation_record_t(object):
''' print a cont_activation_record_t
'''
__slots__ = ('_value')
- name = 'cont_activation_record_t'
+ name = 'tmwa::cont_activation_record_t'
enabled = True
def __init__(self, value):
diff --git a/src/map/magic-interpreter.t.hpp b/src/map/magic-interpreter.t.hpp
index 9310a7b..ab151fc 100644
--- a/src/map/magic-interpreter.t.hpp
+++ b/src/map/magic-interpreter.t.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAGIC_INTERPRETER_T_HPP
-#define TMWA_MAP_MAGIC_INTERPRETER_T_HPP
+#pragma once
// magic-interpreter.t.hpp - Old magic.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -20,10 +19,15 @@
// 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"
+#include "../generic/enum.hpp"
+
+namespace tmwa
+{
+namespace magic
+{
enum class SPELLARG : uint8_t
{
NONE,
@@ -31,90 +35,6 @@ enum class SPELLARG : uint8_t
STRING,
};
-enum class TYPE : uint8_t
-{
- UNDEF,
- INT,
- DIR,
- STRING,
- ENTITY,
- LOCATION,
- AREA,
- SPELL,
- INVOCATION,
- FAIL = 127,
-
- NEGATIVE_1 = 255,
-};
-
-// Note: there is also a typedef by this name in <dirent.h>
-// but we should be fine since we never include it.
-// (in the long term we should still rename this though)
-enum class DIR : uint8_t
-{
- S = 0,
- SW = 1,
- W = 2,
- NW = 3,
- N = 4,
- NE = 5,
- E = 6,
- SE = 7,
-
- COUNT,
-};
-
-constexpr
-earray<int, DIR, DIR::COUNT> dirx //=
-{{
- 0, -1, -1, -1, 0, 1, 1, 1,
-}}, diry //=
-{{
- 1, 1, 0, -1, -1, -1, 0, 1,
-}};
-
-constexpr
-bool dir_is_diagonal(DIR d)
-{
- return static_cast<uint8_t>(d) & 1;
-}
-
-enum class AREA : uint8_t
-{
- LOCATION,
- UNION,
- RECT,
- BAR,
-};
-
-enum class EXPR : uint8_t
-{
- VAL,
- LOCATION,
- AREA,
- FUNAPP,
- ID,
- SPELLFIELD,
-};
-
-// temporary rename to avoid collision with enum value
-// in magic-interpreter-parser
-enum class EFFECT : uint8_t
-{
- SKIP,
- ABORT,
- ASSIGN,
- FOREACH,
- FOR,
- IF,
- SLEEP,
- SCRIPT,
- BREAK,
- OP,
- END,
- CALL,
-};
-
enum class FOREACH_FILTER : uint8_t
{
MOB,
@@ -125,17 +45,6 @@ enum class FOREACH_FILTER : uint8_t
NPC,
};
-enum class SPELLGUARD : uint8_t
-{
- CONDITION,
- COMPONENTS,
- CATALYSTS,
- CHOICE,
- MANA,
- CASTTIME,
- EFFECT,
-};
-
namespace e
{
enum class SPELL_FLAG : uint8_t
@@ -153,13 +62,6 @@ ENUM_BITWISE_OPERATORS(SPELL_FLAG)
}
using e::SPELL_FLAG;
-enum class CONT_STACK : uint8_t
-{
- FOREACH,
- FOR,
- PROC,
-};
-
namespace e
{
enum class INVOCATION_FLAG : uint8_t
@@ -176,5 +78,5 @@ enum class INVOCATION_FLAG : uint8_t
ENUM_BITWISE_OPERATORS(INVOCATION_FLAG)
}
using e::INVOCATION_FLAG;
-
-#endif // TMWA_MAP_MAGIC_INTERPRETER_T_HPP
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp
index ba99409..fd02d45 100644
--- a/src/map/magic-stmt.cpp
+++ b/src/map/magic-stmt.cpp
@@ -29,16 +29,17 @@
#include "../generic/random2.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
-#include "../mmo/timer.hpp"
+#include "../net/timer.hpp"
+#include "battle.hpp"
+#include "clif.hpp"
+#include "magic.hpp"
#include "magic-expr.hpp"
#include "magic-expr-eval.hpp"
#include "magic-interpreter.hpp"
-#include "magic-interpreter-aux.hpp"
-
-#include "battle.hpp"
-#include "clif.hpp"
+#include "magic-interpreter-base.hpp"
#include "mob.hpp"
#include "npc.hpp"
#include "pc.hpp"
@@ -46,69 +47,32 @@
#include "../poison.hpp"
-/* used for local spell effects */
-constexpr int INVISIBLE_NPC = 127;
-
-//#define DEBUG
-#ifdef DEBUG
-static
-void print_val(val_t *v)
+namespace tmwa
{
- switch (v->ty)
- {
- case TYPE::UNDEF:
- FPRINTF(stderr, "UNDEF");
- break;
- case TYPE::INT:
- FPRINTF(stderr, "%d", v->v.v_int);
- break;
- case TYPE::DIR:
- FPRINTF(stderr, "dir%d", v->v.v_int);
- break;
- case TYPE::STRING:
- FPRINTF(stderr, "`%s'", v->v.v_string);
- break;
- default:
- FPRINTF(stderr, "ty%d", v->ty);
- break;
- }
-}
-
-static
-void dump_env(env_t *env)
+namespace magic
{
- int i;
- for (i = 0; i < env->base_env->vars_nr; i++)
- {
- val_t *v = &env->vars[i];
- val_t *bv = &env->base_env->vars[i];
-
- FPRINTF(stderr, "%02x %30s ", i, env->base_env->var_name[i]);
- print_val(v);
- FPRINTF(stderr, "\t(");
- print_val(bv);
- FPRINTF(stderr, ")\n");
- }
-}
-#endif
+/* used for local spell effects */
+constexpr Species INVISIBLE_NPC = wrap<Species>(127);
static
void clear_activation_record(cont_activation_record_t *ar)
{
- switch (ar->ty)
+ MATCH (*ar)
{
- case CONT_STACK::FOREACH:
- ar->c.c_foreach.entities_vp.delete_();
- break;
- case CONT_STACK::PROC:
- ar->c.c_proc.old_actualpa.delete_();
- break;
+ CASE (CarForEach&, c_foreach)
+ {
+ c_foreach.entities_vp.delete_();
+ }
+ CASE (CarProc&, c_proc)
+ {
+ c_proc.old_actualpa.delete_();
+ }
}
}
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);
@@ -123,10 +87,10 @@ void clear_stack(dumb_ptr<invocation> invocation_)
{
int i;
- for (i = 0; i < invocation_->stack_size; i++)
+ for (i = 0; i < invocation_->stack.size(); i++)
clear_activation_record(&invocation_->stack[i]);
- invocation_->stack_size = 0;
+ invocation_->stack.clear();
}
void spell_free_invocation(dumb_ptr<invocation> invocation_)
@@ -153,7 +117,7 @@ void spell_free_invocation(dumb_ptr<invocation> invocation_)
static
void char_set_weapon_icon(dumb_ptr<map_session_data> subject, int count,
- StatusChange icon, int look)
+ StatusChange icon, ItemNameId look)
{
const StatusChange old_icon = subject->attack_spell_icon_override;
@@ -166,7 +130,7 @@ void char_set_weapon_icon(dumb_ptr<map_session_data> subject, int count,
clif_fixpcpos(subject);
if (count)
{
- clif_changelook(subject, LOOK::WEAPON, look);
+ clif_changelook(subject, LOOK::WEAPON, unwrap<ItemNameId>(look));
if (icon != StatusChange::ZERO)
clif_status_change(subject, icon, 1);
}
@@ -202,7 +166,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,8 +176,8 @@ 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;
- char_set_weapon_icon(c, 0, StatusChange::ZERO, 0);
+ c->attack_spell_override = BlockId();
+ char_set_weapon_icon(c, 0, StatusChange::ZERO, ItemNameId());
char_set_attack_info(c, interval_t::zero(), 0);
}
}
@@ -228,7 +192,7 @@ void try_to_finish_invocation(dumb_ptr<invocation> invocation)
{
clear_stack(invocation);
invocation->current_effect = invocation->end_effect;
- invocation->end_effect = NULL;
+ invocation->end_effect = nullptr;
spell_execute(invocation);
}
else
@@ -237,19 +201,18 @@ 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] = ValEntityInt{subject};
return invocation_->bl_id;
}
@@ -265,7 +228,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)
@@ -286,12 +249,12 @@ void magic_unshroud(dumb_ptr<map_session_data> other_char)
other_char->state.shroud_active = 0;
// Now warp the caster out of and back into here to refresh everyone's display
char_update(other_char);
- clif_displaymessage(other_char->sess, "Your shroud has been dispelled!");
+ clif_displaymessage(other_char->sess, "Your shroud has been dispelled!"_s);
// entity_effect(other_char, MAGIC_EFFECT_REVEAL);
}
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);
@@ -302,10 +265,10 @@ dumb_ptr<npc_data> local_spell_effect(map_local *m, int x, int y, int effect,
interval_t tdelay)
{
/* 1 minute should be enough for all interesting spell effects, I hope */
- std::chrono::seconds delay = std::chrono::seconds(30);
+ std::chrono::seconds delay = 30_s;
dumb_ptr<npc_data> effect_npc = npc_spawn_text(m, x, y,
- INVISIBLE_NPC, NpcName(), "?");
- int effect_npc_id = effect_npc->bl_id;
+ INVISIBLE_NPC, NpcName(), "?"_s);
+ BlockId effect_npc_id = effect_npc->bl_id;
entity_effect(effect_npc, effect, tdelay);
Timer(gettick() + delay,
@@ -321,11 +284,11 @@ int op_sfx(dumb_ptr<env_t>, Slice<val_t> args)
{
interval_t delay = static_cast<interval_t>(ARGINT(2));
- if (ARG_TYPE(0) == TYPE::ENTITY)
+ if (args[0].is<ValEntityPtr>())
{
entity_effect(ARGENTITY(0), ARGINT(1), delay);
}
- else if (ARG_TYPE(0) == TYPE::LOCATION)
+ else if (args[0].is<ValLocation>())
{
local_spell_effect(ARGLOCATION(0).m,
ARGLOCATION(0).x,
@@ -340,8 +303,10 @@ int op_sfx(dumb_ptr<env_t>, Slice<val_t> args)
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;
+ assert (!env->VAR(VAR_CASTER).is<ValEntityPtr>());
+ ValEntityInt *caster_id = env->VAR(VAR_CASTER).get_if<ValEntityInt>();
+ dumb_ptr<block_list> caster = caster_id
+ ? map_id2bl(caster_id->v_eid) : nullptr;
dumb_ptr<block_list> subject = ARGENTITY(0);
if (!caster)
caster = subject;
@@ -350,8 +315,8 @@ int op_instaheal(dumb_ptr<env_t> env, Slice<val_t> args)
{
dumb_ptr<map_session_data> caster_pc = caster->is_player();
dumb_ptr<map_session_data> subject_pc = subject->is_player();
- MAP_LOG_PC(caster_pc, "SPELLHEAL-INSTA PC%d FOR %d",
- subject_pc->status_key.char_id, ARGINT(1));
+ MAP_LOG_PC(caster_pc, "SPELLHEAL-INSTA PC%d FOR %d"_fmt,
+ subject_pc->status_key.char_id, ARGINT(1));
}
battle_heal(caster, subject, ARGINT(1), ARGINT(2), 0);
@@ -430,7 +395,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)
@@ -445,7 +410,7 @@ int op_messenger_npc(dumb_ptr<env_t>, Slice<val_t> args)
NpcName npcname = stringish<NpcName>(ARGSTR(2));
npc = npc_spawn_text(loc->m, loc->x, loc->y,
- ARGINT(1), npcname, ARGSTR(3));
+ wrap<Species>(static_cast<uint16_t>(ARGINT(1))), npcname, ARGSTR(3));
Timer(gettick() + static_cast<interval_t>(ARGINT(4)),
std::bind(timer_callback_kill_npc, ph::_1, ph::_2,
@@ -537,7 +502,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 +516,10 @@ 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;
+ assert (!env->VAR(VAR_INVOCATION).is<ValInvocationPtr>());
+ ValInvocationInt *ii = env->VAR(VAR_INVOCATION).get_if<ValInvocationInt>();
+ BlockId invocation_id = ii
+ ? ii->v_iid : BlockId();
dumb_ptr<invocation> invocation_ = map_id_is_spell(invocation_id);
assert (!ARGINT(3));
@@ -563,7 +530,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;
}
@@ -587,7 +554,7 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args)
interval_t attack_delay = static_cast<interval_t>(ARGINT(2));
int attack_range = ARGINT(3);
StatusChange icon = StatusChange(ARGINT(4));
- int look = ARGINT(5);
+ ItemNameId look = wrap<ItemNameId>(static_cast<uint16_t>(ARGINT(5)));
int stopattack = ARGINT(6);
dumb_ptr<map_session_data> subject;
@@ -603,8 +570,9 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args)
spell_free_invocation(old_invocation);
}
+ ValInvocationInt *ii = env->VAR(VAR_INVOCATION).get_if<ValInvocationInt>();
subject->attack_spell_override =
- trigger_spell(subject->bl_id, env->VAR(VAR_INVOCATION).v.v_int);
+ trigger_spell(subject->bl_id, ii->v_iid);
subject->attack_spell_charges = charges;
if (subject->attack_spell_override)
@@ -623,7 +591,7 @@ int op_override_attack(dumb_ptr<env_t> env, Slice<val_t> args)
static
int op_create_item(dumb_ptr<env_t>, Slice<val_t> args)
{
- struct item item;
+ Item item;
dumb_ptr<block_list> entity = ARGENTITY(0);
dumb_ptr<map_session_data> subject;
int stackable;
@@ -698,13 +666,13 @@ 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));
int i;
- dumb_ptr<map_session_data> owner = NULL;
+ dumb_ptr<map_session_data> owner = nullptr;
if (monster_attitude == MonsterAttitude::SERVANT
&& owner_e->bl_type == BL::PC)
owner = owner_e->is_player();
@@ -714,7 +682,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 +692,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)
{
@@ -770,18 +738,21 @@ int op_spawn(dumb_ptr<env_t>, Slice<val_t> args)
}
static
-const char *get_invocation_name(dumb_ptr<env_t> env)
+ZString get_invocation_name(dumb_ptr<env_t> env)
{
- dumb_ptr<invocation> invocation_;
+ assert (!env->VAR(VAR_INVOCATION).is<ValInvocationPtr>());
- if (env->VAR(VAR_INVOCATION).ty != TYPE::INVOCATION)
- return "?";
- invocation_ = map_id_is_spell(env->VAR(VAR_INVOCATION).v.v_int);
+ ValInvocationInt *ii = env->VAR(VAR_INVOCATION).get_if<ValInvocationInt>();
+ if (!ii)
+ return "?"_s;
+
+ dumb_ptr<invocation> invocation_;
+ invocation_ = map_id_is_spell(ii->v_iid);
if (invocation_)
- return invocation_->spell->name.c_str();
+ return invocation_->spell->name;
else
- return "??";
+ return "??"_s;
}
static
@@ -824,9 +795,9 @@ int op_injure(dumb_ptr<env_t> env, Slice<val_t> args)
{
dumb_ptr<mob_data> mob = target->is_mob();
- MAP_LOG_PC(caster_pc, "SPELLDMG MOB%d %d FOR %d BY %s",
- mob->bl_id, mob->mob_class, damage_caused,
- get_invocation_name(env));
+ MAP_LOG_PC(caster_pc, "SPELLDMG MOB%d %d FOR %d BY %s"_fmt,
+ mob->bl_id, mob->mob_class, damage_caused,
+ get_invocation_name(env));
}
}
battle_damage(caster, target, damage_caused, mp_damage);
@@ -847,7 +818,7 @@ int op_emote(dumb_ptr<env_t>, Slice<val_t> args)
static
int op_set_script_variable(dumb_ptr<env_t>, Slice<val_t> args)
{
- dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
VarName varname = stringish<VarName>(ARGSTR(1));
int array_index = 0;
@@ -862,7 +833,7 @@ int op_set_script_variable(dumb_ptr<env_t>, Slice<val_t> args)
static
int op_set_script_str(dumb_ptr<env_t>, Slice<val_t> args)
{
- dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
VarName varname = stringish<VarName>(ARGSTR(1));
int array_index = 0;
@@ -877,7 +848,7 @@ int op_set_script_str(dumb_ptr<env_t>, Slice<val_t> args)
static
int op_set_hair_colour(dumb_ptr<env_t>, Slice<val_t> args)
{
- dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
if (!c)
return 1;
@@ -890,7 +861,7 @@ int op_set_hair_colour(dumb_ptr<env_t>, Slice<val_t> args)
static
int op_set_hair_style(dumb_ptr<env_t>, Slice<val_t> args)
{
- dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
if (!c)
return 1;
@@ -903,25 +874,29 @@ int op_set_hair_style(dumb_ptr<env_t>, Slice<val_t> args)
static
int op_drop_item_for (dumb_ptr<env_t>, Slice<val_t> args)
{
- struct item item;
+ Item item;
int stackable;
location_t *loc = &ARGLOCATION(0);
int count = ARGINT(2);
interval_t interval = static_cast<interval_t>(ARGINT(3));
- dumb_ptr<map_session_data> c = ((args.size() > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : NULL;
+ dumb_ptr<map_session_data> c = ((args.size() > 4) && (ENTITY_TYPE(4) == BL::PC)) ? ARGPC(4) : nullptr;
interval_t delay = (args.size() > 5) ? static_cast<interval_t>(ARGINT(5)) : interval_t::zero();
interval_t delaytime[3] = { delay, delay, delay };
- dumb_ptr<map_session_data> owners[3] = { c, NULL, NULL };
+ dumb_ptr<map_session_data> owners[3] = { c, nullptr, nullptr };
GET_ARG_ITEM(1, item, stackable);
if (stackable)
+ {
map_addflooritem_any(&item, count, loc->m, loc->x, loc->y,
owners, delaytime, interval, 0);
+ }
else
+ {
while (count-- > 0)
map_addflooritem_any(&item, 1, loc->m, loc->x, loc->y,
owners, delaytime, interval, 0);
+ }
return 0;
}
@@ -929,46 +904,46 @@ int op_drop_item_for (dumb_ptr<env_t>, Slice<val_t> args)
static
int op_gain_exp(dumb_ptr<env_t>, Slice<val_t> args)
{
- dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : NULL;
+ dumb_ptr<map_session_data> c = (ENTITY_TYPE(0) == BL::PC) ? ARGPC(0) : nullptr;
if (!c)
return 1;
pc_gainexp_reason(c, ARGINT(1), ARGINT(2),
- PC_GAINEXP_REASON(ARGINT(3)));
+ static_cast<PC_GAINEXP_REASON>(ARGINT(3)));
return 0;
}
#define MAGIC_OPERATION(name, args, impl) {{name}, {{name}, {args}, impl}}
-#define MAGIC_OPERATION1(name, args) MAGIC_OPERATION(#name, args, op_##name)
+#define MAGIC_OPERATION1(name, args) MAGIC_OPERATION(#name##_s, args, op_##name)
static
std::map<ZString, op_t> operations =
{
- MAGIC_OPERATION1(sfx, ".ii"),
- MAGIC_OPERATION1(instaheal, "eii"),
- MAGIC_OPERATION1(itemheal, "eii"),
- MAGIC_OPERATION1(shroud, "ei"),
- MAGIC_OPERATION("unshroud", "e", op_reveal),
- MAGIC_OPERATION1(message, "es"),
- MAGIC_OPERATION1(messenger_npc, "lissi"),
- MAGIC_OPERATION1(move, "ed"),
- MAGIC_OPERATION1(warp, "el"),
- MAGIC_OPERATION1(banish, "e"),
- MAGIC_OPERATION1(status_change, "eiiiiii"),
- MAGIC_OPERATION1(stop_status_change, "ei"),
- MAGIC_OPERATION1(override_attack, "eiiiiii"),
- MAGIC_OPERATION1(create_item, "e.i"),
- MAGIC_OPERATION1(aggravate, "eie"),
- MAGIC_OPERATION1(spawn, "aeiiii"),
- MAGIC_OPERATION1(injure, "eeii"),
- MAGIC_OPERATION1(emote, "ei"),
- MAGIC_OPERATION1(set_script_variable, "esi"),
- MAGIC_OPERATION1(set_script_str, "ess"),
- MAGIC_OPERATION1(set_hair_colour, "ei"),
- MAGIC_OPERATION1(set_hair_style, "ei"),
- MAGIC_OPERATION("drop_item", "l.ii", op_drop_item_for),
- MAGIC_OPERATION1(drop_item_for, "l.iiei"),
- MAGIC_OPERATION("gain_experience", "eiii", op_gain_exp),
+ MAGIC_OPERATION1(sfx, ".ii"_s),
+ MAGIC_OPERATION1(instaheal, "eii"_s),
+ MAGIC_OPERATION1(itemheal, "eii"_s),
+ MAGIC_OPERATION1(shroud, "ei"_s),
+ MAGIC_OPERATION("unshroud"_s, "e"_s, op_reveal),
+ MAGIC_OPERATION1(message, "es"_s),
+ MAGIC_OPERATION1(messenger_npc, "lissi"_s),
+ MAGIC_OPERATION1(move, "ed"_s),
+ MAGIC_OPERATION1(warp, "el"_s),
+ MAGIC_OPERATION1(banish, "e"_s),
+ MAGIC_OPERATION1(status_change, "eiiiiii"_s),
+ MAGIC_OPERATION1(stop_status_change, "ei"_s),
+ MAGIC_OPERATION1(override_attack, "eiiiiii"_s),
+ MAGIC_OPERATION1(create_item, "e.i"_s),
+ MAGIC_OPERATION1(aggravate, "eie"_s),
+ MAGIC_OPERATION1(spawn, "aeiiii"_s),
+ MAGIC_OPERATION1(injure, "eeii"_s),
+ MAGIC_OPERATION1(emote, "ei"_s),
+ MAGIC_OPERATION1(set_script_variable, "esi"_s),
+ MAGIC_OPERATION1(set_script_str, "ess"_s),
+ MAGIC_OPERATION1(set_hair_colour, "ei"_s),
+ MAGIC_OPERATION1(set_hair_style, "ei"_s),
+ MAGIC_OPERATION("drop_item"_s, "l.ii"_s, op_drop_item_for),
+ MAGIC_OPERATION1(drop_item_for, "l.iiei"_s),
+ MAGIC_OPERATION("gain_experience"_s, "eiii"_s, op_gain_exp),
};
op_t *magic_get_op(ZString name)
@@ -979,7 +954,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);
@@ -1004,8 +979,8 @@ void spell_effect_report_termination(int invocation_id, int bl_id,
dumb_ptr<block_list> entity = map_id2bl(bl_id);
if (entity->bl_type == BL::PC)
FPRINTF(stderr,
- "[magic] INTERNAL ERROR: spell-effect-report-termination: tried to terminate on unexpected bl %d, sc %d\n",
- bl_id, sc_id);
+ "[magic] INTERNAL ERROR: spell-effect-report-termination: tried to terminate on unexpected bl %d, sc %d\n"_fmt,
+ bl_id, sc_id);
return;
}
@@ -1014,111 +989,86 @@ void spell_effect_report_termination(int invocation_id, int bl_id,
static
dumb_ptr<effect_t> return_to_stack(dumb_ptr<invocation> invocation_)
{
- if (!invocation_->stack_size)
- return NULL;
+ if (invocation_->stack.empty())
+ return nullptr;
else
{
cont_activation_record_t *ar =
- invocation_->stack + (invocation_->stack_size - 1);
- switch (ar->ty)
+ &invocation_->stack.back();
+ MATCH (*ar)
{
- case CONT_STACK::PROC:
+ CASE (const CarProc&, c_proc)
{
dumb_ptr<effect_t> ret = ar->return_location;
- for (int i = 0; i < ar->c.c_proc.args_nr; i++)
+ for (int i = 0; i < c_proc.args_nr; i++)
{
val_t *var =
- &invocation_->env->varu[ar->c.c_proc.formalap[i]];
+ &invocation_->env->varu[c_proc.formalap[i]];
magic_clear_var(var);
- *var = ar->c.c_proc.old_actualpa[i];
+ *var = std::move(c_proc.old_actualpa[i]);
}
// pop the stack
clear_activation_record(ar);
- --invocation_->stack_size;
+ invocation_->stack.pop_back();
return ret;
}
-
- case CONT_STACK::FOREACH:
+ CASE (CarForEach&, c_foreach)
{
- int entity_id;
- val_t *var = &invocation_->env->varu[ar->c.c_foreach.id];
+ BlockId entity_id;
+ val_t *var = &invocation_->env->varu[c_foreach.id];
do
{
// This >= is really supposed to be a ==, but
// I have no clue if it's actually safe to change it.
- if (ar->c.c_foreach.index >= ar->c.c_foreach.entities_vp->size())
+ if (c_foreach.index >= c_foreach.entities_vp->size())
{
// pop the stack
dumb_ptr<effect_t> ret = ar->return_location;
clear_activation_record(ar);
- --invocation_->stack_size;
+ invocation_->stack.pop_back();
return ret;
}
entity_id =
- (*ar->c.c_foreach.entities_vp)[ar->c.c_foreach.index++];
+ (*c_foreach.entities_vp)[c_foreach.index++];
}
while (!entity_id || !map_id2bl(entity_id));
magic_clear_var(var);
- var->ty = ar->c.c_foreach.ty;
- var->v.v_int = entity_id;
+ if (c_foreach.ty_is_spell_not_entity)
+ *var = ValInvocationInt{entity_id};
+ else
+ *var = ValEntityInt{entity_id};
- return ar->c.c_foreach.body;
+ return c_foreach.body;
}
-
- case CONT_STACK::FOR:
- if (ar->c.c_for.current > ar->c.c_for.stop)
+ CASE (CarFor&, c_for)
+ {
+ if (c_for.current > c_for.stop)
{
dumb_ptr<effect_t> ret = ar->return_location;
// pop the stack
clear_activation_record(ar);
- --invocation_->stack_size;
+ invocation_->stack.pop_back();
return ret;
}
- magic_clear_var(&invocation_->env->varu[ar->c.c_for.id]);
- invocation_->env->varu[ar->c.c_for.id].ty = TYPE::INT;
- invocation_->env->varu[ar->c.c_for.id].v.v_int =
- ar->c.c_for.current++;
-
- return ar->c.c_for.body;
+ magic_clear_var(&invocation_->env->varu[c_for.id]);
+ invocation_->env->varu[c_for.id] = ValInt{c_for.current++};
- default:
- FPRINTF(stderr,
- "[magic] INTERNAL ERROR: While executing spell `%s': stack corruption\n",
- invocation_->spell->name);
- return NULL;
+ return c_for.body;
+ }
}
+ abort();
}
}
static
-cont_activation_record_t *add_stack_entry(dumb_ptr<invocation> invocation_,
- CONT_STACK ty, dumb_ptr<effect_t> return_location)
-{
- cont_activation_record_t *ar =
- invocation_->stack + invocation_->stack_size++;
- if (invocation_->stack_size >= MAX_STACK_SIZE)
- {
- FPRINTF(stderr,
- "[magic] Execution stack size exceeded in spell `%s'; truncating effect\n",
- invocation_->spell->name);
- invocation_->stack_size--;
- return NULL;
- }
-
- ar->ty = ty;
- ar->return_location = return_location;
- return ar;
-}
-
-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,22 +1130,49 @@ 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.
- switch (area->ty)
+ MATCH (area_)
{
- case AREA::UNION:
- find_entities_in_area(*area->a.a_union[0], entities_vp, filter);
- find_entities_in_area(*area->a.a_union[1], entities_vp, filter);
- break;
-
- default:
+ CASE (const AreaUnion&, a)
+ {
+ find_entities_in_area(*a.a_union[0], entities_vp, filter);
+ find_entities_in_area(*a.a_union[1], entities_vp, filter);
+ }
+ CASE (const location_t&, a_loc)
{
+ (void)a_loc;
+ // TODO this can be simplified
map_local *m;
int x, y, width, height;
- magic_area_rect(&m, &x, &y, &width, &height, *area);
+ magic_area_rect(&m, &x, &y, &width, &height, area_);
+ map_foreachinarea(std::bind(find_entities_in_area_c, ph::_1, entities_vp, filter),
+ m,
+ x, y,
+ x + width, y + height,
+ BL::NUL /* filter elsewhere */);
+ }
+ CASE (const AreaRect&, a_rect)
+ {
+ (void)a_rect;
+ // TODO this can be simplified
+ map_local *m;
+ int x, y, width, height;
+ magic_area_rect(&m, &x, &y, &width, &height, area_);
+ map_foreachinarea(std::bind(find_entities_in_area_c, ph::_1, entities_vp, filter),
+ m,
+ x, y,
+ x + width, y + height,
+ BL::NUL /* filter elsewhere */);
+ }
+ CASE (const AreaBar&, a_bar)
+ {
+ (void)a_bar;
+ // TODO this is wrong
+ map_local *m;
+ int x, y, width, height;
+ magic_area_rect(&m, &x, &y, &width, &height, area_);
map_foreachinarea(std::bind(find_entities_in_area_c, ph::_1, entities_vp, filter),
m,
x, y,
@@ -1207,45 +1184,44 @@ void find_entities_in_area(area_t& area_,
static
dumb_ptr<effect_t> run_foreach(dumb_ptr<invocation> invocation,
- dumb_ptr<effect_t> foreach,
+ const EffectForEach *foreach,
dumb_ptr<effect_t> return_location)
{
+ const EffectForEach& e_foreach = *foreach;
+
val_t area;
- FOREACH_FILTER filter = foreach->e.e_foreach.filter;
- int id = foreach->e.e_foreach.id;
- dumb_ptr<effect_t> body = foreach->e.e_foreach.body;
+ FOREACH_FILTER filter = e_foreach.filter;
+ int id = e_foreach.id;
+ dumb_ptr<effect_t> body = e_foreach.body;
- magic_eval(invocation->env, &area, foreach->e.e_foreach.area);
+ magic_eval(invocation->env, &area, e_foreach.area);
- if (area.ty != TYPE::AREA)
+ auto va = area.get_if<ValArea>();
+ if (!va)
{
magic_clear_var(&area);
FPRINTF(stderr,
- "[magic] Error in spell `%s': FOREACH loop over non-area\n",
- invocation->spell->name.c_str());
+ "[magic] Error in spell `%s': FOREACH loop over non-area\n"_fmt,
+ invocation->spell->name);
return return_location;
}
- else
- {
- cont_activation_record_t *ar =
- add_stack_entry(invocation, CONT_STACK::FOREACH, return_location);
- if (!ar)
- return return_location;
-
- std::vector<int> entities_v;
- find_entities_in_area(*area.v.v_area,
+ {
+ std::vector<BlockId> entities_v;
+ find_entities_in_area(*va->v_area,
&entities_v, filter);
entities_v.shrink_to_fit();
// iterator_pair will go away when this gets properly containerized.
random_::shuffle(entities_v);
- ar->c.c_foreach.id = id;
- ar->c.c_foreach.body = body;
- ar->c.c_foreach.index = 0;
- ar->c.c_foreach.entities_vp.new_(std::move(entities_v));
- ar->c.c_foreach.ty =
- (filter == FOREACH_FILTER::SPELL) ? TYPE::INVOCATION : TYPE::ENTITY;
+ CarForEach c_foreach;
+ c_foreach.id = id;
+ c_foreach.body = body;
+ c_foreach.index = 0;
+ c_foreach.entities_vp.new_(std::move(entities_v));
+ c_foreach.ty_is_spell_not_entity =
+ (filter == FOREACH_FILTER::SPELL);
+ invocation->stack.emplace_back(c_foreach, return_location);
magic_clear_var(&area);
@@ -1255,130 +1231,66 @@ dumb_ptr<effect_t> run_foreach(dumb_ptr<invocation> invocation,
static
dumb_ptr<effect_t> run_for (dumb_ptr<invocation> invocation,
- dumb_ptr<effect_t> for_,
+ const EffectFor *for_,
dumb_ptr<effect_t> return_location)
{
- cont_activation_record_t *ar;
- int id = for_->e.e_for.id;
+ const EffectFor& e_for = *for_;
+
+ int id = e_for.id;
val_t start;
val_t stop;
- magic_eval(invocation->env, &start, for_->e.e_for.start);
- magic_eval(invocation->env, &stop, for_->e.e_for.stop);
+ magic_eval(invocation->env, &start, e_for.start);
+ magic_eval(invocation->env, &stop, e_for.stop);
- if (start.ty != TYPE::INT || stop.ty != TYPE::INT)
+ if (!start.is<ValInt>() || !stop.is<ValInt>())
{
magic_clear_var(&start);
magic_clear_var(&stop);
FPRINTF(stderr,
- "[magic] Error in spell `%s': FOR loop start or stop point is not an integer\n",
- invocation->spell->name);
+ "[magic] Error in spell `%s': FOR loop start or stop point is not an integer\n"_fmt,
+ invocation->spell->name);
return return_location;
}
- ar = add_stack_entry(invocation, CONT_STACK::FOR, return_location);
+ CarFor c_for;
- if (!ar)
- return return_location;
-
- ar->c.c_for.id = id;
- ar->c.c_for.current = start.v.v_int;
- ar->c.c_for.stop = stop.v.v_int;
- ar->c.c_for.body = for_->e.e_for.body;
+ c_for.id = id;
+ c_for.current = start.get_if<ValInt>()->v_int;
+ c_for.stop = stop.get_if<ValInt>()->v_int;
+ c_for.body = e_for.body;
+ invocation->stack.emplace_back(c_for, return_location);
return return_to_stack(invocation);
}
static
dumb_ptr<effect_t> run_call(dumb_ptr<invocation> invocation,
+ const EffectCall *call,
dumb_ptr<effect_t> return_location)
{
- dumb_ptr<effect_t> current = invocation->current_effect;
- cont_activation_record_t *ar;
- int args_nr = current->e.e_call.formalv->size();
- int *formals = current->e.e_call.formalv->data();
+ const EffectCall& e_call = *call;
+
+ int args_nr = e_call.formalv->size();
+ int *formals = e_call.formalv->data();
auto old_actuals = dumb_ptr<val_t[]>::make(args_nr);
- ar = add_stack_entry(invocation, CONT_STACK::PROC, return_location);
- ar->c.c_proc.args_nr = args_nr;
- ar->c.c_proc.formalap = formals;
- ar->c.c_proc.old_actualpa = old_actuals;
+ CarProc c_proc;
+ c_proc.args_nr = args_nr;
+ c_proc.formalap = formals;
+ c_proc.old_actualpa = old_actuals;
+ invocation->stack.emplace_back(c_proc, return_location);
+
for (int i = 0; i < args_nr; i++)
{
val_t *env_val = &invocation->env->varu[formals[i]];
magic_copy_var(&old_actuals[i], env_val);
- magic_eval(invocation->env, env_val, (*current->e.e_call.actualvp)[i]);
+ magic_eval(invocation->env, env_val, (*e_call.actualvp)[i]);
}
- return current->e.e_call.body;
+ return e_call.body;
}
-#ifdef DEBUG
-static
-void print_cfg(int i, effect_t *e)
-{
- int j;
- for (j = 0; j < i; j++)
- PRINTF(" ");
-
- PRINTF("%p: ", e);
-
- if (!e)
- {
- puts(" -- end --");
- return;
- }
-
- switch (e->ty)
- {
- case EFFECT::SKIP:
- puts("SKIP");
- break;
- case EFFECT::END:
- puts("END");
- break;
- case EFFECT::ABORT:
- puts("ABORT");
- break;
- case EFFECT::ASSIGN:
- puts("ASSIGN");
- break;
- case EFFECT::FOREACH:
- puts("FOREACH");
- print_cfg(i + 1, e->e.e_foreach.body);
- break;
- case EFFECT::FOR:
- puts("FOR");
- print_cfg(i + 1, e->e.e_for.body);
- break;
- case EFFECT::IF:
- puts("IF");
- for (j = 0; j < i; j++)
- PRINTF(" ");
- puts("THEN");
- print_cfg(i + 1, e->e.e_if.true_branch);
- for (j = 0; j < i; j++)
- PRINTF(" ");
- puts("ELSE");
- print_cfg(i + 1, e->e.e_if.false_branch);
- break;
- case EFFECT::SLEEP:
- puts("SLEEP");
- break;
- case EFFECT::SCRIPT:
- puts("NpcSubtype::SCRIPT");
- break;
- case EFFECT::BREAK:
- puts("BREAK");
- break;
- case EFFECT::OP:
- puts("OP");
- break;
- }
- print_cfg(i, e->next);
-}
-#endif
-
/**
* Execute a spell invocation until we abort, finish, or hit the next `sleep'.
*
@@ -1391,87 +1303,81 @@ 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
- FPRINTF(stderr, "Resuming execution: invocation of `%s'\n",
- invocation_->spell->name);
- print_cfg(1, invocation_->current_effect);
-#endif
while (invocation_->current_effect)
{
dumb_ptr<effect_t> e = invocation_->current_effect;
dumb_ptr<effect_t> next = e->next;
int i;
-#ifdef DEBUG
- FPRINTF(stderr, "Next step of type %d\n", e->ty);
- dump_env(invocation_->env);
-#endif
-
- switch (e->ty)
+ MATCH (*e)
{
- case EFFECT::SKIP:
- break;
-
- case EFFECT::ABORT:
+ CASE (const EffectSkip&, e_)
+ {
+ (void)e_;
+ }
+ CASE (const EffectAbort&, e_)
+ {
+ (void)e_;
invocation_->flags |= INVOCATION_FLAG::ABORTED;
- invocation_->end_effect = NULL;
- FALLTHROUGH;
- case EFFECT::END:
+ invocation_->end_effect = nullptr;
clear_stack(invocation_);
- next = NULL;
- break;
-
- case EFFECT::ASSIGN:
+ next = nullptr;
+ }
+ CASE (const EffectEnd&, e_)
+ {
+ (void)e_;
+ clear_stack(invocation_);
+ next = nullptr;
+ }
+ CASE (const EffectAssign&, e_assign)
+ {
magic_eval(invocation_->env,
- &invocation_->env->varu[e->e.e_assign.id],
- e->e.e_assign.expr);
- break;
-
- case EFFECT::FOREACH:
- next = run_foreach(invocation_, e, next);
- break;
-
- case EFFECT::FOR:
- next = run_for (invocation_, e, next);
- break;
-
- case EFFECT::IF:
- if (magic_eval_int(invocation_->env, e->e.e_if.cond))
- next = e->e.e_if.true_branch;
+ &invocation_->env->varu[e_assign.id],
+ e_assign.expr);
+ }
+ CASE (const EffectForEach&, e_foreach)
+ {
+ next = run_foreach(invocation_, &e_foreach, next);
+ }
+ CASE (const EffectFor&, e_for)
+ {
+ next = run_for (invocation_, &e_for, next);
+ }
+ CASE (const EffectIf&, e_if)
+ {
+ if (magic_eval_int(invocation_->env, e_if.cond))
+ next = e_if.true_branch;
else
- next = e->e.e_if.false_branch;
- break;
-
- case EFFECT::SLEEP:
+ next = e_if.false_branch;
+ }
+ CASE (const EffectSleep&, e_)
{
interval_t sleeptime = static_cast<interval_t>(
- magic_eval_int(invocation_->env, e->e.e_sleep));
+ magic_eval_int(invocation_->env, e_.e_sleep));
invocation_->current_effect = next;
if (sleeptime > interval_t::zero())
return sleeptime;
- break;
}
-
- case EFFECT::SCRIPT:
+ CASE (const EffectScript&, e_)
{
dumb_ptr<map_session_data> caster = map_id_is_player(invocation_->caster);
if (caster)
{
dumb_ptr<env_t> env = invocation_->env;
ZString caster_name = (caster ? caster->status_key.name : CharName()).to__actual();
- argrec_t arg[3] =
+ argrec_t arg[1] =
{
- {"@target", env->VAR(VAR_TARGET).ty == TYPE::ENTITY ? 0 : env->VAR(VAR_TARGET).v.v_int},
- {"@caster", invocation_->caster},
- {"@caster_name$", caster_name},
+ {"@caster_name$"_s, caster_name},
};
- int message_recipient =
- env->VAR(VAR_SCRIPTTARGET).ty ==
- TYPE::ENTITY ? env->VAR(VAR_SCRIPTTARGET).
- v.v_int : invocation_->caster;
+ assert (!env->VAR(VAR_SCRIPTTARGET).is<ValEntityPtr>());
+ ValEntityInt *ei = env->VAR(VAR_SCRIPTTARGET).get_if<ValEntityInt>();
+ BlockId message_recipient =
+ ei
+ ? ei->v_eid
+ : invocation_->caster;
dumb_ptr<map_session_data> recipient = map_id_is_player(message_recipient);
if (recipient->npc_id
@@ -1485,7 +1391,7 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
// dealing with an NPC
int newpos = run_script_l(
- ScriptPointer(&*e->e.e_script, invocation_->script_pos),
+ ScriptPointer(&*e_.e_script, invocation_->script_pos),
message_recipient, invocation_->bl_id,
arg);
/* Returns the new script position, or -1 once the script is finished */
@@ -1501,42 +1407,35 @@ interval_t spell_run(dumb_ptr<invocation> invocation_, int allow_delete)
clif_clearchar_id(invocation_->bl_id, BeingRemoveWhy::DEAD, caster->sess);
}
REFRESH_INVOCATION; // Script may have killed the caster
- break;
}
-
- case EFFECT::BREAK:
+ CASE (const EffectBreak&, e_)
+ {
+ (void)e_;
next = return_to_stack(invocation_);
- break;
-
- case EFFECT::OP:
+ }
+ CASE (const EffectOp&, e_op)
{
- op_t *op = e->e.e_op.opp;
+ op_t *op = e_op.opp;
val_t args[MAX_ARGS];
- for (i = 0; i < e->e.e_op.args_nr; i++)
- magic_eval(invocation_->env, &args[i], e->e.e_op.args[i]);
+ for (i = 0; i < e_op.args_nr; i++)
+ magic_eval(invocation_->env, &args[i], e_op.args[i]);
- if (!magic_signature_check("effect", op->name, op->signature,
- Slice<val_t>(args, e->e.e_op.args_nr),
- e->e.e_op.line_nr,
- e->e.e_op.column))
- op->op(invocation_->env, Slice<val_t>(args, e->e.e_op.args_nr));
+ if (!magic_signature_check("effect"_s, op->name, op->signature,
+ Slice<val_t>(args, e_op.args_nr),
+ e_op.line_nr,
+ e_op.column))
+ op->op(invocation_->env, Slice<val_t>(args, e_op.args_nr));
- for (i = 0; i < e->e.e_op.args_nr; i++)
+ for (i = 0; i < e_op.args_nr; i++)
magic_clear_var(&args[i]);
REFRESH_INVOCATION; // Effect may have killed the caster
- break;
}
-
- case EFFECT::CALL:
- next = run_call(invocation_, next);
- break;
-
- default:
- FPRINTF(stderr,
- "[magic] INTERNAL ERROR: Unknown effect %d\n",
- e->ty);
+ CASE (const EffectCall&, e_call)
+ {
+ next = run_call(invocation_, &e_call, next);
+ }
}
if (!next)
@@ -1583,7 +1482,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_;
@@ -1600,8 +1499,7 @@ int spell_attack(int caster_id, int target_id)
if (invocation_ && caster->attack_spell_charges > 0)
{
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] = ValEntityInt{target_id};
invocation_->current_effect = invocation_->trigger_effect;
invocation_->flags &= ~INVOCATION_FLAG::ABORTED;
@@ -1622,8 +1520,8 @@ int spell_attack(int caster_id, int target_id)
}
else if (!invocation_ || caster->attack_spell_charges <= 0)
{
- caster->attack_spell_override = 0;
- char_set_weapon_icon(caster, 0, StatusChange::ZERO, 0);
+ caster->attack_spell_override = BlockId();
+ char_set_weapon_icon(caster, 0, StatusChange::ZERO, ItemNameId());
char_set_attack_info(caster, interval_t::zero(), 0);
if (stop_attack)
@@ -1635,3 +1533,5 @@ int spell_attack(int caster_id, int target_id)
return 1;
}
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-stmt.hpp b/src/map/magic-stmt.hpp
index 838854f..28af140 100644
--- a/src/map/magic-stmt.hpp
+++ b/src/map/magic-stmt.hpp
@@ -1,8 +1,8 @@
-#ifndef TMWA_MAP_MAGIC_STMT_HPP
-#define TMWA_MAP_MAGIC_STMT_HPP
-// magic-stmt.hpp - dummy header to make Make dependencies work.
+#pragma once
+// magic-stmt.hpp - Imperative commands for the magic backend.
//
-// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
+// Copyright © 2004-2011 The Mana World Development Team
+// Copyright © 2011-2014 Ben Longbons <b.r.longbons@gmail.com>
//
// This file is part of The Mana World (Athena server)
//
@@ -19,6 +19,76 @@
// 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"
-#endif // TMWA_MAP_MAGIC_STMT_HPP
+#include "../range/fwd.hpp"
+
+#include "../strings/zstring.hpp"
+
+#include "../generic/fwd.hpp"
+
+#include "skill.t.hpp"
+
+
+namespace tmwa
+{
+namespace magic
+{
+struct op_t
+{
+ ZString name;
+ ZString signature;
+ int (*op)(dumb_ptr<env_t> env, Slice<val_t> arga);
+};
+
+/**
+ * Retrieves an operation by name
+ * @param name The name to look up
+ * @return An operation of that name, or nullptr, and a function index
+ */
+op_t *magic_get_op(ZString name);
+
+/**
+ * Removes the shroud from a character
+ *
+ * \param character The character to remove the shroud from
+ */
+void magic_unshroud(dumb_ptr<map_session_data> character);
+
+/**
+ * Notifies a running spell that a status_change timer triggered by the spell has expired
+ *
+ * \param invocation The invocation to notify
+ * \param bl_id ID of the PC for whom this happened
+ * \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(BlockId invocation, BlockId bl_id,
+ StatusChange sc_id, int supplanted);
+
+/**
+ * Execute a spell invocation and sets up timers to finish
+ */
+void spell_execute(dumb_ptr<invocation> invocation);
+
+/**
+ * Continue an NPC script embedded in a spell
+ */
+void spell_execute_script(dumb_ptr<invocation> invocation);
+
+/**
+ * Stops all magic bound to the specified character
+ *
+ */
+void magic_stop_completely(dumb_ptr<map_session_data> c);
+
+/**
+ * Attacks with a magical spell charged to the character
+ *
+ * Returns 0 if there is no charged spell or the spell is depleted.
+ */
+int spell_attack(BlockId caster, BlockId target);
+
+void spell_free_invocation(dumb_ptr<invocation> invocation);
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-v2.cpp b/src/map/magic-v2.cpp
index 41d29cd..73b7534 100644
--- a/src/map/magic-v2.cpp
+++ b/src/map/magic-v2.cpp
@@ -18,17 +18,35 @@
// 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 <cstddef>
+
+#include <algorithm>
+#include <map>
#include <set>
-#include "../sexpr/parser.hpp"
+#include "../strings/rstring.hpp"
+#include "../strings/literal.hpp"
-#include "../mmo/dumb_ptr.hpp"
+#include "../generic/dumb_ptr.hpp"
+
+#include "../io/cxxstdio.hpp"
+#include "../io/line.hpp"
+
+#include "../sexpr/parser.hpp"
#include "itemdb.hpp"
#include "magic-expr.hpp"
+#include "magic-interpreter.hpp"
+#include "magic-interpreter-base.hpp"
+#include "magic-stmt.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
+namespace magic
+{
namespace magic_v2
{
static
@@ -49,8 +67,8 @@ namespace magic_v2
/* Must add new */
magic_conf_t::mcvar new_var {};
new_var.name = id_name;
- new_var.val.ty = TYPE::UNDEF;
- magic_conf.varv.push_back(new_var);
+ new_var.val = ValUndef();
+ magic_conf.varv.push_back(std::move(new_var));
return i;
}
@@ -61,8 +79,8 @@ namespace magic_v2
if (zid != id)
{
FPRINTF(stderr,
- "[magic-conf] INTERNAL ERROR: Builtin special var %s interned to %d, not %d as it should be!\n",
- name, zid, id);
+ "[magic-conf] INTERNAL ERROR: Builtin special var %s interned to %d, not %d as it should be!\n"_fmt,
+ name, zid, id);
}
return zid == id;
}
@@ -72,45 +90,38 @@ namespace magic_v2
{
bool ok = true;
- ok &= INTERN_ASSERT("min_casttime", VAR_MIN_CASTTIME);
- ok &= INTERN_ASSERT("obscure_chance", VAR_OBSCURE_CHANCE);
- ok &= INTERN_ASSERT("caster", VAR_CASTER);
- ok &= INTERN_ASSERT("spellpower", VAR_SPELLPOWER);
- ok &= INTERN_ASSERT("self_spell", VAR_SPELL);
- ok &= INTERN_ASSERT("self_invocation", VAR_INVOCATION);
- ok &= INTERN_ASSERT("target", VAR_TARGET);
- ok &= INTERN_ASSERT("script_target", VAR_SCRIPTTARGET);
- ok &= INTERN_ASSERT("location", VAR_LOCATION);
+ ok &= INTERN_ASSERT("min_casttime"_s, VAR_MIN_CASTTIME);
+ ok &= INTERN_ASSERT("obscure_chance"_s, VAR_OBSCURE_CHANCE);
+ ok &= INTERN_ASSERT("caster"_s, VAR_CASTER);
+ ok &= INTERN_ASSERT("spellpower"_s, VAR_SPELLPOWER);
+ ok &= INTERN_ASSERT("self_spell"_s, VAR_SPELL);
+ ok &= INTERN_ASSERT("self_invocation"_s, VAR_INVOCATION);
+ ok &= INTERN_ASSERT("target"_s, VAR_TARGET);
+ ok &= INTERN_ASSERT("script_target"_s, VAR_SCRIPTTARGET);
+ ok &= INTERN_ASSERT("location"_s, VAR_LOCATION);
return ok;
}
static
- bool bind_constant(io::LineSpan span, RString name, val_t *val)
+ bool bind_constant(io::LineSpan span, RString name, val_t val)
{
- if (!const_defm.insert({name, *val}).second)
+ if (!const_defm.insert(std::make_pair(name, std::move(val))).second)
{
- span.error(STRPRINTF("Redefinition of constant '%s'", name));
+ span.error(STRPRINTF("Redefinition of constant '%s'"_fmt, name));
return false;
}
return true;
}
static
- val_t *find_constant(RString name)
+ const val_t *find_constant(RString name)
{
auto it = const_defm.find(name);
if (it != const_defm.end())
return &it->second;
- return NULL;
- }
- static
- dumb_ptr<effect_t> new_effect(EFFECT ty)
- {
- auto effect = dumb_ptr<effect_t>::make();
- effect->ty = ty;
- return effect;
+ return nullptr;
}
static
dumb_ptr<effect_t> set_effect_continuation(dumb_ptr<effect_t> src, dumb_ptr<effect_t> continuation)
@@ -123,10 +134,13 @@ namespace magic_v2
/* For FOR and FOREACH, we use special stack handlers and thus don't have to set
* the continuation. It's only IF that we need to handle in this fashion. */
- if (src->ty == EFFECT::IF)
+ MATCH (*src)
{
- set_effect_continuation(src->e.e_if.true_branch, continuation);
- set_effect_continuation(src->e.e_if.false_branch, continuation);
+ CASE (EffectIf&, e_if)
+ {
+ set_effect_continuation(e_if.true_branch, continuation);
+ set_effect_continuation(e_if.false_branch, continuation);
+ }
}
if (src->next)
@@ -137,13 +151,6 @@ namespace magic_v2
return retval;
}
static
- dumb_ptr<spellguard_t> new_spellguard(SPELLGUARD ty)
- {
- dumb_ptr<spellguard_t> retval = dumb_ptr<spellguard_t>::make();
- retval->ty = ty;
- return retval;
- }
- static
dumb_ptr<spellguard_t> spellguard_implication(dumb_ptr<spellguard_t> a, dumb_ptr<spellguard_t> b)
{
dumb_ptr<spellguard_t> retval = a;
@@ -165,8 +172,13 @@ namespace magic_v2
}
/* If the premise is a disjunction, b is the continuation of _all_ branches */
- if (a->ty == SPELLGUARD::CHOICE)
- spellguard_implication(a->s.s_alt, b);
+ MATCH (*a)
+ {
+ CASE(const GuardChoice&, s)
+ {
+ spellguard_implication(s.s_alt, b);
+ }
+ }
if (a->next)
spellguard_implication(a->next, b);
@@ -184,14 +196,14 @@ namespace magic_v2
auto pair1 = magic_conf.spells_by_name.insert({spell->name, spell});
if (!pair1.second)
{
- span.error(STRPRINTF("Attempt to redefine spell '%s'", spell->name));
+ span.error(STRPRINTF("Attempt to redefine spell '%s'"_fmt, spell->name));
return false;
}
auto pair2 = magic_conf.spells_by_invocation.insert({spell->invocation, spell});
if (!pair2.second)
{
- span.error(STRPRINTF("Attempt to redefine spell invocation '%s'", spell->invocation));
+ span.error(STRPRINTF("Attempt to redefine spell invocation '%s'"_fmt, spell->invocation));
magic_conf.spells_by_name.erase(pair1.first);
return false;
}
@@ -203,14 +215,14 @@ namespace magic_v2
auto pair1 = magic_conf.anchors_by_name.insert({anchor->name, anchor});
if (!pair1.second)
{
- span.error(STRPRINTF("Attempt to redefine teleport anchor '%s'", anchor->name));
+ span.error(STRPRINTF("Attempt to redefine teleport anchor '%s'"_fmt, anchor->name));
return false;
}
auto pair2 = magic_conf.anchors_by_invocation.insert({anchor->name, anchor});
if (!pair2.second)
{
- span.error(STRPRINTF("Attempt to redefine anchor invocation '%s'", anchor->invocation));
+ span.error(STRPRINTF("Attempt to redefine anchor invocation '%s'"_fmt, anchor->invocation));
magic_conf.anchors_by_name.erase(pair1.first);
return false;
}
@@ -223,7 +235,7 @@ namespace magic_v2
RString name = proc->name;
if (!procs.insert({name, std::move(*proc)}).second)
{
- span.error("procedure already exists");
+ span.error("procedure already exists"_s);
return false;
}
return true;
@@ -234,7 +246,7 @@ namespace magic_v2
auto pi = procs.find(name);
if (pi == procs.end())
{
- span.error(STRPRINTF("Unknown procedure '%s'", name));
+ span.error(STRPRINTF("Unknown procedure '%s'"_fmt, name));
return false;
}
@@ -242,15 +254,16 @@ namespace magic_v2
if (p->argv.size() != argvp->size())
{
- span.error(STRPRINTF("Procedure %s/%zu invoked with %zu parameters",
+ span.error(STRPRINTF("Procedure %s/%zu invoked with %zu parameters"_fmt,
name, p->argv.size(), argvp->size()));
return false;
}
- retval = new_effect(EFFECT::CALL);
- retval->e.e_call.body = p->body;
- retval->e.e_call.formalv = &p->argv;
- retval->e.e_call.actualvp = argvp;
+ EffectCall e_call;
+ e_call.body = p->body;
+ e_call.formalv = &p->argv;
+ e_call.actualvp = argvp;
+ retval = dumb_ptr<effect_t>::make(e_call, nullptr);
return true;
}
static
@@ -259,33 +272,35 @@ namespace magic_v2
op_t *op = magic_get_op(name);
if (!op)
{
- span.error(STRPRINTF("Unknown operation '%s'", name));
+ span.error(STRPRINTF("Unknown operation '%s'"_fmt, name));
return false;
}
if (op->signature.size() != argv.size())
{
- span.error(STRPRINTF("Incorrect number of arguments to operation '%s': Expected %zu, found %zu",
- name, op->signature.size(), argv.size()));
+ span.error(STRPRINTF("Incorrect number of arguments to operation '%s': Expected %zu, found %zu"_fmt,
+ name, op->signature.size(), argv.size()));
return false;
}
- effect = new_effect(EFFECT::OP);
- effect->e.e_op.line_nr = span.begin.line;
- effect->e.e_op.column = span.begin.column;
- effect->e.e_op.opp = op;
+ EffectOp e_op;
+ e_op.line_nr = span.begin.line;
+ e_op.column = span.begin.column;
+ e_op.opp = op;
assert (argv.size() <= MAX_ARGS);
- effect->e.e_op.args_nr = argv.size();
+ e_op.args_nr = argv.size();
- std::copy(argv.begin(), argv.end(), effect->e.e_op.args);
+ std::copy(argv.begin(), argv.end(), e_op.args);
+ effect = dumb_ptr<effect_t>::make(e_op, nullptr);
return true;
}
static
dumb_ptr<expr_t> dot_expr(dumb_ptr<expr_t> expr, int id)
{
- dumb_ptr<expr_t> retval = magic_new_expr(EXPR::SPELLFIELD);
- retval->e.e_field.id = id;
- retval->e.e_field.expr = expr;
+ ExprField e_field;
+ e_field.id = id;
+ e_field.expr = expr;
+ dumb_ptr<expr_t> retval = dumb_ptr<expr_t>::make(e_field);
return retval;
}
@@ -295,24 +310,25 @@ namespace magic_v2
fun_t *fun = magic_get_fun(name);
if (!fun)
{
- span.error(STRPRINTF("Unknown function '%s'", name));
+ span.error(STRPRINTF("Unknown function '%s'"_fmt, name));
return false;
}
if (fun->signature.size() != argv.size())
{
- span.error(STRPRINTF("Incorrect number of arguments to function '%s': Expected %zu, found %zu",
- name, fun->signature.size(), argv.size()));
+ span.error(STRPRINTF("Incorrect number of arguments to function '%s': Expected %zu, found %zu"_fmt,
+ name, fun->signature.size(), argv.size()));
return false;
}
- expr = magic_new_expr(EXPR::FUNAPP);
- expr->e.e_funapp.line_nr = span.begin.line;
- expr->e.e_funapp.column = span.begin.column;
- expr->e.e_funapp.funp = fun;
+ ExprFunApp e_funapp;
+ e_funapp.line_nr = span.begin.line;
+ e_funapp.column = span.begin.column;
+ e_funapp.funp = fun;
assert (argv.size() <= MAX_ARGS);
- expr->e.e_funapp.args_nr = argv.size();
+ e_funapp.args_nr = argv.size();
- std::copy(argv.begin(), argv.end(), expr->e.e_funapp.args);
+ std::copy(argv.begin(), argv.end(), e_funapp.args);
+ expr = dumb_ptr<expr_t>::make(e_funapp);
return true;
}
static
@@ -362,20 +378,20 @@ namespace magic_v2
return false;
if (s._list[0]._type != sexpr::TOKEN)
return false;
- return s._list[0]._str == "DISABLED";
+ return s._list[0]._str == "DISABLED"_s;
}
static
bool parse_loc(const SExpr& s, e_location_t& loc)
{
if (s._type != sexpr::LIST)
- return fail(s, "loc not list");
+ return fail(s, "loc not list"_s);
if (s._list.size() != 4)
- return fail(s, "loc not 3 args");
+ return fail(s, "loc not 3 args"_s);
if (s._list[0]._type != sexpr::TOKEN)
- return fail(s._list[0], "loc cmd not tok");
- if (s._list[0]._str != "@")
- return fail(s._list[0], "loc cmd not cmd");
+ return fail(s._list[0], "loc cmd not tok"_s);
+ if (s._list[0]._str != "@"_s)
+ return fail(s._list[0], "loc cmd not cmd"_s);
return parse_expression(s._list[1], loc.m)
&& parse_expression(s._list[2], loc.x)
&& parse_expression(s._list[3], loc.y);
@@ -389,78 +405,74 @@ namespace magic_v2
case sexpr::INT:
{
val_t val;
- val.ty = TYPE::INT;
- val.v.v_int = x._int;
- if (val.v.v_int != x._int)
- return fail(x, "integer too large");
+ val = ValInt{static_cast<int32_t>(x._int)};
+ if (val.get_if<ValInt>()->v_int != x._int)
+ return fail(x, "integer too large"_s);
- out = magic_new_expr(EXPR::VAL);
- out->e.e_val = val;
+ out = dumb_ptr<expr_t>::make(std::move(val));
return true;
}
case sexpr::STRING:
{
val_t val;
- val.ty = TYPE::STRING;
- val.v.v_string = dumb_string::copys(x._str);
+ val = ValString{dumb_string::copys(x._str)};
- out = magic_new_expr(EXPR::VAL);
- out->e.e_val = val;
+ out = dumb_ptr<expr_t>::make(std::move(val));
return true;
}
case sexpr::TOKEN:
{
- ZString dirs[8] = {
- ZString("S"), ZString("SW"), ZString("W"), ZString("NW"), ZString("N"), ZString("NE"), ZString("E"), ZString("SE"),
- };
+ earray<LString, DIR, DIR::COUNT> dirs //=
+ {{
+ "S"_s, "SW"_s, "W"_s, "NW"_s,
+ "N"_s, "NE"_s, "E"_s, "SE"_s,
+ }};
auto begin = std::begin(dirs);
auto end = std::end(dirs);
auto it = std::find(begin, end, x._str);
if (it != end)
{
val_t val;
- val.ty = TYPE::DIR;
- val.v.v_dir = static_cast<DIR>(it - begin);
+ val = ValDir{static_cast<DIR>(it - begin)};
- out = magic_new_expr(EXPR::VAL);
- out->e.e_val = val;
+ out = dumb_ptr<expr_t>::make(std::move(val));
return true;
}
}
{
- if (val_t *val = find_constant(x._str))
+ if (const val_t *val = find_constant(x._str))
{
- out = magic_new_expr(EXPR::VAL);
- out->e.e_val = *val;
+ val_t copy;
+ magic_copy_var(&copy, val);
+ out = dumb_ptr<expr_t>::make(std::move(copy));
return true;
}
else
{
- out = magic_new_expr(EXPR::ID);
- out->e.e_id = intern_id(x._str);
+ ExprId e;
+ e.e_id = intern_id(x._str);
+ out = dumb_ptr<expr_t>::make(e);
return true;
}
}
break;
case sexpr::LIST:
if (x._list.empty())
- return fail(x, "empty list");
+ return fail(x, "empty list"_s);
{
if (x._list[0]._type != sexpr::TOKEN)
- return fail(x._list[0], "op not token");
+ return fail(x._list[0], "op not token"_s);
ZString op = x._list[0]._str;
// area
- if (op == "@")
+ if (op == "@"_s)
{
e_location_t loc;
if (!parse_loc(x, loc))
return false;
- out = magic_new_expr(EXPR::AREA);
- out->e.e_area.ty = AREA::LOCATION;
- out->e.e_area.a.a_loc = loc;
+ out = dumb_ptr<expr_t>::make(loc);
return true;
}
- if (op == "@+")
+ if (op == "@+"_s)
{
e_location_t loc;
dumb_ptr<expr_t> width;
@@ -471,14 +483,14 @@ namespace magic_v2
return false;
if (!parse_expression(x._list[3], height))
return false;
- out = magic_new_expr(EXPR::AREA);
- out->e.e_area.ty = AREA::RECT;
- out->e.e_area.a.a_rect.loc = loc;
- out->e.e_area.a.a_rect.width = width;
- out->e.e_area.a.a_rect.height = height;
+ ExprAreaRect a_rect;
+ a_rect.loc = loc;
+ a_rect.width = width;
+ a_rect.height = height;
+ out = dumb_ptr<expr_t>::make(a_rect);
return true;
}
- if (op == "TOWARDS")
+ if (op == "TOWARDS"_s)
{
e_location_t loc;
dumb_ptr<expr_t> dir;
@@ -492,41 +504,41 @@ namespace magic_v2
return false;
if (!parse_expression(x._list[4], depth))
return false;
- out = magic_new_expr(EXPR::AREA);
- out->e.e_area.ty = AREA::BAR;
- out->e.e_area.a.a_bar.loc = loc;
- out->e.e_area.a.a_bar.dir = dir;
- out->e.e_area.a.a_bar.width = width;
- out->e.e_area.a.a_bar.depth = depth;
+ ExprAreaBar a_bar;
+ a_bar.loc = loc;
+ a_bar.dir = dir;
+ a_bar.width = width;
+ a_bar.depth = depth;
+ out = dumb_ptr<expr_t>::make(a_bar);
return true;
}
- if (op == ".")
+ if (op == "."_s)
{
if (x._list.size() != 3)
- return fail(x, ". not 2");
+ return fail(x, ". not 2"_s);
dumb_ptr<expr_t> expr;
if (!parse_expression(x._list[1], expr))
return false;
if (x._list[2]._type != sexpr::TOKEN)
- return fail(x._list[2], ".elem not name");
+ return fail(x._list[2], ".elem not name"_s);
ZString elem = x._list[2]._str;
out = dot_expr(expr, intern_id(elem));
return true;
}
- static
+ static // TODO LString
std::set<ZString> ops =
{
- "<", ">", "<=", ">=", "==", "!=",
- "+", "-", "*", "%", "/",
- "&", "^", "|", "<<", ">>",
- "&&", "||",
+ "<"_s, ">"_s, "<="_s, ">="_s, "=="_s, "!="_s,
+ "+"_s, "-"_s, "*"_s, "%"_s, "/"_s,
+ "&"_s, "^"_s, "|"_s, "<<"_s, ">>"_s,
+ "&&"_s, "||"_s,
};
// TODO implement unary operators
if (ops.count(op))
{
// operators are n-ary and left-associative
if (x._list.size() < 3)
- return fail(x, "operator not at least 2 args");
+ return fail(x, "operator not at least 2 args"_s);
auto begin = x._list.begin() + 1;
auto end = x._list.end();
if (!parse_expression(*begin, out))
@@ -557,7 +569,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)
{
@@ -565,23 +577,23 @@ namespace magic_v2
item_data *item = itemdb_searchname(s._str);
if (!item)
- return fail(s, "no such item");
+ return fail(s, "no such item"_s);
id = item->nameid;
return true;
}
if (s._type != sexpr::LIST)
- return fail(s, "item not string or list");
+ return fail(s, "item not string or list"_s);
if (s._list.size() != 2)
- return fail(s, "item list is not pair");
+ return fail(s, "item list is not pair"_s);
if (s._list[0]._type != sexpr::INT)
- return fail(s._list[0], "item pair first not int");
+ return fail(s._list[0], "item pair first not int"_s);
count = s._list[0]._int;
if (s._list[1]._type != sexpr::STRING)
- return fail(s._list[1], "item pair second not name");
+ return fail(s._list[1], "item pair second not name"_s);
item_data *item = itemdb_searchname(s._list[1]._str);
if (!item)
- return fail(s, "no such item");
+ return fail(s, "no such item"_s);
id = item->nameid;
return true;
}
@@ -590,18 +602,18 @@ namespace magic_v2
bool parse_spellguard(const SExpr& s, dumb_ptr<spellguard_t>& out)
{
if (s._type != sexpr::LIST)
- return fail(s, "not list");
+ return fail(s, "not list"_s);
if (s._list.empty())
- return fail(s, "empty list");
+ return fail(s, "empty list"_s);
if (s._list[0]._type != sexpr::TOKEN)
- return fail(s._list[0], "not token");
+ return fail(s._list[0], "not token"_s);
ZString cmd = s._list[0]._str;
- if (cmd == "OR")
+ if (cmd == "OR"_s)
{
auto begin = s._list.begin() + 1;
auto end = s._list.end();
if (begin == end)
- return fail(s, "missing arguments");
+ return fail(s, "missing arguments"_s);
if (!parse_spellguard(*begin, out))
return false;
++begin;
@@ -610,21 +622,21 @@ namespace magic_v2
dumb_ptr<spellguard_t> alt;
if (!parse_spellguard(*begin, alt))
return false;
- dumb_ptr<spellguard_t> choice = new_spellguard(SPELLGUARD::CHOICE);
- choice->next = out;
- choice->s.s_alt = alt;
- out = choice;
+ GuardChoice choice;
+ auto next = out;
+ choice.s_alt = alt;
+ out = dumb_ptr<spellguard_t>::make(choice, next);
}
return true;
}
- if (cmd == "GUARD")
+ if (cmd == "GUARD"_s)
{
auto begin = s._list.begin() + 1;
auto end = s._list.end();
while (is_comment(end[-1]))
--end;
if (begin == end)
- return fail(s, "missing arguments");
+ return fail(s, "missing arguments"_s);
if (!parse_spellguard(end[-1], out))
return false;
--end;
@@ -639,68 +651,75 @@ namespace magic_v2
}
return true;
}
- if (cmd == "REQUIRE")
+ if (cmd == "REQUIRE"_s)
{
if (s._list.size() != 2)
- return fail(s, "not one argument");
+ return fail(s, "not one argument"_s);
dumb_ptr<expr_t> condition;
if (!parse_expression(s._list[1], condition))
return false;
- out = new_spellguard(SPELLGUARD::CONDITION);
- out->s.s_condition = condition;
+ GuardCondition cond;
+ cond.s_condition = condition;
+ out = dumb_ptr<spellguard_t>::make(cond, nullptr);
return true;
}
- if (cmd == "MANA")
+ if (cmd == "MANA"_s)
{
if (s._list.size() != 2)
- return fail(s, "not one argument");
+ return fail(s, "not one argument"_s);
dumb_ptr<expr_t> mana;
if (!parse_expression(s._list[1], mana))
return false;
- out = new_spellguard(SPELLGUARD::MANA);
- out->s.s_mana = mana;
+ GuardMana sp;
+ sp.s_mana = mana;
+ out = dumb_ptr<spellguard_t>::make(sp, nullptr);
return true;
}
- if (cmd == "CASTTIME")
+ if (cmd == "CASTTIME"_s)
{
if (s._list.size() != 2)
- return fail(s, "not one argument");
+ return fail(s, "not one argument"_s);
dumb_ptr<expr_t> casttime;
if (!parse_expression(s._list[1], casttime))
return false;
- out = new_spellguard(SPELLGUARD::CASTTIME);
- out->s.s_casttime = casttime;
+ GuardCastTime ct;
+ ct.s_casttime = casttime;
+ out = dumb_ptr<spellguard_t>::make(ct, nullptr);
return true;
}
- if (cmd == "CATALYSTS")
+ if (cmd == "CATALYSTS"_s)
{
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);
}
- out = new_spellguard(SPELLGUARD::CATALYSTS);
- out->s.s_catalysts = items;
+ GuardCatalysts cat;
+ cat.s_catalysts = items;
+ out = dumb_ptr<spellguard_t>::make(cat, nullptr);
return true;
}
- if (cmd == "COMPONENTS")
+ if (cmd == "COMPONENTS"_s)
{
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);
}
- out = new_spellguard(SPELLGUARD::COMPONENTS);
- out->s.s_components = items;
+ GuardComponents comp;
+ comp.s_components = items;
+ out = dumb_ptr<spellguard_t>::make(comp, nullptr);
return true;
}
- return fail(s._list[0], "unknown guard");
+ return fail(s._list[0], "unknown guard"_s);
}
static
@@ -709,7 +728,7 @@ namespace magic_v2
{
// these backward lists could be forward by keeping the reference
// I know this is true because Linus said so
- out = new_effect(EFFECT::SKIP);
+ out = dumb_ptr<effect_t>::make(EffectSkip{}, nullptr);
while (end != begin)
{
const SExpr& s = *--end;
@@ -727,100 +746,102 @@ namespace magic_v2
bool parse_effect(const SExpr& s, dumb_ptr<effect_t>& out)
{
if (s._type != sexpr::LIST)
- return fail(s, "not list");
+ return fail(s, "not list"_s);
if (s._list.empty())
- return fail(s, "empty list");
+ return fail(s, "empty list"_s);
if (s._list[0]._type != sexpr::TOKEN)
- return fail(s._list[0], "not token");
+ return fail(s._list[0], "not token"_s);
ZString cmd = s._list[0]._str;
- if (cmd == "BLOCK")
+ if (cmd == "BLOCK"_s)
{
return build_effect_list(s._list.begin() + 1, s._list.end(), out);
}
- if (cmd == "SET")
+ if (cmd == "SET"_s)
{
if (s._list.size() != 3)
- return fail(s, "not 2 args");
+ return fail(s, "not 2 args"_s);
if (s._list[1]._type != sexpr::TOKEN)
- return fail(s._list[1], "not token");
+ return fail(s._list[1], "not token"_s);
ZString name = s._list[1]._str;
if (find_constant(name))
- return fail(s._list[1], "assigning to constant");
+ return fail(s._list[1], "assigning to constant"_s);
dumb_ptr<expr_t> expr;
if (!parse_expression(s._list[2], expr))
return false;
- out = new_effect(EFFECT::ASSIGN);
- out->e.e_assign.id = intern_id(name);
- out->e.e_assign.expr = expr;
+ EffectAssign e_assign;
+ e_assign.id = intern_id(name);
+ e_assign.expr = expr;
+ out = dumb_ptr<effect_t>::make(e_assign, nullptr);
return true;
}
- if (cmd == "SCRIPT")
+ if (cmd == "SCRIPT"_s)
{
if (s._list.size() != 2)
- return fail(s, "not 1 arg");
+ return fail(s, "not 1 arg"_s);
if (s._list[1]._type != sexpr::STRING)
- return fail(s._list[1], "not string");
+ return fail(s._list[1], "not string"_s);
ZString body = s._list[1]._str;
std::unique_ptr<const ScriptBuffer> script = parse_script(body, s._list[1]._span.begin.line, true);
if (!script)
- return fail(s._list[1], "script does not compile");
- out = new_effect(EFFECT::SCRIPT);
- out->e.e_script = dumb_ptr<const ScriptBuffer>(script.release());
+ return fail(s._list[1], "script does not compile"_s);
+ EffectScript e;
+ e.e_script = dumb_ptr<const ScriptBuffer>(script.release());
+ out = dumb_ptr<effect_t>::make(e, nullptr);
return true;
}
- if (cmd == "SKIP")
+ if (cmd == "SKIP"_s)
{
if (s._list.size() != 1)
- return fail(s, "not 0 arg");
- out = new_effect(EFFECT::SKIP);
+ return fail(s, "not 0 arg"_s);
+ out = dumb_ptr<effect_t>::make(EffectSkip{}, nullptr);
return true;
}
- if (cmd == "ABORT")
+ if (cmd == "ABORT"_s)
{
if (s._list.size() != 1)
- return fail(s, "not 0 arg");
- out = new_effect(EFFECT::ABORT);
+ return fail(s, "not 0 arg"_s);
+ out = dumb_ptr<effect_t>::make(EffectAbort{}, nullptr);
return true;
}
- if (cmd == "END")
+ if (cmd == "END"_s)
{
if (s._list.size() != 1)
- return fail(s, "not 0 arg");
- out = new_effect(EFFECT::END);
+ return fail(s, "not 0 arg"_s);
+ out = dumb_ptr<effect_t>::make(EffectEnd{}, nullptr);
return true;
}
- if (cmd == "BREAK")
+ if (cmd == "BREAK"_s)
{
if (s._list.size() != 1)
- return fail(s, "not 0 arg");
- out = new_effect(EFFECT::BREAK);
+ return fail(s, "not 0 arg"_s);
+ out = dumb_ptr<effect_t>::make(EffectBreak{}, nullptr);
return true;
}
- if (cmd == "FOREACH")
+ if (cmd == "FOREACH"_s)
{
if (s._list.size() != 5)
- return fail(s, "not 4 arg");
+ return fail(s, "not 4 arg"_s);
if (s._list[1]._type != sexpr::TOKEN)
- return fail(s._list[1], "foreach type not token");
+ return fail(s._list[1], "foreach type not token"_s);
ZString type = s._list[1]._str;
FOREACH_FILTER filter;
- if (type == "PC")
+ if (type == "PC"_s)
filter = FOREACH_FILTER::PC;
- else if (type == "MOB")
+ else if (type == "MOB"_s)
filter = FOREACH_FILTER::MOB;
- else if (type == "ENTITY")
+ else if (type == "ENTITY"_s)
filter = FOREACH_FILTER::ENTITY;
- else if (type == "SPELL")
+ else if (type == "SPELL"_s)
filter = FOREACH_FILTER::SPELL;
- else if (type == "TARGET")
+ else if (type == "TARGET"_s)
filter = FOREACH_FILTER::TARGET;
- else if (type == "NPC")
+ else if (type == "NPC"_s)
filter = FOREACH_FILTER::NPC;
else
- return fail(s._list[1], "unknown foreach filter");
+ return fail(s._list[1], "unknown foreach filter"_s);
if (s._list[2]._type != sexpr::TOKEN)
- return fail(s._list[2], "foreach var not token");
+ return fail(s._list[2], "foreach var not token"_s);
ZString var = s._list[2]._str;
dumb_ptr<expr_t> area;
dumb_ptr<effect_t> effect;
@@ -828,19 +849,21 @@ namespace magic_v2
return false;
if (!parse_effect(s._list[4], effect))
return false;
- out = new_effect(EFFECT::FOREACH);
- out->e.e_foreach.id = intern_id(var);
- out->e.e_foreach.area = area;
- out->e.e_foreach.body = effect;
- out->e.e_foreach.filter = filter;
+
+ EffectForEach e_foreach;
+ e_foreach.id = intern_id(var);
+ e_foreach.area = area;
+ e_foreach.body = effect;
+ e_foreach.filter = filter;
+ out = dumb_ptr<effect_t>::make(e_foreach, nullptr);
return true;
}
- if (cmd == "FOR")
+ if (cmd == "FOR"_s)
{
if (s._list.size() != 5)
- return fail(s, "not 4 arg");
+ return fail(s, "not 4 arg"_s);
if (s._list[1]._type != sexpr::TOKEN)
- return fail(s._list[1], "for var not token");
+ return fail(s._list[1], "for var not token"_s);
ZString var = s._list[1]._str;
dumb_ptr<expr_t> low;
dumb_ptr<expr_t> high;
@@ -851,17 +874,19 @@ namespace magic_v2
return false;
if (!parse_effect(s._list[4], effect))
return false;
- out = new_effect(EFFECT::FOR);
- out->e.e_for.id = intern_id(var);
- out->e.e_for.start = low;
- out->e.e_for.stop = high;
- out->e.e_for.body = effect;
+
+ EffectFor e_for;
+ e_for.id = intern_id(var);
+ e_for.start = low;
+ e_for.stop = high;
+ e_for.body = effect;
+ out = dumb_ptr<effect_t>::make(e_for, nullptr);
return true;
}
- if (cmd == "IF")
+ if (cmd == "IF"_s)
{
if (s._list.size() != 3 && s._list.size() != 4)
- return fail(s, "not 2 or 3 args");
+ return fail(s, "not 2 or 3 args"_s);
dumb_ptr<expr_t> cond;
dumb_ptr<effect_t> if_true;
dumb_ptr<effect_t> if_false;
@@ -875,30 +900,33 @@ namespace magic_v2
return false;
}
else
- if_false = new_effect(EFFECT::SKIP);
- out = new_effect(EFFECT::IF);
- out->e.e_if.cond = cond;
- out->e.e_if.true_branch = if_true;
- out->e.e_if.false_branch = if_false;
+ if_false = dumb_ptr<effect_t>::make(EffectSkip{}, nullptr);
+
+ EffectIf e_if;
+ e_if.cond = cond;
+ e_if.true_branch = if_true;
+ e_if.false_branch = if_false;
+ out = dumb_ptr<effect_t>::make(e_if, nullptr);
return true;
}
- if (cmd == "WAIT")
+ if (cmd == "WAIT"_s)
{
if (s._list.size() != 2)
- return fail(s, "not 1 arg");
+ return fail(s, "not 1 arg"_s);
dumb_ptr<expr_t> expr;
if (!parse_expression(s._list[1], expr))
return false;
- out = new_effect(EFFECT::SLEEP);
- out->e.e_sleep = expr;
+ EffectSleep e;
+ e.e_sleep = expr;
+ out = dumb_ptr<effect_t>::make(e, nullptr);
return true;
}
- if (cmd == "CALL")
+ if (cmd == "CALL"_s)
{
if (s._list.size() < 2)
- return fail(s, "call what?");
+ return fail(s, "call what?"_s);
if (s._list[1]._type != sexpr::TOKEN)
- return fail(s._list[1], "call token please");
+ return fail(s._list[1], "call token please"_s);
ZString func = s._list[1]._str;
auto argvp = dumb_ptr<std::vector<dumb_ptr<expr_t>>>::make();
for (auto it = s._list.begin() + 2, end = s._list.end(); it != end; ++it)
@@ -925,16 +953,16 @@ namespace magic_v2
bool parse_spellbody(const SExpr& s, dumb_ptr<spellguard_t>& out)
{
if (s._type != sexpr::LIST)
- return fail(s, "not list");
+ return fail(s, "not list"_s);
if (s._list.empty())
- return fail(s, "empty list");
+ return fail(s, "empty list"_s);
if (s._list[0]._type != sexpr::TOKEN)
- return fail(s._list[0], "not token");
+ return fail(s._list[0], "not token"_s);
ZString cmd = s._list[0]._str;
- if (cmd == "=>")
+ if (cmd == "=>"_s)
{
if (s._list.size() != 3)
- return fail(s, "list does not have exactly 2 arguments");
+ return fail(s, "list does not have exactly 2 arguments"_s);
dumb_ptr<spellguard_t> guard;
if (!parse_spellguard(s._list[1], guard))
return false;
@@ -944,10 +972,10 @@ namespace magic_v2
out = spellguard_implication(guard, body);
return true;
}
- if (cmd == "|")
+ if (cmd == "|"_s)
{
if (s._list.size() == 1)
- return fail(s, "spellbody choice empty");
+ return fail(s, "spellbody choice empty"_s);
auto begin = s._list.begin() + 1;
auto end = s._list.end();
if (!parse_spellbody(*begin, out))
@@ -959,13 +987,13 @@ namespace magic_v2
if (!parse_spellbody(*begin, alt))
return false;
auto tmp = out;
- out = new_spellguard(SPELLGUARD::CHOICE);
- out->next = tmp;
- out->s.s_alt = alt;
+ GuardChoice choice;
+ choice.s_alt = alt;
+ out = dumb_ptr<spellguard_t>::make(choice, tmp);
}
return true;
}
- if (cmd == "EFFECT")
+ if (cmd == "EFFECT"_s)
{
auto begin = s._list.begin() + 1;
auto end = s._list.end();
@@ -978,7 +1006,7 @@ namespace magic_v2
--end;
if (end[-1]._type == sexpr::LIST && !end[-1]._list.empty()
&& end[-1]._list[0]._type == sexpr::TOKEN
- && end[-1]._list[0]._str == "ATEND")
+ && end[-1]._list[0]._str == "ATEND"_s)
{
auto atb = end[-1]._list.begin() + 1;
auto ate = end[-1]._list.end();
@@ -995,7 +1023,7 @@ namespace magic_v2
}
if (end[-1]._type == sexpr::LIST && !end[-1]._list.empty()
&& end[-1]._list[0]._type == sexpr::TOKEN
- && end[-1]._list[0]._str == "ATTRIGGER")
+ && end[-1]._list[0]._str == "ATTRIGGER"_s)
{
auto atb = end[-1]._list.begin() + 1;
auto ate = end[-1]._list.end();
@@ -1009,26 +1037,27 @@ namespace magic_v2
}
if (!build_effect_list(begin, end, effect))
return false;
- out = new_spellguard(SPELLGUARD::EFFECT);
- out->s.s_effect.effect = effect;
- out->s.s_effect.at_trigger = attrig;
- out->s.s_effect.at_end = atend;
+ effect_set_t s_effect;
+ s_effect.effect = effect;
+ s_effect.at_trigger = attrig;
+ s_effect.at_end = atend;
+ out = dumb_ptr<spellguard_t>::make(s_effect, nullptr);
return true;
}
- return fail(s._list[0], "unknown spellbody");
+ return fail(s._list[0], "unknown spellbody"_s);
}
static
bool parse_top_set(const std::vector<SExpr>& in)
{
if (in.size() != 3)
- return fail(in[0], "not 2 arguments");
+ return fail(in[0], "not 2 arguments"_s);
ZString name = in[1]._str;
dumb_ptr<expr_t> expr;
if (!parse_expression(in[2], expr))
return false;
if (find_constant(name))
- return fail(in[1], "assign constant");
+ return fail(in[1], "assign constant"_s);
size_t var_id = intern_id(name);
magic_eval(dumb_ptr<env_t>(&magic_default_env), &magic_conf.varv[var_id].val, expr);
return true;
@@ -1037,28 +1066,28 @@ namespace magic_v2
bool parse_const(io::LineSpan span, const std::vector<SExpr>& in)
{
if (in.size() != 3)
- return fail(in[0], "not 2 arguments");
+ return fail(in[0], "not 2 arguments"_s);
if (in[1]._type != sexpr::TOKEN)
- return fail(in[1], "not token");
+ return fail(in[1], "not token"_s);
ZString name = in[1]._str;
dumb_ptr<expr_t> expr;
if (!parse_expression(in[2], expr))
return false;
val_t tmp;
magic_eval(dumb_ptr<env_t>(&magic_default_env), &tmp, expr);
- return bind_constant(span, name, &tmp);
+ return bind_constant(span, name, std::move(tmp));
}
static
bool parse_anchor(io::LineSpan span, const std::vector<SExpr>& in)
{
if (in.size() != 4)
- return fail(in[0], "not 3 arguments");
+ return fail(in[0], "not 3 arguments"_s);
auto anchor = dumb_ptr<teleport_anchor_t>::make();
if (in[1]._type != sexpr::TOKEN)
- return fail(in[1], "not token");
+ return fail(in[1], "not token"_s);
anchor->name = in[1]._str;
if (in[2]._type != sexpr::STRING)
- return fail(in[2], "not string");
+ return fail(in[2], "not string"_s);
anchor->invocation = in[2]._str;
dumb_ptr<expr_t> expr;
if (!parse_expression(in[3], expr))
@@ -1070,17 +1099,17 @@ namespace magic_v2
bool parse_proc(io::LineSpan span, const std::vector<SExpr>& in)
{
if (in.size() < 4)
- return fail(in[0], "not at least 3 arguments");
+ return fail(in[0], "not at least 3 arguments"_s);
auto proc = dumb_ptr<proc_t>::make();
if (in[1]._type != sexpr::TOKEN)
- return fail(in[1], "name not token");
+ return fail(in[1], "name not token"_s);
proc->name = in[1]._str;
if (in[2]._type != sexpr::LIST)
- return fail(in[2], "args not list");
+ return fail(in[2], "args not list"_s);
for (const SExpr& arg : in[2]._list)
{
if (arg._type != sexpr::TOKEN)
- return fail(arg, "arg not token");
+ return fail(arg, "arg not token"_s);
proc->argv.push_back(intern_id(arg._str));
}
if (!build_effect_list(in.begin() + 3, in.end(), proc->body))
@@ -1091,37 +1120,37 @@ namespace magic_v2
bool parse_spell(io::LineSpan span, const std::vector<SExpr>& in)
{
if (in.size() < 6)
- return fail(in[0], "not at least 5 arguments");
+ return fail(in[0], "not at least 5 arguments"_s);
if (in[1]._type != sexpr::LIST)
- return fail(in[1], "flags not list");
+ return fail(in[1], "flags not list"_s);
auto spell = dumb_ptr<spell_t>::make();
for (const SExpr& s : in[1]._list)
{
if (s._type != sexpr::TOKEN)
- return fail(s, "flag not token");
+ return fail(s, "flag not token"_s);
SPELL_FLAG flag = SPELL_FLAG::ZERO;
- if (s._str == "LOCAL")
+ if (s._str == "LOCAL"_s)
flag = SPELL_FLAG::LOCAL;
- else if (s._str == "NONMAGIC")
+ else if (s._str == "NONMAGIC"_s)
flag = SPELL_FLAG::NONMAGIC;
- else if (s._str == "SILENT")
+ else if (s._str == "SILENT"_s)
flag = SPELL_FLAG::SILENT;
else
- return fail(s, "unknown flag");
+ return fail(s, "unknown flag"_s);
if (bool(spell->flags & flag))
- return fail(s, "duplicate flag");
+ return fail(s, "duplicate flag"_s);
spell->flags |= flag;
}
if (in[2]._type != sexpr::TOKEN)
- return fail(in[2], "name not token");
+ return fail(in[2], "name not token"_s);
spell->name = in[2]._str;
if (in[3]._type != sexpr::STRING)
- return fail(in[3], "invoc not string");
+ return fail(in[3], "invoc not string"_s);
spell->invocation = in[3]._str;
if (in[4]._type != sexpr::LIST)
- return fail(in[4], "spellarg not list");
+ return fail(in[4], "spellarg not list"_s);
if (in[4]._list.size() == 0)
{
spell->spellarg_ty = SPELLARG::NONE;
@@ -1129,18 +1158,18 @@ namespace magic_v2
else
{
if (in[4]._list.size() != 2)
- return fail(in[4], "spellarg not empty list or pair");
+ return fail(in[4], "spellarg not empty list or pair"_s);
if (in[4]._list[0]._type != sexpr::TOKEN)
- return fail(in[4]._list[0], "spellarg type not token");
+ return fail(in[4]._list[0], "spellarg type not token"_s);
if (in[4]._list[1]._type != sexpr::TOKEN)
- return fail(in[4]._list[1], "spellarg name not token");
+ return fail(in[4]._list[1], "spellarg name not token"_s);
ZString ty = in[4]._list[0]._str;
- if (ty == "PC")
+ if (ty == "PC"_s)
spell->spellarg_ty = SPELLARG::PC;
- else if (ty == "STRING")
+ else if (ty == "STRING"_s)
spell->spellarg_ty = SPELLARG::STRING;
else
- return fail(in[4]._list[0], "unknown spellarg type");
+ return fail(in[4]._list[0], "unknown spellarg type"_s);
ZString an = in[4]._list[1]._str;
spell->arg = intern_id(an);
}
@@ -1148,19 +1177,19 @@ namespace magic_v2
for (;; ++it)
{
if (it == in.end())
- return fail(it[-1], "end of list scanning LET defs");
+ return fail(it[-1], "end of list scanning LET defs"_s);
if (is_comment(*it))
continue;
if (it->_type != sexpr::LIST || it->_list.empty())
break;
- if (it->_list[0]._type != sexpr::TOKEN || it->_list[0]._str != "LET")
+ if (it->_list[0]._type != sexpr::TOKEN || it->_list[0]._str != "LET"_s)
break;
if (it->_list[1]._type != sexpr::TOKEN)
- return fail(it->_list[1], "let name not token");
+ return fail(it->_list[1], "let name not token"_s);
ZString name = it->_list[1]._str;
if (find_constant(name))
- return fail(it->_list[1], "constant exists");
+ return fail(it->_list[1], "constant exists"_s);
dumb_ptr<expr_t> expr;
if (!parse_expression(it->_list[2], expr))
return false;
@@ -1170,7 +1199,7 @@ namespace magic_v2
spell->letdefv.push_back(let);
}
if (it + 1 != in.end())
- return fail(*it, "expected only one body entry besides LET");
+ return fail(*it, "expected only one body entry besides LET"_s);
// formally, 'guard' only refers to the first argument of '=>'
// but internally, spellbodies use the same thing
@@ -1186,23 +1215,23 @@ namespace magic_v2
{
if (vs.empty())
{
- span.error("Empty list at top");
+ span.error("Empty list at top"_s);
return false;
}
if (vs[0]._type != sexpr::TOKEN)
- return fail(vs[0], "top not token");
+ return fail(vs[0], "top not token"_s);
ZString cmd = vs[0]._str;
- if (cmd == "CONST")
+ if (cmd == "CONST"_s)
return parse_const(span, vs);
- if (cmd == "PROCEDURE")
+ if (cmd == "PROCEDURE"_s)
return parse_proc(span, vs);
- if (cmd == "SET")
+ if (cmd == "SET"_s)
return parse_top_set(vs);
- if (cmd == "SPELL")
+ if (cmd == "SPELL"_s)
return parse_spell(span, vs);
- if (cmd == "TELEPORT-ANCHOR")
+ if (cmd == "TELEPORT-ANCHOR"_s)
return parse_anchor(span, vs);
- return fail(vs[0], "Unknown top-level command");
+ return fail(vs[0], "Unknown top-level command"_s);
}
static
@@ -1214,14 +1243,14 @@ namespace magic_v2
if (is_comment(s))
continue;
if (s._type != sexpr::LIST)
- return fail(s, "top-level entity not a list or comment");
+ return fail(s, "top-level entity not a list or comment"_s);
if (!parse_top(s._span, s._list))
return false;
}
// handle low-level errors
if (in.peek() != sexpr::TOK_EOF)
{
- in.span().error("parser gave up before end of file");
+ in.span().error("parser gave up before end of file"_s);
return false;
}
return true;
@@ -1239,7 +1268,9 @@ bool load_magic_file_v2(ZString filename)
bool rv = magic_v2::loop(in);
if (!rv)
{
- in.span().error(STRPRINTF("next token: %s '%s'", sexpr::token_name(in.peek()), in.val_string()));
+ in.span().error(STRPRINTF("next token: %s '%s'"_fmt, sexpr::token_name(in.peek()), in.val_string()));
}
return rv;
}
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic-v2.hpp b/src/map/magic-v2.hpp
index 888e183..9ad44a9 100644
--- a/src/map/magic-v2.hpp
+++ b/src/map/magic-v2.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAGIC_V2_HPP
-#define TMWA_MAP_MAGIC_V2_HPP
+#pragma once
// magic-v2.hpp - second generation magic parser
//
// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
@@ -19,12 +18,17 @@
// 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/zstring.hpp"
+#include "../strings/zstring.hpp"
+
+namespace tmwa
+{
+namespace magic
+{
bool magic_init0();
// must be called after itemdb initialization
bool load_magic_file_v2(ZString filename);
-
-#endif // TMWA_MAP_MAGIC_V2_HPP
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic.cpp b/src/map/magic.cpp
index 9896b26..a0238b5 100644
--- a/src/map/magic.cpp
+++ b/src/map/magic.cpp
@@ -1,3 +1,4 @@
+#include "magic.hpp"
// magic.cpp - Entry to the magic system.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -18,25 +19,29 @@
// 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 <cstring>
+#include <algorithm>
+#include <utility>
#include "../strings/xstring.hpp"
-#include "../io/cxxstdio.hpp"
-
-#include "magic-interpreter.hpp"
+#include "../generic/dumb_ptr.hpp"
-#include "pc.hpp"
+#include "../io/cxxstdio.hpp"
#include "magic-expr.hpp"
+#include "magic-interpreter.hpp"
#include "magic-interpreter-base.hpp"
#include "magic-stmt.hpp"
-#include "magic.hpp"
+#include "map.hpp"
+#include "pc.hpp"
#include "../poison.hpp"
-#undef DEBUG
+namespace tmwa
+{
+namespace magic
+{
/// Return a pair of strings, {spellname, parameter}
/// Parameter may be empty.
static
@@ -90,20 +95,15 @@ int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation)
int near_miss;
dumb_ptr<env_t> env =
spell_create_env(&magic_conf, spell, caster, power, parameter);
- effect_set_t *effects;
+ const effect_set_t *effects;
if (bool(spell->flags & SPELL_FLAG::NONMAGIC) || (power >= 1))
effects = spell_trigger(spell, caster, env, &near_miss);
else
- effects = NULL;
-
-#ifdef DEBUG
- FPRINTF(stderr, "Found spell `%s', triggered = %d\n", spell_,
- effects != NULL);
-#endif
+ effects = nullptr;
- MAP_LOG_PC(caster, "CAST %s %s",
- spell->name, effects ? "SUCCESS" : "FAILURE");
+ MAP_LOG_PC(caster, "CAST %s %s"_fmt,
+ spell->name, effects ? "SUCCESS"_s : "FAILURE"_s);
if (effects)
{
@@ -122,3 +122,5 @@ int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation)
return 0; /* Not a spell */
}
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/magic.hpp b/src/map/magic.hpp
index a5a966c..a420872 100644
--- a/src/map/magic.hpp
+++ b/src/map/magic.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAGIC_HPP
-#define TMWA_MAP_MAGIC_HPP
+#pragma once
// magic.hpp - Entry to the magic system.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -20,17 +19,20 @@
// 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 "../strings/fwd.hpp"
-# include "../mmo/dumb_ptr.hpp"
+#include "../generic/fwd.hpp"
-# include "map.hpp"
-# include "skill.t.hpp"
+#include "map.t.hpp"
+#include "skill.t.hpp"
-struct invocation; /* Spell invocation */
+namespace tmwa
+{
+namespace magic
+{
/**
* Try to cast magic.
*
@@ -43,62 +45,5 @@ struct invocation; /* Spell invocation */
* message should not be repeated.
*/
int magic_message(dumb_ptr<map_session_data> caster, XString source_invocation);
-
-/**
- * Removes the shroud from a character
- *
- * \param character The character to remove the shroud from
- */
-void magic_unshroud(dumb_ptr<map_session_data> character);
-
-/**
- * Notifies a running spell that a status_change timer triggered by the spell has expired
- *
- * \param invocation The invocation to notify
- * \param bl_id ID of the PC for whom this happened
- * \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,
- StatusChange sc_id, int supplanted);
-
-/**
- * Identifies the invocation used to trigger a spell
- *
- * Returns empty string if not found
- */
-AString magic_find_invocation(XString spellname);
-
-/**
- * Identifies the invocation used to denote a teleport location
- *
- * Returns empty string if not found
- */
-AString magic_find_anchor_invocation(XString teleport_location);
-
-/**
- * Execute a spell invocation and sets up timers to finish
- */
-void spell_execute(dumb_ptr<invocation> invocation);
-
-/**
- * Continue an NPC script embedded in a spell
- */
-void spell_execute_script(dumb_ptr<invocation> invocation);
-
-/**
- * Stops all magic bound to the specified character
- *
- */
-void magic_stop_completely(dumb_ptr<map_session_data> c);
-
-/**
- * Attacks with a magical spell charged to the character
- *
- * Returns 0 if there is no charged spell or the spell is depleted.
- */
-int spell_attack(int caster, int target);
-
-void spell_free_invocation(dumb_ptr<invocation> invocation);
-
-#endif // TMWA_MAP_MAGIC_HPP
+} // namespace magic
+} // namespace tmwa
diff --git a/src/map/main.cpp b/src/map/main.cpp
index 2db1408..8e8e9d5 100644
--- a/src/map/main.cpp
+++ b/src/map/main.cpp
@@ -1,4 +1,3 @@
-#include "map.hpp"
// map/main.cpp - dummy file to make Make dependencies work
//
// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
@@ -18,4 +17,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 "map.hpp"
+
#include "../poison.hpp"
+
+
+namespace tmwa
+{
+} // namespace tmwa
diff --git a/src/map/map.cpp b/src/map/map.cpp
index b49b225..4a25029 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -29,29 +29,34 @@
#include <cassert>
#include <cstdlib>
-#include <cstring>
#include "../compat/nullpo.hpp"
#include "../compat/fun.hpp"
+#include "../ints/udl.hpp"
+
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
#include "../strings/vstring.hpp"
+#include "../strings/literal.hpp"
#include "../generic/db.hpp"
#include "../generic/random2.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/read.hpp"
#include "../io/tty.hpp"
#include "../io/write.hpp"
+#include "../net/socket.hpp"
+#include "../net/timer.hpp"
+
#include "../mmo/config_parse.hpp"
#include "../mmo/core.hpp"
#include "../mmo/extract.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../mmo/utils.hpp"
#include "../mmo/version.hpp"
#include "atcommand.hpp"
@@ -60,8 +65,8 @@
#include "clif.hpp"
#include "grfio.hpp"
#include "itemdb.hpp"
-#include "magic.hpp"
-#include "magic-interpreter.hpp"
+#include "magic-interpreter.hpp" // for is_spell inline body
+#include "magic-stmt.hpp"
#include "magic-v2.hpp"
#include "mob.hpp"
#include "npc.hpp"
@@ -74,7 +79,10 @@
#include "../poison.hpp"
-DMap<int, dumb_ptr<block_list>> id_db;
+
+namespace tmwa
+{
+DMap<BlockId, dumb_ptr<block_list>> id_db;
UPMap<MapName, map_abstract> maps_db;
@@ -88,21 +96,21 @@ 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;
-AString motd_txt = "conf/motd.txt";
+AString motd_txt = "conf/motd.txt"_s;
-CharName wisp_server_name = stringish<CharName>("Server"); // can be modified in char-server configuration file
+CharName wisp_server_name = stringish<CharName>("Server"_s); // can be modified in char-server configuration file
static
void map_delmap(MapName mapname);
@@ -112,6 +120,10 @@ void SessionDeleter::operator()(SessionData *sd)
really_delete1 static_cast<map_session_data *>(sd);
}
+VString<49> convert_for_printf(NpcEvent ev)
+{
+ return STRNPRINTF(50, "%s::%s"_fmt, ev.npc, ev.label);
+}
bool extract(XString str, NpcEvent *ev)
{
XString mid;
@@ -181,12 +193,12 @@ struct block_list bl_head;
*/
int map_addblock(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_prev)
{
if (battle_config.error_log)
- PRINTF("map_addblock error : bl->bl_prev!=NULL\n");
+ PRINTF("map_addblock error : bl->bl_prev!=nullptr\n"_fmt);
return 0;
}
@@ -226,7 +238,7 @@ int map_addblock(dumb_ptr<block_list> bl)
*/
int map_delblock(dumb_ptr<block_list> bl)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
// 既にblocklistから抜けている
if (!bl->bl_prev)
@@ -235,7 +247,7 @@ int map_delblock(dumb_ptr<block_list> bl)
{
// prevがNULLでnextがNULLでないのは有ってはならない
if (battle_config.error_log)
- PRINTF("map_delblock error : bl->bl_next!=NULL\n");
+ PRINTF("map_delblock error : bl->bl_next!=nullptr\n"_fmt);
}
return 0;
}
@@ -261,8 +273,8 @@ int map_delblock(dumb_ptr<block_list> bl)
{
bl->bl_prev->bl_next = bl->bl_next;
}
- bl->bl_next = NULL;
- bl->bl_prev = NULL;
+ bl->bl_next = nullptr;
+ bl->bl_prev = nullptr;
return 0;
}
@@ -274,7 +286,7 @@ int map_delblock(dumb_ptr<block_list> bl)
int map_count_oncell(map_local *m, int x, int y)
{
int bx, by;
- dumb_ptr<block_list> bl = NULL;
+ dumb_ptr<block_list> bl = nullptr;
int count = 0;
if (x < 0 || y < 0 || (x >= m->xs) || (y >= m->ys))
@@ -533,29 +545,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");
- return 0;
+ PRINTF("map_addobject nullpo?\n"_fmt);
+ 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");
- return 0;
+ PRINTF("no free object id\n"_fmt);
+ 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;
}
@@ -565,32 +575,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",
+ 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;
}
/*==========================================
@@ -601,21 +605,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;
+ if (obj == nullptr)
+ 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;
}
/*==========================================
@@ -626,24 +628,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);
+ }
}
/*==========================================
@@ -656,15 +662,15 @@ 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)
fitem->cleartimer.cancel();
- clif_clearflooritem(fitem, 0);
+ clif_clearflooritem(fitem, nullptr);
map_delobject(fitem->bl_id, BL::ITEM);
}
@@ -678,7 +684,7 @@ std::pair<uint16_t, uint16_t> map_randfreecell(map_local *m,
if (!bool(read_gatp(m, x + dx, y + dy) & MapCell::UNWALKABLE))
return {static_cast<uint16_t>(x + dx), static_cast<uint16_t>(y + dy)};
}
- return {static_cast<uint16_t>(0), static_cast<uint16_t>(0)};
+ return {0_u16, 0_u16};
}
/// Return a randomly selected passable cell within a given range.
@@ -695,36 +701,36 @@ 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(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;
+ dumb_ptr<flooritem_data> fitem = nullptr;
- 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;
- fitem->bl_prev = fitem->bl_next = NULL;
+ fitem->bl_prev = fitem->bl_next = nullptr;
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();
@@ -760,7 +766,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(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,
@@ -784,10 +790,10 @@ 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)
+ if (p == nullptr)
p = charid_db.init(charid);
p->nick = name;
@@ -840,7 +846,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); // パーティのログアウトメッセージ送信
@@ -883,7 +889,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.
@@ -899,7 +905,7 @@ dumb_ptr<map_session_data> map_id2sd(int id)
bl=numdb_search(id_db,id);
if (bl && bl->bl_type==BL::PC)
return (struct map_session_data*)bl;
- return NULL;
+ return nullptr;
*/
for (io::FD i : iter_fds())
{
@@ -914,18 +920,18 @@ dumb_ptr<map_session_data> map_id2sd(int id)
}
}
- return NULL;
+ return nullptr;
}
/*==========================================
* char_id番号の名前を探す
*------------------------------------------
*/
-CharName map_charid2nick(int id)
+CharName map_charid2nick(CharId id)
{
struct charid2nick *p = charid_db.search(id);
- if (p == NULL)
+ if (p == nullptr)
return CharName();
if (p->req_id != 0)
return CharName();
@@ -947,7 +953,7 @@ dumb_ptr<map_session_data> map_get_session(io::FD i)
return dumb_ptr<map_session_data>(d);
}
- return NULL;
+ return nullptr;
}
static
@@ -960,7 +966,7 @@ dumb_ptr<map_session_data> map_get_session_forward(int start)
return d;
}
- return NULL;
+ return nullptr;
}
static
@@ -973,7 +979,7 @@ dumb_ptr<map_session_data> map_get_session_backward(int start)
return d;
}
- return NULL;
+ return nullptr;
}
dumb_ptr<map_session_data> map_get_first_session(void)
@@ -999,7 +1005,7 @@ dumb_ptr<map_session_data> map_get_prev_session(dumb_ptr<map_session_data> d)
/*==========================================
* Search session data from a nick name
* (without sensitive case if necessary)
- * return map_session_data pointer or NULL
+ * return map_session_data pointer or nullptr
*------------------------------------------
*/
dumb_ptr<map_session_data> map_nick2sd(CharName nick)
@@ -1018,7 +1024,7 @@ dumb_ptr<map_session_data> map_nick2sd(CharName nick)
}
}
}
- return NULL;
+ return nullptr;
}
/*==========================================
@@ -1026,11 +1032,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];
+ dumb_ptr<block_list> bl = nullptr;
+ if (id < MAX_FLOORITEM)
+ bl = object[id._value];
else
bl = id_db.get(id);
@@ -1047,12 +1053,12 @@ int map_addnpc(map_local *m, dumb_ptr<npc_data> nd)
if (!m)
return -1;
for (i = 0; i < m->npc_num && i < MAX_NPC_PER_MAP; i++)
- if (m->npc[i] == NULL)
+ if (m->npc[i] == nullptr)
break;
if (i == MAX_NPC_PER_MAP)
{
if (battle_config.error_log)
- PRINTF("too many NPCs in one map %s\n", m->name_);
+ PRINTF("too many NPCs in one map %s\n"_fmt, m->name_);
return -1;
}
if (i == m->npc_num)
@@ -1060,7 +1066,7 @@ int map_addnpc(map_local *m, dumb_ptr<npc_data> nd)
m->npc_num++;
}
- nullpo_ret(nd);
+ nullpo_retz(nd);
m->npc[i] = nd;
nd->n = i;
@@ -1081,7 +1087,7 @@ void map_removenpc(void)
map_local *m = static_cast<map_local *>(mitp.second.get());
for (int i = 0; i < m->npc_num && i < MAX_NPC_PER_MAP; i++)
{
- if (m->npc[i] != NULL)
+ if (m->npc[i] != nullptr)
{
clif_clearchar(m->npc[i], BeingRemoveWhy::QUIT);
map_delblock(m->npc[i]);
@@ -1096,7 +1102,7 @@ void map_removenpc(void)
}
}
}
- PRINTF("%d NPCs removed.\n", n);
+ PRINTF("%d NPCs removed.\n"_fmt, n);
}
/*==========================================
@@ -1106,7 +1112,7 @@ void map_removenpc(void)
map_local *map_mapname2mapid(MapName name)
{
map_abstract *md = maps_db.get(name);
- if (md == NULL || md->gat == NULL)
+ if (md == nullptr || md->gat == nullptr)
return nullptr;
return static_cast<map_local *>(md);
}
@@ -1118,7 +1124,7 @@ map_local *map_mapname2mapid(MapName name)
int map_mapname2ipport(MapName name, IP4Address *ip, int *port)
{
map_abstract *md = maps_db.get(name);
- if (md == NULL || md->gat)
+ if (md == nullptr || md->gat)
return -1;
map_remote *mdos = static_cast<map_remote *>(md);
*ip = mdos->ip;
@@ -1227,12 +1233,12 @@ void map_setcell(map_local *m, int x, int y, MapCell t)
int map_setipport(MapName name, IP4Address ip, int port)
{
map_abstract *md = maps_db.get(name);
- if (md == NULL)
+ if (md == nullptr)
{
// not exist -> add new data
auto mdos = make_unique<map_remote>();
mdos->name_ = name;
- mdos->gat = NULL;
+ mdos->gat = nullptr;
mdos->ip = ip;
mdos->port = port;
maps_db.put(mdos->name_, std::move(mdos));
@@ -1244,7 +1250,7 @@ int map_setipport(MapName name, IP4Address ip, int port)
// local -> check data
if (ip != clif_getip() || port != clif_getport())
{
- PRINTF("from char server : %s -> %s:%d\n",
+ PRINTF("from char server : %s -> %s:%d\n"_fmt,
name, ip, port);
return 1;
}
@@ -1275,7 +1281,7 @@ bool map_readmap(map_local *m, size_t num, MapName fn)
int xs = m->xs = gat_v[0] | gat_v[1] << 8;
int ys = m->ys = gat_v[2] | gat_v[3] << 8;
- PRINTF("\rLoading Maps [%zu/%zu]: %-30s (%i, %i)",
+ PRINTF("\rLoading Maps [%zu/%zu]: %-30s (%i, %i)"_fmt,
num, maps_db.size(),
fn, xs, ys);
fflush(stdout);
@@ -1328,10 +1334,10 @@ bool map_readallmap(void)
}
}
- PRINTF("\rMaps Loaded: %-65zu\n", maps_db.size());
+ PRINTF("\rMaps Loaded: %-65zu\n"_fmt, maps_db.size());
if (maps_removed)
{
- PRINTF("Cowardly refusing to keep going after removing %d maps.\n",
+ PRINTF("Cowardly refusing to keep going after removing %d maps.\n"_fmt,
maps_removed);
return false;
}
@@ -1346,7 +1352,7 @@ bool map_readallmap(void)
static
void map_addmap(MapName mapname)
{
- if (mapname == "clear")
+ if (mapname == "clear"_s)
{
maps_db.clear();
return;
@@ -1366,7 +1372,7 @@ void map_addmap(MapName mapname)
*/
void map_delmap(MapName mapname)
{
- if (mapname == "all")
+ if (mapname == "all"_s)
{
maps_db.clear();
return;
@@ -1389,13 +1395,13 @@ void map_close_logfile(void)
{
if (map_logfile)
{
- AString filename = STRPRINTF("%s.%ld", map_logfile_name, map_logfile_index);
+ AString filename = STRPRINTF("%s.%ld"_fmt, map_logfile_name, map_logfile_index);
const char *args[] =
{
"gzip",
"-f",
filename.c_str(),
- NULL
+ nullptr
};
char **argv = const_cast<char **>(args);
@@ -1406,7 +1412,7 @@ void map_close_logfile(void)
execvp("gzip", argv);
_exit(1);
}
- wait(NULL);
+ wait(nullptr);
}
}
@@ -1416,7 +1422,7 @@ void map_start_logfile(long index)
map_logfile_index = index;
AString filename_buf = STRPRINTF(
- "%s.%ld",
+ "%s.%ld"_fmt,
map_logfile_name,
map_logfile_index);
map_logfile = make_unique<io::AppendFile>(filename_buf);
@@ -1433,11 +1439,11 @@ void map_set_logfile(AString filename)
struct timeval tv;
map_logfile_name = std::move(filename);
- gettimeofday(&tv, NULL);
+ gettimeofday(&tv, nullptr);
map_start_logfile(tv.tv_sec >> LOGFILE_SECONDS_PER_CHUNK_SHIFT);
- MAP_LOG("log-start v5");
+ MAP_LOG("log-start v5"_fmt);
}
void map_log(XString line)
@@ -1464,12 +1470,12 @@ void map_log(XString line)
static
bool map_config_read(ZString cfgName)
{
- struct hostent *h = NULL;
+ struct hostent *h = nullptr;
io::ReadFile in(cfgName);
if (!in.is_open())
{
- PRINTF("Map configuration file not found at: %s\n", cfgName);
+ PRINTF("Map configuration file not found at: %s\n"_fmt, cfgName);
return false;
}
@@ -1483,25 +1489,25 @@ bool map_config_read(ZString cfgName)
ZString w2;
if (!config_split(line, &w1, &w2))
{
- PRINTF("Bad config line: %s\n", line);
+ PRINTF("Bad config line: %s\n"_fmt, line);
rv = false;
continue;
}
- if (w1 == "userid")
+ if (w1 == "userid"_s)
{
AccountName name = stringish<AccountName>(w2);
chrif_setuserid(name);
}
- else if (w1 == "passwd")
+ else if (w1 == "passwd"_s)
{
AccountPass pass = stringish<AccountPass>(w2);
chrif_setpasswd(pass);
}
- else if (w1 == "char_ip")
+ else if (w1 == "char_ip"_s)
{
h = gethostbyname(w2.c_str());
IP4Address w2ip;
- if (h != NULL)
+ if (h != nullptr)
{
w2ip = IP4Address({
static_cast<uint8_t>(h->h_addr[0]),
@@ -1509,25 +1515,25 @@ bool map_config_read(ZString cfgName)
static_cast<uint8_t>(h->h_addr[2]),
static_cast<uint8_t>(h->h_addr[3]),
});
- PRINTF("Character server IP address : %s -> %s\n",
+ PRINTF("Character server IP address : %s -> %s\n"_fmt,
w2, w2ip);
}
else
{
- PRINTF("Bad IP value: %s\n", line);
+ PRINTF("Bad IP value: %s\n"_fmt, line);
return false;
}
chrif_setip(w2ip);
}
- else if (w1 == "char_port")
+ else if (w1 == "char_port"_s)
{
chrif_setport(atoi(w2.c_str()));
}
- else if (w1 == "map_ip")
+ else if (w1 == "map_ip"_s)
{
h = gethostbyname(w2.c_str());
IP4Address w2ip;
- if (h != NULL)
+ if (h != nullptr)
{
w2ip = IP4Address({
static_cast<uint8_t>(h->h_addr[0]),
@@ -1535,61 +1541,61 @@ bool map_config_read(ZString cfgName)
static_cast<uint8_t>(h->h_addr[2]),
static_cast<uint8_t>(h->h_addr[3]),
});
- PRINTF("Map server IP address : %s -> %s\n",
+ PRINTF("Map server IP address : %s -> %s\n"_fmt,
w2, w2ip);
}
else
{
- PRINTF("Bad IP value: %s\n", line);
+ PRINTF("Bad IP value: %s\n"_fmt, line);
return false;
}
clif_setip(w2ip);
}
- else if (w1 == "map_port")
+ else if (w1 == "map_port"_s)
{
clif_setport(atoi(w2.c_str()));
}
- else if (w1 == "map")
+ else if (w1 == "map"_s)
{
MapName name = VString<15>(w2);
map_addmap(name);
}
- else if (w1 == "delmap")
+ else if (w1 == "delmap"_s)
{
MapName name = VString<15>(w2);
map_delmap(name);
}
- else if (w1 == "npc")
+ else if (w1 == "npc"_s)
{
npc_addsrcfile(w2);
}
- else if (w1 == "delnpc")
+ else if (w1 == "delnpc"_s)
{
npc_delsrcfile(w2);
}
- else if (w1 == "autosave_time")
+ else if (w1 == "autosave_time"_s)
{
autosave_time = std::chrono::seconds(atoi(w2.c_str()));
if (autosave_time <= interval_t::zero())
autosave_time = DEFAULT_AUTOSAVE_INTERVAL;
}
- else if (w1 == "motd_txt")
+ else if (w1 == "motd_txt"_s)
{
motd_txt = w2;
}
- else if (w1 == "mapreg_txt")
+ else if (w1 == "mapreg_txt"_s)
{
mapreg_txt = w2;
}
- else if (w1 == "gm_log")
+ else if (w1 == "gm_log"_s)
{
gm_log = std::move(w2);
}
- else if (w1 == "log_file")
+ else if (w1 == "log_file"_s)
{
map_set_logfile(w2);
}
- else if (w1 == "import")
+ else if (w1 == "import"_s)
{
rv &= map_config_read(w2);
}
@@ -1618,7 +1624,7 @@ void cleanup_sub(dumb_ptr<block_list> bl)
map_clearflooritem(bl->bl_id);
break;
case BL::SPELL:
- spell_free_invocation(bl->is_spell());
+ magic::spell_free_invocation(bl->is_spell());
break;
}
}
@@ -1656,7 +1662,7 @@ void term_func(void)
map_close_logfile();
}
-int compare_item(struct item *a, struct item *b)
+int compare_item(Item *a, Item *b)
{
return (a->nameid == b->nameid);
}
@@ -1664,29 +1670,29 @@ int compare_item(struct item *a, struct item *b)
static
bool map_confs(XString key, ZString value)
{
- if (key == "map_conf")
+ if (key == "map_conf"_s)
return map_config_read(value);
- if (key == "battle_conf")
+ if (key == "battle_conf"_s)
return battle_config_read(value);
- if (key == "atcommand_conf")
+ if (key == "atcommand_conf"_s)
return atcommand_config_read(value);
- if (key == "item_db")
+ if (key == "item_db"_s)
return itemdb_readdb(value);
- if (key == "mob_db")
+ if (key == "mob_db"_s)
return mob_readdb(value);
- if (key == "mob_skill_db")
+ if (key == "mob_skill_db"_s)
return mob_readskilldb(value);
- if (key == "skill_db")
+ if (key == "skill_db"_s)
return skill_readdb(value);
- if (key == "magic_conf")
- return load_magic_file_v2(value);
+ if (key == "magic_conf"_s)
+ return magic::load_magic_file_v2(value);
- if (key == "resnametable")
+ if (key == "resnametable"_s)
return load_resnametable(value);
- if (key == "const_db")
+ if (key == "const_db"_s)
return read_constdb(value);
- PRINTF("unknown map conf key: %s\n", AString(key));
+ PRINTF("unknown map conf key: %s\n"_fmt, AString(key));
return false;
}
@@ -1697,7 +1703,7 @@ bool map_confs(XString key, ZString value)
int do_init(Slice<ZString> argv)
{
ZString argv0 = argv.pop_front();
- runflag &= magic_init0();
+ runflag &= magic::magic_init0();
bool loaded_config_yet = false;
while (argv)
@@ -1705,22 +1711,22 @@ int do_init(Slice<ZString> argv)
ZString argvi = argv.pop_front();
if (argvi.startswith('-'))
{
- if (argvi == "--help")
+ if (argvi == "--help"_s)
{
- PRINTF("Usage: %s [--help] [--version] [--write_atcommand_config outfile] [files...]\n",
+ PRINTF("Usage: %s [--help] [--version] [--write_atcommand_config outfile] [files...]\n"_fmt,
argv0);
exit(0);
}
- else if (argvi == "--version")
+ else if (argvi == "--version"_s)
{
- PRINTF("%s\n", CURRENT_VERSION_STRING);
+ PRINTF("%s\n"_fmt, CURRENT_VERSION_STRING);
exit(0);
}
- else if (argvi == "--write-atcommand-config")
+ else if (argvi == "--write-atcommand-config"_s)
{
if (!argv)
{
- PRINTF("Missing argument\n");
+ PRINTF("Missing argument\n"_fmt);
exit(1);
}
ZString filename = argv.pop_front();
@@ -1729,7 +1735,7 @@ int do_init(Slice<ZString> argv)
}
else
{
- FPRINTF(stderr, "Unknown argument: %s\n", argvi);
+ FPRINTF(stderr, "Unknown argument: %s\n"_fmt, argvi);
runflag = false;
}
}
@@ -1741,7 +1747,7 @@ int do_init(Slice<ZString> argv)
}
if (!loaded_config_yet)
- runflag &= load_config_file("conf/tmwa-map.conf", map_confs);
+ runflag &= load_config_file("conf/tmwa-map.conf"_s, map_confs);
battle_config_check();
runflag &= map_readallmap();
@@ -1758,15 +1764,15 @@ int do_init(Slice<ZString> argv)
npc_event_do_oninit(); // npcのOnInitイベント実行
if (battle_config.pk_mode == 1)
- PRINTF("The server is running in " SGR_BOLD SGR_RED "PK Mode" SGR_RESET "\n");
+ PRINTF("The server is running in " SGR_BOLD SGR_RED "PK Mode" SGR_RESET "\n"_fmt);
- PRINTF("The map-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n",
+ PRINTF("The map-server is " SGR_BOLD SGR_GREEN "ready" SGR_RESET " (Server is listening on the port %d).\n\n"_fmt,
clif_getport());
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);
@@ -1778,9 +1784,10 @@ int map_scriptcont(dumb_ptr<map_session_data> sd, int id)
case BL::NPC:
return npc_scriptcont(sd, id);
case BL::SPELL:
- spell_execute_script(bl->is_spell());
+ magic::spell_execute_script(bl->is_spell());
break;
}
return 0;
}
+} // namespace tmwa
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 0cec5e8..55f4823 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAP_HPP
-#define TMWA_MAP_MAP_HPP
+#pragma once
// map.hpp - Core of the map server.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,48 +20,53 @@
// 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"
+#include "map.t.hpp"
-# include <netinet/in.h>
+#include <chrono>
+#include <functional>
+#include <list>
-# include <functional>
-# include <list>
+#include "../ints/udl.hpp"
-# include "../strings/fwd.hpp"
-# include "../strings/rstring.hpp"
-# include "../strings/astring.hpp"
-# include "../strings/vstring.hpp"
+#include "../strings/fwd.hpp"
+#include "../strings/rstring.hpp"
+#include "../strings/astring.hpp"
+#include "../strings/vstring.hpp"
-# include "../generic/db.hpp"
-# include "../generic/matrix.hpp"
+#include "../generic/db.hpp"
+#include "../generic/dumb_ptr.hpp"
+#include "../generic/matrix.hpp"
-# include "../io/cxxstdio.hpp"
+#include "../net/socket.hpp"
+#include "../net/timer.t.hpp"
-# include "../mmo/socket.hpp"
-# include "../mmo/timer.t.hpp"
+#include "../mmo/utils.hpp"
-# include "battle.t.hpp"
-# include "magic-interpreter.t.hpp"
-# include "mapflag.hpp"
-# include "mob.t.hpp"
-# include "script.hpp" // change to script.t.hpp
-# include "skill.t.hpp"
+#include "battle.t.hpp"
+#include "clif.t.hpp"
+#include "mapflag.hpp"
+#include "mob.t.hpp"
+#include "script.hpp" // change to script.t.hpp
+#include "skill.t.hpp"
+
+namespace tmwa
+{
constexpr int MAX_NPC_PER_MAP = 512;
constexpr int BLOCK_SIZE = 8;
-# define AREA_SIZE battle_config.area_size
-constexpr std::chrono::seconds LIFETIME_FLOORITEM = std::chrono::minutes(1);
+#define AREA_SIZE battle_config.area_size
+constexpr std::chrono::seconds LIFETIME_FLOORITEM = 1_min;
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 interval_t NATURAL_HEAL_INTERVAL = 500_ms;
+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;
-constexpr interval_t DEFAULT_AUTOSAVE_INTERVAL = std::chrono::minutes(1);
+constexpr interval_t DEFAULT_AUTOSAVE_INTERVAL = 1_min;
// formerly VString<49>, as name::label
struct NpcEvent
@@ -89,24 +93,14 @@ struct NpcEvent
return l.npc < r.npc || (l.npc == r.npc && l.label < r.label);
}
- friend VString<49> convert_for_printf(NpcEvent ev)
- {
- return STRNPRINTF(50, "%s::%s", ev.npc, ev.label);
- }
+ friend VString<49> convert_for_printf(NpcEvent ev);
};
bool extract(XString str, NpcEvent *ev);
-struct map_session_data;
-struct npc_data;
-struct mob_data;
-struct flooritem_data;
-struct invocation;
-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;
@@ -123,13 +117,13 @@ private:
dumb_ptr<npc_data> as_npc();
dumb_ptr<mob_data> as_mob();
dumb_ptr<flooritem_data> as_item();
- dumb_ptr<invocation> as_spell();
+ dumb_ptr<magic::invocation> as_spell();
public:
dumb_ptr<map_session_data> is_player();
dumb_ptr<npc_data> is_npc();
dumb_ptr<mob_data> is_mob();
dumb_ptr<flooritem_data> is_item();
- dumb_ptr<invocation> is_spell();
+ dumb_ptr<magic::invocation> is_spell();
};
struct walkpath_data
@@ -141,14 +135,9 @@ 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;
-
-struct npc_data;
-struct item_data;
-
struct quick_regeneration
{ // [Fate]
int amount; // Amount of HP/SP left to regenerate
@@ -190,13 +179,14 @@ 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;
CharData status;
- Array<struct item_data *, MAX_INVENTORY> inventory_data;
- earray<short, EQUIP, EQUIP::COUNT> equip_index_maybe;
+ GenericArray<struct item_data *, InventoryIndexing<IOff0, MAX_INVENTORY>> inventory_data;
+ earray<IOff0, EQUIP, EQUIP::COUNT> equip_index_maybe;
int weight, max_weight;
MapName mapname_;
Session *sess; // use this, you idiots!
@@ -206,10 +196,9 @@ struct map_session_data : block_list, SessionData
Opt2 opt2;
Opt3 opt3;
DIR dir, head_dir;
- 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,20 +215,20 @@ 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
+ dumb_ptr<magic::invocation> active_spells; // [Fate] Singly-linked list of active spells linked to this PC
+ 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;
- short attack_spell_look_override; // Weapon `look' (attack animation) override
+ ItemNameId attack_spell_look_override; // Weapon `look' (attack animation) override
short attack_spell_charges; // [Fate] Remaining number of charges for the attack spell
interval_t attack_spell_delay; // [Fate] ms delay after spell attack
short attack_spell_range; // [Fate] spell range
@@ -296,16 +285,18 @@ struct map_session_data : block_list, SessionData
earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
short sc_count;
- int trade_partner;
- Array<int, TRADE_MAX> deal_item_index;
+ AccountId trade_partner;
+ Array<IOff2, 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,18 +340,15 @@ struct npc_label_list
};
struct npc_item_list
{
- int nameid, value;
+ ItemNameId nameid;
+ int value;
};
-class npc_data_script;
-class npc_data_shop;
-class npc_data_warp;
-class npc_data_message;
struct npc_data : block_list
{
NpcSubtype npc_subtype;
short n;
- short npc_class;
+ Species npc_class;
DIR dir;
interval_t speed;
NpcName name;
@@ -446,7 +434,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 +460,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,12 +470,12 @@ struct mob_data : block_list
short move_fail_count;
struct DmgLogEntry
{
- int id;
+ BlockId id;
int dmg;
};
// logically a map ...
std::vector<DmgLogEntry> dmglogv;
- std::vector<struct item> lootitemv;
+ std::vector<Item> lootitemv;
earray<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
short sc_count;
@@ -499,14 +487,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
@@ -522,7 +511,7 @@ struct BlockLists
struct map_abstract
{
MapName name_;
- // gat is NULL for map_remote and non-NULL or map_local
+ // gat is nullptr for map_remote and non-nullptr or map_local
std::unique_ptr<MapCell[]> gat;
virtual ~map_abstract() {}
@@ -537,8 +526,8 @@ struct map_local : map_abstract
int npc_num;
int users;
MapFlags flag;
- struct point save;
- struct point resave;
+ Point save;
+ Point resave;
Array<dumb_ptr<npc_data>, MAX_NPC_PER_MAP> npc;
};
@@ -560,9 +549,9 @@ 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;
+ Item item_data;
};
extern interval_t autosave_time;
@@ -607,9 +596,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);
//
@@ -618,64 +607,64 @@ void map_quit(dumb_ptr<map_session_data>);
int map_addnpc(map_local *, dumb_ptr<npc_data>);
void map_log(XString line);
-# define MAP_LOG(format, ...) \
+#define MAP_LOG(format, ...) \
map_log(STRPRINTF(format, ## __VA_ARGS__))
-# define MAP_LOG_PC(sd, fmt, ...) \
+#define MAP_LOG_PC(sd, fmt, ...) \
MAP_LOG("PC%d %s:%d,%d " fmt, \
- sd->status_key.char_id, (sd->bl_m ? sd->bl_m->name_ : stringish<MapName>("undefined.gat")), sd->bl_x, sd->bl_y, ## __VA_ARGS__)
+ 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(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(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<magic::invocation> map_id_is_spell(BlockId id)
{
dumb_ptr<block_list> bl = map_id2bl(id);
return bl ? bl->is_spell() : nullptr;
@@ -688,9 +677,9 @@ 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);
+int compare_item(Item *a, Item *b);
dumb_ptr<map_session_data> map_get_first_session(void);
dumb_ptr<map_session_data> map_get_last_session(void);
@@ -733,5 +722,4 @@ inline dumb_ptr<npc_data_script> npc_data::is_script() { return npc_subtype == N
inline dumb_ptr<npc_data_shop> npc_data::is_shop() { return npc_subtype == NpcSubtype::SHOP ? as_shop() : nullptr ; }
inline dumb_ptr<npc_data_warp> npc_data::is_warp() { return npc_subtype == NpcSubtype::WARP ? as_warp() : nullptr ; }
inline dumb_ptr<npc_data_message> npc_data::is_message() { return npc_subtype == NpcSubtype::MESSAGE ? as_message() : nullptr ; }
-
-#endif // TMWA_MAP_MAP_HPP
+} // namespace tmwa
diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp
index b73cbdd..b475f9b 100644
--- a/src/map/map.t.hpp
+++ b/src/map/map.t.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAP_T_HPP
-#define TMWA_MAP_MAP_T_HPP
+#pragma once
// map.t.hpp - Core of the map server.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,73 +20,20 @@
// 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 <cstdint>
-# include "../mmo/mmo.hpp"
+#include "../strings/vstring.hpp"
-namespace e
-{
-// [Fate] status.option properties. These are persistent status changes.
-// IDs that are not listed are not used in the code (to the best of my knowledge)
-enum class Option : uint16_t
-{
- ZERO = 0x0000,
+#include "../generic/enum.hpp"
- // [Fate] This is the GM `@hide' flag
- HIDE = 0x0040,
- // [Fate] Complete invisibility to other clients
- INVISIBILITY = 0x1000,
+#include "../mmo/ids.hpp"
+#include "../mmo/mmo.hpp"
- // ?
- REAL_ANY_HIDE = HIDE,
-};
-enum class Opt1 : uint16_t
-{
- ZERO = 0,
- _stone1 = 1,
- _freeze = 2,
- _stan = 3,
- _sleep = 4,
- _stone6 = 6,
-};
-enum class Opt2 : uint16_t
-{
- ZERO = 0x0000,
- _poison = 0x0001,
- _curse = 0x0002,
- _silence = 0x0004,
- BLIND = 0x0010,
- _speedpotion0 = 0x0020,
- _signumcrucis = 0x0040,
- _atkpot = 0x0080,
- _heal = 0x0100,
- _slowpoison = 0x0200,
-};
-enum class Opt3 : uint16_t
-{
- ZERO = 0x0000,
- _concentration = 0x0001,
- _overthrust = 0x0002,
- _energycoat = 0x0004,
- _explosionspirits = 0x0008,
- _steelbody = 0x0010,
- _berserk = 0x0080,
-
- _marionette = 0x0400,
- _assumptio = 0x0800,
-};
-
-ENUM_BITWISE_OPERATORS(Option)
-ENUM_BITWISE_OPERATORS(Opt2)
-ENUM_BITWISE_OPERATORS(Opt3)
-}
-using e::Option;
-using e::Opt1;
-using e::Opt2;
-using e::Opt3;
+namespace tmwa
+{
enum class BL : uint8_t
{
NUL,
@@ -103,6 +49,8 @@ enum class NpcSubtype : uint8_t
SHOP,
SCRIPT,
MESSAGE,
+
+ COUNT,
};
enum class mob_stat
@@ -146,325 +94,6 @@ enum class ATK
DEF,
};
-enum class SP : uint16_t
-{
- // sent to client
- SPEED = 0,
-
- // when used as "no stat"
- ZERO = 0,
-
- // sent to client
- BASEEXP = 1,
- // sent to client
- JOBEXP = 2,
-# if 0
- KARMA = 3,
-# endif
-
- // sent to client
- HP = 5,
- // sent to client
- MAXHP = 6,
- // sent to client
- SP = 7,
- // sent to client
- MAXSP = 8,
- // sent to client
- STATUSPOINT = 9,
-
- // sent to client
- BASELEVEL = 11,
- // sent to client
- SKILLPOINT = 12,
- // sent to client
- STR = 13,
- // sent to client
- AGI = 14,
- // sent to client
- VIT = 15,
- // sent to client
- INT = 16,
- // sent to client
- DEX = 17,
- // sent to client
- LUK = 18,
- CLASS = 19,
- // sent to client
- ZENY = 20,
- SEX = 21,
- // sent to client
- NEXTBASEEXP = 22,
- // sent to client
- NEXTJOBEXP = 23,
- // sent to client
- WEIGHT = 24,
- // sent to client
- MAXWEIGHT = 25,
-
- // sent to client
- USTR = 32,
- // sent to client
- UAGI = 33,
- // sent to client
- UVIT = 34,
- // sent to client
- UINT = 35,
- // sent to client
- UDEX = 36,
- // sent to client
- ULUK = 37,
-
- // sent to client
- ATK1 = 41,
- // sent to client
- ATK2 = 42,
- // sent to client
- MATK1 = 43,
- // sent to client
- MATK2 = 44,
- // sent to client
- DEF1 = 45,
- // sent to client
- DEF2 = 46,
- // sent to client
- MDEF1 = 47,
- // sent to client
- MDEF2 = 48,
- // sent to client
- HIT = 49,
- // sent to client
- FLEE1 = 50,
- // sent to client
- FLEE2 = 51,
- // sent to client
- CRITICAL = 52,
- // sent to client
- ASPD = 53,
-
- // sent to client
- JOBLEVEL = 55,
-
-# if 0
- PARTNER = 57,
- CART = 58,
- FAME = 59,
- UNBREAKABLE = 60,
-# endif
-
- DEAF = 70,
-
- // sent to client
- GM = 500,
-
- // sent to client
- ATTACKRANGE = 1000,
-# if 0
- ATKELE = 1001,
-# endif
-# if 0
- DEFELE = 1002,
-# endif
-# if 0
- CASTRATE = 1003,
-# endif
- MAXHPRATE = 1004,
-# if 0
- MAXSPRATE = 1005,
-# endif
-# if 0
- SPRATE = 1006,
-# endif
-
-# if 0
- ADDEFF = 1012,
-# endif
-# if 0
- RESEFF = 1013,
-# endif
- BASE_ATK = 1014,
- ASPD_RATE = 1015,
- HP_RECOV_RATE = 1016,
-# if 0
- SP_RECOV_RATE = 1017,
-# endif
-# if 0
- SPEED_RATE = 1018,
-# endif
- CRITICAL_DEF = 1019,
-# if 0
- NEAR_ATK_DEF = 1020,
-# endif
-# if 0
- LONG_ATK_DEF = 1021,
-# endif
-# if 0
- DOUBLE_RATE = 1022,
-# endif
- DOUBLE_ADD_RATE = 1023,
-# if 0
- MATK = 1024,
-# endif
-# if 0
- MATK_RATE = 1025,
-# endif
-# if 0
- IGNORE_DEF_ELE = 1026,
-# endif
-# if 0
- IGNORE_DEF_RACE = 1027,
-# endif
-# if 0
- ATK_RATE = 1028,
-# endif
- SPEED_ADDRATE = 1029,
-# if 0
- ASPD_ADDRATE = 1030,
-# endif
-# if 0
- MAGIC_ATK_DEF = 1031,
-# endif
-# if 0
- MISC_ATK_DEF = 1032,
-# endif
-# if 0
- IGNORE_MDEF_ELE = 1033,
-# endif
-# if 0
- IGNORE_MDEF_RACE = 1034,
-# endif
-
-# if 0
- PERFECT_HIT_RATE = 1038,
-# endif
-# if 0
- PERFECT_HIT_ADD_RATE = 1039,
-# endif
-# if 0
- CRITICAL_RATE = 1040,
-# endif
-# if 0
- GET_ZENY_NUM = 1041,
-# endif
-# if 0
- ADD_GET_ZENY_NUM = 1042,
-# endif
-
-# if 0
- ADD_MONSTER_DROP_ITEM = 1047,
-# endif
-# if 0
- DEF_RATIO_ATK_ELE = 1048,
-# endif
-# if 0
- DEF_RATIO_ATK_RACE = 1049,
-# endif
-# if 0
- ADD_SPEED = 1050,
-# endif
-# if 0
- HIT_RATE = 1051,
-# endif
-# if 0
- FLEE_RATE = 1052,
-# endif
-# if 0
- FLEE2_RATE = 1053,
-# endif
- DEF_RATE = 1054,
- DEF2_RATE = 1055,
-# if 0
- MDEF_RATE = 1056,
-# endif
-# if 0
- MDEF2_RATE = 1057,
-# endif
-# if 0
- SPLASH_RANGE = 1058,
-# endif
-# if 0
- SPLASH_ADD_RANGE = 1059,
-# endif
-
- HP_DRAIN_RATE = 1061,
-# if 0
- SP_DRAIN_RATE = 1062,
-# endif
-# if 0
- SHORT_WEAPON_DAMAGE_RETURN = 1063,
-# endif
-# if 0
- LONG_WEAPON_DAMAGE_RETURN = 1064,
-# endif
-
-# if 0
- ADDEFF2 = 1067,
-# endif
- BREAK_WEAPON_RATE = 1068,
- BREAK_ARMOR_RATE = 1069,
- ADD_STEAL_RATE = 1070,
- MAGIC_DAMAGE_RETURN = 1071,
-# if 0
- RANDOM_ATTACK_INCREASE = 1072,
-# endif
-};
-
-constexpr
-SP attr_to_sp(ATTR attr)
-{
- return SP(uint16_t(attr) + uint16_t(SP::STR));
-}
-
-constexpr
-ATTR sp_to_attr(SP sp)
-{
- return ATTR(uint16_t(sp) - uint16_t(SP::STR));
-}
-
-constexpr
-SP attr_to_usp(ATTR attr)
-{
- return SP(uint16_t(attr) + uint16_t(SP::USTR));
-}
-
-constexpr
-ATTR usp_to_attr(SP sp)
-{
- return ATTR(uint16_t(sp) - uint16_t(SP::USTR));
-}
-
-constexpr
-SP sp_to_usp(SP sp)
-{
- return attr_to_usp(sp_to_attr(sp));
-}
-
-constexpr
-SP usp_to_sp(SP sp)
-{
- return attr_to_sp(usp_to_attr(sp));
-}
-
-
-enum class LOOK : uint8_t
-{
- BASE = 0,
- HAIR = 1,
- WEAPON = 2,
- HEAD_BOTTOM = 3,
- HEAD_TOP = 4,
- HEAD_MID = 5,
- HAIR_COLOR = 6,
- CLOTHES_COLOR = 7,
- SHIELD = 8,
- SHOES = 9,
- GLOVES = 10,
- CAPE = 11,
- MISC1 = 12,
- MISC2 = 13,
-
- COUNT,
-};
enum class EQUIP
{
@@ -514,22 +143,6 @@ EQUIP EQUIPs_noarrow[] =
EQUIP::WEAPON,
};
-enum class ItemType : uint8_t
-{
- USE = 0, // in eA, healing only
- _1 = 1, // unused
- _2 = 2, // in eA, other usable items
- JUNK = 3, // "useless" items (e.g. quests)
- WEAPON = 4, // all weapons
- ARMOR = 5, // all other equipment
- _6 = 6, // in eA, card
- _7 = 7, // in eA, pet egg
- _8 = 8, // in eA, pet equipment
- _9 = 9, // unused
- ARROW = 10, // ammo
- _11 = 11, // in eA, delayed use (special script)
-};
-
namespace e
{
enum class MobMode : uint16_t
@@ -583,4 +196,8 @@ struct NpcName : VString<23> {};
struct ScriptLabel : VString<23> {};
struct ItemName : VString<23> {};
-#endif // TMWA_MAP_MAP_T_HPP
+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)); }
+} // namespace tmwa
diff --git a/src/map/mapflag.cpp b/src/map/mapflag.cpp
index 51af30a..be2ae67 100644
--- a/src/map/mapflag.cpp
+++ b/src/map/mapflag.cpp
@@ -20,6 +20,9 @@
#include "../poison.hpp"
+
+namespace tmwa
+{
// because bitfields, that's why
bool MapFlags::get(MapFlag mf) const
@@ -35,46 +38,45 @@ void MapFlags::set(MapFlag mf, bool val)
flags &=~ static_cast<unsigned>(mf);
}
-template<>
-bool extract<MapFlag, void, void>(XString str, MapFlag *mf)
+bool extract(XString str, MapFlag *mf)
{
const struct
{
- ZString str;
+ LString str;
MapFlag id;
} flags[] =
{
- //{ZString("alias"), MapFlag::ALIAS},
- //{ZString("nomemo"), MapFlag::NOMEMO},
- {ZString("noteleport"), MapFlag::NOTELEPORT},
- {ZString("noreturn"), MapFlag::NORETURN},
- {ZString("monster_noteleport"), MapFlag::MONSTER_NOTELEPORT},
- {ZString("nosave"), MapFlag::NOSAVE},
- //{ZString("nobranch"), MapFlag::NOBRANCH},
- {ZString("nopenalty"), MapFlag::NOPENALTY},
- {ZString("pvp"), MapFlag::PVP},
- {ZString("pvp_noparty"), MapFlag::PVP_NOPARTY},
- //{ZString("pvp_noguild"), MapFlag::PVP_NOGUILD},
- //{ZString("pvp_nightmaredrop"), MapFlag::PVP_NIGHTMAREDROP},
- {ZString("pvp_nocalcrank"), MapFlag::PVP_NOCALCRANK},
- //{ZString("gvg"), MapFlag::GVG},
- //{ZString("gvg_noparty"), MapFlag::GVG_NOPARTY},
- //{ZString("nozenypenalty"), MapFlag::NOZENYPENALTY},
- //{ZString("notrade"), MapFlag::NOTRADE},
- //{ZString("noskill"), MapFlag::NOSKILL},
- {ZString("nowarp"), MapFlag::NOWARP},
- {ZString("nowarpto"), MapFlag::NOWARPTO},
- {ZString("nopvp"), MapFlag::NOPVP},
- //{ZString("noicewall"), MapFlag::NOICEWALL},
- {ZString("snow"), MapFlag::SNOW},
- {ZString("fog"), MapFlag::FOG},
- {ZString("sakura"), MapFlag::SAKURA},
- {ZString("leaves"), MapFlag::LEAVES},
- {ZString("rain"), MapFlag::RAIN},
- {ZString("no_player_drops"), MapFlag::NO_PLAYER_DROPS},
- {ZString("town"), MapFlag::TOWN},
- {ZString("outside"), MapFlag::OUTSIDE},
- {ZString("resave"), MapFlag::RESAVE},
+ //{"alias"_s, MapFlag::ALIAS},
+ //{"nomemo"_s, MapFlag::NOMEMO},
+ {"noteleport"_s, MapFlag::NOTELEPORT},
+ {"noreturn"_s, MapFlag::NORETURN},
+ {"monster_noteleport"_s, MapFlag::MONSTER_NOTELEPORT},
+ {"nosave"_s, MapFlag::NOSAVE},
+ //{"nobranch"_s, MapFlag::NOBRANCH},
+ {"nopenalty"_s, MapFlag::NOPENALTY},
+ {"pvp"_s, MapFlag::PVP},
+ {"pvp_noparty"_s, MapFlag::PVP_NOPARTY},
+ //{"pvp_noguild"_s, MapFlag::PVP_NOGUILD},
+ //{"pvp_nightmaredrop"_s, MapFlag::PVP_NIGHTMAREDROP},
+ {"pvp_nocalcrank"_s, MapFlag::PVP_NOCALCRANK},
+ //{"gvg"_s, MapFlag::GVG},
+ //{"gvg_noparty"_s, MapFlag::GVG_NOPARTY},
+ //{"nozenypenalty"_s, MapFlag::NOZENYPENALTY},
+ //{"notrade"_s, MapFlag::NOTRADE},
+ //{"noskill"_s, MapFlag::NOSKILL},
+ {"nowarp"_s, MapFlag::NOWARP},
+ {"nowarpto"_s, MapFlag::NOWARPTO},
+ {"nopvp"_s, MapFlag::NOPVP},
+ //{"noicewall"_s, MapFlag::NOICEWALL},
+ {"snow"_s, MapFlag::SNOW},
+ {"fog"_s, MapFlag::FOG},
+ {"sakura"_s, MapFlag::SAKURA},
+ {"leaves"_s, MapFlag::LEAVES},
+ {"rain"_s, MapFlag::RAIN},
+ {"no_player_drops"_s, MapFlag::NO_PLAYER_DROPS},
+ {"town"_s, MapFlag::TOWN},
+ {"outside"_s, MapFlag::OUTSIDE},
+ {"resave"_s, MapFlag::RESAVE},
};
for (auto& pair : flags)
if (str == pair.str)
@@ -89,3 +91,4 @@ MapFlag map_flag_from_int(int shift)
{
return static_cast<MapFlag>(1 << shift);
}
+} // namespace tmwa
diff --git a/src/map/mapflag.hpp b/src/map/mapflag.hpp
index e3a55f5..6d046fa 100644
--- a/src/map/mapflag.hpp
+++ b/src/map/mapflag.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MAPFLAG_HPP
-#define TMWA_MAP_MAPFLAG_HPP
+#pragma once
// mapflag.hpp - booleans that apply to an entire map
//
// Copyright © 2014 Ben Longbons <b.r.longbons@gmail.com>
@@ -19,12 +18,15 @@
// 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/extract.hpp" // TODO remove this (requires specializing the *other* half)
+#include <cstdint>
-# include "../strings/xstring.hpp"
+#include "../mmo/extract.hpp" // TODO remove this (requires specializing the *other* half)
+
+namespace tmwa
+{
// originally from script.cpp
// These are part of the script API, so they can't change ever,
// even though they are silly.
@@ -75,9 +77,7 @@ public:
void set(MapFlag, bool);
};
-template<>
-bool extract<MapFlag, void, void>(XString str, MapFlag *mf);
+bool extract(XString str, MapFlag *mf);
MapFlag map_flag_from_int(int shift);
-
-#endif // TMWA_MAP_MAPFLAG_HPP
+} // namespace tmwa
diff --git a/src/map/mapflag.py b/src/map/mapflag.py
index 3bc9f1a..fec8c05 100644
--- a/src/map/mapflag.py
+++ b/src/map/mapflag.py
@@ -2,7 +2,7 @@ class MapFlags(object):
''' print a set of map flags
'''
__slots__ = ('_value')
- name = 'MapFlags'
+ name = 'tmwa::MapFlags'
enabled = True
def __init__(self, value):
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index a96f829..dd061d0 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -23,8 +23,6 @@
#include <cassert>
#include <cmath>
-#include <cstdlib>
-#include <cstring>
#include <algorithm>
@@ -32,17 +30,21 @@
#include "../compat/nullpo.hpp"
#include "../strings/astring.hpp"
+#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/read.hpp"
+#include "../net/socket.hpp"
+#include "../net/timer.hpp"
+
#include "../mmo/config_parse.hpp"
#include "../mmo/extract.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../mmo/extract_enums.hpp"
#include "battle.hpp"
#include "clif.hpp"
@@ -56,14 +58,22 @@
#include "../poison.hpp"
-constexpr interval_t MIN_MOBTHINKTIME = std::chrono::milliseconds(100);
+
+namespace tmwa
+{
+constexpr interval_t MIN_MOBTHINKTIME = 100_ms;
// Move probability in the negligent mode MOB (rate of 1000 minute)
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 +82,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 +93,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,27 +126,27 @@ 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;
- md->bl_prev = NULL;
- md->bl_next = NULL;
+ md->bl_prev = nullptr;
+ md->bl_next = nullptr;
md->n = 0;
md->mob_class = mob_class;
md->bl_id = npc_get_new_npc_id();
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);
}
@@ -265,12 +274,16 @@ void mob_mutate(dumb_ptr<mob_data> md, mob_stat stat, int intensity)
int real_intensity2 = (((new_stat - old_stat) << 8) / mut_base);
if (real_intensity < 0)
+ {
if (real_intensity2 > real_intensity)
real_intensity = real_intensity2;
+ }
if (real_intensity > 0)
+ {
if (real_intensity2 < real_intensity)
real_intensity = real_intensity2;
+ }
}
real_intensity *= sign;
@@ -322,7 +335,7 @@ int mob_gen_exp(mob_db_ *mob)
* static_cast<double>(battle_config.base_exp_rate) / 100.);
if (xp < 1)
xp = 1;
- PRINTF("Exp for mob '%s' generated: %d\n", mob->name, xp);
+ PRINTF("Exp for mob '%s' generated: %d\n"_fmt, mob->name, xp);
return xp;
}
@@ -330,24 +343,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 +404,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;
+ dumb_ptr<mob_data> md = nullptr;
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)
{
@@ -417,7 +430,7 @@ int mob_once_spawn(dumb_ptr<map_session_data> sd,
}
else if (x <= 0 || y <= 0)
{
- PRINTF("mob_once_spawn: ??\n");
+ PRINTF("mob_once_spawn: ??\n"_fmt);
}
for (count = 0; count < amount; count++)
@@ -429,9 +442,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 +456,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 +481,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 +502,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 +512,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;
}
/*==========================================
@@ -553,7 +564,7 @@ int mob_get_equip(int mob_class) // mob equip [Valaris]
static
int mob_can_move(dumb_ptr<mob_data> md)
{
- nullpo_ret(md);
+ nullpo_retz(md);
if (md->canmove_tick > gettick()
|| (bool(md->opt1) && md->opt1 != Opt1::_stone6))
@@ -591,7 +602,7 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data)
int moveblock;
int x, y, dx, dy;
- nullpo_ret(md);
+ nullpo_retz(md);
md->state.state = MS::IDLE;
if (md->walkpath.path_pos >= md->walkpath.path_len
@@ -667,7 +678,7 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data)
{
i = i / 2;
if (md->walkpath.path_half == 0)
- i = std::max(i, std::chrono::milliseconds(1));
+ i = std::max(i, 1_ms);
md->timer = Timer(tick + i,
std::bind(mob_timer, ph::_1, ph::_2,
md->bl_id, md->walkpath.path_pos));
@@ -686,14 +697,14 @@ int mob_walk(dumb_ptr<mob_data> md, tick_t tick, unsigned char data)
static
int mob_check_attack(dumb_ptr<mob_data> md)
{
- dumb_ptr<block_list> tbl = NULL;
- dumb_ptr<map_session_data> tsd = NULL;
- dumb_ptr<mob_data> tmd = NULL;
+ dumb_ptr<block_list> tbl = nullptr;
+ dumb_ptr<map_session_data> tsd = nullptr;
+ dumb_ptr<mob_data> tmd = nullptr;
MobMode mode;
int range;
- nullpo_ret(md);
+ nullpo_retz(md);
md->min_chase = 13;
md->state.state = MS::IDLE;
@@ -705,9 +716,9 @@ int mob_check_attack(dumb_ptr<mob_data> md)
if (bool(md->opt1))
return 0;
- if ((tbl = map_id2bl(md->target_id)) == NULL)
+ if ((tbl = map_id2bl(md->target_id)) == nullptr)
{
- md->target_id = 0;
+ md->target_id = BlockId();
md->state.attackable = false;
return 0;
}
@@ -722,34 +733,34 @@ int mob_check_attack(dumb_ptr<mob_data> md)
if (tsd)
{
if (pc_isdead(tsd) || tsd->invincible_timer
- || pc_isinvisible(tsd) || md->bl_m != tbl->bl_m || tbl->bl_prev == NULL
+ || pc_isinvisible(tsd) || md->bl_m != tbl->bl_m || tbl->bl_prev == nullptr
|| 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 (tmd)
{
- if (md->bl_m != tbl->bl_m || tbl->bl_prev == NULL
+ if (md->bl_m != tbl->bl_m || tbl->bl_prev == nullptr
|| 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 +770,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)
@@ -788,11 +799,11 @@ void mob_ancillary_attack(dumb_ptr<block_list> bl,
static
int mob_attack(dumb_ptr<mob_data> md, tick_t tick)
{
- dumb_ptr<block_list> tbl = NULL;
+ dumb_ptr<block_list> tbl = nullptr;
- nullpo_ret(md);
+ nullpo_retz(md);
- if ((tbl = map_id2bl(md->target_id)) == NULL)
+ if ((tbl = map_id2bl(md->target_id)) == nullptr)
return 0;
if (!mob_check_attack(md))
@@ -834,7 +845,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);
@@ -849,7 +860,7 @@ void mob_stopattacked(dumb_ptr<map_session_data> sd, int id)
static
int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type)
{
- nullpo_ret(md);
+ nullpo_retz(md);
md->timer.cancel();
md->state.state = state;
@@ -874,7 +885,7 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type)
{
tick_t tick = gettick();
interval_t i = md->attackabletime - tick;
- if (i > interval_t::zero() && i < std::chrono::seconds(2))
+ if (i > interval_t::zero() && i < 2_s)
md->timer = Timer(md->attackabletime,
std::bind(mob_timer, ph::_1, ph::_2,
md->bl_id, 0));
@@ -887,7 +898,7 @@ int mob_changestate(dumb_ptr<mob_data> md, MS state, bool type)
}
else
{
- md->attackabletime = tick + std::chrono::milliseconds(1);
+ md->attackabletime = tick + 1_ms;
md->timer = Timer(md->attackabletime,
std::bind(mob_timer, ph::_1, ph::_2,
md->bl_id, 0));
@@ -903,7 +914,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,12 +930,12 @@ 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;
bl = map_id2bl(id);
- if (bl == NULL)
+ if (bl == nullptr)
{ //攻撃してきた敵がもういないのは正常のようだ
return;
}
@@ -933,7 +945,7 @@ void mob_timer(TimerData *, tick_t tick, int id, unsigned char data)
md = bl->is_mob();
- if (md->bl_prev == NULL || md->state.state == MS::DEAD)
+ if (md->bl_prev == nullptr || md->state.state == MS::DEAD)
return;
MapBlockLock lock;
@@ -948,7 +960,7 @@ void mob_timer(TimerData *, tick_t tick, int id, unsigned char data)
break;
default:
if (battle_config.error_log == 1)
- PRINTF("mob_timer : %d ?\n",
+ PRINTF("mob_timer : %d ?\n"_fmt,
md->state.state);
break;
}
@@ -963,7 +975,7 @@ int mob_walktoxy_sub(dumb_ptr<mob_data> md)
{
struct walkpath_data wpd;
- nullpo_ret(md);
+ nullpo_retz(md);
if (path_search(&wpd, md->bl_m, md->bl_x, md->bl_y, md->to_x, md->to_y,
md->state.walk_easy))
@@ -986,7 +998,7 @@ int mob_walktoxy(dumb_ptr<mob_data> md, int x, int y, int easy)
{
struct walkpath_data wpd;
- nullpo_ret(md);
+ nullpo_retz(md);
if (md->state.state == MS::WALK
&& path_search(&wpd, md->bl_m, md->bl_x, md->bl_y, x, y, easy))
@@ -1012,7 +1024,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,12 +1034,12 @@ 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;
- if ((bl = map_id2bl(id)) == NULL)
+ if ((bl = map_id2bl(id)) == nullptr)
return -1;
if (!bl || bl->bl_type == BL::NUL || bl->bl_type != BL::MOB)
@@ -1052,7 +1064,7 @@ int mob_setdelayspawn(int id)
tick_t spawntime1 = md->last_spawntime + md->spawn.delay1;
tick_t spawntime2 = md->last_deadtime + md->spawn.delay2;
- tick_t spawntime3 = gettick() + std::chrono::seconds(5);
+ tick_t spawntime3 = gettick() + 5_s;
tick_t spawntime = std::max({spawntime1, spawntime2, spawntime3});
Timer(spawntime,
@@ -1066,7 +1078,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();
@@ -1086,7 +1098,7 @@ int mob_spawn(int id)
return -1;
md->last_spawntime = tick;
- if (md->bl_prev != NULL)
+ if (md->bl_prev != nullptr)
{
map_delblock(md);
}
@@ -1115,9 +1127,7 @@ int mob_spawn(int id)
if (i >= 50)
{
- // if(battle_config.error_log==1)
- // PRINTF("MOB spawn error %d @ %s\n",id,map[md->bl_m].name);
- Timer(tick + std::chrono::seconds(5),
+ Timer(tick + 5_s,
std::bind(mob_delayspawn, ph::_1, ph::_2,
id)
).detach();
@@ -1132,31 +1142,31 @@ 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;
md->state.skillstate = MobSkillState::MSS_IDLE;
assert (!md->timer);
md->last_thinktime = tick;
- md->next_walktime = tick + std::chrono::seconds(5) + std::chrono::milliseconds(random_::to(50));
+ md->next_walktime = tick + 5_s + std::chrono::milliseconds(random_::to(50));
md->attackabletime = tick;
md->canmove_tick = tick;
// 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[i] = tick - std::chrono::hours(10);
+ 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 - 10_h;
md->skillid = SkillID();
md->skilllv = 0;
@@ -1206,9 +1216,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;
}
@@ -1218,7 +1228,7 @@ int mob_stopattack(dumb_ptr<mob_data> md)
*/
int mob_stop_walking(dumb_ptr<mob_data> md, int type)
{
- nullpo_ret(md);
+ nullpo_retz(md);
if (md->state.state == MS::WALK || md->state.state == MS::IDLE)
{
@@ -1271,8 +1281,8 @@ int mob_can_reach(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int range)
struct walkpath_data wpd;
int i;
- nullpo_ret(md);
- nullpo_ret(bl);
+ nullpo_retz(md);
+ nullpo_retz(bl);
dx = abs(bl->bl_x - md->bl_x);
dy = abs(bl->bl_y - md->bl_y);
@@ -1328,16 +1338,16 @@ int mob_target(dumb_ptr<mob_data> md, dumb_ptr<block_list> bl, int dist)
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
MobMode mode;
- nullpo_ret(md);
- nullpo_ret(bl);
+ nullpo_retz(md);
+ nullpo_retz(bl);
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
{
@@ -1345,25 +1355,25 @@ 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;
// Coercion is exerted if it is MVPMOB.
if (bool(mode & MobMode::BOSS)
- || (option != NULL
+ || (option != nullptr
|| race == Race::_insect
|| race == Race::_demon))
{
if (bl->bl_type == BL::PC)
{
sd = bl->is_player();
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->invincible_timer || pc_isinvisible(sd))
return 0;
if (!bool(mode & MobMode::BOSS) && race != Race::_insect && race != Race::_demon
@@ -1391,8 +1401,8 @@ static
void mob_ai_sub_hard_activesearch(dumb_ptr<block_list> bl,
dumb_ptr<mob_data> smd, int *pcc)
{
- dumb_ptr<map_session_data> tsd = NULL;
- dumb_ptr<mob_data> tmd = NULL;
+ dumb_ptr<map_session_data> tsd = nullptr;
+ dumb_ptr<mob_data> tmd = nullptr;
MobMode mode;
int dist;
@@ -1412,14 +1422,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) &&
@@ -1479,7 +1489,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
{
@@ -1518,8 +1528,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
@@ -1543,17 +1553,17 @@ void mob_ai_sub_hard_linksearch(dumb_ptr<block_list> bl, dumb_ptr<mob_data> md,
static
int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
{
- dumb_ptr<mob_data> mmd = NULL;
+ dumb_ptr<mob_data> mmd = nullptr;
dumb_ptr<block_list> bl;
MobMode mode;
int old_dist;
- nullpo_ret(md);
+ nullpo_retz(md);
- if ((bl = map_id2bl(md->master_id)) != NULL)
+ if ((bl = map_id2bl(md->master_id)) != nullptr)
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)
@@ -1636,20 +1646,20 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
while (ret && i < 10);
}
- md->next_walktime = tick + std::chrono::milliseconds(500);
+ md->next_walktime = tick + 500_ms;
md->state.master_check = 1;
}
// 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);
- if (sd != NULL && !pc_isdead(sd) && !sd->invincible_timer
+ if (sd != nullptr && !pc_isdead(sd) && !sd->invincible_timer
&& !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,12 +1685,12 @@ int mob_ai_sub_hard_slavemob(dumb_ptr<mob_data> md, tick_t tick)
static
int mob_unlocktarget(dumb_ptr<mob_data> md, tick_t tick)
{
- nullpo_ret(md);
+ nullpo_retz(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));
+ md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(3000));
return 0;
}
@@ -1693,7 +1703,7 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick)
{
const int retrycount = 20;
- nullpo_ret(md);
+ nullpo_retz(md);
interval_t speed = battle_get_speed(md);
if (md->next_walktime < tick)
@@ -1718,8 +1728,8 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick)
if (md->move_fail_count > 1000)
{
if (battle_config.error_log == 1)
- PRINTF("MOB cant move. random spawn %d, mob_class = %d\n",
- md->bl_id, md->mob_class);
+ PRINTF("MOB cant move. random spawn %d, mob_class = %d\n"_fmt,
+ md->bl_id, md->mob_class);
md->move_fail_count = 0;
mob_spawn(md->bl_id);
}
@@ -1734,7 +1744,7 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick)
else
c += speed;
}
- md->next_walktime = tick + std::chrono::seconds(3) + std::chrono::milliseconds(random_::to(3000)) + c;
+ md->next_walktime = tick + 3_s + std::chrono::milliseconds(random_::to(3000)) + c;
md->state.skillstate = MobSkillState::MSS_WALK;
return 1;
}
@@ -1748,9 +1758,9 @@ int mob_randomwalk(dumb_ptr<mob_data> md, tick_t tick)
static
void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
{
- dumb_ptr<mob_data> md, tmd = NULL;
- dumb_ptr<map_session_data> tsd = NULL;
- dumb_ptr<block_list> tbl = NULL;
+ dumb_ptr<mob_data> md, tmd = nullptr;
+ dumb_ptr<map_session_data> tsd = nullptr;
+ dumb_ptr<block_list> tbl = nullptr;
dumb_ptr<flooritem_data> fitem;
int i, dx, dy, ret, dist;
int attack_type = 0;
@@ -1763,7 +1773,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
return;
md->last_thinktime = tick;
- if (md->skilltimer || md->bl_prev == NULL)
+ if (md->skilltimer || md->bl_prev == nullptr)
{
// Under a skill aria and death
if (tick > md->next_walktime + MIN_MOBTHINKTIME)
@@ -1772,20 +1782,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)
@@ -1802,28 +1812,28 @@ 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}))))
{
dumb_ptr<block_list> abl = map_id2bl(md->attacked_id);
- dumb_ptr<map_session_data> asd = NULL;
+ dumb_ptr<map_session_data> asd = nullptr;
if (abl)
{
if (abl->bl_type == BL::PC)
asd = abl->is_player();
- if (asd == NULL || md->bl_m != abl->bl_m || abl->bl_prev == NULL
+ if (asd == nullptr || md->bl_m != abl->bl_m || abl->bl_prev == nullptr
|| asd->invincible_timer || pc_isinvisible(asd)
|| (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;
@@ -1833,7 +1843,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)
@@ -1874,7 +1884,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)))
{
@@ -1884,7 +1894,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
tmd = tbl->is_mob();
if (tsd || tmd)
{
- if (tbl->bl_m != md->bl_m || tbl->bl_prev == NULL
+ if (tbl->bl_m != md->bl_m || tbl->bl_prev == nullptr
|| (dist =
distance(md->bl_x, md->bl_y, tbl->bl_x,
tbl->bl_y)) >= md->min_chase)
@@ -1894,7 +1904,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))
@@ -1915,7 +1925,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
else
{
// 追跡
- md->next_walktime = tick + std::chrono::milliseconds(500);
+ md->next_walktime = tick + 500_ms;
i = 0;
do
{
@@ -1973,11 +1983,11 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
}
else
{ // ルートモンスター処理
- if (tbl == NULL || tbl->bl_type != BL::ITEM || tbl->bl_m != md->bl_m
+ if (tbl == nullptr || tbl->bl_type != BL::ITEM || tbl->bl_m != md->bl_m
|| (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);
@@ -1999,7 +2009,7 @@ void mob_ai_sub_hard(dumb_ptr<block_list> bl, tick_t tick)
&& (md->next_walktime < tick
|| distance(md->to_x, md->to_y, tbl->bl_x, tbl->bl_y) <= 0))
return; // 既に移動中
- md->next_walktime = tick + std::chrono::milliseconds(500);
+ md->next_walktime = tick + 500_ms;
dx = tbl->bl_x - md->bl_x;
dy = tbl->bl_y - md->bl_y;
ret = mob_walktoxy(md, md->bl_x + dx, md->bl_y + dy, 0);
@@ -2036,16 +2046,16 @@ 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,
// set it to somewhere between 3 and 5 seconds
- if (md->next_walktime > tick + std::chrono::seconds(7)
+ if (md->next_walktime > tick + 7_s
&& (md->walkpath.path_len == 0
|| md->walkpath.path_pos >= md->walkpath.path_len))
{
- md->next_walktime = tick + std::chrono::seconds(3)
+ md->next_walktime = tick + 3_s
+ std::chrono::milliseconds(random_::to(2000));
}
@@ -2104,7 +2114,7 @@ void mob_ai_sub_lazy(dumb_ptr<block_list> bl, tick_t tick)
return;
md->last_thinktime = tick;
- if (md->bl_prev == NULL || md->skilltimer)
+ if (md->bl_prev == nullptr || md->skilltimer)
{
if (tick > md->next_walktime + MIN_MOBTHINKTIME * 10)
md->next_walktime = tick;
@@ -2112,7 +2122,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))
{
@@ -2127,8 +2137,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);
}
@@ -2139,12 +2149,12 @@ 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);
}
- md->next_walktime = tick + std::chrono::seconds(5) + std::chrono::milliseconds(random_::to(10 * 1000));
+ md->next_walktime = tick + 5_s + std::chrono::milliseconds(random_::to(10 * 1000));
}
}
@@ -2169,7 +2179,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;
};
@@ -2177,7 +2188,7 @@ struct delay_item_drop2
{
map_local *m;
int x, y;
- struct item item_data;
+ Item item_data;
dumb_ptr<map_session_data> first_sd, second_sd, third_sd;
};
@@ -2188,7 +2199,7 @@ struct delay_item_drop2
static
void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem)
{
- struct item temp_item {};
+ Item temp_item {};
PickupFail flag;
temp_item.nameid = ditem.nameid;
@@ -2201,7 +2212,7 @@ void mob_delay_item_drop(TimerData *, tick_t, struct delay_item_drop ditem)
pc_additem(ditem.first_sd, &temp_item, ditem.amount))
!= PickupFail::OKAY)
{
- clif_additem(ditem.first_sd, 0, 0, flag);
+ clif_additem(ditem.first_sd, IOff0::from(0), 0, flag);
map_addflooritem(&temp_item, 1,
ditem.m, ditem.x, ditem.y,
ditem.first_sd, ditem.second_sd, ditem.third_sd);
@@ -2231,7 +2242,7 @@ void mob_delay_item_drop2(TimerData *, tick_t, struct delay_item_drop2 ditem)
ditem.item_data.amount))
!= PickupFail::OKAY)
{
- clif_additem(ditem.first_sd, 0, 0, flag);
+ clif_additem(ditem.first_sd, IOff0::from(0), 0, flag);
map_addflooritem(&ditem.item_data, ditem.item_data.amount,
ditem.m, ditem.x, ditem.y,
ditem.first_sd, ditem.second_sd, ditem.third_sd);
@@ -2252,7 +2263,7 @@ int mob_delete(dumb_ptr<mob_data> md)
{
nullpo_retr(1, md);
- if (md->bl_prev == NULL)
+ if (md->bl_prev == nullptr)
return 1;
mob_changestate(md, MS::DEAD, 0);
clif_clearchar(md, BeingRemoveWhy::DEAD);
@@ -2266,7 +2277,7 @@ int mob_catch_delete(dumb_ptr<mob_data> md, BeingRemoveWhy type)
{
nullpo_retr(1, md);
- if (md->bl_prev == NULL)
+ if (md->bl_prev == nullptr)
return 1;
mob_changestate(md, MS::DEAD, 0);
clif_clearchar(md, type);
@@ -2275,7 +2286,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;
@@ -2291,15 +2302,15 @@ 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)
- mob_damage(NULL, md, md->hp, 1);
+ if (md->master_id && md->master_id == id)
+ mob_damage(nullptr, md, md->hp, 1);
}
/*==========================================
@@ -2308,7 +2319,7 @@ void mob_deleteslave_sub(dumb_ptr<block_list> bl, int id)
*/
int mob_deleteslave(dumb_ptr<mob_data> md)
{
- nullpo_ret(md);
+ nullpo_retz(md);
map_foreachinarea(std::bind(mob_deleteslave_sub, ph::_1, md->bl_id),
md->bl_m,
@@ -2333,18 +2344,18 @@ double damage_bonus_factor[DAMAGE_BONUS_COUNT + 1] =
int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
int type)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
int max_hp;
tick_t tick = gettick();
- dumb_ptr<map_session_data> mvp_sd = NULL, second_sd = NULL, third_sd = NULL;
+ dumb_ptr<map_session_data> mvp_sd = nullptr, second_sd = nullptr, third_sd = nullptr;
- nullpo_ret(md); //srcはNULLで呼ばれる場合もあるので、他でチェック
+ nullpo_retz(md); //srcはNULLで呼ばれる場合もあるので、他でチェック
if (src && src->bl_id == md->master_id
&& 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;
@@ -2358,18 +2369,16 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
mvp_sd = sd;
}
-// if(battle_config.battle_log)
-// PRINTF("mob_damage %d %d %d\n",md->hp,max_hp,damage);
- if (md->bl_prev == NULL)
+ if (md->bl_prev == nullptr)
{
if (battle_config.error_log == 1)
- PRINTF("mob_damage : BlockError!!\n");
+ PRINTF("mob_damage : BlockError!!\n"_fmt);
return 0;
}
if (md->state.state == MS::DEAD || md->hp <= 0)
{
- if (md->bl_prev != NULL)
+ if (md->bl_prev != nullptr)
{
mob_changestate(md, MS::DEAD, 0);
// It is skill at the time of death.
@@ -2395,7 +2404,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
if (!(type & 2))
{
- if (sd != NULL)
+ if (sd != nullptr)
{
for (mob_data::DmgLogEntry& dle : md->dmglogv)
{
@@ -2414,7 +2423,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
@@ -2425,12 +2434,12 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
if (master_bl && master_bl->bl_type == BL::PC)
{
MAP_LOG_PC(master_bl->is_player(),
- "MOB-TO-MOB-DMG FROM MOB%d %d TO MOB%d %d FOR %d",
- md2->bl_id, md2->mob_class, md->bl_id, md->mob_class,
- damage);
+ "MOB-TO-MOB-DMG FROM MOB%d %d TO MOB%d %d FOR %d"_fmt,
+ md2->bl_id, md2->mob_class, md->bl_id, md->mob_class,
+ damage);
}
- nullpo_ret(md2);
+ nullpo_retz(md2);
for (mob_data::DmgLogEntry& dle : md->dmglogv)
{
if (dle.id == md2->master_id)
@@ -2446,7 +2455,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:
@@ -2461,7 +2470,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
return 0;
}
- MAP_LOG("MOB%d DEAD", md->bl_id);
+ MAP_LOG("MOB%d DEAD"_fmt, md->bl_id);
// ----- ここから死亡処理 -----
@@ -2491,7 +2500,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
{
struct DmgLogParty
{
- struct party *p;
+ PartyPair p;
int base_exp, job_exp;
};
std::vector<DmgLogParty> ptv;
@@ -2501,7 +2510,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
{
dumb_ptr<map_session_data> tmpsdi = map_id2sd(dle.id);
int tmpdmg = dle.dmg;
- if (tmpsdi == NULL)
+ if (tmpsdi == nullptr)
continue;
if (tmpsdi->bl_m != md->bl_m || pc_isdead(tmpsdi))
continue;
@@ -2532,7 +2541,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
int base_exp, job_exp, flag = 1;
double per;
- struct party *p;
+ PartyPair p;
// [Fate] The above is the old formula. We do a more involved computation below.
// [o11c] Look in git history for old code, you idiot!
@@ -2548,23 +2557,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]
}
@@ -2572,19 +2581,19 @@ 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)
{
- return dlp.p->party_id == pid;
+ return dlp.p.party_id == pid;
}
);
if (it == ptv.end())
{
p = party_search(pid);
- if (p != NULL && p->exp != 0)
+ if (p && p->exp != 0)
{
DmgLogParty pn {};
pn.p = p;
@@ -2617,19 +2626,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;
@@ -2637,14 +2646,14 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
ditem.first_sd = mvp_sd;
ditem.second_sd = second_sd;
ditem.third_sd = third_sd;
- Timer(tick + std::chrono::milliseconds(500) + static_cast<interval_t>(i),
+ Timer(tick + 500_ms + static_cast<interval_t>(i),
std::bind(mob_delay_item_drop, ph::_1, ph::_2,
ditem)
).detach();
}
{
int i = 0;
- for (struct item lit : md->lootitemv)
+ for (Item lit : md->lootitemv)
{
struct delay_item_drop2 ditem {};
ditem.item_data = lit;
@@ -2655,7 +2664,7 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
ditem.second_sd = second_sd;
ditem.third_sd = third_sd;
// ?
- Timer(tick + std::chrono::milliseconds(540) + static_cast<interval_t>(i),
+ Timer(tick + 540_ms + static_cast<interval_t>(i),
std::bind(mob_delay_item_drop2, ph::_1, ph::_2,
ditem)
).detach();
@@ -2668,9 +2677,9 @@ int mob_damage(dumb_ptr<block_list> src, dumb_ptr<mob_data> md, int damage,
// SCRIPT実行
if (md->npc_event)
{
- if (sd == NULL)
+ if (sd == nullptr)
{
- if (mvp_sd != NULL)
+ if (mvp_sd != nullptr)
sd = mvp_sd;
else
{
@@ -2711,7 +2720,7 @@ int mob_heal(dumb_ptr<mob_data> md, int heal)
{
int max_hp = battle_get_max_hp(md);
- nullpo_ret(md);
+ nullpo_retz(md);
md->hp += heal;
if (max_hp < md->hp)
@@ -2725,7 +2734,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();
@@ -2742,7 +2751,6 @@ void mob_warpslave_sub(dumb_ptr<block_list> bl, int id, int x, int y)
static
int mob_warpslave(dumb_ptr<mob_data> md, int x, int y)
{
-//PRINTF("warp slave\n");
map_foreachinarea(std::bind(mob_warpslave_sub, ph::_1, md->bl_id, md->bl_x, md->bl_y),
md->bl_m,
x - AREA_SIZE, y - AREA_SIZE,
@@ -2759,9 +2767,9 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t
{
int i = 0, xs = 0, ys = 0, bx = x, by = y;
- nullpo_ret(md);
+ nullpo_retz(md);
- if (md->bl_prev == NULL)
+ if (md->bl_prev == nullptr)
return 0;
if (m == nullptr)
@@ -2808,12 +2816,12 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t
else
{
if (battle_config.error_log == 1)
- PRINTF("MOB %d warp failed, mob_class = %d\n", md->bl_id, md->mob_class);
+ 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);
@@ -2821,7 +2829,7 @@ int mob_warp(dumb_ptr<mob_data> md, map_local *m, int x, int y, BeingRemoveWhy t
&& i == 1000)
{
if (battle_config.battle_log == 1)
- PRINTF("MOB %d warp to (%d,%d), mob_class = %d\n", md->bl_id, x, y,
+ PRINTF("MOB %d warp to (%d,%d), mob_class = %d\n"_fmt, md->bl_id, x, y,
md->mob_class);
}
@@ -2840,7 +2848,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;
@@ -2860,7 +2868,7 @@ int mob_countslave(dumb_ptr<mob_data> md)
{
int c = 0;
- nullpo_ret(md);
+ nullpo_retz(md);
map_foreachinarea(std::bind(mob_countslave_sub, ph::_1, md->bl_id, &c),
md->bl_m,
@@ -2874,36 +2882,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_retz(md2);
+ nullpo_retz(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
@@ -2921,8 +2931,8 @@ int mob_summonslave(dumb_ptr<mob_data> md2, int *value, int amount, int flag)
}
mob_spawn_dataset(md, JAPANESE_NAME, mob_class);
- md->bl_prev = NULL;
- md->bl_next = NULL;
+ md->bl_prev = nullptr;
+ md->bl_next = nullptr;
md->bl_m = m;
md->bl_x = x;
md->bl_y = y;
@@ -2954,7 +2964,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);
@@ -2986,7 +2996,7 @@ int mob_counttargeted(dumb_ptr<mob_data> md, dumb_ptr<block_list> src,
{
int c = 0;
- nullpo_ret(md);
+ nullpo_retz(md);
map_foreachinarea(std::bind(mob_counttargeted_sub, ph::_1, md->bl_id, &c, src, target_lv),
md->bl_m,
@@ -3004,21 +3014,21 @@ 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<mob_data> md = nullptr;
dumb_ptr<block_list> bl;
dumb_ptr<block_list> mbl;
int range;
- if ((mbl = map_id2bl(id)) == NULL) //詠唱したMobがもういないというのは良くある正常処理
+ if ((mbl = map_id2bl(id)) == nullptr) //詠唱したMobがもういないというのは良くある正常処理
return;
- if ((md = mbl->is_mob()) == NULL)
+ if ((md = mbl->is_mob()) == nullptr)
{
- PRINTF("mobskill_castend_id nullpo mbl->bl_id:%d\n", mbl->bl_id);
+ PRINTF("mobskill_castend_id nullpo mbl->bl_id:%d\n"_fmt, mbl->bl_id);
return;
}
- if (md->bl_type != BL::MOB || md->bl_prev == NULL)
+ if (md->bl_type != BL::MOB || md->bl_prev == nullptr)
return;
if (bool(md->opt1))
@@ -3027,9 +3037,8 @@ void mobskill_castend_id(TimerData *, tick_t tick, int id)
if (md->skillid != SkillID::NPC_EMOTION)
md->last_thinktime = tick + battle_get_adelay(md);
- if ((bl = map_id2bl(md->skilltarget)) == NULL || bl->bl_prev == NULL)
+ if ((bl = map_id2bl(md->skilltarget)) == nullptr || bl->bl_prev == nullptr)
{ //スキルターゲットが存在しない
- //PRINTF("mobskill_castend_id nullpo\n");//ターゲットがいないときはnullpoじゃなくて普通に終了
return;
}
if (md->bl_m != bl->bl_m)
@@ -3044,10 +3053,10 @@ 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",
+ PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt,
md->skillid, md->mob_class);
mob_stop_walking(md, 0);
@@ -3071,20 +3080,20 @@ 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<mob_data> md = nullptr;
dumb_ptr<block_list> bl;
int range;
//mobskill_castend_id同様詠唱したMobが詠唱完了時にもういないというのはありそうなのでnullpoから除外
- if ((bl = map_id2bl(id)) == NULL)
+ if ((bl = map_id2bl(id)) == nullptr)
return;
md = bl->is_mob();
nullpo_retv(md);
- if (md->bl_type != BL::MOB || md->bl_prev == NULL)
+ if (md->bl_type != BL::MOB || md->bl_prev == nullptr)
return;
if (bool(md->opt1))
@@ -3095,10 +3104,10 @@ 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",
+ PRINTF("MOB skill castend skill=%d, mob_class = %d\n"_fmt,
md->skillid, md->mob_class);
mob_stop_walking(md, 0);
}
@@ -3115,13 +3124,13 @@ int mobskill_use_id(dumb_ptr<mob_data> md, dumb_ptr<block_list> target,
SkillID skill_id;
int skill_lv;
- nullpo_ret(md);
+ nullpo_retz(md);
ms = &skill_idx;
- if (target == NULL && (target = map_id2bl(md->target_id)) == NULL)
+ if (target == nullptr && (target = map_id2bl(md->target_id)) == nullptr)
return 0;
- if (target->bl_prev == NULL || md->bl_prev == NULL)
+ if (target->bl_prev == nullptr || md->bl_prev == nullptr)
return 0;
skill_id = ms->skill_id;
@@ -3145,10 +3154,10 @@ 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",
+ PRINTF("MOB skill use target_id=%d skill=%d lv=%d cast=%d, mob_class = %d\n"_fmt,
target->bl_id, skill_id, skill_lv,
static_cast<uint32_t>(casttime.count()), md->mob_class);
@@ -3190,10 +3199,10 @@ int mobskill_use_pos(dumb_ptr<mob_data> md,
struct block_list bl;
int skill_lv;
- nullpo_ret(md);
+ nullpo_retz(md);
ms = &skill_idx;
- if (md->bl_prev == NULL)
+ if (md->bl_prev == nullptr)
return 0;
SkillID skill_id = ms->skill_id;
@@ -3215,13 +3224,13 @@ 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)
- PRINTF("MOB skill use target_pos= (%d,%d) skill=%d lv=%d cast=%d, mob_class = %d\n",
- skill_x, skill_y, skill_id, skill_lv,
- static_cast<uint32_t>(casttime.count()), md->mob_class);
+ PRINTF("MOB skill use target_pos= (%d,%d) skill=%d lv=%d cast=%d, mob_class = %d\n"_fmt,
+ skill_x, skill_y, skill_id, skill_lv,
+ static_cast<uint32_t>(casttime.count()), md->mob_class);
if (casttime <= interval_t::zero())
// A skill without a cast time wont be cancelled.
@@ -3229,7 +3238,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;
@@ -3257,8 +3266,8 @@ 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;
+ nullpo_retz(md);
+ std::vector<mob_skill>& ms = get_mob_db(md->mob_class).skills;
max_hp = battle_get_max_hp(md);
@@ -3312,7 +3321,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick,
if (skill_get_inf(msii.skill_id) & 2)
{
// 場所指定
- dumb_ptr<block_list> bl = NULL;
+ dumb_ptr<block_list> bl = nullptr;
int x = 0, y = 0;
{
if (msii.target == MobSkillTarget::MST_TARGET)
@@ -3334,7 +3343,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick,
else
{
{
- dumb_ptr<block_list> bl = NULL;
+ dumb_ptr<block_list> bl = nullptr;
if (msii.target == MobSkillTarget::MST_TARGET)
bl = map_id2bl(md->target_id);
else
@@ -3358,7 +3367,7 @@ int mobskill_use(dumb_ptr<mob_data> md, tick_t tick,
*/
int mobskill_event(dumb_ptr<mob_data> md, BF flag)
{
- nullpo_ret(md);
+ nullpo_retz(md);
if (flag == BF::NEGATIVE_1
&& mobskill_use(md, gettick(), MobSkillCondition::ANY))
@@ -3380,42 +3389,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", mob_class);
- SNPRINTF(mob_db[mob_class].jname, 24, "mob%d", 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,13 +3448,13 @@ bool mob_readdb(ZString filename)
io::ReadFile in(filename);
if (!in.is_open())
{
- PRINTF("Unable to read mob db: %s\n", filename);
+ PRINTF("Unable to read mob db: %s\n"_fmt, filename);
return false;
}
AString line;
while (in.getline(line))
{
- int mob_class;
+ Species mob_class;
if (is_comment(line))
continue;
@@ -3515,80 +3524,80 @@ 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", line);
+ PRINTF("bad mob line: %s\n"_fmt, line);
rv = false;
continue;
}
// 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", filename);
+ PRINTF("read %s done\n"_fmt, filename);
}
return rv;
}
-template<>
-bool extract<MobSkillCondition, void, void>(XString str, MobSkillCondition *msc)
+static
+bool extract(XString str, MobSkillCondition *msc)
{
const struct
{
- ZString str;
+ LString str;
MobSkillCondition id;
} cond1[] =
{
- {ZString("always"), MobSkillCondition::MSC_ALWAYS},
- {ZString("myhpltmaxrate"), MobSkillCondition::MSC_MYHPLTMAXRATE},
- {ZString("notintown"), MobSkillCondition::MSC_NOTINTOWN},
- {ZString("slavelt"), MobSkillCondition::MSC_SLAVELT},
- {ZString("slavele"), MobSkillCondition::MSC_SLAVELE},
+ {"always"_s, MobSkillCondition::MSC_ALWAYS},
+ {"myhpltmaxrate"_s, MobSkillCondition::MSC_MYHPLTMAXRATE},
+ {"notintown"_s, MobSkillCondition::MSC_NOTINTOWN},
+ {"slavelt"_s, MobSkillCondition::MSC_SLAVELT},
+ {"slavele"_s, MobSkillCondition::MSC_SLAVELE},
};
for (auto& pair : cond1)
if (str == pair.str)
@@ -3599,19 +3608,19 @@ bool extract<MobSkillCondition, void, void>(XString str, MobSkillCondition *msc)
return false;
}
-template<>
-bool extract<MobSkillState, void, void>(XString str, MobSkillState *mss)
+static
+bool extract(XString str, MobSkillState *mss)
{
const struct
{
- ZString str;
+ LString str;
MobSkillState id;
} state[] =
{
- {ZString("any"), MobSkillState::ANY},
- {ZString("idle"), MobSkillState::MSS_IDLE},
- {ZString("walk"), MobSkillState::MSS_WALK},
- {ZString("attack"), MobSkillState::MSS_ATTACK},
+ {"any"_s, MobSkillState::ANY},
+ {"idle"_s, MobSkillState::MSS_IDLE},
+ {"walk"_s, MobSkillState::MSS_WALK},
+ {"attack"_s, MobSkillState::MSS_ATTACK},
};
for (auto& pair : state)
if (str == pair.str)
@@ -3622,17 +3631,17 @@ bool extract<MobSkillState, void, void>(XString str, MobSkillState *mss)
return false;
}
-template<>
-bool extract<MobSkillTarget, void, void>(XString str, MobSkillTarget *mst)
+static
+bool extract(XString str, MobSkillTarget *mst)
{
const struct
{
- ZString str;
+ LString str;
MobSkillTarget id;
} target[] =
{
- {ZString("target"), MobSkillTarget::MST_TARGET},
- {ZString("self"), MobSkillTarget::MST_SELF},
+ {"target"_s, MobSkillTarget::MST_TARGET},
+ {"self"_s, MobSkillTarget::MST_SELF},
};
for (auto& pair : target)
if (str == pair.str)
@@ -3650,21 +3659,21 @@ bool mob_readskilldb(ZString filename)
io::ReadFile in(filename);
if (!in.is_open())
{
- PRINTF("can't read %s\n", filename);
+ PRINTF("can't read %s\n"_fmt, filename);
return false;
}
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")
+ 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;
}
@@ -3699,9 +3708,9 @@ bool mob_readskilldb(ZString filename)
)
)
continue;
- if (cancellable == "yes")
+ if (cancellable == "yes"_s)
msv.cancel = true;
- else if (cancellable == "no")
+ else if (cancellable == "no"_s)
msv.cancel = false;
else
{
@@ -3712,15 +3721,15 @@ 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", filename);
+ PRINTF("read %s done\n"_fmt, filename);
}
return rv;
}
@@ -3736,3 +3745,4 @@ void do_init_mob2(void)
MIN_MOBTHINKTIME * 10
).detach();
}
+} // namespace tmwa
diff --git a/src/map/mob.hpp b/src/map/mob.hpp
index e7d81bd..d0cc07a 100644
--- a/src/map/mob.hpp
+++ b/src/map/mob.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MOB_HPP
-#define TMWA_MAP_MOB_HPP
+#pragma once
// mob.hpp - Really scary code.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,22 +20,27 @@
// 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"
+#include "mob.t.hpp"
-# include "../generic/random.t.hpp"
+#include "../generic/fwd.hpp"
+#include "../generic/enum.hpp"
+#include "../generic/random.t.hpp"
-# include "../mmo/mmo.hpp"
-# include "../mmo/timer.t.hpp"
+#include "../net/timer.t.hpp"
-# include "clif.t.hpp"
-# include "map.hpp"
-# include "skill.t.hpp"
+#include "battle.t.hpp"
+#include "clif.t.hpp"
+#include "map.hpp"
+#include "skill.t.hpp"
-# define ENGLISH_NAME stringish<MobName>("--en--")
-# define JAPANESE_NAME stringish<MobName>("--ja--")
-# define MOB_THIS_MAP stringish<MapName>("this")
+
+namespace tmwa
+{
+#define ENGLISH_NAME stringish<MobName>("--en--"_s)
+#define JAPANESE_NAME stringish<MobName>("--ja--"_s)
+#define MOB_THIS_MAP stringish<MapName>("this"_s)
struct mob_skill
{
@@ -72,41 +76,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 +120,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,10 +131,9 @@ 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);
-
-#endif // TMWA_MAP_MOB_HPP
+} // namespace tmwa
diff --git a/src/map/mob.t.hpp b/src/map/mob.t.hpp
index 37fd13e..160a8a3 100644
--- a/src/map/mob.t.hpp
+++ b/src/map/mob.t.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_MOB_T_HPP
-#define TMWA_MAP_MOB_T_HPP
+#pragma once
// mob.t.hpp - Really scary code.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,10 +20,13 @@
// 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 <cstdint>
+
+namespace tmwa
+{
enum class MobSkillTarget
{
MST_TARGET = 0,
@@ -59,5 +61,4 @@ enum class MobSkillState : uint8_t
MSS_LOOT,
MSS_CHASE,
};
-
-#endif // TMWA_MAP_MOB_T_HPP
+} // namespace tmwa
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 7fe13f1..a6427d6 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -21,10 +21,9 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cassert>
-#include <cstdlib>
-#include <cstring>
#include <ctime>
+#include <algorithm>
#include <list>
#include "../compat/fun.hpp"
@@ -34,16 +33,20 @@
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
+#include "../strings/literal.hpp"
#include "../generic/db.hpp"
#include "../io/cxxstdio.hpp"
#include "../io/read.hpp"
+#include "../net/timer.hpp"
+
#include "../mmo/config_parse.hpp"
#include "../mmo/extract.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../mmo/utils.hpp"
+
+#include "../proto2/map-user.hpp"
#include "battle.hpp"
#include "clif.hpp"
@@ -56,17 +59,22 @@
#include "../poison.hpp"
+
+namespace tmwa
+{
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
@@ -107,7 +115,7 @@ void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd)
NpcEvent aname;
aname.npc = nd->name;
- aname.label = stringish<ScriptLabel>("OnTouch");
+ aname.label = stringish<ScriptLabel>("OnTouch"_s);
if (sd->areanpc_id == nd->bl_id)
return;
sd->areanpc_id = nd->bl_id;
@@ -118,9 +126,9 @@ void npc_enable_sub(dumb_ptr<block_list> bl, dumb_ptr<npc_data> nd)
int npc_enable(NpcName name, bool flag)
{
dumb_ptr<npc_data> nd = npc_name2id(name);
- if (nd == NULL)
+ if (nd == nullptr)
{
- PRINTF("npc_enable(%s, %s) failed.\n", name, flag ? "true" : "false");
+ PRINTF("npc_enable(%s, %s) failed.\n"_fmt, name, flag ? "true"_s : "false"_s);
return 0;
}
@@ -167,15 +175,15 @@ dumb_ptr<npc_data> npc_name2id(NpcName name)
*/
int npc_event_dequeue(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
- sd->npc_id = 0;
+ sd->npc_id = BlockId();
if (!sd->eventqueuel.empty())
{
- if (!pc_addeventtimer(sd, std::chrono::milliseconds(100), sd->eventqueuel.front()))
+ if (!pc_addeventtimer(sd, 100_ms, sd->eventqueuel.front()))
{
- PRINTF("npc_event_dequeue(): Event timer is full.\n");
+ PRINTF("npc_event_dequeue(): Event timer is full.\n"_fmt);
return 0;
}
@@ -190,7 +198,7 @@ int npc_delete(dumb_ptr<npc_data> nd)
{
nullpo_retr(1, nd);
- if (nd->bl_prev == NULL)
+ if (nd->bl_prev == nullptr)
return 1;
clif_clearchar(nd, BeingRemoveWhy::DEAD);
@@ -204,9 +212,9 @@ void npc_timer_event(NpcEvent eventname)
dumb_ptr<npc_data_script> nd;
// int xs,ys;
- if ((ev == NULL || (nd = ev->nd) == NULL))
+ if ((ev == nullptr || (nd = ev->nd) == nullptr))
{
- PRINTF("npc_event: event not found [%s]\n",
+ PRINTF("npc_event: event not found [%s]\n"_fmt,
eventname);
return;
}
@@ -220,7 +228,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 +242,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 +253,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 +265,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;
@@ -283,19 +291,19 @@ void npc_event_do_clock(TimerData *, tick_t)
ScriptLabel buf;
if (t.tm_min != ev_tm_b.tm_min)
{
- SNPRINTF(buf, 24, "OnMinute%02d", t.tm_min);
+ SNPRINTF(buf, 24, "OnMinute%02d"_fmt, t.tm_min);
npc_event_doall(buf);
- SNPRINTF(buf, 24, "OnClock%02d%02d", t.tm_hour, t.tm_min);
+ SNPRINTF(buf, 24, "OnClock%02d%02d"_fmt, t.tm_hour, t.tm_min);
npc_event_doall(buf);
}
if (t.tm_hour != ev_tm_b.tm_hour)
{
- SNPRINTF(buf, 24, "OnHour%02d", t.tm_hour);
+ SNPRINTF(buf, 24, "OnHour%02d"_fmt, t.tm_hour);
npc_event_doall(buf);
}
if (t.tm_mday != ev_tm_b.tm_mday)
{
- SNPRINTF(buf, 24, "OnDay%02d%02d", t.tm_mon + 1, t.tm_mday);
+ SNPRINTF(buf, 24, "OnDay%02d%02d"_fmt, t.tm_mon + 1, t.tm_mday);
npc_event_doall(buf);
}
ev_tm_b = t;
@@ -307,12 +315,12 @@ void npc_event_do_clock(TimerData *, tick_t)
*/
int npc_event_do_oninit(void)
{
- int c = npc_event_doall(stringish<ScriptLabel>("OnInit"));
- PRINTF("npc: OnInit Event done. (%d npc)\n", c);
+ int c = npc_event_doall(stringish<ScriptLabel>("OnInit"_s));
+ PRINTF("npc: OnInit Event done. (%d npc)\n"_fmt, c);
- Timer(gettick() + std::chrono::milliseconds(100),
+ Timer(gettick() + 100_ms,
npc_event_do_clock,
- std::chrono::seconds(1)
+ 1_s
).detach();
return 0;
@@ -322,10 +330,10 @@ 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);
+ assert (nd != nullptr);
assert (nd->npc_subtype == NpcSubtype::SCRIPT);
assert (nd->scr.next_event != nd->scr.timer_eventv.end());
@@ -345,7 +353,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.
@@ -461,15 +469,15 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname,
dumb_ptr<npc_data_script> nd;
int xs, ys;
- if (sd == NULL)
+ if (sd == nullptr)
{
- PRINTF("npc_event nullpo?\n");
+ PRINTF("npc_event nullpo?\n"_fmt);
}
- if (ev == NULL && eventname.label == stringish<ScriptLabel>("OnTouch"))
+ if (ev == nullptr && eventname.label == stringish<ScriptLabel>("OnTouch"_s))
return 1;
- if (ev == NULL || (nd = ev->nd) == NULL)
+ if (ev == nullptr || (nd = ev->nd) == nullptr)
{
if (mob_kill)
{
@@ -480,7 +488,7 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname,
else
{
if (battle_config.error_log)
- PRINTF("npc_event: event not found [%s]\n",
+ PRINTF("npc_event: event not found [%s]\n"_fmt,
eventname);
return 0;
}
@@ -500,7 +508,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;
@@ -521,12 +529,12 @@ static
void npc_command_sub(NpcEvent key, struct event_data *ev, NpcName npcname, XString command)
{
if (ev->nd->name == npcname
- && key.label.startswith("OnCommand"))
+ && key.label.startswith("OnCommand"_s))
{
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);
}
}
@@ -567,7 +575,7 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y)
ys = m->npc[i]->is_warp()->warp.ys;
break;
case NpcSubtype::MESSAGE:
- assert (0 && "I'm pretty sure these are never put on a map");
+ assert (0 && "I'm pretty sure these are never put on a map"_s);
xs = 0;
ys = 0;
break;
@@ -589,7 +597,7 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y)
if (f)
{
if (battle_config.error_log)
- PRINTF("npc_touch_areanpc : some bug \n");
+ PRINTF("npc_touch_areanpc : some bug \n"_fmt);
}
return 1;
}
@@ -601,13 +609,13 @@ int npc_touch_areanpc(dumb_ptr<map_session_data> sd, map_local *m, int x, int y)
m->npc[i]->is_warp()->warp.x, m->npc[i]->is_warp()->warp.y, BeingRemoveWhy::GONE);
break;
case NpcSubtype::MESSAGE:
- assert (0 && "I'm pretty sure these NPCs are never put on a map.");
+ assert (0 && "I'm pretty sure these NPCs are never put on a map."_s);
break;
case NpcSubtype::SCRIPT:
{
NpcEvent aname;
aname.npc = m->npc[i]->name;
- aname.label = stringish<ScriptLabel>("OnTouch");
+ aname.label = stringish<ScriptLabel>("OnTouch"_s);
if (sd->areanpc_id == m->npc[i]->bl_id)
return 1;
@@ -626,20 +634,20 @@ 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;
- nullpo_ret(sd);
+ nullpo_retz(sd);
nd = map_id_is_npc(id);
// this actually happens
- if (nd == NULL)
+ if (nd == nullptr)
return 1;
if (nd->bl_type != BL::NPC)
return 1;
- if (nd->npc_class < 0) // イベント系は常にOK
+ if (nd->npc_class == NEGATIVE_SPECIES)
return 0;
// エリア判定
@@ -657,16 +665,16 @@ 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");
+ PRINTF("npc_click: npc_id != 0\n"_fmt);
return 1;
}
@@ -706,7 +714,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 +746,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;
@@ -751,8 +759,8 @@ int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type)
if (nd->npc_subtype != NpcSubtype::SHOP)
{
if (battle_config.error_log)
- PRINTF("no such shop npc : %d\n", id);
- sd->npc_id = 0;
+ PRINTF("no such shop npc : %d\n"_fmt, id);
+ sd->npc_id = BlockId();
return 1;
}
if (nd->flag & 1) // 無効化されている
@@ -775,15 +783,14 @@ int npc_buysellsel(dumb_ptr<map_session_data> sd, int id, int type)
*------------------------------------------
*/
// TODO enumify return type
-int npc_buylist(dumb_ptr<map_session_data> sd, int n,
- const uint16_t *item_list)
+int npc_buylist(dumb_ptr<map_session_data> sd,
+ const std::vector<Packet_Repeat<0x00c8>>& item_list)
{
dumb_ptr<npc_data> nd;
double z;
int i, j, w, itemamount = 0, new_stacks = 0;
nullpo_retr(3, sd);
- nullpo_retr(3, item_list);
if (npc_checknear(sd, sd->npc_shopid))
return 3;
@@ -792,26 +799,29 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
if (nd->npc_subtype != NpcSubtype::SHOP)
return 3;
- for (i = 0, w = 0, z = 0; i < n; i++)
+ for (i = 0, w = 0, z = 0; i < item_list.size(); i++)
{
+ const uint16_t& item_l_count = item_list[i].count;
+ const ItemNameId& item_l_id = item_list[i].name_id;
+
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 +829,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,18 +838,21 @@ 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++)
+ for (i = 0; i < item_list.size(); i++)
{
+ const uint16_t& item_l_count = item_list[i].count;
+ const ItemNameId& item_l_id = item_list[i].name_id;
+
struct item_data *item_data;
- if ((item_data = itemdb_exists(item_list[i * 2 + 1])) != NULL)
+ if ((item_data = itemdb_exists(item_l_id)) != nullptr)
{
- int amount = item_list[i * 2];
- struct item item_tmp {};
+ int amount = item_l_count;
+ Item item_tmp {};
item_tmp.nameid = item_data->nameid;
@@ -868,39 +881,37 @@ int npc_buylist(dumb_ptr<map_session_data> sd, int n,
*
*------------------------------------------
*/
-int npc_selllist(dumb_ptr<map_session_data> sd, int n,
- const uint16_t *item_list)
+int npc_selllist(dumb_ptr<map_session_data> sd,
+ const std::vector<Packet_Repeat<0x00c9>>& item_list)
{
double z;
int i, itemamount = 0;
nullpo_retr(1, sd);
- nullpo_retr(1, item_list);
if (npc_checknear(sd, sd->npc_shopid))
return 1;
- for (i = 0, z = 0; i < n; i++)
+ for (i = 0, z = 0; i < item_list.size(); i++)
{
- int nameid;
- if (item_list[i * 2] - 2 < 0 || item_list[i * 2] - 2 >= MAX_INVENTORY)
+ if (!item_list[i].ioff2.ok())
return 1;
- nameid = sd->status.inventory[item_list[i * 2] - 2].nameid;
- if (nameid == 0 ||
- sd->status.inventory[item_list[i * 2] - 2].amount < item_list[i * 2 + 1])
+ ItemNameId nameid = sd->status.inventory[item_list[i].ioff2.unshift()].nameid;
+ if (!nameid ||
+ sd->status.inventory[item_list[i].ioff2.unshift()].amount < item_list[i].count)
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];
+ z += static_cast<double>(itemdb_value_sell(nameid)) * item_list[i].count;
+ itemamount += item_list[i].count;
}
if (z > MAX_ZENY)
z = MAX_ZENY;
pc_getzeny(sd, static_cast<int>(z));
- for (i = 0; i < n; i++)
+ for (i = 0; i < item_list.size(); i++)
{
- int item_id = item_list[i * 2] - 2;
- pc_delitem(sd, item_id, item_list[i * 2 + 1], 0);
+ IOff0 item_id = item_list[i].ioff2.unshift();
+ pc_delitem(sd, item_id, item_list[i].count, 0);
}
return 0;
@@ -927,7 +938,7 @@ void npc_clearsrcfile(void)
*/
void npc_addsrcfile(AString name)
{
- if (name == "clear")
+ if (name == "clear"_s)
{
npc_clearsrcfile();
return;
@@ -942,7 +953,7 @@ void npc_addsrcfile(AString name)
*/
void npc_delsrcfile(XString name)
{
- if (name == "all")
+ if (name == "all"_s)
{
npc_clearsrcfile();
return;
@@ -961,19 +972,19 @@ void npc_delsrcfile(XString name)
static
void register_npc_name(dumb_ptr<npc_data> nd)
{
- ZString types[4] =
- {
- {"WARP"},
- {"SHOP"},
- {"SCRIPT"},
- {"MESSAGE"},
- };
+ earray<LString, NpcSubtype, NpcSubtype::COUNT> types //=
+ {{
+ "WARP"_s,
+ "SHOP"_s,
+ "SCRIPT"_s,
+ "MESSAGE"_s,
+ }};
if (!nd->name)
{
if (nd->npc_subtype == NpcSubtype::MESSAGE)
return;
- PRINTF("WARNING: npc with no name:\n%s @ %s,%d,%d\n",
- types[static_cast<int>(nd->npc_subtype)],
+ PRINTF("WARNING: npc with no name:\n%s @ %s,%d,%d\n"_fmt,
+ types[nd->npc_subtype],
nd->bl_m->name_, nd->bl_x, nd->bl_y);
return;
}
@@ -982,12 +993,12 @@ void register_npc_name(dumb_ptr<npc_data> nd)
if (nd->npc_subtype != NpcSubtype::WARP
|| nd_old->npc_subtype != NpcSubtype::WARP)
{
- PRINTF("WARNING: replacing npc with name: %s\n", nd->name);
- PRINTF("old: %s @ %s,%d,%d\n",
- types[static_cast<int>(nd_old->npc_subtype)],
+ PRINTF("WARNING: replacing npc with name: %s\n"_fmt, nd->name);
+ PRINTF("old: %s @ %s,%d,%d\n"_fmt,
+ types[nd_old->npc_subtype],
nd_old->bl_m->name_, nd_old->bl_x, nd_old->bl_y);
- PRINTF("new: %s @ %s,%d,%d\n",
- types[static_cast<int>(nd->npc_subtype)],
+ PRINTF("new: %s @ %s,%d,%d\n"_fmt,
+ types[nd->npc_subtype],
nd->bl_m->name_, nd->bl_x, nd->bl_y);
}
}
@@ -1009,7 +1020,7 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4)
if (!extract(w1, record<','>(&mapname, &x, &y)) ||
!extract(w4, record<','>(&xs, &ys, &to_mapname, &to_x, &to_y)))
{
- PRINTF("bad warp line : %s\n", w3);
+ PRINTF("bad warp line : %s\n"_fmt, w3);
return 1;
}
@@ -1019,7 +1030,7 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4)
nd->bl_id = npc_get_new_npc_id();
nd->n = map_addnpc(m, nd);
- nd->bl_prev = nd->bl_next = NULL;
+ nd->bl_prev = nd->bl_next = nullptr;
nd->bl_m = m;
nd->bl_x = x;
nd->bl_y = y;
@@ -1031,7 +1042,7 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4)
nd->npc_class = WARP_CLASS;
else
nd->npc_class = WARP_DEBUG_CLASS;
- nd->speed = std::chrono::milliseconds(200);
+ nd->speed = 200_ms;
nd->option = Option::ZERO;
nd->opt1 = Opt1::ZERO;
nd->opt2 = Opt2::ZERO;
@@ -1059,7 +1070,6 @@ int npc_parse_warp(XString w1, XString, NpcName w3, XString w4)
}
}
-// PRINTF("warp npc %s %d read done\n",mapname,nd->bl_id);
npc_warp++;
nd->bl_type = BL::NPC;
nd->npc_subtype = NpcSubtype::WARP;
@@ -1077,11 +1087,11 @@ 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());
- if (id == NULL)
+ if (id == nullptr)
return false;
itv->nameid = id->nameid;
goto return_true;
@@ -1089,7 +1099,7 @@ bool extract(XString xs, npc_item_list *itv)
return_true:
if (itv->value < 0)
{
- if (id == NULL)
+ if (id == nullptr)
id = itemdb_search(itv->nameid);
itv->value = id->value_buy * abs(itv->value);
}
@@ -1108,7 +1118,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a)
MapName mapname;
dumb_ptr<npc_data_shop> nd;
ZString::iterator w4comma;
- int npc_class;
+ Species npc_class;
int dir_; // TODO use enum directly in extract
if (!extract(w1, record<','>(&mapname, &x, &y, &dir_))
@@ -1116,7 +1126,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a)
|| (w4comma = std::find(w4a.begin(), w4a.end(), ',')) == w4a.end()
|| !extract(w4a.xislice_h(w4comma), &npc_class))
{
- PRINTF("bad shop line : %s\n", w3);
+ PRINTF("bad shop line : %s\n"_fmt, w3);
return 1;
}
dir = static_cast<DIR>(dir_);
@@ -1127,8 +1137,8 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a)
if (!extract(w4b, vrec<','>(&nd->shop_items)))
{
- PRINTF("bad shop items : %s\n", w3);
- PRINTF(" somewhere --> %s\n", w4b);
+ PRINTF("bad shop items : %s\n"_fmt, w3);
+ PRINTF(" somewhere --> %s\n"_fmt, w4b);
nd->shop_items.clear();
}
@@ -1138,7 +1148,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a)
return 1;
}
- nd->bl_prev = nd->bl_next = NULL;
+ nd->bl_prev = nd->bl_next = nullptr;
nd->bl_m = m;
nd->bl_x = x;
nd->bl_y = y;
@@ -1147,7 +1157,7 @@ int npc_parse_shop(XString w1, XString, NpcName w3, ZString w4a)
nd->flag = 0;
nd->name = w3;
nd->npc_class = npc_class;
- nd->speed = std::chrono::milliseconds(200);
+ nd->speed = 200_ms;
nd->option = Option::ZERO;
nd->opt1 = Opt1::ZERO;
nd->opt2 = Opt2::ZERO;
@@ -1190,13 +1200,14 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
int x, y;
DIR dir = DIR::S;
map_local *m;
- int xs = 0, ys = 0, npc_class = 0; // [Valaris] thanks to fov
+ int xs = 0, ys = 0; // [Valaris] thanks to fov
+ Species npc_class;
MapName mapname;
- std::unique_ptr<const ScriptBuffer> script = NULL;
+ std::unique_ptr<const ScriptBuffer> script = nullptr;
dumb_ptr<npc_data_script> nd;
int evflag = 0;
- if (w1 == "-")
+ if (w1 == "-"_s)
{
x = 0;
y = 0;
@@ -1207,16 +1218,16 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
int dir_; // TODO use enum directly in extract
if (!extract(w1, record<','>(&mapname, &x, &y, &dir_))
|| dir_ < 0 || dir_ >= 8
- || (w2 == "script" && !w4.contains(',')))
+ || (w2 == "script"_s && !w4.contains(',')))
{
- PRINTF("bad script line : %s\n", w3);
+ PRINTF("bad script line : %s\n"_fmt, w3);
return 1;
}
dir = static_cast<DIR>(dir_);
m = map_mapname2mapid(mapname);
}
- if (w2 == "script")
+ if (w2 == "script"_s)
{
// may be empty
MString srcbuf;
@@ -1249,13 +1260,13 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
srcbuf += '\n';
}
script = parse_script(AString(srcbuf), startline, false);
- if (script == NULL)
+ if (script == nullptr)
// script parse error?
return 1;
}
else
{
- assert(0 && "duplicate() is no longer supported!\n");
+ assert(0 && "duplicate() is no longer supported!\n"_s);
return 0;
}
@@ -1271,7 +1282,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
if (ys >= 0)
ys = ys * 2 + 1;
- if (npc_class >= 0)
+ if (npc_class != NEGATIVE_SPECIES)
{
for (int i = 0; i < ys; i++)
@@ -1295,26 +1306,31 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
}
else
{
- npc_class = atoi(w4.c_str());
+ XString w4x = w4;
+ if (w4x.endswith(','))
+ w4x = w4x.xrslice_h(1);
+ if (!extract(w4x, &npc_class))
+ abort();
nd->scr.xs = 0;
nd->scr.ys = 0;
}
- if (npc_class < 0 && m != nullptr)
+ if (npc_class == NEGATIVE_SPECIES && m != nullptr)
{
evflag = 1;
}
if (w3.contains(':'))
{
- assert(false && "feature removed");
+ assert(false && "feature removed"_s);
abort();
}
+
{
nd->name = w3;
}
- nd->bl_prev = nd->bl_next = NULL;
+ nd->bl_prev = nd->bl_next = nullptr;
nd->bl_m = m;
nd->bl_x = x;
nd->bl_y = y;
@@ -1322,14 +1338,13 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
nd->dir = dir;
nd->flag = 0;
nd->npc_class = npc_class;
- nd->speed = std::chrono::milliseconds(200);
+ nd->speed = 200_ms;
nd->scr.script = std::move(script);
nd->option = Option::ZERO;
nd->opt1 = Opt1::ZERO;
nd->opt2 = Opt2::ZERO;
nd->opt3 = Opt3::ZERO;
- //PRINTF("script npc %s %d %d read done\n",mapname,nd->bl_id,nd->class);
npc_script++;
nd->bl_type = BL::NPC;
nd->npc_subtype = NpcSubtype::SCRIPT;
@@ -1361,7 +1376,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
ScriptLabel lname = el.name;
int pos = el.pos;
- if (lname.startswith("On"))
+ if (lname.startswith("On"_s))
{
struct event_data ev {};
ev.nd = nd;
@@ -1380,7 +1395,7 @@ int npc_parse_script(XString w1, XString w2, NpcName w3, ZString w4,
int t_ = 0;
ScriptLabel lname = el.name;
int pos = el.pos;
- if (lname.startswith("OnTimer") && extract(lname.xslice_t(7), &t_) && t_ > 0)
+ if (lname.startswith("OnTimer"_s) && extract(lname.xslice_t(7), &t_) && t_ > 0)
{
interval_t t = static_cast<interval_t>(t_);
@@ -1440,7 +1455,7 @@ int npc_parse_function(XString, XString, XString w3, ZString,
srcbuf += '\n';
}
std::unique_ptr<const ScriptBuffer> script = parse_script(AString(srcbuf), startline, false);
- if (script == NULL)
+ if (script == nullptr)
{
// script parse error?
return 1;
@@ -1458,7 +1473,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;
@@ -1469,7 +1485,7 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4)
if (!extract(w1, record<',', 3>(&mapname, &x, &y, &xs, &ys)) ||
!extract(w4, record<',', 2>(&mob_class, &num, &delay1_, &delay2_, &eventname)))
{
- PRINTF("bad monster line : %s\n", w3);
+ PRINTF("bad monster line : %s\n"_fmt, w3);
return 1;
}
interval_t delay1 = std::chrono::milliseconds(delay1_);
@@ -1487,15 +1503,15 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4)
{
md.new_();
- md->bl_prev = NULL;
- md->bl_next = NULL;
+ md->bl_prev = nullptr;
+ md->bl_next = nullptr;
md->bl_m = m;
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;
@@ -1512,8 +1528,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();
@@ -1525,7 +1541,6 @@ int npc_parse_mob(XString w1, XString, MobName w3, ZString w4)
npc_mob++;
}
- //PRINTF("warp npc %s %d read done\n",mapname,nd->bl_id);
return 0;
}
@@ -1561,9 +1576,9 @@ int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4)
if (mf == MapFlag::NOSAVE)
{
- if (w4 == "SavePoint")
+ if (w4 == "SavePoint"_s)
{
- m->save.map_ = stringish<MapName>("SavePoint");
+ m->save.map_ = stringish<MapName>("SavePoint"_s);
m->save.x = -1;
m->save.y = -1;
}
@@ -1589,7 +1604,7 @@ int npc_parse_mapflag(XString w1, XString, XString w3, ZString w4)
}
dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y,
- int npc_class, NpcName name, AString message)
+ Species npc_class, NpcName name, AString message)
{
dumb_ptr<npc_data_message> retval;
retval.new_();
@@ -1605,7 +1620,7 @@ dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y,
retval->message = message;
retval->npc_class = npc_class;
- retval->speed = std::chrono::milliseconds(200);
+ retval->speed = 200_ms;
clif_spawnnpc(retval);
map_addblock(retval);
@@ -1679,11 +1694,11 @@ bool do_init_npc(void)
io::ReadFile fp(nsl);
if (!fp.is_open())
{
- PRINTF("file not found : %s\n", nsl);
+ PRINTF("file not found : %s\n"_fmt, nsl);
rv = false;
continue;
}
- PRINTF("\rLoading NPCs [%d]: %-54s", 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;
@@ -1698,7 +1713,7 @@ bool do_init_npc(void)
if (!extract(zline, record<'|', 3>(&w1, &w2, &w3, &w4x)) || !w1 || !w2 || !w3)
{
- FPRINTF(stderr, "%s:%d: Broken script line: %s\n", nsl, lines, zline);
+ FPRINTF(stderr, "%s:%d: Broken script line: %s\n"_fmt, nsl, lines, zline);
rv = false;
continue;
}
@@ -1708,7 +1723,7 @@ bool do_init_npc(void)
}
assert(bool(w4x) == bool(w4z));
- if (w1 != "-" && w1 != "function")
+ if (w1 != "-"_s && w1 != "function"_s)
{
auto comma = std::find(w1.begin(), w1.end(), ',');
MapName mapname = stringish<MapName>(w1.xislice_h(comma));
@@ -1716,24 +1731,24 @@ bool do_init_npc(void)
if (m == nullptr)
{
// "mapname" is not assigned to this server
- FPRINTF(stderr, "%s:%d: Map not found: %s\n", nsl, lines, mapname);
+ FPRINTF(stderr, "%s:%d: Map not found: %s\n"_fmt, nsl, lines, mapname);
rv = false;
continue;
}
}
- if (w2 == "warp")
+ if (w2 == "warp"_s)
{
NpcName npcname = stringish<NpcName>(w3);
npc_parse_warp(w1, w2, npcname, w4z);
}
- else if (w2 == "shop")
+ else if (w2 == "shop"_s)
{
NpcName npcname = stringish<NpcName>(w3);
npc_parse_shop(w1, w2, npcname, w4z);
}
- else if (w2 == "script")
+ else if (w2 == "script"_s)
{
- if (w1 == "function")
+ if (w1 == "function"_s)
{
npc_parse_function(w1, w2, w3, w4z,
w4x, fp, &lines);
@@ -1745,30 +1760,31 @@ bool do_init_npc(void)
w4x, fp, &lines);
}
}
- else if (w2 == "monster")
+ else if (w2 == "monster"_s)
{
MobName mobname = stringish<MobName>(w3);
npc_parse_mob(w1, w2, mobname, w4z);
}
- else if (w2 == "mapflag")
+ else if (w2 == "mapflag"_s)
{
npc_parse_mapflag(w1, w2, w3, w4z);
}
else
{
- PRINTF("odd script line: %s\n", zline);
+ PRINTF("odd script line: %s\n"_fmt, zline);
script_errors++;
}
}
fflush(stdout);
}
- PRINTF("\rNPCs Loaded: %d [Warps:%d Shops:%d Scripts:%d Mobs:%d] %20s\n",
- npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, "");
+ PRINTF("\rNPCs Loaded: %d [Warps:%d Shops:%d Scripts:%d Mobs:%d] %20s\n"_fmt,
+ unwrap<BlockId>(npc_id) - unwrap<BlockId>(START_NPC_NUM), npc_warp, npc_shop, npc_script, npc_mob, ""_s);
if (script_errors)
{
- PRINTF("Cowardly refusing to continue after %d errors\n", script_errors);
+ PRINTF("Cowardly refusing to continue after %d errors\n"_fmt, script_errors);
rv = false;
}
return rv;
}
+} // namespace tmwa
diff --git a/src/map/npc.hpp b/src/map/npc.hpp
index eb9a5eb..33dd378 100644
--- a/src/map/npc.hpp
+++ b/src/map/npc.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_NPC_HPP
-#define TMWA_MAP_NPC_HPP
+#pragma once
// npc.hpp - Noncombatants.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,47 +20,55 @@
// 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>
+#include <cstdint>
-# include "../strings/fwd.hpp"
+#include "../strings/fwd.hpp"
-# include "../mmo/timer.t.hpp"
+#include "../generic/fwd.hpp"
-# include "map.hpp"
+#include "../net/timer.t.hpp"
-constexpr int START_NPC_NUM = 110000000;
+#include "../proto2/fwd.hpp"
-constexpr int WARP_CLASS = 45;
-constexpr int WARP_DEBUG_CLASS = 722;
-constexpr int INVISIBLE_CLASS = 32767;
+#include "map.hpp"
+
+
+namespace tmwa
+{
+constexpr BlockId START_NPC_NUM = wrap<BlockId>(110000000);
+
+// TODO make these species, see npc_class in npc_data
+constexpr Species WARP_CLASS = wrap<Species>(45);
+constexpr Species FAKE_NPC_CLASS = wrap<Species>(127);
+constexpr Species WARP_DEBUG_CLASS = wrap<Species>(722);
+constexpr Species INVISIBLE_CLASS = wrap<Species>(32767);
int npc_event_dequeue(dumb_ptr<map_session_data> sd);
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_buylist(dumb_ptr<map_session_data>, int, const uint16_t *);
-int npc_selllist(dumb_ptr<map_session_data>, int, const uint16_t *);
+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>, const std::vector<Packet_Repeat<0x00c8>>&);
+int npc_selllist(dumb_ptr<map_session_data>, const std::vector<Packet_Repeat<0x00c9>>&);
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
*
- * \param message The message to speak. If message is NULL, the NPC will not do anything at all.
+ * \param message The message to speak. If message is nullptr, the NPC will not do anything at all.
*/
dumb_ptr<npc_data> npc_spawn_text(map_local *m, int x, int y,
- int class_, NpcName name, AString message);
+ Species class_, NpcName name, AString message);
/**
* Uninstalls and frees an NPC
@@ -73,17 +80,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);
@@ -91,5 +98,4 @@ void npc_timerevent_stop(dumb_ptr<npc_data_script> nd);
interval_t npc_gettimerevent_tick(dumb_ptr<npc_data_script> nd);
void npc_settimerevent_tick(dumb_ptr<npc_data_script> nd, interval_t newtimer);
int npc_delete(dumb_ptr<npc_data> nd);
-
-#endif // TMWA_MAP_NPC_HPP
+} // namespace tmwa
diff --git a/src/map/party.cpp b/src/map/party.cpp
index 75c54cf..8713c60 100644
--- a/src/map/party.cpp
+++ b/src/map/party.cpp
@@ -21,8 +21,6 @@
// 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 <cstring>
-
#include "../compat/nullpo.hpp"
#include "../strings/xstring.hpp"
@@ -31,23 +29,27 @@
#include "../io/cxxstdio.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../net/timer.hpp"
+
+#include "../mmo/ids.hpp"
+#include "../mmo/mmo.hpp"
#include "battle.hpp"
#include "clif.hpp"
#include "intif.hpp"
#include "map.hpp"
#include "pc.hpp"
-#include "tmw.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
// 座標やHP送信の間隔
-constexpr interval_t PARTY_SEND_XYHP_INVERVAL = std::chrono::seconds(1);
+constexpr interval_t PARTY_SEND_XYHP_INVERVAL = 1_s;
static
-Map<int, struct party> party_db;
+Map<PartyId, PartyMost> party_db;
static
void party_check_conflict(dumb_ptr<map_session_data> sd);
@@ -64,31 +66,40 @@ void do_init_party(void)
}
// 検索
-struct party *party_search(int party_id)
+PartyPair party_search(PartyId party_id)
{
- return party_db.search(party_id);
+ PartyPair p;
+ p.party_most = party_db.search(party_id);
+ if (p)
+ p.party_id = party_id;
+ return p;
}
static
-void party_searchname_sub(struct party *p, PartyName str, struct party **dst)
+void party_searchname_sub(PartyPair p, PartyName str, PartyPair *dst)
{
if (p->name == str)
*dst = p;
}
// パーティ名検索
-struct party *party_searchname(PartyName str)
+PartyPair party_searchname(PartyName str)
{
- struct party *p = NULL;
+ PartyPair p;
for (auto& pair : party_db)
- party_searchname_sub(&pair.second, str, &p);
+ {
+ PartyPair tmp;
+ tmp.party_id = pair.first;
+ tmp.party_most = &pair.second;
+ party_searchname_sub(tmp, str, &p);
+ }
return p;
}
/* Process a party creation request. */
int party_create(dumb_ptr<map_session_data> sd, PartyName name)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
name = stringish<PartyName>(name.strip());
@@ -97,7 +108,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 +117,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);
@@ -118,15 +129,15 @@ void party_created(int account_id, int fail, int party_id, PartyName name)
{
sd->status.party_id = party_id;
- struct party *p = party_db.search(party_id);
- if (p != NULL)
+ PartyPair p = party_search(party_id);
+ if (p)
{
- PRINTF("party_created(): ID already exists!\n");
+ PRINTF("party_created(): ID already exists!\n"_fmt);
exit(1);
}
- p = party_db.init(party_id);
- p->party_id = party_id;
+ p.party_most = party_db.init(party_id);
+ p.party_id = party_id;
p->name = name;
/* The party was created successfully. */
@@ -138,16 +149,16 @@ 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);
}
// 所属キャラの確認
static
-int party_check_member(struct party *p)
+int party_check_member(PartyPair p)
{
- nullpo_ret(p);
+ nullpo_retz(p);
for (io::FD i : iter_fds())
{
@@ -157,7 +168,7 @@ int party_check_member(struct party *p)
map_session_data *sd = static_cast<map_session_data *>(s->session_data.get());
if (sd && sd->state.auth)
{
- if (sd->status.party_id == p->party_id)
+ if (sd->status.party_id == p.party_id)
{
int j, f = 1;
for (j = 0; j < MAX_PARTY; j++)
@@ -169,15 +180,15 @@ int party_check_member(struct party *p)
else
{
// I can prove it was already zeroed
- // p->member[j].sd = NULL; // 同垢別キャラだった
+ // p->member[j].sd = nullptr; // 同垢別キャラだった
}
}
}
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",
+ PRINTF("party: check_member %d[%s] is not member\n"_fmt,
sd->status_key.account_id, sd->status_key.name);
}
}
@@ -187,7 +198,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,36 +209,36 @@ 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;
}
// 情報所得
-int party_recv_info(const struct party *sp)
+int party_recv_info(const PartyPair sp)
{
int i;
- nullpo_ret(sp);
+ nullpo_retz(sp);
- struct party *p = party_db.search(sp->party_id);
- if (p == NULL)
+ PartyPair p = party_search(sp.party_id);
+ if (!p)
{
- p = party_db.init(sp->party_id);
+ p.party_most = party_db.init(sp.party_id);
// 最初のロードなのでユーザーのチェックを行う
- *p = *sp;
+ *p.party_most = *sp.party_most;
party_check_member(p);
}
else
- *p = *sp;
+ *p.party_most = *sp.party_most;
for (i = 0; i < MAX_PARTY; i++)
{ // sdの設定
- dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id);
- p->member[i].sd = (sd != NULL
- && sd->status.party_id == p->party_id) ? sd.operator->() : NULL;
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id));
+ p->member[i].sd = (sd != nullptr
+ && sd->status.party_id == p.party_id) ? sd.operator->() : nullptr;
}
clif_party_info(p, nullptr);
@@ -236,7 +247,7 @@ int party_recv_info(const struct party *sp)
{ // 設定情報の送信
// dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id);
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd);
- if (sd != NULL && sd->party_sended == 0)
+ if (sd != nullptr && sd->party_sended == 0)
{
clif_party_option(p, sd, 0x100);
sd->party_sended = 1;
@@ -247,14 +258,14 @@ 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);
- struct party *p = party_search(sd->status.party_id);
+ dumb_ptr<map_session_data> tsd = map_id2sd(account_to_block(account_id));
+ PartyPair p = party_search(sd->status.party_id);
int i;
int full = 1; /* Indicates whether or not there's room for one more. */
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (!tsd || !p || !tsd->sess)
return 0;
@@ -271,7 +282,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,9 +322,9 @@ 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);
+ nullpo_retz(sd);
/* There is no pending invitation. */
if (!sd->party_invite || !sd->party_invite_account)
@@ -333,48 +344,48 @@ int party_reply_invite(dumb_ptr<map_session_data> sd, int account_id, int flag)
else
{
/* This is the player who sent the invitation. */
- dumb_ptr<map_session_data> tsd = NULL;
+ dumb_ptr<map_session_data> tsd = nullptr;
- 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;
- struct party *p = party_search(party_id);
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)), sd2;
+ PartyPair p = party_search(party_id);
- if (sd == NULL)
+ if (sd == nullptr)
{
if (flag == 0)
{
if (battle_config.error_log)
- PRINTF("party: member added error %d is not online\n",
+ PRINTF("party: member added error %d is not online\n"_fmt,
account_id);
intif_party_leave(party_id, account_id); // キャラ側に登録できなかったため脱退要求を出す
}
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)
+ if (!p)
{
- PRINTF("party_member_added: party %d not found.\n", party_id);
+ PRINTF("party_member_added: party %d not found.\n"_fmt, party_id);
intif_party_leave(party_id, account_id);
return 0;
}
if (flag == 1)
{ // 失敗
- if (sd2 != NULL)
+ if (sd2 != nullptr)
clif_party_inviteack(sd2, sd->status_key.name, 0);
return 0;
}
@@ -383,7 +394,7 @@ int party_member_added(int party_id, int account_id, int flag)
sd->party_sended = 0;
sd->status.party_id = party_id;
- if (sd2 != NULL)
+ if (sd2 != nullptr)
clif_party_inviteack(sd2, sd->status_key.name, 2);
// いちおう競合確認
@@ -395,28 +406,30 @@ 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;
+ PartyPair p;
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if ((p = party_search(sd->status.party_id)) == NULL)
+ if (!(p = party_search(sd->status.party_id)))
return 0;
for (i = 0; i < MAX_PARTY; i++)
{ // リーダーかどうかチェック
if (p->member[i].account_id == sd->status_key.account_id)
+ {
if (p->member[i].leader == 0)
return 0;
+ }
}
for (i = 0; i < MAX_PARTY; i++)
{ // 所属しているか調べる
if (p->member[i].account_id == account_id)
{
- intif_party_leave(p->party_id, account_id);
+ intif_party_leave(p.party_id, account_id);
return 0;
}
}
@@ -426,19 +439,19 @@ int party_removemember(dumb_ptr<map_session_data> sd, int account_id)
// パーティ脱退要求
int party_leave(dumb_ptr<map_session_data> sd)
{
- struct party *p;
+ PartyPair p;
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if ((p = party_search(sd->status.party_id)) == NULL)
+ if (!(p = party_search(sd->status.party_id)))
return 0;
for (i = 0; i < MAX_PARTY; i++)
{ // 所属しているか
if (p->member[i].account_id == sd->status_key.account_id)
{
- intif_party_leave(p->party_id, sd->status_key.account_id);
+ intif_party_leave(p.party_id, sd->status_key.account_id);
return 0;
}
}
@@ -446,45 +459,45 @@ 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);
- struct party *p = party_search(party_id);
- if (p != NULL)
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id));
+ PartyPair p = party_search(party_id);
+ if (p)
{
int i;
for (i = 0; i < MAX_PARTY; i++)
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].sd = NULL;
+ p->member[i].account_id = AccountId();
+ p->member[i].sd = nullptr;
}
}
- if (sd != NULL && sd->status.party_id == party_id)
+ if (sd != nullptr && 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;
+ PartyPair p;
int i;
- if ((p = party_search(party_id)) == NULL)
+ if (!(p = party_search(party_id)))
return 0;
for (i = 0; i < MAX_PARTY; i++)
{
- if (p->member[i].sd != NULL)
+ if (p->member[i].sd != nullptr)
{
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;
}
}
@@ -495,12 +508,12 @@ int party_broken(int party_id)
// パーティの設定変更要求
int party_changeoption(dumb_ptr<map_session_data> sd, int exp, int item)
{
- struct party *p;
+ PartyPair p;
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if (sd->status.party_id == 0
- || (p = party_search(sd->status.party_id)) == NULL)
+ if (!sd->status.party_id
+ || !(p = party_search(sd->status.party_id)))
return 0;
intif_party_changeoption(sd->status.party_id, sd->status_key.account_id, exp,
item);
@@ -508,12 +521,12 @@ 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);
- if ((p = party_search(party_id)) == NULL)
+ PartyPair p;
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id));
+ if (!(p = party_search(party_id)))
return 0;
if (!(flag & 0x01))
@@ -525,19 +538,19 @@ 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;
+ PartyPair p;
int i;
- if ((p = party_search(party_id)) == NULL)
+ if (!(p = party_search(party_id)))
return;
for (i = 0; i < MAX_PARTY; i++)
{
- struct party_member *m = &p->member[i];
- if (m == NULL)
+ PartyMember *m = &p->member[i];
+ if (m == nullptr)
{
- PRINTF("party_recv_movemap nullpo?\n");
+ PRINTF("party_recv_movemap nullpo?\n"_fmt);
return;
}
if (m->account_id == account_id)
@@ -551,16 +564,16 @@ void party_recv_movemap(int party_id, int account_id, MapName mapname,
if (i == MAX_PARTY)
{
if (battle_config.error_log)
- PRINTF("party: not found member %d on %d[%s]", account_id,
+ PRINTF("party: not found member %d on %d[%s]"_fmt, account_id,
party_id, p->name);
return;
}
for (i = 0; i < MAX_PARTY; i++)
{ // sd再設定
- dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id);
- p->member[i].sd = (sd != NULL
- && sd->status.party_id == p->party_id) ? sd.operator->() : NULL;
+ dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id));
+ p->member[i].sd = (sd != nullptr
+ && sd->status.party_id == p.party_id) ? sd.operator->() : nullptr;
}
party_send_xy_clear(p); // 座標再通知要請
@@ -571,11 +584,11 @@ void party_recv_movemap(int party_id, int account_id, MapName mapname,
// パーティメンバの移動
int party_send_movemap(dumb_ptr<map_session_data> sd)
{
- struct party *p;
+ PartyPair p;
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if (sd->status.party_id == 0)
+ if (!sd->status.party_id)
return 0;
intif_party_changemap(sd, 1);
@@ -586,10 +599,10 @@ int party_send_movemap(dumb_ptr<map_session_data> sd)
party_check_conflict(sd);
// あるならパーティ情報送信
- if ((p = party_search(sd->status.party_id)) != NULL)
+ if ((p = party_search(sd->status.party_id)))
{
party_check_member(p); // 所属を確認する
- if (sd->status.party_id == p->party_id)
+ if (sd->status.party_id == p.party_id)
{
clif_party_info(p, sd->sess);
clif_party_option(p, sd, 0x100);
@@ -603,20 +616,20 @@ int party_send_movemap(dumb_ptr<map_session_data> sd)
// パーティメンバのログアウト
int party_send_logout(dumb_ptr<map_session_data> sd)
{
- struct party *p;
+ PartyPair p;
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if (sd->status.party_id > 0)
+ if (sd->status.party_id)
intif_party_changemap(sd, 0);
// sdが無効になるのでパーティ情報から削除
- if ((p = party_search(sd->status.party_id)) != NULL)
+ if ((p = party_search(sd->status.party_id)))
{
int i;
for (i = 0; i < MAX_PARTY; i++)
if (dumb_ptr<map_session_data>(p->member[i].sd) == sd)
- p->member[i].sd = NULL;
+ p->member[i].sd = nullptr;
}
return 0;
@@ -625,16 +638,16 @@ 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)
+ PartyPair p;
+ if (!(p = party_search(party_id)))
return;
clif_party_message(p, account_id, mes);
}
@@ -650,7 +663,7 @@ void party_check_conflict(dumb_ptr<map_session_data> sd)
// 位置やHP通知用
static
-void party_send_xyhp_timer_sub(struct party *p)
+void party_send_xyhp_timer_sub(PartyPair p)
{
int i;
@@ -659,7 +672,7 @@ void party_send_xyhp_timer_sub(struct party *p)
for (i = 0; i < MAX_PARTY; i++)
{
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd);
- if (sd != NULL)
+ if (sd != nullptr)
{
// 座標通知
if (sd->party_x != sd->bl_x || sd->party_y != sd->bl_y)
@@ -683,11 +696,16 @@ void party_send_xyhp_timer_sub(struct party *p)
void party_send_xyhp_timer(TimerData *, tick_t)
{
for (auto& pair : party_db)
- party_send_xyhp_timer_sub(&pair.second);
+ {
+ PartyPair tmp;
+ tmp.party_id = pair.first;
+ tmp.party_most = &pair.second;
+ party_send_xyhp_timer_sub(tmp);
+ }
}
// 位置通知クリア
-void party_send_xy_clear(struct party *p)
+void party_send_xy_clear(PartyPair p)
{
int i;
@@ -696,7 +714,7 @@ void party_send_xy_clear(struct party *p)
for (i = 0; i < MAX_PARTY; i++)
{
dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd);
- if (sd != NULL)
+ if (sd != nullptr)
{
sd->party_x = -1;
sd->party_y = -1;
@@ -706,7 +724,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;
@@ -721,17 +739,17 @@ void party_send_hp_check(dumb_ptr<block_list> bl, int party_id, int *flag)
}
// 経験値公平分配
-int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp)
+int party_exp_share(PartyPair p, map_local *mapid, int base_exp, int job_exp)
{
dumb_ptr<map_session_data> sd;
int i, c;
- nullpo_ret(p);
+ nullpo_retz(p);
for (i = c = 0; i < MAX_PARTY; i++)
{
sd = dumb_ptr<map_session_data>(p->member[i].sd);
- if (sd != NULL && sd->bl_m == mapid)
+ if (sd != nullptr && sd->bl_m == mapid)
c++;
}
if (c == 0)
@@ -739,7 +757,7 @@ int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp
for (i = 0; i < MAX_PARTY; i++)
{
sd = dumb_ptr<map_session_data>(p->member[i].sd);
- if (sd != NULL && sd->bl_m == mapid)
+ if (sd != nullptr && sd->bl_m == mapid)
pc_gainexp_reason(sd, base_exp / c + 1, job_exp / c + 1,
PC_GAINEXP_REASON::SHARING);
}
@@ -752,7 +770,7 @@ int party_exp_share(struct party *p, map_local *mapid, int base_exp, int job_exp
void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func,
dumb_ptr<map_session_data> sd, int type)
{
- struct party *p;
+ PartyPair p;
int i;
int x0, y0, x1, y1;
dumb_ptr<map_session_data> list[MAX_PARTY];
@@ -760,7 +778,7 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func,
nullpo_retv(sd);
- if ((p = party_search(sd->status.party_id)) == NULL)
+ if (!(p = party_search(sd->status.party_id)))
return;
x0 = sd->bl_x - AREA_SIZE;
@@ -770,8 +788,8 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func,
for (i = 0; i < MAX_PARTY; i++)
{
- struct party_member *m = &p->member[i];
- if (m->sd != NULL)
+ PartyMember *m = &p->member[i];
+ if (m->sd != nullptr)
{
if (sd->bl_m != m->sd->bl_m)
continue;
@@ -789,3 +807,4 @@ void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func,
if (list[i]->bl_prev) // 有効かどうかチェック
func(list[i]);
}
+} // namespace tmwa
diff --git a/src/map/party.hpp b/src/map/party.hpp
index 007de6b..01a8125 100644
--- a/src/map/party.hpp
+++ b/src/map/party.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_PARTY_HPP
-#define TMWA_MAP_PARTY_HPP
+#pragma once
// party.hpp - Small groups of temporary allies.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,38 +20,39 @@
// 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>
+#include <functional>
-# include "../strings/fwd.hpp"
+#include "../strings/fwd.hpp"
-# include "map.hpp"
+#include "../generic/fwd.hpp"
-struct party;
-struct map_session_data;
-struct block_list;
+#include "../mmo/fwd.hpp"
+
+namespace tmwa
+{
void do_init_party(void);
-struct party *party_search(int party_id);
-struct party *party_searchname(PartyName str);
+PartyPair party_search(PartyId party_id);
+PartyPair 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_info(const struct party *sp);
-void party_recv_movemap(int party_id, int account_id, MapName map,
+int party_recv_noinfo(PartyId party_id);
+int party_recv_info(const PartyPair sp);
+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,14 +60,13 @@ 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_xy_clear(PartyPair p);
+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);
+int party_exp_share(PartyPair p, map_local *map, int base_exp, int job_exp);
void party_foreachsamemap(std::function<void(dumb_ptr<block_list>)> func,
dumb_ptr<map_session_data> sd, int type);
-
-#endif // TMWA_MAP_PARTY_HPP
+} // namespace tmwa
diff --git a/src/map/path.cpp b/src/map/path.cpp
index f0204a4..6950797 100644
--- a/src/map/path.cpp
+++ b/src/map/path.cpp
@@ -22,19 +22,23 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cassert>
+#include <cstddef>
+#include <cstdlib>
#include "../compat/nullpo.hpp"
-#include "../generic/random.hpp"
+#include "../strings/literal.hpp"
#include "../io/cxxstdio.hpp"
-#include "battle.hpp"
+#include "clif.t.hpp"
+#include "map.hpp"
#include "../poison.hpp"
-//#define PATH_STANDALONETEST
+namespace tmwa
+{
constexpr int MAX_HEAP = 150;
struct tmp_path
{
@@ -58,9 +62,9 @@ void push_heap_path(int *heap, struct tmp_path *tp, int index)
{
int i, h;
- if (heap == NULL || tp == NULL)
+ if (heap == nullptr || tp == nullptr)
{
- PRINTF("push_heap_path nullpo\n");
+ PRINTF("push_heap_path nullpo\n"_fmt);
return;
}
@@ -90,7 +94,7 @@ void update_heap_path(int *heap, struct tmp_path *tp, int index)
break;
if (h == heap[0])
{
- FPRINTF(stderr, "update_heap_path bug\n");
+ FPRINTF(stderr, "update_heap_path bug\n"_fmt);
exit(1);
}
for (i = (h - 1) / 2;
@@ -144,7 +148,7 @@ int calc_cost(struct tmp_path *p, int x1, int y1)
{
int xd, yd;
- nullpo_ret(p);
+ nullpo_retz(p);
xd = x1 - p->x;
if (xd < 0)
@@ -165,8 +169,8 @@ int add_path(int *heap, struct tmp_path *tp, int x, int y, int dist,
{
int i;
- nullpo_ret(heap);
- nullpo_ret(tp);
+ nullpo_retz(heap);
+ nullpo_retz(tp);
i = calc_index(x, y);
@@ -210,7 +214,7 @@ int add_path(int *heap, struct tmp_path *tp, int x, int y, int dist,
static
bool can_place(struct map_local *m, int x, int y)
{
- nullpo_ret(m);
+ nullpo_retz(m);
return !bool(read_gatp(m, x, y) & MapCell::UNWALKABLE);
}
@@ -222,7 +226,7 @@ bool can_place(struct map_local *m, int x, int y)
static
int can_move(struct map_local *m, int x0, int y0, int x1, int y1)
{
- nullpo_ret(m);
+ nullpo_retz(m);
if (x0 - x1 < -1 || x0 - x1 > 1 || y0 - y1 < -1 || y0 - y1 > 1)
return 0;
@@ -249,7 +253,7 @@ int path_search(struct walkpath_data *wpd, map_local *m, int x0, int y0, int x1,
int i, rp, x, y;
int dx, dy;
- nullpo_ret(wpd);
+ nullpo_retz(wpd);
assert (m->gat);
map_local *md = m;
@@ -357,3 +361,4 @@ int path_search(struct walkpath_data *wpd, map_local *m, int x0, int y0, int x1,
return -1;
}
}
+} // namespace tmwa
diff --git a/src/map/path.hpp b/src/map/path.hpp
index 47b9814..3619e2e 100644
--- a/src/map/path.hpp
+++ b/src/map/path.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_PATH_HPP
-#define TMWA_MAP_PATH_HPP
+#pragma once
// path.hpp - Pathfinding system.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,10 +20,10 @@
// 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"
+namespace tmwa
+{
int path_search(struct walkpath_data *, map_local *, int, int, int, int, int);
-
-#endif // TMWA_MAP_PATH_HPP
+} // namespace tmwa
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 0256eff..2fa8bb7 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -23,24 +23,28 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cassert>
-#include <cstdlib>
-#include <cstring>
-#include "../compat/alg.hpp"
+#include <algorithm>
+
#include "../compat/fun.hpp"
#include "../compat/nullpo.hpp"
#include "../strings/rstring.hpp"
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
+#include "../strings/literal.hpp"
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/read.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../net/timer.hpp"
+
+#include "../mmo/utils.hpp"
+
+#include "../proto2/char-map.hpp"
#include "atcommand.hpp"
#include "battle.hpp"
@@ -48,9 +52,8 @@
#include "clif.hpp"
#include "intif.hpp"
#include "itemdb.hpp"
-#include "magic.hpp"
+#include "magic-stmt.hpp"
#include "map.hpp"
-#include "mob.hpp"
#include "npc.hpp"
#include "party.hpp"
#include "path.hpp"
@@ -61,9 +64,12 @@
#include "../poison.hpp"
+
+namespace tmwa
+{
// PVP順位計算の間隔
constexpr std::chrono::milliseconds PVP_CALCRANK_INTERVAL =
- std::chrono::seconds(1);
+ 1_s;
//define it here, since the ifdef only occurs in this file
#define USE_ASTRAL_SOUL_SKILL
@@ -86,7 +92,7 @@ constexpr int MAGIC_SKILL_THRESHOLD = 200;
MAP_LOG_PC(sd, "XP %d %d JOB %d %d %d ZENY %d + %d " suffix, \
sd->status.base_level, sd->status.base_exp, \
sd->status.job_level, sd->status.job_exp, sd->status.skill_point, \
- sd->status.zeny, pc_readaccountreg(sd, stringish<VarName>("BankAccount")))
+ sd->status.zeny, pc_readaccountreg(sd, stringish<VarName>("BankAccount"_s)))
#define MAP_LOG_MAGIC(sd, suffix) \
MAP_LOG_PC(sd, "MAGIC %d %d %d %d %d %d EXP %d %d " suffix, \
@@ -96,8 +102,8 @@ constexpr int MAGIC_SKILL_THRESHOLD = 200;
sd->status.skill[SkillID::TMW_MAGIC_TRANSMUTE].lv, \
sd->status.skill[SkillID::TMW_MAGIC_NATURE].lv, \
sd->status.skill[SkillID::TMW_MAGIC_ETHER].lv, \
- pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE")) & 0xffff, \
- (pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE")) >> 24) & 0xff)
+ pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE"_s)) & 0xffff, \
+ (pc_readglobalreg(sd, stringish<VarName>("MAGIC_EXPERIENCE"_s)) >> 24) & 0xff)
static //const
int max_weight_base_0 = 20000;
@@ -116,23 +122,23 @@ int sp_coefficient_0 = 100;
static //const
earray<interval_t, ItemLook, ItemLook::SINGLE_HANDED_COUNT> aspd_base_0 //=
{{
-std::chrono::milliseconds(650),
-std::chrono::milliseconds(700),
-std::chrono::milliseconds(750),
-std::chrono::milliseconds(600),
-std::chrono::milliseconds(2000),
-std::chrono::milliseconds(2000),
-std::chrono::milliseconds(800),
-std::chrono::milliseconds(2000),
-std::chrono::milliseconds(700),
-std::chrono::milliseconds(700),
-std::chrono::milliseconds(650),
-std::chrono::milliseconds(900),
-std::chrono::milliseconds(2000),
-std::chrono::milliseconds(2000),
-std::chrono::milliseconds(2000),
-std::chrono::milliseconds(2000),
-std::chrono::milliseconds(2000),
+650_ms,
+700_ms,
+750_ms,
+600_ms,
+2000_ms,
+2000_ms,
+800_ms,
+2000_ms,
+700_ms,
+700_ms,
+650_ms,
+900_ms,
+2000_ms,
+2000_ms,
+2000_ms,
+2000_ms,
+2000_ms,
}};
static const
int exp_table_0[MAX_LEVEL] =
@@ -248,8 +254,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,20 +272,20 @@ 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,
dumb_ptr<map_session_data> target)
{
- nullpo_ret(src);
+ nullpo_retz(src);
if (src->bl_type != BL::PC)
return 0;
@@ -293,7 +300,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,17 +319,17 @@ 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);
- assert (sd != NULL);
+ assert (sd != nullptr);
assert (sd->bl_type == BL::PC);
}
int pc_setinvincibletimer(dumb_ptr<map_session_data> sd, interval_t val)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->invincible_timer = Timer(gettick() + val,
std::bind(pc_invincible_timer, ph::_1, ph::_2,
@@ -332,7 +339,7 @@ int pc_setinvincibletimer(dumb_ptr<map_session_data> sd, interval_t val)
int pc_delinvincibletimer(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->invincible_timer.cancel();
return 0;
@@ -340,7 +347,7 @@ int pc_delinvincibletimer(dumb_ptr<map_session_data> sd)
int pc_setrestartvalue(dumb_ptr<map_session_data> sd, int type)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
{
if (battle_config.restart_hp_rate < 50)
@@ -380,7 +387,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);
@@ -458,7 +465,7 @@ void pc_makesavestatus(dumb_ptr<map_session_data> sd)
if (sd->bl_m->flag.get(MapFlag::NOSAVE))
{
map_local *m = sd->bl_m;
- if (m->save.map_ == "SavePoint")
+ if (m->save.map_ == "SavePoint"_s)
sd->status.last_point = sd->status.save_point;
else
sd->status.last_point = m->save;
@@ -469,16 +476,21 @@ 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 login_id1, tick_t client_tick, SEX sex)
-{
- nullpo_ret(sd);
-
- sd->bl_id = account_id;
- sd->char_id = char_id;
+int pc_setnewpc(dumb_ptr<map_session_data> sd, AccountId account_id, CharId char_id,
+ int login_id1, uint32_t client_tick, SEX sex)
+{
+ nullpo_retz(sd);
+
+ // 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;
+ (void)client_tick;
sd->sex = sex;
sd->state.auth = 0;
sd->bl_type = BL::PC;
@@ -489,7 +501,7 @@ int pc_setnewpc(dumb_ptr<map_session_data> sd, int account_id, int char_id,
return 0;
}
-EPOS pc_equippoint(dumb_ptr<map_session_data> sd, int n)
+EPOS pc_equippoint(dumb_ptr<map_session_data> sd, IOff0 n)
{
nullpo_retr(EPOS::ZERO, sd);
@@ -504,13 +516,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_retz(sd);
- nullpo_ret(sd);
-
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
- id = sd->status.inventory[i].nameid;
+ ItemNameId id = sd->status.inventory[i].nameid;
sd->inventory_data[i] = itemdb_search(id);
}
return 0;
@@ -519,7 +529,7 @@ int pc_setinventorydata(dumb_ptr<map_session_data> sd)
static
int pc_calcweapontype(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->weapontype1 != ItemLook::NONE
&& sd->weapontype2 == ItemLook::NONE)
@@ -562,14 +572,14 @@ int pc_calcweapontype(dumb_ptr<map_session_data> sd)
static
int pc_setequipindex(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
for (EQUIP i : EQUIPs)
- sd->equip_index_maybe[i] = -1;
+ sd->equip_index_maybe[i] = IOff0::from(-1);
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
- if (sd->status.inventory[i].nameid <= 0)
+ if (!sd->status.inventory[i].nameid)
continue;
if (bool(sd->status.inventory[i].equip))
{
@@ -608,22 +618,22 @@ int pc_setequipindex(dumb_ptr<map_session_data> sd)
}
static
-int pc_isequip(dumb_ptr<map_session_data> sd, int n)
+int pc_isequip(dumb_ptr<map_session_data> sd, IOff0 n)
{
struct item_data *item;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
//転生や養子の場合の元の職業を算出する
- nullpo_ret(sd);
+ nullpo_retz(sd);
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)
+ if (item == nullptr)
return 0;
if (item->sex != SEX::NEUTRAL && sd->status.sex != item->sex)
return 0;
@@ -638,16 +648,16 @@ 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;
+ dumb_ptr<map_session_data> sd = nullptr;
- struct party *p;
+ PartyPair p;
tick_t tick = gettick();
- sd = map_id2sd(id);
- if (sd == NULL)
+ sd = map_id2sd(account_to_block(id));
+ if (sd == nullptr)
return 1;
sd->login_id2 = login_id2;
@@ -662,14 +672,14 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
return 1;
}
- MAP_LOG_STATS(sd, "LOGIN");
- MAP_LOG_XP(sd, "LOGIN");
- MAP_LOG_MAGIC(sd, "LOGIN");
+ MAP_LOG_STATS(sd, "LOGIN"_fmt);
+ MAP_LOG_XP(sd, "LOGIN"_fmt);
+ MAP_LOG_MAGIC(sd, "LOGIN"_fmt);
really_memzero_this(&sd->state);
// 基本的な初期化
sd->state.connect_new = 1;
- sd->bl_prev = sd->bl_next = NULL;
+ sd->bl_prev = sd->bl_next = nullptr;
sd->weapontype1 = sd->weapontype2 = ItemLook::NONE;
sd->speed = DEFAULT_WALK_SPEED;
@@ -682,7 +692,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();
@@ -702,7 +712,7 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
// The above is no longer accurate now that we use <chrono>, but
// I'm still not reverting this.
// -o11c
- sd->cast_tick = tick; // + pc_readglobalreg (sd, "MAGIC_CAST_TICK");
+ sd->cast_tick = tick; // + pc_readglobalreg (sd, "MAGIC_CAST_TICK"_s);
// アカウント変数の送信要求
intif_request_accountreg(sd);
@@ -725,17 +735,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", 0);
+ is_atcommand(sd->sess, sd, "@invisible"_s, GmLevel());
if (bool(old_option & Option::HIDE))
- is_atcommand(sd->sess, sd, "@hide", 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,8 +758,8 @@ 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
- && (p = party_search(sd->status.party_id)) == NULL)
+ if (sd->status.party_id
+ && !(p = party_search(sd->status.party_id)))
party_request_info(sd->status.party_id);
// pvpの設定
@@ -765,19 +775,19 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
map_addchariddb(sd->status_key.char_id, sd->status_key.name);
//スパノビ用死にカウンターのスクリプト変数からの読み出しとsdへのセット
- sd->die_counter = pc_readglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"));
+ sd->die_counter = pc_readglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"_s));
// ステータス初期計算など
pc_calcstatus(sd, 1);
if (pc_isGM(sd))
{
- PRINTF("Connection accepted: character '%s' (account: %d; GM level %d).\n",
- sd->status_key.name, sd->status_key.account_id, pc_isGM(sd));
+ PRINTF("Connection accepted: character '%s' (account: %d; GM level %d).\n"_fmt,
+ sd->status_key.name, sd->status_key.account_id, pc_isGM(sd));
clif_updatestatus(sd, SP::GM);
}
else
- PRINTF("Connection accepted: Character '%s' (account: %d).\n",
+ PRINTF("Connection accepted: Character '%s' (account: %d).\n"_fmt,
sd->status_key.name, sd->status_key.account_id);
sd->auto_ban_info.in_progress = 0;
@@ -796,11 +806,11 @@ int pc_authok(int id, int login_id2, TimeT connect_until_time,
// message of the limited time of the account
if (connect_until_time)
{
- // don't display if it's unlimited or unknow value
- char tmpstr[] = WITH_TIMESTAMP("Your account time limit is: ");
- REPLACE_TIMESTAMP(tmpstr, connect_until_time);
+ timestamp_seconds_buffer buffer;
+ stamp_time(buffer, &connect_until_time);
+ AString tmpstr = STRPRINTF("Your account time limit is: %s"_fmt, buffer);
- clif_wis_message(sd->sess, wisp_server_name, const_(tmpstr));
+ clif_wis_message(sd->sess, wisp_server_name, tmpstr);
}
pc_calcstatus(sd, 1);
@@ -817,7 +827,7 @@ void pc_show_motd(dumb_ptr<map_session_data> sd)
// If you remove the sending of this message,
// the license does not permit you to publicly use this software.
- clif_displaymessage(sd->sess, "This server is Free Software, for details type @source in chat or use the tmwa-source tool");
+ clif_displaymessage(sd->sess, "This server is Free Software, for details type @source in chat or use the tmwa-source tool"_s);
sd->state.seen_motd = true;
io::ReadFile in(motd_txt);
@@ -835,12 +845,12 @@ 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);
- if (sd == NULL)
+ sd = map_id2sd(account_to_block(id));
+ if (sd == nullptr)
return 1;
clif_authfail_fd(sd->sess, 0);
@@ -853,7 +863,7 @@ int pc_calc_skillpoint(dumb_ptr<map_session_data> sd)
{
int i, skill_points = 0;
- nullpo_ret(sd);
+ nullpo_retz(sd);
for (i = 0; i < skill_pool_skills_size; i++) {
int lv = sd->status.skill[skill_pool_skills[i]].lv;
@@ -872,7 +882,7 @@ int pc_checkweighticon(dumb_ptr<map_session_data> sd)
{
int flag = 0;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->weight * 2 >= sd->max_weight
&& !sd->sc_data[StatusChange::SC_FLYING_BACKPACK].timer)
@@ -907,7 +917,7 @@ void pc_set_weapon_look(dumb_ptr<map_session_data> sd)
{
if (sd->attack_spell_override)
clif_changelook(sd, LOOK::WEAPON,
- sd->attack_spell_look_override);
+ unwrap<ItemNameId>(sd->attack_spell_look_override));
else
clif_changelook(sd, LOOK::WEAPON,
static_cast<uint16_t>(sd->status.weapon));
@@ -931,7 +941,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
int aspd_rate, refinedef = 0;
int str, dstr, dex;
- nullpo_ret(sd);
+ nullpo_retz(sd);
interval_t b_speed = sd->speed;
b_max_hp = sd->status.max_hp;
@@ -942,7 +952,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
b_max_weight = sd->max_weight;
earray<int, ATTR, ATTR::COUNT> b_paramb = sd->paramb;
earray<int, ATTR, ATTR::COUNT> b_parame = sd->paramc;
- earray<skill_value, SkillID, MAX_SKILL> b_skill = sd->status.skill;
+ earray<SkillValue, SkillID, MAX_SKILL> b_skill = sd->status.skill;
b_hit = sd->hit;
b_flee = sd->flee;
interval_t b_aspd = sd->aspd;
@@ -964,10 +974,10 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (first & 1)
{
sd->weight = 0;
- for (int i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
- if (sd->status.inventory[i].nameid == 0
- || sd->inventory_data[i] == NULL)
+ if (!sd->status.inventory[i].nameid
+ || sd->inventory_data[i] == nullptr)
continue;
sd->weight +=
sd->inventory_data[i]->weight *
@@ -1035,8 +1045,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
for (EQUIP i : EQUIPs_noarrow)
{
- int index = sd->equip_index_maybe[i];
- if (index < 0)
+ IOff0 index = sd->equip_index_maybe[i];
+ if (!index.ok())
continue;
if (i == EQUIP::WEAPON && sd->equip_index_maybe[EQUIP::SHIELD] == index)
continue;
@@ -1060,7 +1070,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->spellpower_bonus_target < 0)
sd->spellpower_bonus_target =
(sd->spellpower_bonus_target * 256) /
- (min(128 + skill_power(sd, SkillID::TMW_ASTRAL_SOUL), 256));
+ (std::min(128 + skill_power(sd, SkillID::TMW_ASTRAL_SOUL), 256));
#endif
if (sd->spellpower_bonus_target < sd->spellpower_bonus_current)
@@ -1071,8 +1081,8 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
// 装備品によるステータス変化はここで実行
for (EQUIP i : EQUIPs_noarrow)
{
- int index = sd->equip_index_maybe[i];
- if (index < 0)
+ IOff0 index = sd->equip_index_maybe[i];
+ if (!index.ok())
continue;
if (i == EQUIP::WEAPON && sd->equip_index_maybe[EQUIP::SHIELD] == index)
continue;
@@ -1099,11 +1109,11 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
{
argrec_t arg[2] =
{
- {"@slotId", static_cast<int>(i)},
- {"@itemId", sd->inventory_data[index]->nameid},
+ {"@slotId"_s, static_cast<int>(i)},
+ {"@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;
@@ -1113,14 +1123,14 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
//二刀流武器以外
argrec_t arg[2] =
{
- {"@slotId", static_cast<int>(i)},
- {"@itemId", sd->inventory_data[index]->nameid},
+ {"@slotId"_s, static_cast<int>(i)},
+ {"@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);
}
}
@@ -1128,12 +1138,12 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
{
argrec_t arg[2] =
{
- {"@slotId", static_cast<int>(i)},
- {"@itemId", sd->inventory_data[index]->nameid},
+ {"@slotId"_s, static_cast<int>(i)},
+ {"@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);
}
}
@@ -1147,20 +1157,20 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->watk_2 += skill_power(sd, SkillID::TMW_BRAWLING) >> 3; // +25 for 200
}
- int aidx = sd->equip_index_maybe[EQUIP::ARROW];
- if (aidx >= 0)
- { // 矢
- int index = aidx;
+ IOff0 aidx = sd->equip_index_maybe[EQUIP::ARROW];
+ if (aidx.ok())
+ {
+ IOff0 index = aidx;
if (sd->inventory_data[index])
{ //まだ属性が入っていない
argrec_t arg[2] =
{
- {"@slotId", static_cast<int>(EQUIP::ARROW)},
- {"@itemId", sd->inventory_data[index]->nameid},
+ {"@slotId"_s, static_cast<int>(EQUIP::ARROW)},
+ {"@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;
@@ -1189,7 +1199,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->aspd_rate = 20;
for (ATTR attr : ATTRs)
- sd->paramc[attr] = max(0, sd->status.attrs[attr] + sd->paramb[attr] + sd->parame[attr]);
+ sd->paramc[attr] = std::max(0, sd->status.attrs[attr] + sd->paramb[attr] + sd->parame[attr]);
if (sd->status.weapon == ItemLook::BOW
|| sd->status.weapon == ItemLook::_13
@@ -1206,7 +1216,6 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
}
dstr = str / 10;
sd->base_atk += str + dstr * dstr + dex / 5 + sd->paramc[ATTR::LUK] / 5;
-//FPRINTF(stderr, "baseatk = %d = x + %d + %d + %d + %d\n", sd->base_atk, str, dstr*dstr, dex/5, sd->paramc[ATTR::LUK]/5);
sd->matk1 += sd->paramc[ATTR::INT] + (sd->paramc[ATTR::INT] / 5) * (sd->paramc[ATTR::INT] / 5);
sd->matk2 += sd->paramc[ATTR::INT] + (sd->paramc[ATTR::INT] / 7) * (sd->paramc[ATTR::INT] / 7);
if (sd->matk1 < sd->matk2)
@@ -1304,7 +1313,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->attackrange > 2)
{
// [fate] ranged weapon?
- sd->attackrange += min(skill_power(sd, SkillID::AC_OWL) / 60, 3);
+ sd->attackrange += std::min(skill_power(sd, SkillID::AC_OWL) / 60, 3);
sd->hit += skill_power(sd, SkillID::AC_OWL) / 10; // 20 for 200
}
@@ -1385,7 +1394,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
if (sd->speed_rate != 100)
sd->speed = sd->speed * sd->speed_rate / 100;
- sd->speed = std::max(sd->speed, std::chrono::milliseconds(1));
+ sd->speed = std::max(sd->speed, 1_ms);
if (aspd_rate != 100)
sd->aspd = sd->aspd * aspd_rate / 100;
@@ -1395,7 +1404,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
sd->aspd = std::max(sd->aspd, static_cast<interval_t>(battle_config.max_aspd));
sd->amotion = sd->aspd;
sd->dmotion = std::chrono::milliseconds(800 - sd->paramc[ATTR::AGI] * 4);
- sd->dmotion = std::max(sd->dmotion, std::chrono::milliseconds(400));
+ sd->dmotion = std::max(sd->dmotion, 400_ms);
if (sd->status.hp > sd->status.max_hp)
sd->status.hp = sd->status.max_hp;
@@ -1479,7 +1488,7 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first)
*/
int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
switch (type)
{
@@ -1731,7 +1740,7 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val)
break;
default:
if (battle_config.error_log)
- PRINTF("pc_bonus: unknown type %d %d !\n",
+ PRINTF("pc_bonus: unknown type %d %d !\n"_fmt,
type, val);
break;
}
@@ -1744,7 +1753,7 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val)
*/
int pc_bonus2(dumb_ptr<map_session_data> sd, SP type, int type2, int val)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
switch (type)
{
@@ -1776,7 +1785,7 @@ int pc_bonus2(dumb_ptr<map_session_data> sd, SP type, int type2, int val)
#endif
default:
if (battle_config.error_log)
- PRINTF("pc_bonus2: unknown type %d %d %d!\n",
+ PRINTF("pc_bonus2: unknown type %d %d %d!\n"_fmt,
type, type2, val);
break;
}
@@ -1789,12 +1798,12 @@ int pc_bonus2(dumb_ptr<map_session_data> sd, SP type, int type2, int val)
*/
int pc_skill(dumb_ptr<map_session_data> sd, SkillID id, int level, int flag)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (level > MAX_SKILL_LEVEL)
{
if (battle_config.error_log)
- PRINTF("support card skill only!\n");
+ PRINTF("support card skill only!\n"_fmt);
return 0;
}
if (!flag && (sd->status.skill[id].lv || level == 0))
@@ -1817,16 +1826,14 @@ 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;
-
nullpo_retr(ADDITEM::ZERO, sd);
if (itemdb_isequip(nameid))
return ADDITEM::NEW;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid == nameid)
{
@@ -1847,13 +1854,13 @@ ADDITEM pc_checkadditem(dumb_ptr<map_session_data> sd, int nameid, int amount)
*/
int pc_inventoryblank(dumb_ptr<map_session_data> sd)
{
- int i, b;
+ int b = 0;
- nullpo_ret(sd);
+ nullpo_retz(sd);
- for (i = 0, b = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
- if (sd->status.inventory[i].nameid == 0)
+ if (!sd->status.inventory[i].nameid)
b++;
}
@@ -1866,7 +1873,7 @@ int pc_inventoryblank(dumb_ptr<map_session_data> sd)
*/
int pc_payzeny(dumb_ptr<map_session_data> sd, int zeny)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
double z = sd->status.zeny;
if (sd->status.zeny < zeny || z - zeny > MAX_ZENY)
@@ -1883,7 +1890,7 @@ int pc_payzeny(dumb_ptr<map_session_data> sd, int zeny)
*/
int pc_getzeny(dumb_ptr<map_session_data> sd, int zeny)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
double z = sd->status.zeny;
if (z + zeny > MAX_ZENY)
@@ -1901,30 +1908,27 @@ int pc_getzeny(dumb_ptr<map_session_data> sd, int zeny)
* アイテムを探して、インデックスを返す
*------------------------------------------
*/
-int pc_search_inventory(dumb_ptr<map_session_data> sd, int item_id)
+IOff0 pc_search_inventory(dumb_ptr<map_session_data> sd, ItemNameId item_id)
{
- int i;
+ nullpo_retr(IOff0::from(-1), sd);
- nullpo_retr(-1, sd);
-
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
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;
+ return IOff0::from(-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;
- nullpo_ret(player);
+ nullpo_retz(player);
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (player->status.inventory[i].nameid == item_id)
count += player->status.inventory[i].amount;
@@ -1933,14 +1937,14 @@ 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;
-
- nullpo_ret(player);
+ nullpo_retz(player);
- for (i = 0; i < MAX_INVENTORY && count; i++)
+ for (IOff0 i : IOff0::iter())
{
+ if (!count)
+ break;
if (player->status.inventory[i].nameid == item_id)
{
int to_delete = count;
@@ -1964,29 +1968,30 @@ int pc_remove_items(dumb_ptr<map_session_data> player, int item_id, int count)
* アイテム追加。個数のみitem構造体の数字を無視
*------------------------------------------
*/
-PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data,
+PickupFail pc_additem(dumb_ptr<map_session_data> sd, Item *item_data,
int amount)
{
struct item_data *data;
- int i, w;
+ int w;
- MAP_LOG_PC(sd, "PICKUP %d %d", item_data->nameid, amount);
+ MAP_LOG_PC(sd, "PICKUP %d %d"_fmt, item_data->nameid, amount);
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)
return PickupFail::TOO_HEAVY;
- i = MAX_INVENTORY;
+ IOff0 i = IOff0::from(MAX_INVENTORY);
if (!itemdb_isequip2(data))
{
- // 装 備品ではないので、既所有品なら個数のみ変化させる
- for (i = 0; i < MAX_INVENTORY; i++)
+ // TODO see if there's any nicer way to preserve the foreach var
+ for (i = IOff0::from(0); i != IOff0::from(MAX_INVENTORY); ++i)
+ {
if (sd->status.inventory[i].nameid == item_data->nameid)
{
if (sd->status.inventory[i].amount + amount > MAX_AMOUNT)
@@ -1995,12 +2000,12 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data,
clif_additem(sd, i, amount, PickupFail::OKAY);
break;
}
+ }
}
- if (i >= MAX_INVENTORY)
+ if (!i.ok())
{
- // 装 備品か未所有品だったので空き欄へ追加
- i = pc_search_inventory(sd, 0);
- if (i >= 0)
+ i = pc_search_inventory(sd, ItemNameId());
+ if (i.ok())
{
sd->status.inventory[i] = *item_data;
@@ -2024,16 +2029,16 @@ PickupFail pc_additem(dumb_ptr<map_session_data> sd, struct item *item_data,
* アイテムを減らす
*------------------------------------------
*/
-int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type)
+int pc_delitem(dumb_ptr<map_session_data> sd, IOff0 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)
+ || sd->inventory_data[n] == nullptr)
return 1;
sd->status.inventory[n].amount -= amount;
@@ -2042,8 +2047,8 @@ int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type)
{
if (bool(sd->status.inventory[n].equip))
pc_unequipitem(sd, n, CalcStatus::NOW);
- sd->status.inventory[n] = item{};
- sd->inventory_data[n] = NULL;
+ sd->status.inventory[n] = Item{};
+ sd->inventory_data[n] = nullptr;
}
if (!(type & 1))
clif_delitem(sd, n, amount);
@@ -2057,14 +2062,14 @@ int pc_delitem(dumb_ptr<map_session_data> sd, int n, int amount, int type)
* アイテムを落す
*------------------------------------------
*/
-int pc_dropitem(dumb_ptr<map_session_data> sd, int n, int amount)
+int pc_dropitem(dumb_ptr<map_session_data> sd, IOff0 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)
+ if (!n.ok())
return 0;
if (amount <= 0)
@@ -2072,13 +2077,13 @@ 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,
- NULL, NULL, NULL);
+ nullptr, nullptr, nullptr);
pc_delitem(sd, n, amount, 0);
return 0;
@@ -2090,9 +2095,9 @@ 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);
+ PartyPair p = party_search(self->status.party_id);
/* From ourselves or from no-one? */
if (!self || self->bl_id == other_id || !other_id)
@@ -2133,19 +2138,19 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem)
tick_t tick = gettick();
int can_take;
- nullpo_ret(sd);
- nullpo_ret(fitem);
+ nullpo_retz(sd);
+ nullpo_retz(fitem);
/* Sometimes the owners reported to us are buggy: */
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);
@@ -2167,7 +2172,7 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem)
PickupFail flag = pc_additem(sd, &fitem->item_data, fitem->item_data.amount);
if (flag != PickupFail::OKAY)
// 重量overで取得失敗
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
else
{
// 取得成功
@@ -2180,22 +2185,22 @@ int pc_takeitem(dumb_ptr<map_session_data> sd, dumb_ptr<flooritem_data> fitem)
}
/* Otherwise, we can't pick up */
- clif_additem(sd, 0, 0, PickupFail::DROP_STEAL);
+ clif_additem(sd, IOff0::from(0), 0, PickupFail::DROP_STEAL);
return 0;
}
static
-int pc_isUseitem(dumb_ptr<map_session_data> sd, int n)
+int pc_isUseitem(dumb_ptr<map_session_data> sd, IOff0 n)
{
struct item_data *item;
- int nameid;
+ ItemNameId nameid;
- nullpo_ret(sd);
+ nullpo_retz(sd);
item = sd->inventory_data[n];
nameid = sd->status.inventory[n].nameid;
- if (item == NULL)
+ if (item == nullptr)
return 0;
if (itemdb_type(nameid) != ItemType::USE)
return 0;
@@ -2212,16 +2217,16 @@ int pc_isUseitem(dumb_ptr<map_session_data> sd, int n)
* アイテムを使う
*------------------------------------------
*/
-int pc_useitem(dumb_ptr<map_session_data> sd, int n)
+int pc_useitem(dumb_ptr<map_session_data> sd, IOff0 n)
{
int amount;
nullpo_retr(1, sd);
- if (n >= 0 && n < MAX_INVENTORY && sd->inventory_data[n])
+ if (n.ok() && 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))
{
@@ -2233,7 +2238,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;
@@ -2251,14 +2256,14 @@ int pc_setpos(dumb_ptr<map_session_data> sd,
{
MapName mapname_;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->trade_partner) // 取引を中断する
trade_tradecancel(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); // 詠唱中断
@@ -2314,7 +2319,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd,
if (x || y)
{
if (battle_config.error_log)
- PRINTF("stacked (%d,%d)\n", x, y);
+ PRINTF("stacked (%d,%d)\n"_fmt, x, y);
}
do
{
@@ -2324,7 +2329,7 @@ int pc_setpos(dumb_ptr<map_session_data> sd,
while (bool(read_gatp(m, x, y) & MapCell::UNWALKABLE));
}
- if (sd->mapname_ && sd->bl_prev != NULL)
+ if (sd->mapname_ && sd->bl_prev != nullptr)
{
clif_clearchar(sd, clrtype);
map_delblock(sd);
@@ -2355,7 +2360,7 @@ int pc_randomwarp(dumb_ptr<map_session_data> sd, BeingRemoveWhy type)
{
int x, y, i = 0;
- nullpo_ret(sd);
+ nullpo_retz(sd);
map_local *m = sd->bl_m;
@@ -2385,7 +2390,7 @@ int pc_can_reach(dumb_ptr<map_session_data> sd, int x, int y)
{
struct walkpath_data wpd;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->bl_x == x && sd->bl_y == y) // 同じマス
return 1;
@@ -2422,14 +2427,14 @@ 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;
int x, y, dx, dy;
sd = map_id2sd(id);
- if (sd == NULL)
+ if (sd == nullptr)
return;
if (sd->walkpath.path_pos >= sd->walkpath.path_len
@@ -2497,10 +2502,10 @@ 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)
+ PartyPair p = party_search(sd->status.party_id);
+ if (p)
{
int p_flag = 0;
map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &p_flag),
@@ -2517,14 +2522,14 @@ 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())
{
i = i / 2;
if (sd->walkpath.path_half == 0)
- i = std::max(i, std::chrono::milliseconds(1));
+ i = std::max(i, 1_ms);
sd->walktimer = Timer(tick + i,
std::bind(pc_walk, ph::_1, ph::_2,
@@ -2570,7 +2575,7 @@ int pc_walktoxy_sub(dumb_ptr<map_session_data> sd)
int pc_walktoxy(dumb_ptr<map_session_data> sd, int x, int y)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->to_x = x;
sd->to_y = y;
@@ -2598,7 +2603,7 @@ int pc_walktoxy(dumb_ptr<map_session_data> sd, int x, int y)
*/
int pc_stop_walking(dumb_ptr<map_session_data> sd, int type)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->walktimer.cancel();
@@ -2623,7 +2628,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();
}
/*==========================================
@@ -2637,7 +2642,7 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y)
struct walkpath_data wpd;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (path_search(&wpd, sd->bl_m, sd->bl_x, sd->bl_y, dst_x, dst_y, 0))
return 1;
@@ -2671,10 +2676,10 @@ 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)
+ PartyPair p = party_search(sd->status.party_id);
+ if (p)
{
int flag = 0;
map_foreachinmovearea(std::bind(party_send_hp_check, ph::_1, sd->status.party_id, &flag),
@@ -2701,7 +2706,7 @@ int pc_movepos(dumb_ptr<map_session_data> sd, int dst_x, int dst_y)
*/
int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id)
{
- if (sd == NULL)
+ if (sd == nullptr)
return 0;
return sd->status.skill[skill_id].lv;
@@ -2711,9 +2716,9 @@ int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id)
* 装 備品のチェック
*------------------------------------------
*/
-int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos)
+IOff0 pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos)
{
- nullpo_retr(-1, sd);
+ nullpo_retr(IOff0::from(-1), sd);
for (EQUIP i : EQUIPs)
{
@@ -2721,7 +2726,7 @@ int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos)
return sd->equip_index_maybe[i];
}
- return -1;
+ return IOff0::from(-1);
}
/*==========================================
@@ -2729,7 +2734,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;
@@ -2737,14 +2742,14 @@ void pc_attack_timer(TimerData *, tick_t tick, int id)
int dist, range;
sd = map_id2sd(id);
- if (sd == NULL)
+ if (sd == nullptr)
return;
- if (sd->bl_prev == NULL)
+ if (sd->bl_prev == nullptr)
return;
bl = map_id2bl(sd->attacktarget);
- if (bl == NULL || bl->bl_prev == NULL)
+ if (bl == nullptr || bl->bl_prev == nullptr)
return;
if (bl->bl_type == BL::PC && pc_isdead(bl->is_player()))
@@ -2760,7 +2765,7 @@ void pc_attack_timer(TimerData *, tick_t tick, int id)
return;
Option *opt = battle_get_option(bl);
- if (opt != NULL && bool(*opt & Option::REAL_ANY_HIDE))
+ if (opt != nullptr && bool(*opt & Option::REAL_ANY_HIDE))
return;
if (!battle_config.skill_delay_attack_enable)
@@ -2777,7 +2782,7 @@ void pc_attack_timer(TimerData *, tick_t tick, int id)
interval_t attack_spell_delay = sd->attack_spell_delay;
if (sd->attack_spell_override // [Fate] If we have an active attack spell, use that
- && spell_attack(id, sd->attacktarget))
+ && magic::spell_attack(id, sd->attacktarget))
{
// Return if the spell succeeded. If the spell had disspiated, spell_attack() may fail.
sd->attackabletime = tick + attack_spell_delay;
@@ -2836,19 +2841,19 @@ 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;
- nullpo_ret(sd);
+ nullpo_retz(sd);
bl = map_id2bl(target_id);
- if (bl == NULL)
+ if (bl == nullptr)
return 1;
if (bl->bl_type == BL::NPC)
{ // monster npcs [Valaris]
- npc_click(sd, RFIFOL(sd->sess, 2));
+ npc_click(sd, target_id);
return 0;
}
@@ -2860,7 +2865,7 @@ int pc_attack(dumb_ptr<map_session_data> sd, int target_id, int type)
sd->state.attack_continue = type;
interval_t d = sd->attackabletime - gettick();
- if (d > interval_t::zero() && d < std::chrono::seconds(2))
+ if (d > interval_t::zero() && d < 2_s)
{ // 攻撃delay中
sd->attacktimer = Timer(sd->attackabletime,
std::bind(pc_attack_timer, ph::_1, ph::_2,
@@ -2881,11 +2886,11 @@ int pc_attack(dumb_ptr<map_session_data> sd, int target_id, int type)
*/
int pc_stopattack(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->attacktimer.cancel();
- sd->attacktarget = 0;
+ sd->attacktarget = BlockId();
sd->state.attack_continue = 0;
return 0;
@@ -2896,7 +2901,7 @@ int pc_checkbaselevelup(dumb_ptr<map_session_data> sd)
{
int next = pc_nextbaseexp(sd);
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.base_exp >= next && next > 0)
{
@@ -2915,7 +2920,7 @@ int pc_checkbaselevelup(dumb_ptr<map_session_data> sd)
//レベルアップしたのでパーティー情報を更新する
//(公平範囲チェック)
party_send_movemap(sd);
- MAP_LOG_XP(sd, "LEVELUP");
+ MAP_LOG_XP(sd, "LEVELUP"_fmt);
return 1;
}
@@ -2937,8 +2942,7 @@ int pc_skillpt_potential(dumb_ptr<map_session_data> sd)
{
int potential = 0;
- for (SkillID skill_id = SkillID(); skill_id < MAX_SKILL;
- skill_id = SkillID(uint16_t(skill_id) + 1))
+ for (SkillID skill_id : erange(SkillID(), MAX_SKILL))
if (sd->status.skill[skill_id].lv
&& sd->status.skill[skill_id].lv < skill_db[skill_id].max_raise)
potential += RAISE_COST(skill_db[skill_id].max_raise)
@@ -2952,7 +2956,7 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd)
{
int next = pc_nextjobexp(sd);
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.job_exp >= next && next > 0)
{
@@ -2971,7 +2975,7 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd)
clif_updatestatus(sd, SP::SKILLPOINT);
pc_calcstatus(sd, 0);
- MAP_LOG_PC(sd, "SKILLPOINTS-UP %d", sd->status.skill_point);
+ MAP_LOG_PC(sd, "SKILLPOINTS-UP %d"_fmt, sd->status.skill_point);
if (sd->status.job_level < 250
&& sd->status.job_level < sd->status.base_level * 2)
@@ -2987,21 +2991,21 @@ int pc_checkjoblevelup(dumb_ptr<map_session_data> sd)
int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
PC_GAINEXP_REASON reason)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if (sd->bl_prev == NULL || pc_isdead(sd))
+ if (sd->bl_prev == nullptr || pc_isdead(sd))
return 0;
- earray<const char *, PC_GAINEXP_REASON, PC_GAINEXP_REASON::COUNT> reasons //=
+ earray<LString, PC_GAINEXP_REASON, PC_GAINEXP_REASON::COUNT> reasons //=
{{
- "KILLXP",
- "HEALXP",
- "SCRIPTXP",
- "SHAREXP",
+ "KILLXP"_s,
+ "HEALXP"_s,
+ "SCRIPTXP"_s,
+ "SHAREXP"_s,
/* Insert new types here */
- "UNKNOWNXP"
+ "UNKNOWNXP"_s
}};
- MAP_LOG_PC(sd, "GAINXP %d %d %s", base_exp, job_exp, reasons[reason]);
+ MAP_LOG_PC(sd, "GAINXP %d %d %s"_fmt, base_exp, job_exp, reasons[reason]);
if (!battle_config.multi_level_up && pc_nextbaseafter(sd))
{
@@ -3029,7 +3033,8 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
if (sd->status.base_exp < 0)
sd->status.base_exp = 0;
- while (pc_checkbaselevelup(sd));
+ while (pc_checkbaselevelup(sd))
+ {}
clif_updatestatus(sd, SP::BASEEXP);
if (!battle_config.multi_level_up && pc_nextjobafter(sd))
@@ -3046,14 +3051,15 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
if (sd->status.job_exp < 0)
sd->status.job_exp = 0;
- while (pc_checkjoblevelup(sd));
+ while (pc_checkjoblevelup(sd))
+ {}
clif_updatestatus(sd, SP::JOBEXP);
if (battle_config.disp_experience)
{
AString output = STRPRINTF(
- "Experienced Gained Base:%d Job:%d",
+ "Experienced Gained Base:%d Job:%d"_fmt,
base_exp, job_exp);
clif_displaymessage(sd->sess, output);
}
@@ -3064,7 +3070,7 @@ int pc_gainexp_reason(dumb_ptr<map_session_data> sd, int base_exp, int job_exp,
int pc_extract_healer_exp(dumb_ptr<map_session_data> sd, int max)
{
int amount;
- nullpo_ret(sd);
+ nullpo_retz(sd);
amount = sd->heal_xp;
if (max < amount)
@@ -3080,7 +3086,7 @@ int pc_extract_healer_exp(dumb_ptr<map_session_data> sd, int max)
*/
int pc_nextbaseexp(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.base_level >= MAX_LEVEL || sd->status.base_level <= 0)
return 0;
@@ -3108,7 +3114,7 @@ int pc_nextjobexp(dumb_ptr<map_session_data> sd)
*/
int pc_nextbaseafter(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.base_level >= MAX_LEVEL || sd->status.base_level <= 0)
return 0;
@@ -3122,7 +3128,7 @@ int pc_nextbaseafter(dumb_ptr<map_session_data> sd)
*/
int pc_nextjobafter(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.job_level >= MAX_LEVEL || sd->status.job_level <= 0)
return 0;
@@ -3156,7 +3162,7 @@ int pc_statusup(dumb_ptr<map_session_data> sd, SP type)
{
int need, val = 0;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (SP::STR <= type && type <= SP::LUK)
val = sd->status.attrs[sp_to_attr(type)];
@@ -3181,7 +3187,7 @@ int pc_statusup(dumb_ptr<map_session_data> sd, SP type)
pc_calcstatus(sd, 0);
clif_statusupack(sd, type, 1, val);
- MAP_LOG_STATS(sd, "STATUP");
+ MAP_LOG_STATS(sd, "STATUP"_fmt);
return 0;
}
@@ -3192,7 +3198,7 @@ int pc_statusup(dumb_ptr<map_session_data> sd, SP type)
*/
int pc_statusup2(dumb_ptr<map_session_data> sd, SP type, int val)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (type < SP::STR || type > SP::LUK)
{
@@ -3208,7 +3214,7 @@ int pc_statusup2(dumb_ptr<map_session_data> sd, SP type, int val)
clif_updatestatus(sd, type);
pc_calcstatus(sd, 0);
clif_statusupack(sd, type, 1, val);
- MAP_LOG_STATS(sd, "STATUP2");
+ MAP_LOG_STATS(sd, "STATUP2"_fmt);
return 0;
}
@@ -3219,7 +3225,7 @@ int pc_statusup2(dumb_ptr<map_session_data> sd, SP type, int val)
*/
int pc_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.skill[skill_num].lv
&& sd->status.skill_point >= sd->status.skill[skill_num].lv
@@ -3232,7 +3238,7 @@ int pc_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num)
clif_skillup(sd, skill_num);
clif_updatestatus(sd, SP::SKILLPOINT);
clif_skillinfoblock(sd);
- MAP_LOG_PC(sd, "SKILLUP %d %d %d",
+ MAP_LOG_PC(sd, "SKILLUP %d %d %d"_fmt,
skill_num, sd->status.skill[skill_num].lv,
skill_power(sd, skill_num));
}
@@ -3246,7 +3252,7 @@ int pc_skillup(dumb_ptr<map_session_data> sd, SkillID skill_num)
*/
int pc_resetlvl(dumb_ptr<map_session_data> sd, int type)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
for (SkillID i : erange(SkillID(1), MAX_SKILL))
{
@@ -3309,13 +3315,13 @@ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type)
for (EQUIP i : EQUIPs)
{
// unequip items that can't be equipped by base 1 [Valaris]
- short *idx = &sd->equip_index_maybe[i];
- if (*idx >= 0)
+ IOff0 *idx = &sd->equip_index_maybe[i];
+ if ((*idx).ok())
{
if (!pc_isequip(sd, *idx))
{
pc_unequipitem(sd, *idx, CalcStatus::LATER);
- *idx = -1;
+ *idx = IOff0::from(-1);
}
}
}
@@ -3323,7 +3329,7 @@ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type)
clif_skillinfoblock(sd);
pc_calcstatus(sd, 0);
- MAP_LOG_STATS(sd, "STATRESET");
+ MAP_LOG_STATS(sd, "STATRESET"_fmt);
return 0;
}
@@ -3335,7 +3341,7 @@ int pc_resetlvl(dumb_ptr<map_session_data> sd, int type)
int pc_resetstate(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->status.status_point = stat_p[sd->status.base_level - 1];
@@ -3361,7 +3367,7 @@ int pc_resetskill(dumb_ptr<map_session_data> sd)
{
int skill;
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->status.skill_point += pc_calc_skillpoint(sd);
@@ -3386,7 +3392,7 @@ int pc_resetskill(dumb_ptr<map_session_data> sd)
int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
int damage)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
// 既に死んでいたら無効
if (pc_isdead(sd))
@@ -3401,17 +3407,17 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
{
if (src->bl_type == BL::PC)
{
- MAP_LOG_PC(sd, "INJURED-BY PC%d FOR %d",
- src->is_player()->status_key.char_id,
- damage);
+ MAP_LOG_PC(sd, "INJURED-BY PC%d FOR %d"_fmt,
+ src->is_player()->status_key.char_id,
+ damage);
}
else
{
- MAP_LOG_PC(sd, "INJURED-BY MOB%d FOR %d", src->bl_id, damage);
+ MAP_LOG_PC(sd, "INJURED-BY MOB%d FOR %d"_fmt, src->bl_id, damage);
}
}
else
- MAP_LOG_PC(sd, "INJURED-BY null FOR %d", damage);
+ MAP_LOG_PC(sd, "INJURED-BY null FOR %d"_fmt, damage);
pc_stop_walking(sd, 3);
// 演奏/ダンスの中断
@@ -3427,17 +3433,17 @@ 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)
+ PartyPair p = party_search(sd->status.party_id);
+ if (p)
clif_party_hp(p, sd);
} // end addition [Valaris]
return 0;
}
- MAP_LOG_PC(sd, "DEAD%s", "");
+ MAP_LOG_PC(sd, "DEAD%s"_fmt, ""_s);
// Character is dead!
@@ -3452,13 +3458,13 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
pc_stop_walking(sd, 0);
skill_castcancel(sd, 0); // 詠唱の中止
clif_clearchar(sd, BeingRemoveWhy::DEAD);
- pc_setglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"), ++sd->die_counter); //死にカウンター書き込み
+ pc_setglobalreg(sd, stringish<VarName>("PC_DIE_COUNTER"_s), ++sd->die_counter); //死にカウンター書き込み
skill_status_change_clear(sd, 0); // ステータス異常を解除する
clif_updatestatus(sd, SP::HP);
pc_calcstatus(sd, 0);
// [Fate] Reset magic
sd->cast_tick = gettick();
- magic_stop_completely(sd);
+ magic::magic_stop_completely(sd);
if (battle_config.death_penalty_type > 0 && sd->status.base_level >= 20)
{
@@ -3544,14 +3550,14 @@ int pc_damage(dumb_ptr<block_list> src, dumb_ptr<map_session_data> sd,
// [Fate] PK death, trigger scripts
argrec_t arg[3] =
{
- {"@killerrid", src->bl_id},
- {"@victimrid", sd->bl_id},
- {"@victimlvl", sd->status.base_level},
+ {"@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"), sd->bl_id, arg);
- npc_event_doall_l(stringish<ScriptLabel>("OnPCKillEvent"), src->bl_id, arg);
+ npc_event_doall_l(stringish<ScriptLabel>("OnPCKilledEvent"_s), sd->bl_id, arg);
+ npc_event_doall_l(stringish<ScriptLabel>("OnPCKillEvent"_s), src->bl_id, arg);
}
- npc_event_doall_l(stringish<ScriptLabel>("OnPCDieEvent"), sd->bl_id, nullptr);
+ npc_event_doall_l(stringish<ScriptLabel>("OnPCDieEvent"_s), sd->bl_id, nullptr);
return 0;
}
@@ -3567,7 +3573,7 @@ int pc_readparam(dumb_ptr<map_session_data> sd, SP type)
{
int val = 0;
- nullpo_ret(sd);
+ nullpo_retz(sd);
switch (type)
{
@@ -3587,7 +3593,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);
@@ -3643,7 +3649,7 @@ int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val)
{
int i = 0, up_level = 50;
- nullpo_ret(sd);
+ nullpo_retz(sd);
switch (type)
{
@@ -3691,7 +3697,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;
@@ -3762,10 +3768,7 @@ int pc_setparam(dumb_ptr<map_session_data> sd, SP type, int val)
*/
int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp)
{
-// if(battle_config.battle_log)
-// PRINTF("heal %d %d\n",hp,sp);
-
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (pc_checkoverhp(sd))
{
@@ -3786,7 +3789,7 @@ int pc_heal(dumb_ptr<map_session_data> sd, int hp, int sp)
if (sd->status.hp <= 0)
{
sd->status.hp = 0;
- pc_damage(NULL, sd, 1);
+ pc_damage(nullptr, sd, 1);
hp = 0;
}
sd->status.sp += sp;
@@ -3797,10 +3800,10 @@ 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)
+ PartyPair p = party_search(sd->status.party_id);
+ if (p)
clif_party_hp(p, sd);
} // end addition [Valaris]
@@ -3847,9 +3850,9 @@ void pc_heal_quick_accumulate(int new_amount,
int average_speed = ((new_speed * new_amount) + (current_speed * current_amount)) / (current_amount + new_amount); // new_amount > 0, current_amount >= 0
quick_regen->speed = average_speed;
- quick_regen->amount = min(current_amount + new_amount, max);
+ quick_regen->amount = std::min(current_amount + new_amount, max);
- quick_regen->tickdelay = min(quick_regen->speed, quick_regen->tickdelay);
+ quick_regen->tickdelay = std::min(quick_regen->speed, quick_regen->tickdelay);
}
int pc_itemheal(dumb_ptr<map_session_data> sd, int hp, int sp)
@@ -3884,7 +3887,7 @@ int pc_itemheal(dumb_ptr<map_session_data> sd, int hp, int sp)
static
int pc_itemheal_effect(dumb_ptr<map_session_data> sd, int hp, int sp)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (pc_checkoverhp(sd))
{
@@ -3914,7 +3917,7 @@ int pc_itemheal_effect(dumb_ptr<map_session_data> sd, int hp, int sp)
if (sd->status.hp <= 0)
{
sd->status.hp = 0;
- pc_damage(NULL, sd, 1);
+ pc_damage(nullptr, sd, 1);
hp = 0;
}
sd->status.sp += sp;
@@ -3934,7 +3937,7 @@ int pc_itemheal_effect(dumb_ptr<map_session_data> sd, int hp, int sp)
*/
int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (pc_checkoverhp(sd))
{
@@ -3955,7 +3958,7 @@ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp)
else if (hp <= -100)
{
sd->status.hp = 0;
- pc_damage(NULL, sd, 1);
+ pc_damage(nullptr, sd, 1);
}
else
{
@@ -3965,7 +3968,7 @@ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp)
if (sd->status.hp <= 0)
{
sd->status.hp = 0;
- pc_damage(NULL, sd, 1);
+ pc_damage(nullptr, sd, 1);
hp = 0;
}
}
@@ -4003,7 +4006,7 @@ int pc_percentheal(dumb_ptr<map_session_data> sd, int hp, int sp)
*/
int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
switch (type)
{
@@ -4014,13 +4017,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;
@@ -4029,7 +4032,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;
@@ -4045,7 +4048,7 @@ int pc_changelook(dumb_ptr<map_session_data> sd, LOOK type, int val)
*/
int pc_setoption(dumb_ptr<map_session_data> sd, Option type)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
sd->status.option = type;
clif_changeoption(sd);
@@ -4060,7 +4063,7 @@ int pc_setoption(dumb_ptr<map_session_data> sd, Option type)
*/
int pc_readreg(dumb_ptr<map_session_data> sd, SIR reg)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
return sd->regm.get(reg);
}
@@ -4116,7 +4119,7 @@ int pc_readglobalreg(dumb_ptr<map_session_data> sd, VarName reg)
{
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
assert (sd->status.global_reg_num < GLOBAL_REG_NUM);
for (i = 0; i < sd->status.global_reg_num; i++)
@@ -4136,10 +4139,10 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
{
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
//PC_DIE_COUNTERがスクリプトなどで変更された時の処理
- if (reg == stringish<VarName>("PC_DIE_COUNTER") && sd->die_counter != val)
+ if (reg == stringish<VarName>("PC_DIE_COUNTER"_s) && sd->die_counter != val)
{
sd->die_counter = val;
pc_calcstatus(sd, 0);
@@ -4175,7 +4178,7 @@ int pc_setglobalreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
return 0;
}
if (battle_config.error_log)
- PRINTF("pc_setglobalreg : couldn't set %s (GLOBAL_REG_NUM = %d)\n",
+ PRINTF("pc_setglobalreg : couldn't set %s (GLOBAL_REG_NUM = %d)\n"_fmt,
reg, GLOBAL_REG_NUM);
return 1;
@@ -4189,7 +4192,7 @@ int pc_readaccountreg(dumb_ptr<map_session_data> sd, VarName reg)
{
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
assert (sd->status.account_reg_num < ACCOUNT_REG_NUM);
for (i = 0; i < sd->status.account_reg_num; i++)
@@ -4209,7 +4212,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
{
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (val == 0)
{
@@ -4244,7 +4247,7 @@ int pc_setaccountreg(dumb_ptr<map_session_data> sd, VarName reg, int val)
return 0;
}
if (battle_config.error_log)
- PRINTF("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %d)\n",
+ PRINTF("pc_setaccountreg : couldn't set %s (ACCOUNT_REG_NUM = %zu)\n"_fmt,
reg, ACCOUNT_REG_NUM);
return 1;
@@ -4258,7 +4261,7 @@ int pc_readaccountreg2(dumb_ptr<map_session_data> sd, VarName reg)
{
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
for (i = 0; i < sd->status.account_reg2_num; i++)
{
@@ -4312,8 +4315,8 @@ int pc_setaccountreg2(dumb_ptr<map_session_data> sd, VarName reg, int val)
return 0;
}
if (battle_config.error_log)
- PRINTF("pc_setaccountreg2 : couldn't set %s (ACCOUNT_REG2_NUM = %d)\n",
- reg, ACCOUNT_REG2_NUM);
+ PRINTF("pc_setaccountreg2 : couldn't set %s (ACCOUNT_REG2_NUM = %zu)\n"_fmt,
+ reg, ACCOUNT_REG2_NUM);
return 1;
}
@@ -4323,10 +4326,10 @@ 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);
+ assert (sd != nullptr);
npc_event(sd, data, 0);
}
@@ -4339,7 +4342,7 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, NpcEvent na
{
int i;
- nullpo_ret(sd);
+ nullpo_retz(sd);
for (i = 0; i < MAX_EVENTTIMER; i++)
if (!sd->eventtimer[i])
@@ -4362,7 +4365,7 @@ int pc_addeventtimer(dumb_ptr<map_session_data> sd, interval_t tick, NpcEvent na
*/
int pc_cleareventtimer(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
for (int i = 0; i < MAX_EVENTTIMER; i++)
sd->eventtimer[i].cancel();
@@ -4378,7 +4381,7 @@ int pc_cleareventtimer(dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, int n)
+int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, IOff0 n)
{
if (bool(sd->status.inventory[n].equip & EPOS::SHOES))
clif_changelook(sd, LOOK::SHOES, 0);
@@ -4393,17 +4396,17 @@ int pc_signal_advanced_equipment_change(dumb_ptr<map_session_data> sd, int n)
return 0;
}
-int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
+int pc_equipitem(dumb_ptr<map_session_data> sd, IOff0 n, EPOS)
{
- int nameid;
+ ItemNameId nameid;
struct item_data *id;
//ソス]ソスソスソスソスソス{ソスqソスフ場合ソスフ鯉ソスソスフ職ソスニゑソスソスZソスoソスソスソスソス
- nullpo_ret(sd);
+ nullpo_retz(sd);
- if (n < 0 || n >= MAX_INVENTORY)
+ if (!n.ok())
{
- clif_equipitemack(sd, 0, EPOS::ZERO, 0);
+ clif_equipitemack(sd, IOff0::from(0), EPOS::ZERO, 0);
return 0;
}
@@ -4414,7 +4417,7 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
EPOS pos = pc_equippoint(sd, n);
if (battle_config.battle_log)
- PRINTF("equip %d (%d) %x:%x\n",
+ PRINTF("equip %d (%d) %x:%x\n"_fmt,
nameid, n, id->equip, pos);
if (!pc_isequip(sd, n) || pos == EPOS::ZERO)
{
@@ -4428,11 +4431,11 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
{
// アクセサリ用例外処理
EPOS epor = EPOS::ZERO;
- int midx = sd->equip_index_maybe[EQUIP::MISC2];
- int cidx = sd->equip_index_maybe[EQUIP::CAPE];
- if (midx >= 0)
+ IOff0 midx = sd->equip_index_maybe[EQUIP::MISC2];
+ IOff0 cidx = sd->equip_index_maybe[EQUIP::CAPE];
+ if (midx.ok())
epor |= sd->status.inventory[midx].equip;
- if (cidx >= 0)
+ if (cidx.ok())
epor |= sd->status.inventory[cidx].equip;
epor &= (EPOS::MISC2 | EPOS::CAPE);
pos = (epor == EPOS::CAPE ? EPOS::MISC2 : EPOS::CAPE);
@@ -4442,8 +4445,8 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
{
if (bool(pos & equip_pos[i]))
{
- short *idx = &sd->equip_index_maybe[i];
- if (*idx >= 0) //Slot taken, remove item from there.
+ IOff0 *idx = &sd->equip_index_maybe[i];
+ if ((*idx).ok()) //Slot taken, remove item from there.
pc_unequipitem(sd, *idx, CalcStatus::LATER);
*idx = n;
}
@@ -4468,7 +4471,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])
@@ -4495,7 +4498,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;
}
@@ -4507,26 +4510,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);
@@ -4539,14 +4542,14 @@ int pc_equipitem(dumb_ptr<map_session_data> sd, int n, EPOS)
* 装 備した物を外す
*------------------------------------------
*/
-int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
+int pc_unequipitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
// -- moonsoul (if player is berserk then cannot unequip)
//
if (battle_config.battle_log)
- PRINTF("unequip %d %x:%x\n",
+ PRINTF("unequip %d %x:%x\n"_fmt,
n, pc_equippoint(sd, n),
sd->status.inventory[n].equip);
if (bool(sd->status.inventory[n].equip))
@@ -4554,7 +4557,7 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
for (EQUIP i : EQUIPs)
{
if (bool(sd->status.inventory[n].equip & equip_pos[i]))
- sd->equip_index_maybe[i] = -1;
+ sd->equip_index_maybe[i] = IOff0::from(-1);
}
if (bool(sd->status.inventory[n].equip & EPOS::WEAPON))
{
@@ -4565,26 +4568,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);
@@ -4603,7 +4605,7 @@ int pc_unequipitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
return 0;
}
-int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
+int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, IOff0 n, CalcStatus type)
{
nullpo_retr(1, sd);
@@ -4615,7 +4617,7 @@ int pc_unequipinvyitem(dumb_ptr<map_session_data> sd, int n, CalcStatus type)
{
//Slot taken, remove item from there.
pc_unequipitem(sd, sd->equip_index_maybe[i], type);
- sd->equip_index_maybe[i] = -1;
+ sd->equip_index_maybe[i] = IOff0::from(-1);
}
}
@@ -4629,30 +4631,31 @@ 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 calc_flag = 0;
- nullpo_ret(sd);
+ nullpo_retz(sd);
- // 所持品空き詰め
- for (i = j = 0; i < MAX_INVENTORY; i++)
+ IOff0 j = IOff0::from(0);
+ for (IOff0 i : IOff0::iter())
{
- if ((id = sd->status.inventory[i].nameid) == 0)
+ if (!(sd->status.inventory[i].nameid))
continue;
- if (i > j)
+ if (i != j)
{
sd->status.inventory[j] = sd->status.inventory[i];
sd->inventory_data[j] = sd->inventory_data[i];
}
- j++;
+ ++j;
+ }
+ for (IOff0 k = j; k != IOff0::from(MAX_INVENTORY); ++k)
+ {
+ sd->status.inventory[k] = Item{};
+ sd->inventory_data[k] = nullptr;
}
- for (k = j; k < MAX_INVENTORY; ++k)
- sd->status.inventory[k] = item{};
- for (k = j; k < MAX_INVENTORY; k++)
- sd->inventory_data[k] = NULL;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
- 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)))
{
@@ -4670,7 +4673,7 @@ int pc_checkitem(dumb_ptr<map_session_data> sd)
int pc_checkoverhp(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.hp == sd->status.max_hp)
return 1;
@@ -4686,7 +4689,7 @@ int pc_checkoverhp(dumb_ptr<map_session_data> sd)
int pc_checkoversp(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->status.sp == sd->status.max_sp)
return 1;
@@ -4723,9 +4726,9 @@ void pc_calc_pvprank_sub(dumb_ptr<block_list> bl, dumb_ptr<map_session_data> sd2
*/
int pc_calc_pvprank(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
map_local *m = sd->bl_m;
- nullpo_ret(m);
+ nullpo_retz(m);
if (!(m->flag.get(MapFlag::PVP)))
return 0;
@@ -4742,20 +4745,22 @@ 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;
+ dumb_ptr<map_session_data> sd = nullptr;
if (battle_config.pk_mode) // disable pvp ranking if pk_mode on [Valaris]
return;
sd = map_id2sd(id);
- if (sd == NULL)
+ if (sd == nullptr)
return;
sd->pvp_timer.cancel();
if (pc_calc_pvprank(sd) > 0)
+ {
sd->pvp_timer = Timer(gettick() + PVP_CALCRANK_INTERVAL,
std::bind(pc_calc_pvprank_timer, ph::_1, ph::_2,
id));
+ }
}
/*==========================================
@@ -4763,14 +4768,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)
+ if (sd == nullptr)
+ return CharId();
+ if (sd->status.partner_id)
return sd->status.partner_id;
else
- return 0;
+ return CharId();
}
/*==========================================
@@ -4779,8 +4784,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 == nullptr || dstsd == nullptr || 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;
@@ -4793,23 +4798,23 @@ 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> p_sd = NULL;
- if (sd == NULL || !pc_ismarried(sd))
+ dumb_ptr<map_session_data> p_sd = nullptr;
+ if (sd == nullptr || !pc_ismarried(sd))
return -1;
// If both are on map server we don't need to bother the char server
if ((p_sd =
- map_nick2sd(map_charid2nick(sd->status.partner_id))) != NULL)
+ map_nick2sd(map_charid2nick(sd->status.partner_id))) != nullptr)
{
if (p_sd->status.partner_id != sd->status_key.char_id
|| sd->status.partner_id != p_sd->status_key.char_id)
{
- PRINTF("pc_divorce: Illegal partner_id sd=%d p_sd=%d\n",
+ PRINTF("pc_divorce: Illegal partner_id sd=%d p_sd=%d\n"_fmt,
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)
{
@@ -4829,17 +4834,17 @@ int pc_divorce(dumb_ptr<map_session_data> sd)
*/
dumb_ptr<map_session_data> pc_get_partner(dumb_ptr<map_session_data> sd)
{
- dumb_ptr<map_session_data> p_sd = NULL;
- if (sd == NULL || !pc_ismarried(sd))
- return NULL;
+ dumb_ptr<map_session_data> p_sd = nullptr;
+ if (sd == nullptr || !pc_ismarried(sd))
+ return nullptr;
CharName nick = map_charid2nick(sd->status.partner_id);
if (!nick.to__actual())
- return NULL;
+ return nullptr;
- if ((p_sd = map_nick2sd(nick)) == NULL)
- return NULL;
+ if ((p_sd = map_nick2sd(nick)) == nullptr)
+ return nullptr;
return p_sd;
}
@@ -4890,7 +4895,7 @@ int pc_natural_heal_hp(dumb_ptr<map_session_data> sd)
int bhp;
int bonus;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (pc_checkoverhp(sd))
{
@@ -4962,7 +4967,7 @@ int pc_natural_heal_sp(dumb_ptr<map_session_data> sd)
int bsp;
int bonus;
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (pc_checkoversp(sd))
{
@@ -5035,7 +5040,7 @@ int pc_quickregenerate_effect(struct quick_regeneration *quick_regen,
if (!(quick_regen->tickdelay--))
{
int bonus =
- min(heal_speed * battle_config.itemheal_regeneration_factor,
+ std::min(heal_speed * battle_config.itemheal_regeneration_factor,
quick_regen->amount);
quick_regen->amount -= bonus;
@@ -5171,21 +5176,20 @@ void pc_autosave(TimerData *, tick_t)
interval_t interval = autosave_time / (clif_countusers() + 1);
if (interval <= interval_t::zero())
- interval = std::chrono::milliseconds(1);
+ interval = 1_ms;
Timer(gettick() + interval,
pc_autosave
).detach();
}
-int pc_read_gm_account(Session *s)
+int pc_read_gm_account(Session *, const std::vector<Packet_Repeat<0x2b15>>& repeat)
{
gm_accountm.clear();
- // (RFIFOW(fd, 2) - 4) / 5
- for (int i = 4; i < RFIFOW(s, 2); i += 5)
+ for (const auto& i : repeat)
{
- int account_id = RFIFOL(s, i);
- uint8_t level = RFIFOB(s, i + 4);
+ AccountId account_id = i.account_id;
+ GmLevel level = i.gm_level;
gm_accountm[account_id] = level;
}
return gm_accountm.size();
@@ -5230,7 +5234,7 @@ void do_init_pc(void)
void pc_cleanup(dumb_ptr<map_session_data> sd)
{
- magic_stop_completely(sd);
+ magic::magic_stop_completely(sd);
}
void pc_invisibility(dumb_ptr<map_session_data> sd, int enabled)
@@ -5265,13 +5269,14 @@ int pc_logout(dumb_ptr<map_session_data> sd) // [fate] Player logs out
// Removed because it's buggy, see above.
if (sd->cast_tick > tick)
{
- if (pc_setglobalreg(sd, "MAGIC_CAST_TICK", sd->cast_tick - tick))
+ if (pc_setglobalreg(sd, "MAGIC_CAST_TICK"_s, sd->cast_tick - tick))
sd->status.sp = 1;
}
else
#endif
- pc_setglobalreg(sd, stringish<VarName>("MAGIC_CAST_TICK"), 0);
+ pc_setglobalreg(sd, stringish<VarName>("MAGIC_CAST_TICK"_s), 0);
- MAP_LOG_STATS(sd, "LOGOUT");
+ MAP_LOG_STATS(sd, "LOGOUT"_fmt);
return 0;
}
+} // namespace tmwa
diff --git a/src/map/pc.hpp b/src/map/pc.hpp
index 35d9c70..3187cd9 100644
--- a/src/map/pc.hpp
+++ b/src/map/pc.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_PC_HPP
-#define TMWA_MAP_PC_HPP
+#pragma once
// pc.hpp - Player state changes.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,15 +20,24 @@
// 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"
+#include "pc.t.hpp"
-# include "../strings/fwd.hpp"
+#include "../strings/fwd.hpp"
-# include "clif.t.hpp"
-# include "map.hpp"
+#include "../generic/dumb_ptr.hpp"
+#include "../mmo/utils.hpp"
+
+#include "../proto2/fwd.hpp"
+
+#include "clif.t.hpp"
+#include "map.hpp"
+
+
+namespace tmwa
+{
inline
void pc_setsit(dumb_ptr<map_session_data> sd)
{
@@ -66,7 +74,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,14 +82,14 @@ 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, uint32_t /*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);
+EPOS pc_equippoint(dumb_ptr<map_session_data> sd, IOff0 n);
int pc_checkskill(dumb_ptr<map_session_data> sd, SkillID skill_id);
-int pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos);
+IOff0 pc_checkequip(dumb_ptr<map_session_data> sd, EPOS pos);
int pc_walktoxy(dumb_ptr<map_session_data>, int, int);
int pc_stop_walking(dumb_ptr<map_session_data>, int);
@@ -90,20 +98,20 @@ 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);
+IOff0 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);
+PickupFail pc_additem(dumb_ptr<map_session_data>, Item *, int);
int pc_getzeny(dumb_ptr<map_session_data>, int);
-int pc_delitem(dumb_ptr<map_session_data>, int, int, int);
+int pc_delitem(dumb_ptr<map_session_data>, IOff0, 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);
+int pc_dropitem(dumb_ptr<map_session_data>, IOff0, int);
int pc_checkweighticon(dumb_ptr<map_session_data> sd);
@@ -112,7 +120,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,
@@ -128,10 +136,10 @@ int pc_skillup(dumb_ptr<map_session_data>, SkillID);
int pc_resetlvl(dumb_ptr<map_session_data>, int type);
int pc_resetstate(dumb_ptr<map_session_data>);
int pc_resetskill(dumb_ptr<map_session_data>);
-int pc_equipitem(dumb_ptr<map_session_data>, int, EPOS);
-int pc_unequipitem(dumb_ptr<map_session_data>, int, CalcStatus);
-int pc_unequipinvyitem(dumb_ptr<map_session_data>, int, CalcStatus);
-int pc_useitem(dumb_ptr<map_session_data>, int);
+int pc_equipitem(dumb_ptr<map_session_data>, IOff0, EPOS);
+int pc_unequipitem(dumb_ptr<map_session_data>, IOff0, CalcStatus);
+int pc_unequipinvyitem(dumb_ptr<map_session_data>, IOff0, CalcStatus);
+int pc_useitem(dumb_ptr<map_session_data>, IOff0);
int pc_damage(dumb_ptr<block_list>, dumb_ptr<map_session_data>, int);
int pc_heal(dumb_ptr<map_session_data>, int, int);
@@ -158,17 +166,17 @@ 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
-int pc_read_gm_account(Session *);
+int pc_read_gm_account(Session *, const std::vector<Packet_Repeat<0x2b15>>&);
int pc_setinvincibletimer(dumb_ptr<map_session_data> sd, interval_t);
int pc_delinvincibletimer(dumb_ptr<map_session_data> sd);
int pc_logout(dumb_ptr<map_session_data> sd); // [fate] Player logs out
@@ -176,5 +184,4 @@ int pc_logout(dumb_ptr<map_session_data> sd); // [fate] Player logs out
void pc_show_motd(dumb_ptr<map_session_data> sd);
void do_init_pc(void);
-
-#endif // TMWA_MAP_PC_HPP
+} // namespace tmwa
diff --git a/src/map/pc.t.hpp b/src/map/pc.t.hpp
index 65e1046..427e8c3 100644
--- a/src/map/pc.t.hpp
+++ b/src/map/pc.t.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_PC_T_HPP
-#define TMWA_MAP_PC_T_HPP
+#pragma once
// pc.t.hpp - Player state changes.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -22,10 +21,13 @@
// 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 <cstdint>
+
+namespace tmwa
+{
enum class PC_GAINEXP_REASON
{
KILLING = 0,
@@ -50,18 +52,6 @@ enum class ADDITEM
enum class CalcStatus
{
NOW,
- LATER ,
-};
-
-enum class PickupFail : uint8_t
-{
- OKAY = 0,
- BAD_ITEM = 1,
- TOO_HEAVY = 2,
- TOO_FAR = 3,
- INV_FULL = 4,
- STACK_FULL = 5,
- DROP_STEAL = 6,
+ LATER,
};
-
-#endif // TMWA_MAP_PC_T_HPP
+} // namespace tmwa
diff --git a/src/map/script.cpp b/src/map/script.cpp
index 93f9d31..329b47f 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -23,12 +23,11 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cassert>
-#include <cctype>
#include <cmath>
#include <cstdlib>
-#include <cstring>
#include <ctime>
+#include <algorithm>
#include <set>
#include "../compat/fun.hpp"
@@ -38,21 +37,25 @@
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
+#include "../strings/literal.hpp"
#include "../generic/db.hpp"
#include "../generic/intern-pool.hpp"
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/lock.hpp"
#include "../io/read.hpp"
+#include "../io/write.hpp"
+
+#include "../net/socket.hpp"
+#include "../net/timer.hpp"
-#include "../mmo/config_parse.hpp"
#include "../mmo/core.hpp"
#include "../mmo/extract.hpp"
-#include "../mmo/socket.hpp"
+#include "../mmo/human_time_diff.hpp"
#include "../mmo/utils.hpp"
-#include "../mmo/timer.hpp"
#include "atcommand.hpp"
#include "battle.hpp"
@@ -60,7 +63,7 @@
#include "clif.hpp"
#include "intif.hpp"
#include "itemdb.hpp"
-#include "magic.hpp"
+#include "magic-interpreter-base.hpp"
#include "map.hpp"
#include "mob.hpp"
#include "npc.hpp"
@@ -71,6 +74,9 @@
#include "../poison.hpp"
+
+namespace tmwa
+{
constexpr bool DEBUG_DISP = false;
constexpr bool DEBUG_RUN = false;
@@ -93,8 +99,8 @@ static
Map<SIR, RString> mapregstr_db;
static
int mapreg_dirty = -1;
-AString mapreg_txt = "save/mapreg.txt";
-constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = std::chrono::seconds(10);
+AString mapreg_txt = "save/mapreg.txt"_s;
+constexpr std::chrono::milliseconds MAPREG_AUTOSAVE_INTERVAL = 10_s;
Map<ScriptLabel, int> scriptlabel_db;
static
@@ -102,19 +108,19 @@ std::set<ScriptLabel> probable_labels;
UPMap<RString, const ScriptBuffer> userfunc_db;
static
-Array<ZString, 11> pos_str //=
+Array<LString, 11> pos_str //=
{{
- ZString("Head"),
- ZString("Body"),
- ZString("Left hand"),
- ZString("Right hand"),
- ZString("Robe"),
- ZString("Shoes"),
- ZString("Accessory 1"),
- ZString("Accessory 2"),
- ZString("Head 2"),
- ZString("Head 3"),
- ZString("Not Equipped"),
+ "Head"_s,
+ "Body"_s,
+ "Left hand"_s,
+ "Right hand"_s,
+ "Robe"_s,
+ "Shoes"_s,
+ "Accessory 1"_s,
+ "Accessory 2"_s,
+ "Head 2"_s,
+ "Head 3"_s,
+ "Not Equipped"_s,
}};
static
@@ -150,8 +156,9 @@ void mapreg_setregstr(SIR num, XString str);
struct BuiltinFunction
{
void (*func)(ScriptState *);
- ZString name;
- ZString arg;
+ LString name;
+ LString arg;
+ char ret;
};
// defined later
extern BuiltinFunction builtin_functions[];
@@ -382,15 +389,15 @@ void disp_error_message(ZString mes, ZString::iterator pos_)
ZString::iterator lineend = std::find(p, startptr.end(), '\n');
if (pos_ < lineend)
{
- PRINTF("\n%s\nline %d : ", mes, line);
+ PRINTF("\n%s\nline %d : "_fmt, mes, line);
for (int i = 0; linestart + i != lineend; i++)
{
if (linestart + i != pos_)
- PRINTF("%c", linestart[i]);
+ PRINTF("%c"_fmt, linestart[i]);
else
- PRINTF("\'%c\'", linestart[i]);
+ PRINTF("\'%c\'"_fmt, linestart[i]);
}
- PRINTF("\a\n");
+ PRINTF("\a\n"_fmt);
return;
}
p = lineend + 1;
@@ -407,7 +414,7 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p)
if (*p == ';' || *p == ',')
{
- disp_error_message("unexpected expr end", p);
+ disp_error_message("unexpected expr end"_s, p);
exit(1);
}
if (*p == '(')
@@ -417,7 +424,7 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p)
p = skip_space(p);
if ((*p++) != ')')
{
- disp_error_message("unmatch ')'", p);
+ disp_error_message("unmatch ')'"_s, p);
exit(1);
}
}
@@ -438,14 +445,14 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p)
p++;
else if (*p == '\n')
{
- disp_error_message("unexpected newline @ string", p);
+ disp_error_message("unexpected newline @ string"_s, p);
exit(1);
}
add_scriptb(*p++);
}
if (!*p)
{
- disp_error_message("unexpected eof @ string", p);
+ disp_error_message("unexpected eof @ string"_s, p);
exit(1);
}
add_scriptb(0);
@@ -457,35 +464,35 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p)
ZString::iterator p2 = skip_word(p);
if (p2 == p)
{
- disp_error_message("unexpected character", p);
+ disp_error_message("unexpected character"_s, p);
exit(1);
}
XString word(&*p, &*p2, nullptr);
- if (word.startswith("On") || word.startswith("L_") || word.startswith("S_"))
+ if (word.startswith("On"_s) || word.startswith("L_"_s) || word.startswith("S_"_s))
probable_labels.insert(stringish<ScriptLabel>(word));
- if (parse_cmd_if && (word == "callsub" || word == "callfunc" || word == "return"))
+ if (parse_cmd_if && (word == "callsub"_s || word == "callfunc"_s || word == "return"_s))
{
- disp_error_message("Sorry, callsub/callfunc/return have never worked properly in an if statement.", p);
+ disp_error_message("Sorry, callsub/callfunc/return have never worked properly in an if statement."_s, p);
}
str_data_t *ld = add_strp(word);
parse_cmdp = ld; // warn_*_mismatch_paramnumのために必要
- // why not just check l->str == "if" or std::string(p, p2) == "if"?
- if (ld == search_strp("if")) // warn_cmd_no_commaのために必要
+ // why not just check l->str == "if"_s or std::string(p, p2) == "if"_s?
+ if (ld == search_strp("if"_s)) // warn_cmd_no_commaのために必要
parse_cmd_if++;
p = p2;
if (ld->type != ByteCode::FUNC_ && *p == '[')
{
// array(name[i] => getelementofarray(name,i) )
- add_scriptl(search_strp("getelementofarray"));
+ add_scriptl(search_strp("getelementofarray"_s));
add_scriptc(ByteCode::ARG);
add_scriptl(ld);
p = parse_subexpr(p + 1, -1);
p = skip_space(p);
if (*p != ']')
{
- disp_error_message("unmatch ']'", p);
+ disp_error_message("unmatch ']'"_s, p);
exit(1);
}
p++;
@@ -515,7 +522,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit)
ZString::iterator tmpp = skip_space(p + 1);
if (*tmpp == ';' || *tmpp == ',')
{
- --script_errors; disp_error_message("deprecated: implicit 'next statement' label", p);
+ --script_errors; disp_error_message("deprecated: implicit 'next statement' label"_s, p);
add_scriptl(&LABEL_NEXTLINE_);
p++;
return p;
@@ -560,7 +567,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit)
if (funcp->type != ByteCode::FUNC_)
{
- disp_error_message("expect function", tmpp);
+ disp_error_message("expect function"_s, tmpp);
exit(0);
}
@@ -574,7 +581,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit)
p++;
else if (*p != ')' && script_config.warn_func_no_comma)
{
- disp_error_message("expect ',' or ')' at func params",
+ disp_error_message("expect ',' or ')' at func params"_s,
p);
}
p = skip_space(p);
@@ -583,7 +590,7 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit)
plist[i] = p;
if (*p != ')')
{
- disp_error_message("func request '(' ')'", p);
+ disp_error_message("func request '(' ')'"_s, p);
exit(1);
}
p++;
@@ -593,14 +600,19 @@ ZString::iterator ScriptBuffer::parse_subexpr(ZString::iterator p, int limit)
{
ZString arg = builtin_functions[funcp->val].arg;
int j = 0;
+ // TODO handle ? and multiple * correctly
for (j = 0; arg[j]; j++)
- if (arg[j] == '*')
+ if (arg[j] == '*' || arg[j] == '?')
break;
- if ((arg[j] == 0 && i != j) || (arg[j] == '*' && i < j))
+ if ((arg[j] == 0 && i != j) || ((arg[j] == '*' || arg[j] == '?') && i < j))
{
- disp_error_message("illegal number of parameters",
+ disp_error_message("illegal number of parameters"_s,
plist[std::min(i, j)]);
}
+ if (!builtin_functions[funcp->val].ret)
+ {
+ disp_error_message("statement in function context"_s, tmpp);
+ }
}
}
else // not op == ByteCode::FUNC
@@ -627,7 +639,7 @@ ZString::iterator ScriptBuffer::parse_expr(ZString::iterator p)
case '[':
case ']':
case '}':
- disp_error_message("unexpected char", p);
+ disp_error_message("unexpected char"_s, p);
exit(1);
}
p = parse_subexpr(p, -1);
@@ -657,21 +669,22 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step)
str_data_t *cmd = parse_cmdp;
if (cmd->type != ByteCode::FUNC_)
{
- disp_error_message("expect command", p2);
+ disp_error_message("expect command"_s, p2);
// exit(0);
}
{
+ // TODO should be LString, but no heterogenous lookup yet
static
std::set<ZString> terminators =
{
- "goto",
- "return",
- "close",
- "menu",
- "end",
- "mapexit",
- "shop",
+ "goto"_s,
+ "return"_s,
+ "close"_s,
+ "menu"_s,
+ "end"_s,
+ "mapexit"_s,
+ "shop"_s,
};
*can_step = terminators.count(cmd->strs) == 0;
}
@@ -689,7 +702,7 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step)
else if (*p != ';' && script_config.warn_cmd_no_comma
&& parse_cmd_if * 2 <= i)
{
- disp_error_message("expect ',' or ';' at cmd params", p);
+ disp_error_message("expect ',' or ';' at cmd params"_s, p);
}
p = skip_space(p);
i++;
@@ -697,7 +710,7 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step)
plist[i] = p;
if (*(p++) != ';')
{
- disp_error_message("need ';'", p);
+ disp_error_message("need ';'"_s, p);
exit(1);
}
add_scriptc(ByteCode::FUNC_);
@@ -707,14 +720,19 @@ ZString::iterator ScriptBuffer::parse_line(ZString::iterator p, bool *can_step)
{
ZString arg = builtin_functions[cmd->val].arg;
int j = 0;
+ // TODO see above
for (j = 0; arg[j]; j++)
- if (arg[j] == '*')
+ if (arg[j] == '*' || arg[j] == '?')
break;
- if ((arg[j] == 0 && i != j) || (arg[j] == '*' && i < j))
+ if ((arg[j] == 0 && i != j) || ((arg[j] == '*' || arg[j] == '?') && i < j))
{
- disp_error_message("illegal number of parameters",
+ disp_error_message("illegal number of parameters"_s,
plist[std::min(i, j)]);
}
+ if (builtin_functions[cmd->val].ret)
+ {
+ disp_error_message("function in statement context"_s, p2);
+ }
}
return p;
@@ -740,24 +758,50 @@ bool read_constdb(ZString filename)
io::ReadFile in(filename);
if (!in.is_open())
{
- PRINTF("can't read %s\n", filename);
+ PRINTF("can't read %s\n"_fmt, filename);
return false;
}
bool rv = true;
- AString line;
- while (in.getline(line))
- {
- if (is_comment(line))
+ AString line_;
+ while (in.getline(line_))
+ {
+ // is_comment only works for whole-line comments
+ // that could change once the Z dependency is dropped ...
+ LString comment = "//"_s;
+ XString line = line_.xislice_h(std::search(line_.begin(), line_.end(), comment.begin(), comment.end())).rstrip();
+ if (!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", &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", line);
+ PRINTF("Bad const line: %s\n"_fmt, line_);
rv = false;
continue;
}
@@ -815,7 +859,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end)
p = skip_space(p);
if (*p != '{')
{
- disp_error_message("not found '{'", p);
+ disp_error_message("not found '{'"_s, p);
abort();
}
for (p++; *p && *p != '}';)
@@ -825,7 +869,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end)
{
if (can_step)
{
- --script_errors; disp_error_message("deprecated: implicit fallthrough", p);
+ --script_errors; disp_error_message("deprecated: implicit fallthrough"_s, p);
}
can_step = true;
@@ -838,7 +882,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end)
assert (e1 == e2 && e2 == e3);
if (e3)
{
- disp_error_message("dup label ", p);
+ disp_error_message("dup label "_s, p);
exit(1);
}
set_label(ld, script_buf.size());
@@ -849,7 +893,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end)
if (!can_step)
{
- --script_errors; disp_error_message("deprecated: unreachable statement", p);
+ --script_errors; disp_error_message("deprecated: unreachable statement"_s, p);
}
// 他は全部一緒くた
p = parse_line(p, &can_step);
@@ -864,7 +908,7 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end)
if (can_step && !implicit_end)
{
- --script_errors; disp_error_message("deprecated: implicit end", p);
+ --script_errors; disp_error_message("deprecated: implicit end"_s, p);
}
add_scriptc(ByteCode::NOP);
@@ -893,17 +937,17 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end)
for (const auto& pair : scriptlabel_db)
{
ScriptLabel key = pair.first;
- if (key.startswith("On"))
+ if (key.startswith("On"_s))
continue;
- if (!(key.startswith("L_") || key.startswith("S_")))
- PRINTF("Warning: ugly label: %s\n", key);
+ if (!(key.startswith("L_"_s) || key.startswith("S_"_s)))
+ PRINTF("Warning: ugly label: %s\n"_fmt, key);
else if (!probable_labels.count(key))
- PRINTF("Warning: unused label: %s\n", key);
+ PRINTF("Warning: unused label: %s\n"_fmt, key);
}
for (ScriptLabel used : probable_labels)
{
if (!scriptlabel_db.search(used))
- PRINTF("Warning: no such label: %s\n", used);
+ PRINTF("Warning: no such label: %s\n"_fmt, used);
}
probable_labels.clear();
@@ -912,12 +956,12 @@ void ScriptBuffer::parse_script(ZString src, int line, bool implicit_end)
for (size_t i = 0; i < script_buf.size(); i++)
{
if ((i & 15) == 0)
- PRINTF("%04zx : ", i);
- PRINTF("%02x ", script_buf[i]);
+ PRINTF("%04zx : "_fmt, i);
+ PRINTF("%02x "_fmt, script_buf[i]);
if ((i & 15) == 15)
- PRINTF("\n");
+ PRINTF("\n"_fmt);
}
- PRINTF("\n");
+ PRINTF("\n"_fmt);
}
//
@@ -943,7 +987,7 @@ dumb_ptr<map_session_data> script_rid2sd(ScriptState *st)
dumb_ptr<map_session_data> sd = map_id2sd(st->rid);
if (!sd)
{
- PRINTF("script_rid2sd: fatal error ! player not attached!\n");
+ PRINTF("script_rid2sd: fatal error ! player not attached!\n"_fmt);
}
return sd;
}
@@ -957,8 +1001,8 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
{
if (data->type == ByteCode::PARAM_)
{
- if (sd == NULL)
- PRINTF("get_val error param SP::%d\n", data->u.reg.sp());
+ if (sd == nullptr)
+ PRINTF("get_val error param SP::%d\n"_fmt, data->u.reg.sp());
data->type = ByteCode::INT;
if (sd)
data->u.numi = pc_readparam(sd, data->u.reg.sp());
@@ -972,8 +1016,8 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
if (prefix != '$')
{
- if (sd == NULL)
- PRINTF("get_val error name?:%s\n", name);
+ if (sd == nullptr)
+ PRINTF("get_val error name?:%s\n"_fmt, name);
}
if (postfix == '$')
{
@@ -990,11 +1034,11 @@ void get_val(dumb_ptr<map_session_data> sd, struct script_data *data)
}
else
{
- PRINTF("script: get_val: illegal scope string variable.\n");
- data->u.str = dumb_string::fake("!!ERROR!!");
+ PRINTF("script: get_val: illegal scope string variable.\n"_fmt);
+ data->u.str = dumb_string::fake("!!ERROR!!"_s);
}
if (!data->u.str)
- data->u.str = dumb_string::fake("");
+ data->u.str = dumb_string::fake(""_s);
}
else
{
@@ -1085,7 +1129,7 @@ void set_reg(dumb_ptr<map_session_data> sd, ByteCode type, SIR reg, struct scrip
}
else
{
- PRINTF("script: set_reg: illegal scope string variable !");
+ PRINTF("script: set_reg: illegal scope string variable !"_fmt);
}
}
else
@@ -1143,7 +1187,7 @@ dumb_string conv_str(ScriptState *st, struct script_data *data)
assert (data->type != ByteCode::RETINFO);
if (data->type == ByteCode::INT)
{
- AString buf = STRPRINTF("%d", data->u.numi);
+ AString buf = STRPRINTF("%d"_fmt, data->u.numi);
data->type = ByteCode::STR;
data->u.str = dumb_string::copys(buf);
}
@@ -1285,7 +1329,7 @@ void builtin_goto(ScriptState *st)
{
if (AARGO2(2).type != ByteCode::POS)
{
- PRINTF("script: goto: not label !\n");
+ PRINTF("script: goto: not label !\n"_fmt);
st->state = ScriptEndState::END;
return;
}
@@ -1324,7 +1368,7 @@ void builtin_callfunc(ScriptState *st)
}
else
{
- PRINTF("script:callfunc: function not found! [%s]\n", str);
+ PRINTF("script:callfunc: function not found! [%s]\n"_fmt, str);
st->state = ScriptEndState::END;
}
}
@@ -1442,7 +1486,7 @@ void builtin_menu(ScriptState *st)
// not just the displayed number that ends with the "".
// (Would it be better to pop the stack before rerunning?)
int menu_choices = (st->end - (st->start + 2)) / 2;
- pc_setreg(sd, SIR::from(variable_names.intern("@menu")), sd->npc_menu);
+ pc_setreg(sd, SIR::from(variable_names.intern("@menu"_s)), sd->npc_menu);
sd->state.menu_or_input = 0;
if (sd->npc_menu > 0 && sd->npc_menu <= menu_choices)
{
@@ -1481,23 +1525,6 @@ void builtin_rand(ScriptState *st)
}
/*==========================================
- *
- *------------------------------------------
- */
-static
-void builtin_pow(ScriptState *st)
-{
- int a, b;
-
- a = conv_num(st, &AARGO2(2));
- b = conv_num(st, &AARGO2(3));
-
-#warning "This is silly"
- push_int(st->stack, ByteCode::INT, static_cast<int>(pow(a * 0.001, b)));
-
-}
-
-/*==========================================
* Check whether the PC is at the specified location
*------------------------------------------
*/
@@ -1532,9 +1559,9 @@ void builtin_warp(ScriptState *st)
MapName str = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
x = conv_num(st, &AARGO2(3));
y = conv_num(st, &AARGO2(4));
- if (str == "Random")
+ if (str == "Random"_s)
pc_randomwarp(sd, BeingRemoveWhy::WARPED);
- else if (str == "SavePoint" or str == "Save")
+ else if (str == "SavePoint"_s or str == "Save"_s)
{
if (sd->bl_m->flag.get(MapFlag::NORETURN))
return;
@@ -1554,7 +1581,7 @@ static
void builtin_areawarp_sub(dumb_ptr<block_list> bl, MapName mapname, int x, int y)
{
dumb_ptr<map_session_data> sd = bl->is_player();
- if (mapname == "Random")
+ if (mapname == "Random"_s)
pc_randomwarp(sd, BeingRemoveWhy::WARPED);
else
pc_setpos(sd, mapname, x, y, BeingRemoveWhy::GONE);
@@ -1635,7 +1662,7 @@ void builtin_percentheal(ScriptState *st)
static
void builtin_input(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
script_data& scrd = AARGO2(2);
ByteCode type = scrd.type;
assert (type == ByteCode::VARIABLE);
@@ -1712,7 +1739,7 @@ void builtin_if (ScriptState *st)
static
void builtin_set(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
SIR reg = AARGO2(2).u.reg;
if (AARGO2(2).type == ByteCode::PARAM_)
{
@@ -1753,7 +1780,7 @@ void builtin_set(ScriptState *st)
static
void builtin_setarray(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
assert (AARGO2(2).type == ByteCode::VARIABLE);
SIR reg = AARGO2(2).u.reg;
ZString name = variable_names.outtern(reg.base());
@@ -1762,7 +1789,7 @@ void builtin_setarray(ScriptState *st)
if (prefix != '$' && prefix != '@')
{
- PRINTF("builtin_setarray: illegal scope !\n");
+ PRINTF("builtin_setarray: illegal scope !\n"_fmt);
return;
}
if (prefix != '$')
@@ -1784,7 +1811,7 @@ void builtin_setarray(ScriptState *st)
static
void builtin_cleararray(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
assert (AARGO2(2).type == ByteCode::VARIABLE);
SIR reg = AARGO2(2).u.reg;
ZString name = variable_names.outtern(reg.base());
@@ -1794,7 +1821,7 @@ void builtin_cleararray(ScriptState *st)
if (prefix != '$' && prefix != '@')
{
- PRINTF("builtin_cleararray: illegal scope !\n");
+ PRINTF("builtin_cleararray: illegal scope !\n"_fmt);
return;
}
if (prefix != '$')
@@ -1839,7 +1866,7 @@ void builtin_getarraysize(ScriptState *st)
if (prefix != '$' && prefix != '@')
{
- PRINTF("builtin_copyarray: illegal scope !\n");
+ PRINTF("builtin_copyarray: illegal scope !\n"_fmt);
return;
}
@@ -1858,8 +1885,8 @@ void builtin_getelementofarray(ScriptState *st)
int i = conv_num(st, &AARGO2(3));
if (i > 255 || i < 0)
{
- PRINTF("script: getelementofarray (operator[]): param2 illegal number %d\n",
- i);
+ PRINTF("script: getelementofarray (operator[]): param2 illegal number %d\n"_fmt,
+ i);
push_int(st->stack, ByteCode::INT, 0);
}
else
@@ -1870,7 +1897,7 @@ void builtin_getelementofarray(ScriptState *st)
}
else
{
- PRINTF("script: getelementofarray (operator[]): param1 not name !\n");
+ PRINTF("script: getelementofarray (operator[]): param1 not name !\n"_fmt);
push_int(st->stack, ByteCode::INT, 0);
}
}
@@ -1896,7 +1923,8 @@ void builtin_setlook(ScriptState *st)
static
void builtin_countitem(ScriptState *st)
{
- int nameid = 0, count = 0, i;
+ ItemNameId nameid;
+ int count = 0;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -1909,22 +1937,24 @@ void builtin_countitem(ScriptState *st)
{
ZString name = ZString(conv_str(st, data));
struct item_data *item_data = itemdb_searchname(name);
- if (item_data != NULL)
+ if (item_data != nullptr)
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
- for (i = 0; i < MAX_INVENTORY; i++)
+ if (nameid)
+ {
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid == nameid)
count += sd->status.inventory[i].amount;
}
+ }
else
{
if (battle_config.error_log)
- PRINTF("wrong item ID : countitem (%i)\n", nameid);
+ PRINTF("wrong item ID : countitem (%i)\n"_fmt, nameid);
}
push_int(st->stack, ByteCode::INT, count);
@@ -1937,7 +1967,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;
@@ -1953,10 +1984,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);
@@ -1981,7 +2012,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;
@@ -1993,12 +2025,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)
+ if (item_data != nullptr)
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)
@@ -2006,21 +2037,21 @@ void builtin_getitem(ScriptState *st)
return; //return if amount <=0, skip the useles iteration
}
- if (nameid > 0)
+ if (nameid)
{
- struct item item_tmp {};
+ Item item_tmp {};
item_tmp.nameid = nameid;
if (HARGO2(5)) //アイテムを指定したIDに渡す
- sd = map_id2sd(conv_num(st, &AARGO2(5)));
- if (sd == NULL) //アイテムを渡す相手がいなかったらお帰り
+ sd = map_id2sd(wrap<BlockId>(conv_num(st, &AARGO2(5))));
+ if (sd == nullptr) //アイテムを渡す相手がいなかったらお帰り
return;
PickupFail flag;
if ((flag = pc_additem(sd, &item_tmp, amount)) != PickupFail::OKAY)
{
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
map_addflooritem(&item_tmp, amount,
sd->bl_m, sd->bl_x, sd->bl_y,
- NULL, NULL, NULL);
+ nullptr, nullptr, nullptr);
}
}
@@ -2033,7 +2064,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;
@@ -2046,12 +2078,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))));
@@ -2064,12 +2095,12 @@ void builtin_makeitem(ScriptState *st)
else
m = map_mapname2mapid(mapname);
- if (nameid > 0)
+ if (nameid)
{
- struct item item_tmp {};
+ Item item_tmp {};
item_tmp.nameid = nameid;
- map_addflooritem(&item_tmp, amount, m, x, y, NULL, NULL, NULL);
+ map_addflooritem(&item_tmp, amount, m, x, y, nullptr, nullptr, nullptr);
}
}
@@ -2080,7 +2111,8 @@ void builtin_makeitem(ScriptState *st)
static
void builtin_delitem(ScriptState *st)
{
- int nameid = 0, amount, i;
+ ItemNameId nameid;
+ int amount;
dumb_ptr<map_session_data> sd;
struct script_data *data;
@@ -2092,31 +2124,21 @@ 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
- //PRINTF("wrong item ID or amount<=0 : delitem %i,\n",nameid,amount);
return;
}
- 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++)
+ for (IOff0 i : IOff0::iter())
{
if (sd->status.inventory[i].nameid == nameid)
{
@@ -2153,7 +2175,7 @@ void builtin_readparam(ScriptState *st)
else
sd = script_rid2sd(st);
- if (sd == NULL)
+ if (sd == nullptr)
{
push_int(st->stack, ByteCode::INT, -1);
return;
@@ -2178,19 +2200,19 @@ void builtin_getcharid(ScriptState *st)
sd = map_nick2sd(stringish<CharName>(ZString(conv_str(st, &AARGO2(3)))));
else
sd = script_rid2sd(st);
- if (sd == NULL)
+ if (sd == nullptr)
{
push_int(st->stack, ByteCode::INT, -1);
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,9 +2220,9 @@ 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);
+ PartyPair p = party_search(party_id);
if (p)
return dumb_string::copys(p->name);
@@ -2231,12 +2253,12 @@ void builtin_strcharinfo(ScriptState *st)
if (buf)
push_str(st->stack, ByteCode::STR, buf);
else
- push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""));
+ push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""_s));
}
if (num == 2)
{
// was: guild name
- push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""));
+ push_str(st->stack, ByteCode::CONSTSTR, dumb_string::fake(""_s));
}
}
@@ -2266,23 +2288,23 @@ Array<EPOS, 11> equip //=
static
void builtin_getequipid(ScriptState *st)
{
- int i, num;
+ int num;
dumb_ptr<map_session_data> sd;
struct item_data *item;
sd = script_rid2sd(st);
- if (sd == NULL)
+ if (sd == nullptr)
{
- PRINTF("getequipid: sd == NULL\n");
+ PRINTF("getequipid: sd == nullptr\n"_fmt);
return;
}
num = conv_num(st, &AARGO2(2));
- i = pc_checkequip(sd, equip[num - 1]);
- if (i >= 0)
+ IOff0 i = pc_checkequip(sd, equip[num - 1]);
+ if (i.ok())
{
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);
}
@@ -2299,7 +2321,7 @@ void builtin_getequipid(ScriptState *st)
static
void builtin_getequipname(ScriptState *st)
{
- int i, num;
+ int num;
dumb_ptr<map_session_data> sd;
struct item_data *item;
@@ -2307,18 +2329,18 @@ void builtin_getequipname(ScriptState *st)
sd = script_rid2sd(st);
num = conv_num(st, &AARGO2(2));
- i = pc_checkequip(sd, equip[num - 1]);
- if (i >= 0)
+ IOff0 i = pc_checkequip(sd, equip[num - 1]);
+ if (i.ok())
{
item = sd->inventory_data[i];
if (item)
- buf = STRPRINTF("%s-[%s]", pos_str[num - 1], item->jname);
+ buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], item->jname);
else
- buf = STRPRINTF("%s-[%s]", pos_str[num - 1], pos_str[10]);
+ buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]);
}
else
{
- buf = STRPRINTF("%s-[%s]", pos_str[num - 1], pos_str[10]);
+ buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]);
}
push_str(st->stack, ByteCode::STR, dumb_string::copys(buf));
@@ -2423,7 +2445,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());
}
/*==========================================
@@ -2448,7 +2470,7 @@ void builtin_getopt2(ScriptState *st)
sd = script_rid2sd(st);
- push_int(st->stack, ByteCode::INT, uint16_t(sd->opt2));
+ push_int(st->stack, ByteCode::INT, static_cast<uint16_t>(sd->opt2));
}
@@ -2613,14 +2635,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 +2659,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 +2669,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);
@@ -2683,7 +2707,7 @@ void builtin_killmonster(ScriptState *st)
MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARGO2(2))));
ZString event_ = ZString(conv_str(st, &AARGO2(3)));
NpcEvent event;
- if (event_ != "All")
+ if (event_ != "All"_s)
extract(event_, &event);
map_local *m = map_mapname2mapid(mapname);
@@ -2997,7 +3021,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,14 +3031,14 @@ 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();
if (drop->item_data.nameid == item)
{
(*amount) += drop->item_data.amount;
- clif_clearflooritem(drop, 0);
+ clif_clearflooritem(drop, nullptr);
map_delobject(drop->bl_id, drop->bl_type);
}
}
@@ -3022,7 +3046,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 +3062,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));
@@ -3102,7 +3126,7 @@ void builtin_sc_start(ScriptState *st)
int val1;
StatusChange type = static_cast<StatusChange>(conv_num(st, &AARGO2(2)));
interval_t tick = static_cast<interval_t>(conv_num(st, &AARGO2(3)));
- if (tick < std::chrono::seconds(1))
+ if (tick < 1_s)
// work around old behaviour of:
// speed potion
// atk potion
@@ -3113,7 +3137,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);
@@ -3151,7 +3175,7 @@ static
void builtin_debugmes(ScriptState *st)
{
dumb_string mes = conv_str(st, &AARGO2(2));
- PRINTF("script debug : %d %d : %s\n",
+ PRINTF("script debug : %d %d : %s\n"_fmt,
st->rid, st->oid, mes);
}
@@ -3174,10 +3198,10 @@ void builtin_resetstatus(ScriptState *st)
static
void builtin_changesex(ScriptState *st)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
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,8 +3212,8 @@ void builtin_changesex(ScriptState *st)
static
void builtin_attachrid(ScriptState *st)
{
- st->rid = conv_num(st, &AARGO2(2));
- push_int(st->stack, ByteCode::INT, (map_id2sd(st->rid) != NULL));
+ st->rid = wrap<BlockId>(conv_num(st, &AARGO2(2)));
+ push_int(st->stack, ByteCode::INT, (map_id2sd(st->rid) != nullptr));
}
/*==========================================
@@ -3199,7 +3223,7 @@ void builtin_attachrid(ScriptState *st)
static
void builtin_detachrid(ScriptState *st)
{
- st->rid = 0;
+ st->rid = BlockId();
}
/*==========================================
@@ -3210,8 +3234,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)))) != nullptr);
}
static
@@ -3279,7 +3302,7 @@ void builtin_pvpon(ScriptState *st)
{
if (m == pl_sd->bl_m && !pl_sd->pvp_timer)
{
- pl_sd->pvp_timer = Timer(gettick() + std::chrono::milliseconds(200),
+ 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;
@@ -3411,7 +3434,7 @@ void builtin_marriage(ScriptState *st)
dumb_ptr<map_session_data> sd = script_rid2sd(st);
dumb_ptr<map_session_data> p_sd = map_nick2sd(partner);
- if (sd == NULL || p_sd == NULL || pc_marriage(sd, p_sd) < 0)
+ if (sd == nullptr || p_sd == nullptr || pc_marriage(sd, p_sd) < 0)
{
push_int(st->stack, ByteCode::INT, 0);
return;
@@ -3428,7 +3451,7 @@ void builtin_divorce(ScriptState *st)
sd->npc_flags.divorce = 1;
- if (sd == NULL || pc_divorce(sd) < 0)
+ if (sd == nullptr || pc_divorce(sd) < 0)
{
push_int(st->stack, ByteCode::INT, 0);
return;
@@ -3456,7 +3479,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);
}
@@ -3464,7 +3487,7 @@ void builtin_getitemname(ScriptState *st)
if (i_data)
item_name = dumb_string::copys(i_data->jname);
else
- item_name = dumb_string::copys("Unknown Item");
+ item_name = dumb_string::copys("Unknown Item"_s);
push_str(st->stack, ByteCode::STR, item_name);
}
@@ -3474,9 +3497,9 @@ void builtin_getspellinvocation(ScriptState *st)
{
dumb_string name = conv_str(st, &AARGO2(2));
- AString invocation = magic_find_invocation(name.str());
+ AString invocation = magic::magic_find_invocation(name.str());
if (!invocation)
- invocation = "...";
+ invocation = "..."_s;
push_str(st->stack, ByteCode::STR, dumb_string::copys(invocation));
}
@@ -3486,7 +3509,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));
}
/*==========================================
@@ -3497,24 +3520,24 @@ static
void builtin_getinventorylist(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- int i, j = 0;
+ int j = 0;
if (!sd)
return;
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
- 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"), j),
- sd->status.inventory[i].nameid);
- pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_amount"), j),
+ pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_id"_s), j),
+ 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"), j),
+ pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_equip"_s), j),
static_cast<uint16_t>(sd->status.inventory[i].equip));
j++;
}
}
- pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_count")), j);
+ pc_setreg(sd, SIR::from(variable_names.intern("@inventorylist_count"_s)), j);
}
static
@@ -3534,18 +3557,18 @@ void builtin_getactivatedpoolskilllist(ScriptState *st)
if (sd->status.skill[skill_id].lv)
{
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"), count),
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"_s), count),
static_cast<uint16_t>(skill_id));
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"), count),
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"_s), count),
sd->status.skill[skill_id].lv);
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"), count),
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"_s), count),
static_cast<uint16_t>(sd->status.skill[skill_id].flags));
- pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"), count),
+ pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"_s), count),
skill_name(skill_id));
++count;
}
}
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count")), count);
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count"_s)), count);
}
@@ -3565,18 +3588,18 @@ void builtin_getunactivatedpoolskilllist(ScriptState *st)
if (sd->status.skill[skill_id].lv
&& !bool(sd->status.skill[skill_id].flags & SkillFlags::POOL_ACTIVATED))
{
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"), count),
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_id"_s), count),
static_cast<uint16_t>(skill_id));
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"), count),
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_lv"_s), count),
sd->status.skill[skill_id].lv);
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"), count),
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_flag"_s), count),
static_cast<uint16_t>(sd->status.skill[skill_id].flags));
- pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"), count),
+ pc_setregstr(sd, SIR::from(variable_names.intern("@skilllist_name$"_s), count),
skill_name(skill_id));
++count;
}
}
- pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count")), count);
+ pc_setreg(sd, SIR::from(variable_names.intern("@skilllist_count"_s)), count);
}
static
@@ -3616,9 +3639,9 @@ static
void builtin_misceffect(ScriptState *st)
{
int type;
- int id = 0;
+ BlockId id;
CharName name;
- dumb_ptr<block_list> bl = NULL;
+ dumb_ptr<block_list> bl = nullptr;
type = conv_num(st, &AARGO2(2));
@@ -3631,7 +3654,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())
@@ -3665,7 +3688,7 @@ void builtin_specialeffect(ScriptState *st)
{
dumb_ptr<block_list> bl = map_id2bl(st->oid);
- if (bl == NULL)
+ if (bl == nullptr)
return;
clif_specialeffect(bl,
@@ -3680,7 +3703,7 @@ void builtin_specialeffect2(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- if (sd == NULL)
+ if (sd == nullptr)
return;
clif_specialeffect(sd,
@@ -3700,13 +3723,13 @@ void builtin_nude(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- if (sd == NULL)
+ if (sd == nullptr)
return;
for (EQUIP i : EQUIPs)
{
- int idx = sd->equip_index_maybe[i];
- if (idx >= 0)
+ IOff0 idx = sd->equip_index_maybe[i];
+ if (idx.ok())
pc_unequipitem(sd, idx, CalcStatus::LATER);
}
pc_calcstatus(sd, 0);
@@ -3722,15 +3745,15 @@ static
void builtin_unequipbyid(ScriptState *st)
{
dumb_ptr<map_session_data> sd = script_rid2sd(st);
- if (sd == NULL)
+ if (sd == nullptr)
return;
EQUIP slot_id = EQUIP(conv_num(st, &AARGO2(2)));
if (slot_id >= EQUIP() && slot_id < EQUIP::COUNT)
{
- int idx = sd->equip_index_maybe[slot_id];
- if (idx >= 0)
+ IOff0 idx = sd->equip_index_maybe[slot_id];
+ if (idx.ok())
pc_unequipitem(sd, idx, CalcStatus::LATER);
}
@@ -3753,7 +3776,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));
}
@@ -3766,7 +3789,7 @@ static
void builtin_npcwarp(ScriptState *st)
{
int x, y;
- dumb_ptr<npc_data> nd = NULL;
+ dumb_ptr<npc_data> nd = nullptr;
x = conv_num(st, &AARGO2(2));
y = conv_num(st, &AARGO2(3));
@@ -3775,7 +3798,7 @@ void builtin_npcwarp(ScriptState *st)
if (!nd)
{
- PRINTF("builtin_npcwarp: no such npc: %s\n", npc);
+ PRINTF("builtin_npcwarp: no such npc: %s\n"_fmt, npc);
return;
}
@@ -3808,7 +3831,7 @@ void builtin_message(ScriptState *st)
ZString msg = ZString(conv_str(st, &AARGO2(3)));
dumb_ptr<map_session_data> pl_sd = map_nick2sd(player);
- if (pl_sd == NULL)
+ if (pl_sd == nullptr)
return;
clif_displaymessage(pl_sd->sess, msg);
@@ -3828,11 +3851,7 @@ void builtin_npctalk(ScriptState *st)
if (nd)
{
- MString message;
- message += nd->name;
- message += " : ";
- message += ZString(str);
- clif_message(nd, AString(message));
+ clif_message(nd, XString(str));
}
}
@@ -3856,13 +3875,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;
@@ -3871,7 +3890,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;
@@ -3988,7 +4007,7 @@ void builtin_shop(ScriptState *st)
nd = npc_name2id(name);
if (!nd)
{
- PRINTF("builtin_shop: no such npc: %s\n", name);
+ PRINTF("builtin_shop: no such npc: %s\n"_fmt, name);
return;
}
@@ -4017,11 +4036,11 @@ void builtin_fakenpcname(ScriptState *st)
{
NpcName name = stringish<NpcName>(ZString(conv_str(st, &AARGO2(2))));
NpcName newname = stringish<NpcName>(ZString(conv_str(st, &AARGO2(3))));
- int newsprite = conv_num(st, &AARGO2(4));
+ Species newsprite = wrap<Species>(static_cast<uint16_t>(conv_num(st, &AARGO2(4))));
dumb_ptr<npc_data> nd = npc_name2id(name);
if (!nd)
{
- PRINTF("builtin_fakenpcname: no such npc: %s\n", name);
+ PRINTF("builtin_fakenpcname: no such npc: %s\n"_fmt, name);
return;
}
nd->name = newname;
@@ -4205,7 +4224,7 @@ void op_2str(ScriptState *st, ByteCode op, dumb_string s1_, dumb_string s2_)
a = s1 <= s2;
break;
default:
- PRINTF("illegal string operater\n");
+ PRINTF("illegal string operater\n"_fmt);
break;
}
@@ -4308,7 +4327,7 @@ void op_2(ScriptState *st, ByteCode op)
else
{
// si,is => error
- PRINTF("script: op_2: int&str, str&int not allow.\n");
+ PRINTF("script: op_2: int&str, str&int not allow.\n"_fmt);
push_int(st->stack, ByteCode::INT, 0);
}
}
@@ -4351,7 +4370,7 @@ void run_func(ScriptState *st)
if (start_sp == 0)
{
if (battle_config.error_log)
- PRINTF("function not found\n");
+ PRINTF("function not found\n"_fmt);
st->state = ScriptEndState::END;
return;
}
@@ -4364,52 +4383,52 @@ void run_func(ScriptState *st)
size_t func = st->stack->stack_datav[st->start].u.numi;
if (st->stack->stack_datav[st->start].type != ByteCode::FUNC_REF)
{
- PRINTF("run_func: not function and command! \n");
+ PRINTF("run_func: not function and command! \n"_fmt);
st->state = ScriptEndState::END;
return;
}
if (DEBUG_RUN && battle_config.etc_log)
{
- PRINTF("run_func : %s\n",
+ PRINTF("run_func : %s\n"_fmt,
builtin_functions[func].name);
- PRINTF("stack dump :");
+ PRINTF("stack dump :"_fmt);
for (script_data& d : st->stack->stack_datav)
{
switch (d.type)
{
case ByteCode::INT:
- PRINTF(" int(%d)", d.u.numi);
+ PRINTF(" int(%d)"_fmt, d.u.numi);
break;
case ByteCode::RETINFO:
- PRINTF(" retinfo(%p)", static_cast<const void *>(d.u.script));
+ PRINTF(" retinfo(%p)"_fmt, static_cast<const void *>(d.u.script));
break;
case ByteCode::PARAM_:
- PRINTF(" param(%d)", d.u.reg.sp());
+ PRINTF(" param(%d)"_fmt, d.u.reg.sp());
break;
case ByteCode::VARIABLE:
- PRINTF(" name(%s)[%d]", variable_names.outtern(d.u.reg.base()), d.u.reg.index());
+ PRINTF(" name(%s)[%d]"_fmt, variable_names.outtern(d.u.reg.base()), d.u.reg.index());
break;
case ByteCode::ARG:
- PRINTF(" arg");
+ PRINTF(" arg"_fmt);
break;
case ByteCode::POS:
- PRINTF(" pos(%d)", d.u.numi);
+ PRINTF(" pos(%d)"_fmt, d.u.numi);
break;
case ByteCode::STR:
- PRINTF(" str(%s)", d.u.str);
+ PRINTF(" str(%s)"_fmt, d.u.str);
break;
case ByteCode::CONSTSTR:
- PRINTF(" cstr(%s)", d.u.str);
+ PRINTF(" cstr(%s)"_fmt, d.u.str);
break;
case ByteCode::FUNC_REF:
- PRINTF(" func(%s)", builtin_functions[d.u.numi].name);
+ PRINTF(" func(%s)"_fmt, builtin_functions[d.u.numi].name);
break;
default:
- PRINTF(" %d,%d", d.type, d.u.numi);
+ PRINTF(" %d,%d"_fmt, d.type, d.u.numi);
}
}
- PRINTF("\n");
+ PRINTF("\n"_fmt);
}
builtin_functions[func].func(st);
@@ -4424,7 +4443,7 @@ void run_func(ScriptState *st)
if (st->defsp < 4
|| st->stack->stack_datav[st->defsp - 1].type != ByteCode::RETINFO)
{
- PRINTF("script:run_func (return) return without callfunc or callsub!\n");
+ PRINTF("script:run_func (return) return without callfunc or callsub!\n"_fmt);
st->state = ScriptEndState::END;
return;
}
@@ -4449,15 +4468,15 @@ void dump_script(const ScriptBuffer *script)
ScriptPointer scriptp(script, 0);
while (scriptp.pos < reinterpret_cast<const std::vector<ByteCode> *>(script)->size())
{
- PRINTF("%6zu: ", scriptp.pos);
+ PRINTF("%6zu: "_fmt, scriptp.pos);
switch (ByteCode c = get_com(&scriptp))
{
case ByteCode::EOL:
- PRINTF("EOL\n"); // extra newline between functions
+ PRINTF("EOL\n"_fmt); // extra newline between functions
break;
case ByteCode::INT:
// synthesized!
- PRINTF("INT %d", get_num(&scriptp));
+ PRINTF("INT %d"_fmt, get_num(&scriptp));
break;
case ByteCode::POS:
@@ -4472,103 +4491,103 @@ void dump_script(const ScriptBuffer *script)
switch(c)
{
case ByteCode::POS:
- PRINTF("POS %d", arg);
+ PRINTF("POS %d"_fmt, arg);
break;
case ByteCode::VARIABLE:
- PRINTF("VARIABLE %s", variable_names.outtern(arg));
+ PRINTF("VARIABLE %s"_fmt, variable_names.outtern(arg));
break;
case ByteCode::FUNC_REF:
- PRINTF("FUNC_REF %s", builtin_functions[arg].name);
+ PRINTF("FUNC_REF %s"_fmt, builtin_functions[arg].name);
break;
case ByteCode::PARAM_:
- PRINTF("PARAM SP::#%d (sorry)", arg);
+ PRINTF("PARAM SP::#%d (sorry)"_fmt, arg);
break;
}
}
break;
case ByteCode::ARG:
- PRINTF("ARG");
+ PRINTF("ARG"_fmt);
break;
case ByteCode::STR:
- PRINTF("STR \"%s\"", scriptp.pops());
+ PRINTF("STR \"%s\""_fmt, scriptp.pops());
break;
case ByteCode::FUNC_:
- PRINTF("FUNC_");
+ PRINTF("FUNC_"_fmt);
break;
case ByteCode::ADD:
- PRINTF("ADD");
+ PRINTF("ADD"_fmt);
break;
case ByteCode::SUB:
- PRINTF("SUB");
+ PRINTF("SUB"_fmt);
break;
case ByteCode::MUL:
- PRINTF("MUL");
+ PRINTF("MUL"_fmt);
break;
case ByteCode::DIV:
- PRINTF("DIV");
+ PRINTF("DIV"_fmt);
break;
case ByteCode::MOD:
- PRINTF("MOD");
+ PRINTF("MOD"_fmt);
break;
case ByteCode::EQ:
- PRINTF("EQ");
+ PRINTF("EQ"_fmt);
break;
case ByteCode::NE:
- PRINTF("NE");
+ PRINTF("NE"_fmt);
break;
case ByteCode::GT:
- PRINTF("GT");
+ PRINTF("GT"_fmt);
break;
case ByteCode::GE:
- PRINTF("GE");
+ PRINTF("GE"_fmt);
break;
case ByteCode::LT:
- PRINTF("LT");
+ PRINTF("LT"_fmt);
break;
case ByteCode::LE:
- PRINTF("LE");
+ PRINTF("LE"_fmt);
break;
case ByteCode::AND:
- PRINTF("AND");
+ PRINTF("AND"_fmt);
break;
case ByteCode::OR:
- PRINTF("OR");
+ PRINTF("OR"_fmt);
break;
case ByteCode::XOR:
- PRINTF("XOR");
+ PRINTF("XOR"_fmt);
break;
case ByteCode::LAND:
- PRINTF("LAND");
+ PRINTF("LAND"_fmt);
break;
case ByteCode::LOR:
- PRINTF("LOR");
+ PRINTF("LOR"_fmt);
break;
case ByteCode::R_SHIFT:
- PRINTF("R_SHIFT");
+ PRINTF("R_SHIFT"_fmt);
break;
case ByteCode::L_SHIFT:
- PRINTF("L_SHIFT");
+ PRINTF("L_SHIFT"_fmt);
break;
case ByteCode::NEG:
- PRINTF("NEG");
+ PRINTF("NEG"_fmt);
break;
case ByteCode::NOT:
- PRINTF("NOT");
+ PRINTF("NOT"_fmt);
break;
case ByteCode::LNOT:
- PRINTF("LNOT");
+ PRINTF("LNOT"_fmt);
break;
case ByteCode::NOP:
- PRINTF("NOP");
+ PRINTF("NOP"_fmt);
break;
default:
- PRINTF("??? %d", c);
+ PRINTF("??? %d"_fmt, c);
break;
}
- PRINTF("\n");
+ PRINTF("\n"_fmt);
}
}
@@ -4595,7 +4614,7 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript)
if (stack->stack_datav.size() != st->defsp)
{
if (battle_config.error_log)
- PRINTF("stack.sp (%zu) != default (%d)\n",
+ PRINTF("stack.sp (%zu) != default (%d)\n"_fmt,
stack->stack_datav.size(),
st->defsp);
stack->stack_datav.resize(st->defsp);
@@ -4650,7 +4669,7 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript)
st->state = ScriptEndState::ZERO;
if (gotocount > 0 && (--gotocount) <= 0)
{
- PRINTF("run_script: infinity loop !\n");
+ PRINTF("run_script: infinity loop !\n"_fmt);
st->state = ScriptEndState::END;
}
}
@@ -4692,14 +4711,14 @@ void run_script_main(ScriptState *st, const ScriptBuffer *rootscript)
default:
if (battle_config.error_log)
- PRINTF("unknown command : %d @ %zu\n",
+ PRINTF("unknown command : %d @ %zu\n"_fmt,
c, st->scriptp.pos);
st->state = ScriptEndState::END;
break;
}
if (cmdcount > 0 && (--cmdcount) <= 0)
{
- PRINTF("run_script: infinity loop !\n");
+ PRINTF("run_script: infinity loop !\n"_fmt);
st->state = ScriptEndState::END;
}
}
@@ -4739,12 +4758,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;
@@ -4752,7 +4771,7 @@ int run_script_l(ScriptPointer sp, int rid, int oid,
dumb_ptr<map_session_data> sd = map_id2sd(rid);
const ScriptBuffer *rootscript = sp.code;
int i;
- if (sp.code == NULL || sp.pos >> 24)
+ if (sp.code == nullptr || sp.pos >> 24)
return -1;
if (sd && !sd->npc_stackbuf.empty() && sd->npc_scriptroot == rootscript)
@@ -4846,7 +4865,7 @@ void script_load_mapreg(void)
else
{
borken:
- PRINTF("%s: %s broken data !\n", mapreg_txt, AString(buf1));
+ PRINTF("%s: %s broken data !\n"_fmt, mapreg_txt, AString(buf1));
continue;
}
}
@@ -4865,9 +4884,9 @@ void script_save_mapreg_intsub(SIR key, int data, io::WriteFile& fp)
if (name[1] != '@')
{
if (i == 0)
- FPRINTF(fp, "%s\t%d\n", name, data);
+ FPRINTF(fp, "%s\t%d\n"_fmt, name, data);
else
- FPRINTF(fp, "%s,%d\t%d\n", name, i, data);
+ FPRINTF(fp, "%s,%d\t%d\n"_fmt, name, i, data);
}
}
@@ -4879,9 +4898,9 @@ void script_save_mapreg_strsub(SIR key, ZString data, io::WriteFile& fp)
if (name[1] != '@')
{
if (i == 0)
- FPRINTF(fp, "%s\t%s\n", name, data);
+ FPRINTF(fp, "%s\t%s\n"_fmt, name, data);
else
- FPRINTF(fp, "%s,%d\t%s\n", name, i, data);
+ FPRINTF(fp, "%s,%d\t%s\n"_fmt, name, i, data);
}
}
@@ -4932,129 +4951,128 @@ void do_init_script(void)
).detach();
}
-#define BUILTIN(func, args) \
-{builtin_##func, {#func}, {args}}
+#define BUILTIN(func, args, ret) \
+{builtin_##func, #func ## _s, args, ret}
BuiltinFunction builtin_functions[] =
{
- BUILTIN(mes, "s"),
- BUILTIN(next, ""),
- BUILTIN(close, ""),
- BUILTIN(close2, ""),
- BUILTIN(menu, "sL*"),
- BUILTIN(goto, "L"),
- BUILTIN(callsub, "L"),
- BUILTIN(callfunc, "F"),
- BUILTIN(return, ""),
- BUILTIN(input, "N"),
- BUILTIN(warp, "Mxy"),
- BUILTIN(isat, "Mxy"),
- BUILTIN(areawarp, "MxyxyMxy"),
- BUILTIN(setlook, "ii"),
- BUILTIN(set, "Ne"),
- BUILTIN(setarray, "Ne*"),
- BUILTIN(cleararray, "Nei"),
- BUILTIN(getarraysize, "N"),
- BUILTIN(getelementofarray, "Ni"),
- BUILTIN(if, "iF*"),
- BUILTIN(getitem, "Ii**"),
- BUILTIN(makeitem, "IiMxy"),
- BUILTIN(delitem, "Ii"),
- BUILTIN(heal, "ii"),
- BUILTIN(itemheal, "ii"),
- BUILTIN(percentheal, "ii"),
- BUILTIN(rand, "i*"),
- BUILTIN(pow, "ii"),
- BUILTIN(countitem, "I"),
- BUILTIN(checkweight, "Ii"),
- BUILTIN(readparam, "i*"),
- BUILTIN(getcharid, "i*"),
- BUILTIN(strcharinfo, "i"),
- BUILTIN(getequipid, "i"),
- BUILTIN(getequipname, "i"),
- BUILTIN(statusup2, "ii"),
- BUILTIN(bonus, "ii"),
- BUILTIN(bonus2, "iii"),
- BUILTIN(skill, "ii*"),
- BUILTIN(setskill, "ii"),
- BUILTIN(getskilllv, "i"),
- BUILTIN(getgmlevel, ""),
- BUILTIN(end, ""),
- BUILTIN(getopt2, ""),
- BUILTIN(setopt2, "i"),
- BUILTIN(savepoint, "Mxy"),
- BUILTIN(gettimetick, "i"),
- BUILTIN(gettime, "i"),
- BUILTIN(openstorage, "*"),
- BUILTIN(monster, "Mxysmi*"),
- BUILTIN(areamonster, "Mxyxysmi*"),
- BUILTIN(killmonster, "ME"),
- BUILTIN(killmonsterall, "M"),
- BUILTIN(donpcevent, "E"),
- BUILTIN(addtimer, "tE"),
- BUILTIN(initnpctimer, ""),
- BUILTIN(stopnpctimer, ""),
- BUILTIN(startnpctimer, "*"),
- BUILTIN(setnpctimer, "i"),
- BUILTIN(getnpctimer, "i"),
- BUILTIN(announce, "si"),
- BUILTIN(mapannounce, "Msi"),
- BUILTIN(getusers, "i"),
- BUILTIN(getmapusers, "M"),
- BUILTIN(getareausers, "Mxyxy*"),
- BUILTIN(getareadropitem, "Mxyxyi*"),
- BUILTIN(enablenpc, "s"),
- BUILTIN(disablenpc, "s"),
- BUILTIN(sc_start, "iTi*"),
- BUILTIN(sc_end, "i"),
- BUILTIN(sc_check, "i"),
- BUILTIN(debugmes, "s"),
- BUILTIN(resetstatus, ""),
- BUILTIN(changesex, ""),
- BUILTIN(attachrid, "i"),
- BUILTIN(detachrid, ""),
- BUILTIN(isloggedin, "i"),
- BUILTIN(setmapflag, "Mi"),
- BUILTIN(removemapflag, "Mi"),
- BUILTIN(getmapflag, "Mi"),
- BUILTIN(pvpon, "M"),
- BUILTIN(pvpoff, "M"),
- BUILTIN(emotion, "i"),
- BUILTIN(marriage, "P"),
- BUILTIN(divorce, ""),
- BUILTIN(getitemname, "I"),
- BUILTIN(getspellinvocation, "s"),
- BUILTIN(getpartnerid2, ""),
- BUILTIN(getexp, "ii"),
- BUILTIN(getinventorylist, ""),
- BUILTIN(getactivatedpoolskilllist, ""),
- BUILTIN(getunactivatedpoolskilllist, ""),
- BUILTIN(poolskill, "i"),
- BUILTIN(unpoolskill, "i"),
- BUILTIN(misceffect, "i*"),
- BUILTIN(specialeffect, "i"),
- BUILTIN(specialeffect2, "i"),
- BUILTIN(nude, ""),
- BUILTIN(mapwarp, "MMxy"),
- BUILTIN(cmdothernpc, "ss"),
- BUILTIN(gmcommand, "s"),
- BUILTIN(npcwarp, "xys"),
- BUILTIN(message, "Ps"),
- BUILTIN(npctalk, "s"),
- BUILTIN(mobcount, "ME"),
- BUILTIN(getlook, "i"),
- BUILTIN(getsavepoint, "i"),
- BUILTIN(areatimer, "MxyxytE"),
- BUILTIN(isin, "Mxyxy"),
- BUILTIN(shop, "s"),
- BUILTIN(isdead, ""),
- BUILTIN(unequipbyid, "i"),
- BUILTIN(fakenpcname, "ssi"),
- BUILTIN(getx, ""),
- BUILTIN(gety, ""),
- BUILTIN(getmap, ""),
- BUILTIN(mapexit, ""),
- {nullptr, ZString(), ZString()},
+ BUILTIN(mes, "s"_s, '\0'),
+ BUILTIN(goto, "L"_s, '\0'),
+ BUILTIN(callfunc, "F"_s, '\0'),
+ BUILTIN(callsub, "L"_s, '\0'),
+ BUILTIN(return, ""_s, '\0'),
+ BUILTIN(next, ""_s, '\0'),
+ BUILTIN(close, ""_s, '\0'),
+ BUILTIN(close2, ""_s, '\0'),
+ BUILTIN(menu, "sL**"_s, '\0'),
+ BUILTIN(rand, "i?"_s, 'i'),
+ BUILTIN(isat, "Mxy"_s, 'i'),
+ BUILTIN(warp, "Mxy"_s, '\0'),
+ BUILTIN(areawarp, "MxyxyMxy"_s, '\0'),
+ BUILTIN(heal, "ii"_s, '\0'),
+ BUILTIN(itemheal, "ii"_s, '\0'),
+ BUILTIN(percentheal, "ii"_s, '\0'),
+ BUILTIN(input, "N"_s, '\0'),
+ BUILTIN(if, "iF*"_s, '\0'),
+ BUILTIN(set, "Ne"_s, '\0'),
+ BUILTIN(setarray, "Ne*"_s, '\0'),
+ BUILTIN(cleararray, "Nei"_s, '\0'),
+ BUILTIN(getarraysize, "N"_s, 'i'),
+ BUILTIN(getelementofarray, "Ni"_s, '.'),
+ BUILTIN(setlook, "ii"_s, '\0'),
+ BUILTIN(countitem, "I"_s, 'i'),
+ BUILTIN(checkweight, "Ii"_s, 'i'),
+ BUILTIN(getitem, "Ii??"_s, '\0'),
+ BUILTIN(makeitem, "IiMxy"_s, '\0'),
+ BUILTIN(delitem, "Ii"_s, '\0'),
+ BUILTIN(readparam, "i?"_s, 'i'),
+ BUILTIN(getcharid, "i?"_s, 'i'),
+ BUILTIN(strcharinfo, "i"_s, 's'),
+ BUILTIN(getequipid, "i"_s, 'i'),
+ BUILTIN(getequipname, "i"_s, 's'),
+ BUILTIN(statusup2, "ii"_s, '\0'),
+ BUILTIN(bonus, "ii"_s, '\0'),
+ BUILTIN(bonus2, "iii"_s, '\0'),
+ BUILTIN(skill, "ii?"_s, '\0'),
+ BUILTIN(setskill, "ii"_s, '\0'),
+ BUILTIN(getskilllv, "i"_s, 'i'),
+ BUILTIN(getgmlevel, ""_s, 'i'),
+ BUILTIN(end, ""_s, '\0'),
+ BUILTIN(getopt2, ""_s, 'i'),
+ BUILTIN(setopt2, "i"_s, '\0'),
+ BUILTIN(savepoint, "Mxy"_s, '\0'),
+ BUILTIN(gettimetick, "i"_s, 'i'),
+ BUILTIN(gettime, "i"_s, 'i'),
+ BUILTIN(openstorage, ""_s, '\0'),
+ BUILTIN(getexp, "ii"_s, '\0'),
+ BUILTIN(monster, "Mxysmi?"_s, '\0'),
+ BUILTIN(areamonster, "Mxyxysmi?"_s, '\0'),
+ BUILTIN(killmonster, "ME"_s, '\0'),
+ BUILTIN(killmonsterall, "M"_s, '\0'),
+ BUILTIN(donpcevent, "E"_s, '\0'),
+ BUILTIN(addtimer, "tE"_s, '\0'),
+ BUILTIN(initnpctimer, ""_s, '\0'),
+ BUILTIN(startnpctimer, "?"_s, '\0'),
+ BUILTIN(stopnpctimer, ""_s, '\0'),
+ BUILTIN(getnpctimer, "i"_s, 'i'),
+ BUILTIN(setnpctimer, "i"_s, '\0'),
+ BUILTIN(announce, "si"_s, '\0'),
+ BUILTIN(mapannounce, "Msi"_s, '\0'),
+ BUILTIN(getusers, "i"_s, 'i'),
+ BUILTIN(getmapusers, "M"_s, 'i'),
+ BUILTIN(getareausers, "Mxyxy?"_s, 'i'),
+ BUILTIN(getareadropitem, "Mxyxyi?"_s, 'i'),
+ BUILTIN(enablenpc, "s"_s, '\0'),
+ BUILTIN(disablenpc, "s"_s, '\0'),
+ BUILTIN(sc_start, "iTi?"_s, '\0'),
+ BUILTIN(sc_end, "i"_s, '\0'),
+ BUILTIN(sc_check, "i"_s, 'i'),
+ BUILTIN(debugmes, "s"_s, '\0'),
+ BUILTIN(resetstatus, ""_s, '\0'),
+ BUILTIN(changesex, ""_s, '\0'),
+ BUILTIN(attachrid, "i"_s, 'i'),
+ BUILTIN(detachrid, ""_s, '\0'),
+ BUILTIN(isloggedin, "i"_s, 'i'),
+ BUILTIN(setmapflag, "Mi"_s, '\0'),
+ BUILTIN(removemapflag, "Mi"_s, '\0'),
+ BUILTIN(getmapflag, "Mi"_s, 'i'),
+ BUILTIN(pvpon, "M"_s, '\0'),
+ BUILTIN(pvpoff, "M"_s, '\0'),
+ BUILTIN(emotion, "i"_s, '\0'),
+ BUILTIN(mapwarp, "MMxy"_s, '\0'),
+ BUILTIN(cmdothernpc, "ss"_s, '\0'),
+ BUILTIN(mobcount, "ME"_s, 'i'),
+ BUILTIN(marriage, "P"_s, 'i'),
+ BUILTIN(divorce, ""_s, 'i'),
+ BUILTIN(getitemname, "I"_s, 's'),
+ BUILTIN(getspellinvocation, "s"_s, 's'),
+ BUILTIN(getpartnerid2, ""_s, 'i'),
+ BUILTIN(getinventorylist, ""_s, '\0'),
+ BUILTIN(getactivatedpoolskilllist, ""_s, '\0'),
+ BUILTIN(getunactivatedpoolskilllist, ""_s, '\0'),
+ BUILTIN(poolskill, "i"_s, '\0'),
+ BUILTIN(unpoolskill, "i"_s, '\0'),
+ BUILTIN(misceffect, "i?"_s, '\0'),
+ BUILTIN(specialeffect, "i"_s, '\0'),
+ BUILTIN(specialeffect2, "i"_s, '\0'),
+ BUILTIN(nude, ""_s, '\0'),
+ BUILTIN(unequipbyid, "i"_s, '\0'),
+ BUILTIN(gmcommand, "s"_s, '\0'),
+ BUILTIN(npcwarp, "xys"_s, '\0'),
+ BUILTIN(message, "Ps"_s, '\0'),
+ BUILTIN(npctalk, "s"_s, '\0'),
+ BUILTIN(getlook, "i"_s, 'i'),
+ BUILTIN(getsavepoint, "i"_s, '.'),
+ BUILTIN(areatimer, "MxyxytE"_s, '\0'),
+ BUILTIN(isin, "Mxyxy"_s, 'i'),
+ BUILTIN(shop, "s"_s, '\0'),
+ BUILTIN(isdead, ""_s, 'i'),
+ BUILTIN(fakenpcname, "ssi"_s, '\0'),
+ BUILTIN(getx, ""_s, 'i'),
+ BUILTIN(gety, ""_s, 'i'),
+ BUILTIN(getmap, ""_s, 's'),
+ BUILTIN(mapexit, ""_s, '\0'),
+ {nullptr, ""_s, ""_s, '\0'},
};
void set_script_var_i(dumb_ptr<map_session_data> sd, VarName var, int e, int val)
@@ -5079,7 +5097,7 @@ int get_script_var_i(dumb_ptr<map_session_data> sd, VarName var, int e)
get_val(sd, &dat);
if (dat.type == ByteCode::INT)
return dat.u.numi;
- PRINTF("Warning: you lied about the type and I'm too lazy to fix it!");
+ PRINTF("Warning: you lied about the type and I'm too lazy to fix it!"_fmt);
return 0;
}
ZString get_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e)
@@ -5092,6 +5110,7 @@ ZString get_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e)
get_val(sd, &dat);
if (dat.type == ByteCode::CONSTSTR)
return dat.u.str;
- PRINTF("Warning: you lied about the type and I can't fix it!");
+ PRINTF("Warning: you lied about the type and I can't fix it!"_fmt);
return ZString();
}
+} // namespace tmwa
diff --git a/src/map/script.hpp b/src/map/script.hpp
index 9ae893d..ee9a5a9 100644
--- a/src/map/script.hpp
+++ b/src/map/script.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_SCRIPT_HPP
-#define TMWA_MAP_SCRIPT_HPP
+#pragma once
// script.hpp - EAthena script frontend, engine, and library.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,26 +20,27 @@
// 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
+#include <cstdint>
-# include <vector>
+#include <vector>
-# include "../range/slice.hpp"
+#include "../range/slice.hpp"
-# include "../strings/rstring.hpp"
-# include "../strings/astring.hpp"
-# include "../strings/zstring.hpp"
+#include "../strings/zstring.hpp"
-# include "../generic/db.hpp"
+#include "../generic/db.hpp"
+#include "../generic/dumb_ptr.hpp"
-# include "../mmo/dumb_ptr.hpp"
-# include "../mmo/utils.hpp"
+#include "../mmo/ids.hpp"
-# include "map.t.hpp"
+#include "clif.t.hpp"
+#include "map.t.hpp"
+
+namespace tmwa
+{
enum class ByteCode : uint8_t;
struct str_data_t;
@@ -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,10 +177,9 @@ 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
Map<ScriptLabel, int> scriptlabel_db;
extern
@@ -200,5 +199,4 @@ void set_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e, XString
int get_script_var_i(dumb_ptr<map_session_data> sd, VarName var, int e);
ZString get_script_var_s(dumb_ptr<map_session_data> sd, VarName var, int e);
-
-#endif // TMWA_MAP_SCRIPT_HPP
+} // namespace tmwa
diff --git a/src/map/script.py b/src/map/script.py
index 068307a..dcde08d 100644
--- a/src/map/script.py
+++ b/src/map/script.py
@@ -3,7 +3,7 @@ class ByteCode:
(workaround for gcc bug 58150)
'''
__slots__ = ('_value')
- name = 'ByteCode'
+ name = 'tmwa::ByteCode'
enabled = True
def __init__(self, value):
@@ -34,7 +34,7 @@ class script_data(object):
''' print a script_data
'''
__slots__ = ('_value')
- name = 'script_data'
+ name = 'tmwa::script_data'
enabled = True
def __init__(self, value):
diff --git a/src/map/skill-pools.cpp b/src/map/skill-pools.cpp
index 6b46d79..89bf426 100644
--- a/src/map/skill-pools.cpp
+++ b/src/map/skill-pools.cpp
@@ -1,3 +1,4 @@
+#include "skill-pools.hpp"
#include "skill.hpp"
// skill-pools.cpp - Additional support for focusable skills.
//
@@ -20,12 +21,16 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "battle.hpp"
#include "pc.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
Array<SkillID, MAX_POOL_SKILLS> skill_pool_skills;
int skill_pool_skills_size = 0;
@@ -34,7 +39,7 @@ void skill_pool_register(SkillID id)
if (skill_pool_skills_size + 1 >= MAX_POOL_SKILLS)
{
FPRINTF(stderr,
- "Too many pool skills! Increase MAX_POOL_SKILLS and recompile.");
+ "Too many pool skills! Increase MAX_POOL_SKILLS and recompile."_fmt);
return;
}
@@ -61,7 +66,7 @@ int skill_pool(dumb_ptr<map_session_data> sd, SkillID *skills)
int skill_pool_size(dumb_ptr<map_session_data> sd)
{
- return skill_pool(sd, NULL);
+ return skill_pool(sd, nullptr);
}
int skill_pool_max(dumb_ptr<map_session_data> sd)
@@ -78,7 +83,7 @@ int skill_pool_activate(dumb_ptr<map_session_data> sd, SkillID skill_id)
{
sd->status.skill[skill_id].flags |= SkillFlags::POOL_ACTIVATED;
pc_calcstatus(sd, 0);
- MAP_LOG_PC(sd, "SKILL-ACTIVATE %d %d %d",
+ MAP_LOG_PC(sd, "SKILL-ACTIVATE %d %d %d"_fmt,
skill_id, sd->status.skill[skill_id].lv,
skill_power(sd, skill_id));
return 0;
@@ -97,7 +102,7 @@ int skill_pool_deactivate(dumb_ptr<map_session_data> sd, SkillID skill_id)
if (bool(sd->status.skill[skill_id].flags & SkillFlags::POOL_ACTIVATED))
{
sd->status.skill[skill_id].flags &= ~SkillFlags::POOL_ACTIVATED;
- MAP_LOG_PC(sd, "SKILL-DEACTIVATE %d", skill_id);
+ MAP_LOG_PC(sd, "SKILL-DEACTIVATE %d"_fmt, skill_id);
pc_calcstatus(sd, 0);
return 0;
}
@@ -142,3 +147,4 @@ int skill_power_bl(dumb_ptr<block_list> bl, SkillID skill)
else
return 0;
}
+} // namespace tmwa
diff --git a/src/map/skill-pools.hpp b/src/map/skill-pools.hpp
index 6781907..c8890e8 100644
--- a/src/map/skill-pools.hpp
+++ b/src/map/skill-pools.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_SKILL_POOLS_HPP
-#define TMWA_MAP_SKILL_POOLS_HPP
+#pragma once
// skill-pools.hpp - dummy header to make Make dependencies work.
//
// Copyright © 2013 Ben Longbons <b.r.longbons@gmail.com>
@@ -19,6 +18,9 @@
// 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"
-#endif // TMWA_MAP_SKILL_POOLS_HPP
+
+namespace tmwa
+{
+} // namespace tmwa
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index 37a3b44..add6a42 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -22,9 +22,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <cassert>
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
+
+#include <algorithm>
#include "../compat/attr.hpp"
#include "../compat/fun.hpp"
@@ -32,56 +31,63 @@
#include "../strings/mstring.hpp"
#include "../strings/rstring.hpp"
+#include "../strings/astring.hpp"
+#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
+#include "../strings/literal.hpp"
#include "../generic/random.hpp"
#include "../io/cxxstdio.hpp"
+#include "../io/cxxstdio_enums.hpp"
#include "../io/read.hpp"
+#include "../net/timer.hpp"
+
#include "../mmo/extract.hpp"
-#include "../mmo/socket.hpp"
-#include "../mmo/timer.hpp"
+#include "../mmo/extract_enums.hpp"
#include "battle.hpp"
#include "clif.hpp"
-#include "magic.hpp"
-#include "map.hpp"
+#include "magic-stmt.hpp"
#include "mob.hpp"
#include "pc.hpp"
#include "../poison.hpp"
+
+namespace tmwa
+{
struct skill_name_db skill_names[] =
{
- {SkillID::AC_OWL, "OWL", "Owl's_Eye"},
-
- {SkillID::NPC_EMOTION, "EMOTION", "NPC_EMOTION"},
- {SkillID::NPC_POISON, "POISON", "NPC_POISON"},
- {SkillID::NPC_SELFDESTRUCTION, "SELFDESTRUCTION", "Kabooooom!"},
- {SkillID::NPC_SUMMONSLAVE, "SUMMONSLAVE", "NPC_SUMMONSLAVE"},
-
- {SkillID::NV_EMOTE, "EMOTE", "Emote_Skill"},
- {SkillID::NV_TRADE, "TRADE", "Trade_Skill"},
- {SkillID::NV_PARTY, "PARTY", "Party_Skill"},
-
- {SkillID::TMW_MAGIC, "MAGIC", "General Magic"},
- {SkillID::TMW_MAGIC_LIFE, "MAGIC_LIFE", "Life Magic"},
- {SkillID::TMW_MAGIC_WAR, "MAGIC_WAR", "War Magic"},
- {SkillID::TMW_MAGIC_TRANSMUTE, "MAGIC_TRANSMUTE", "Transmutation Magic"},
- {SkillID::TMW_MAGIC_NATURE, "MAGIC_NATURE", "Nature Magic"},
- {SkillID::TMW_MAGIC_ETHER, "MAGIC_ETHER", "Astral Magic"},
- {SkillID::TMW_MAGIC_DARK, "MAGIC_DARK", "Dark Magic"},
- {SkillID::TMW_MAGIC_LIGHT, "MAGIC_LIGHT", "Light Magic"},
-
- {SkillID::TMW_BRAWLING, "BRAWLING", "Brawling"},
- {SkillID::TMW_LUCKY_COUNTER, "LUCKY_COUNTER", "Lucky Counter"},
- {SkillID::TMW_SPEED, "SPEED", "Speed"},
- {SkillID::TMW_RESIST_POISON, "RESIST_POISON", "Resist Poison"},
- {SkillID::TMW_ASTRAL_SOUL, "ASTRAL_SOUL", "Astral Soul"},
- {SkillID::TMW_RAGING, "RAGING", "Raging"},
-
- {SkillID::ZERO, "", ""}
+ {SkillID::AC_OWL, "OWL"_s, "Owl's_Eye"_s},
+
+ {SkillID::NPC_EMOTION, "EMOTION"_s, "NPC_EMOTION"_s},
+ {SkillID::NPC_POISON, "POISON"_s, "NPC_POISON"_s},
+ {SkillID::NPC_SELFDESTRUCTION, "SELFDESTRUCTION"_s, "Kabooooom!"_s},
+ {SkillID::NPC_SUMMONSLAVE, "SUMMONSLAVE"_s, "NPC_SUMMONSLAVE"_s},
+
+ {SkillID::NV_EMOTE, "EMOTE"_s, "Emote_Skill"_s},
+ {SkillID::NV_TRADE, "TRADE"_s, "Trade_Skill"_s},
+ {SkillID::NV_PARTY, "PARTY"_s, "Party_Skill"_s},
+
+ {SkillID::TMW_MAGIC, "MAGIC"_s, "General Magic"_s},
+ {SkillID::TMW_MAGIC_LIFE, "MAGIC_LIFE"_s, "Life Magic"_s},
+ {SkillID::TMW_MAGIC_WAR, "MAGIC_WAR"_s, "War Magic"_s},
+ {SkillID::TMW_MAGIC_TRANSMUTE, "MAGIC_TRANSMUTE"_s, "Transmutation Magic"_s},
+ {SkillID::TMW_MAGIC_NATURE, "MAGIC_NATURE"_s, "Nature Magic"_s},
+ {SkillID::TMW_MAGIC_ETHER, "MAGIC_ETHER"_s, "Astral Magic"_s},
+ {SkillID::TMW_MAGIC_DARK, "MAGIC_DARK"_s, "Dark Magic"_s},
+ {SkillID::TMW_MAGIC_LIGHT, "MAGIC_LIGHT"_s, "Light Magic"_s},
+
+ {SkillID::TMW_BRAWLING, "BRAWLING"_s, "Brawling"_s},
+ {SkillID::TMW_LUCKY_COUNTER, "LUCKY_COUNTER"_s, "Lucky Counter"_s},
+ {SkillID::TMW_SPEED, "SPEED"_s, "Speed"_s},
+ {SkillID::TMW_RESIST_POISON, "RESIST_POISON"_s, "Resist Poison"_s},
+ {SkillID::TMW_ASTRAL_SOUL, "ASTRAL_SOUL"_s, "Astral Soul"_s},
+ {SkillID::TMW_RAGING, "RAGING"_s, "Raging"_s},
+
+ {SkillID::ZERO, ""_s, ""_s}
};
earray<skill_db_, SkillID, SkillID::MAX_SKILL_DB> skill_db;
@@ -94,7 +100,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)
{
@@ -169,16 +175,16 @@ int skill_get_castnodex(SkillID id, int lv)
int skill_additional_effect(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
SkillID skillid, int skilllv)
{
- dumb_ptr<map_session_data> sd = NULL;
- dumb_ptr<mob_data> md = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
+ dumb_ptr<mob_data> md = nullptr;
int luk;
int sc_def_mdef, sc_def_vit, sc_def_int, sc_def_luk;
int sc_def_phys_shield_spell;
- nullpo_ret(src);
- nullpo_ret(bl);
+ nullpo_retz(src);
+ nullpo_retz(bl);
if (skilllv < 0)
return 0;
@@ -256,16 +262,16 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src,
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
int type, lv, damage;
- nullpo_ret(src);
- nullpo_ret(dsrc);
- nullpo_ret(bl);
+ nullpo_retz(src);
+ nullpo_retz(dsrc);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
//何もしない判定ここから
if (dsrc->bl_m != bl->bl_m) //対象が同じマップにいなければ何もしない
return 0;
- if (src->bl_prev == NULL || dsrc->bl_prev == NULL || bl->bl_prev == NULL) //prevよくわからない※
+ if (src->bl_prev == nullptr || dsrc->bl_prev == nullptr || bl->bl_prev == nullptr) //prevよくわからない※
return 0;
if (src->bl_type == BL::PC && pc_isdead(src->is_player())) //術者?がPCですでに死んでいたら何もしない
return 0;
@@ -304,7 +310,7 @@ int skill_attack(BF attack_type, dumb_ptr<block_list> src,
battle_damage(src, bl, damage, 0);
/* ダメージがあるなら追加効果判定 */
- if (bl->bl_prev != NULL)
+ if (bl->bl_prev != nullptr)
{
dumb_ptr<map_session_data> sd = bl->is_player();
if (bl->bl_type != BL::PC || !pc_isdead(sd))
@@ -316,8 +322,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 +394,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;
/*==========================================
@@ -401,7 +408,7 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
SkillID skillid, int skilllv,
tick_t tick, BCT flag)
{
- dumb_ptr<map_session_data> sd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
nullpo_retr(1, src);
nullpo_retr(1, bl);
@@ -411,7 +418,7 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
if (sd && pc_isdead(sd))
return 1;
- if (bl->bl_prev == NULL)
+ if (bl->bl_prev == nullptr)
return 1;
if (bl->bl_type == BL::PC && pc_isdead(bl->is_player()))
return 1;
@@ -496,10 +503,10 @@ int skill_castend_damage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
int skill_castend_nodamage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
SkillID skillid, int skilllv)
{
- dumb_ptr<map_session_data> sd = NULL;
- dumb_ptr<map_session_data> dstsd = NULL;
- dumb_ptr<mob_data> md = NULL;
- dumb_ptr<mob_data> dstmd = NULL;
+ dumb_ptr<map_session_data> sd = nullptr;
+ dumb_ptr<map_session_data> dstsd = nullptr;
+ dumb_ptr<mob_data> md = nullptr;
+ dumb_ptr<mob_data> dstmd = nullptr;
int sc_def_vit, sc_def_mdef, strip_fix;
nullpo_retr(1, src);
@@ -534,7 +541,7 @@ int skill_castend_nodamage_id(dumb_ptr<block_list> src, dumb_ptr<block_list> bl,
if (strip_fix < 0)
strip_fix = 0;
- if (bl == NULL || bl->bl_prev == NULL)
+ if (bl == nullptr || bl->bl_prev == nullptr)
return 1;
if (sd && pc_isdead(sd))
return 1;
@@ -594,7 +601,7 @@ interval_t skill_castfix(dumb_ptr<block_list> bl, interval_t interval)
sc_data = battle_get_sc_data(bl);
dex = battle_get_dex(bl);
- if (skill > SkillID::MAX_SKILL_DB /*|| skill < SkillID()*/)
+ if (skill >= SkillID::MAX_SKILL_DB /*|| skill < SkillID()*/)
return interval_t::zero();
castnodex = skill_get_castnodex(skill, lv);
@@ -649,7 +656,7 @@ interval_t skill_delayfix(dumb_ptr<block_list> bl, interval_t interval)
*/
int skill_castcancel(dumb_ptr<block_list> bl, int)
{
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type == BL::PC)
{
@@ -686,11 +693,11 @@ int skill_status_change_active(dumb_ptr<block_list> bl, StatusChange type)
{
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
- nullpo_ret(bl);
+ nullpo_retz(bl);
if (bl->bl_type != BL::PC && bl->bl_type != BL::MOB)
{
if (battle_config.error_log)
- PRINTF("skill_status_change_active: neither MOB nor PC !\n");
+ PRINTF("skill_status_change_active: neither MOB nor PC !\n"_fmt);
return 0;
}
@@ -715,7 +722,7 @@ void skill_status_change_end(dumb_ptr<block_list> bl, StatusChange type, TimerDa
if (bl->bl_type != BL::PC && bl->bl_type != BL::MOB)
{
if (battle_config.error_log)
- PRINTF("skill_status_change_end: neither MOB nor PC !\n");
+ PRINTF("skill_status_change_end: neither MOB nor PC !\n"_fmt);
return;
}
sc_data = battle_get_sc_data(bl);
@@ -804,7 +811,7 @@ int skill_update_heal_animation(dumb_ptr<map_session_data> sd)
{
const Opt2 mask = Opt2::_heal;
- nullpo_ret(sd);
+ nullpo_retz(sd);
bool wis_active = bool(sd->opt2 & mask);
bool is_active = sd->quick_regeneration_hp.amount > 0;
@@ -823,14 +830,14 @@ 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;
+ dumb_ptr<map_session_data> sd = nullptr;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
//short *sc_count; //使ってない?
- if ((bl = map_id2bl(id)) == NULL)
+ if ((bl = map_id2bl(id)) == nullptr)
return;
//該当IDがすでに消滅しているというのはいかにもありそうなのでスルーしてみる
sc_data = battle_get_sc_data(bl);
@@ -844,9 +851,9 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange
if (sc_data[type].spell_invocation)
{ // Must report termination
- spell_effect_report_termination(sc_data[type].spell_invocation,
+ magic::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)
@@ -878,7 +885,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange
md->hp -= hp;
}
}
- sc_data[type].timer = Timer(tick + std::chrono::seconds(1),
+ sc_data[type].timer = Timer(tick + 1_s,
std::bind(skill_status_change_timer, ph::_1, ph::_2,
bl->bl_id, type));
return;
@@ -886,7 +893,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange
}
else
{
- sc_data[type].timer = Timer(tick + std::chrono::seconds(2),
+ sc_data[type].timer = Timer(tick + 2_s,
std::bind(skill_status_change_timer, ph::_1, ph::_2,
bl->bl_id, type));
return;
@@ -898,7 +905,7 @@ void skill_status_change_timer(TimerData *tid, tick_t tick, int id, StatusChange
/* 時間切れ無し?? */
case StatusChange::SC_WEIGHT50:
case StatusChange::SC_WEIGHT90:
- sc_data[type].timer = Timer(tick + std::chrono::minutes(10),
+ sc_data[type].timer = Timer(tick + 10_min,
std::bind(skill_status_change_timer, ph::_1, ph::_2,
bl->bl_id, type));
return;
@@ -920,14 +927,14 @@ 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;
+ dumb_ptr<map_session_data> sd = nullptr;
eptr<struct status_change, StatusChange, StatusChange::MAX_STATUSCHANGE> sc_data;
short *sc_count;
Option *option;
@@ -938,20 +945,20 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
SP updateflag = SP::ZERO;
int scdef = 0;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (not sc_data)
return 0;
sc_count = battle_get_sc_count(bl);
- nullpo_ret(sc_count);
+ nullpo_retz(sc_count);
option = battle_get_option(bl);
- nullpo_ret(option);
+ nullpo_retz(option);
opt1 = battle_get_opt1(bl);
- nullpo_ret(opt1);
+ nullpo_retz(opt1);
opt2 = battle_get_opt2(bl);
- nullpo_ret(opt2);
+ nullpo_retz(opt2);
opt3 = battle_get_opt3(bl);
- nullpo_ret(opt3);
+ nullpo_retz(opt3);
switch (type)
{
@@ -971,7 +978,7 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
else
{
if (battle_config.error_log)
- PRINTF("skill_status_change_start: neither MOB nor PC !\n");
+ PRINTF("skill_status_change_start: neither MOB nor PC !\n"_fmt);
return 0;
}
@@ -1024,12 +1031,12 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
}
// huh?
- tick = std::chrono::seconds(1);
+ tick = 1_s;
break;
case StatusChange::SC_WEIGHT50:
case StatusChange::SC_WEIGHT90:
- tick = std::chrono::minutes(10);
+ tick = 10_min;
break;
case StatusChange::SC_HASTE:
@@ -1045,7 +1052,7 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
break;
default:
if (battle_config.error_log)
- PRINTF("UnknownStatusChange [%d]\n", type);
+ PRINTF("UnknownStatusChange [%d]\n"_fmt, type);
return 0;
}
@@ -1077,7 +1084,7 @@ int skill_status_effect(dumb_ptr<block_list> bl, StatusChange type,
sc_data[type].val1 = val1;
if (sc_data[type].spell_invocation) // Supplant by newer spell
- spell_effect_report_termination(sc_data[type].spell_invocation,
+ magic::spell_effect_report_termination(sc_data[type].spell_invocation,
bl->bl_id, type, 1);
sc_data[type].spell_invocation = spell_invocation;
@@ -1109,20 +1116,20 @@ int skill_status_change_clear(dumb_ptr<block_list> bl, int type)
Opt2 *opt2;
Opt3 *opt3;
- nullpo_ret(bl);
+ nullpo_retz(bl);
sc_data = battle_get_sc_data(bl);
if (not sc_data)
return 0;
sc_count = battle_get_sc_count(bl);
- nullpo_ret(sc_count);
+ nullpo_retz(sc_count);
option = battle_get_option(bl);
- nullpo_ret(option);
+ nullpo_retz(option);
opt1 = battle_get_opt1(bl);
- nullpo_ret(opt1);
+ nullpo_retz(opt1);
opt2 = battle_get_opt2(bl);
- nullpo_ret(opt2);
+ nullpo_retz(opt2);
opt3 = battle_get_opt3(bl);
- nullpo_ret(opt3);
+ nullpo_retz(opt3);
if (*sc_count == 0)
return 0;
@@ -1175,22 +1182,22 @@ void skill_unit_timer_sub_ondelete(dumb_ptr<block_list> bl,
static
SP scan_stat(XString statname)
{
- if (statname == "str")
+ if (statname == "str"_s)
return SP::STR;
- if (statname == "dex")
+ if (statname == "dex"_s)
return SP::DEX;
- if (statname == "agi")
+ if (statname == "agi"_s)
return SP::AGI;
- if (statname == "vit")
+ if (statname == "vit"_s)
return SP::VIT;
- if (statname == "int")
+ if (statname == "int"_s)
return SP::INT;
- if (statname == "luk")
+ if (statname == "luk"_s)
return SP::LUK;
- if (statname == "none")
+ if (statname == "none"_s)
return SP::ZERO;
- FPRINTF(stderr, "Unknown stat `%s'\n", AString(statname));
+ FPRINTF(stderr, "Unknown stat `%s'\n"_fmt, AString(statname));
return SP::ZERO;
}
@@ -1199,7 +1206,7 @@ bool skill_readdb(ZString filename)
io::ReadFile in(filename);
if (!in.is_open())
{
- PRINTF("can't read %s\n", filename);
+ PRINTF("can't read %s\n"_fmt, filename);
return false;
}
@@ -1209,7 +1216,7 @@ bool skill_readdb(ZString filename)
{
// is_comment only works for whole-line comments
// that could change once the Z dependency is dropped ...
- XString comment = "//";
+ LString comment = "//"_s;
XString line = line_.xislice_h(std::search(line_.begin(), line_.end(), comment.begin(), comment.end())).rstrip();
if (!line)
continue;
@@ -1245,15 +1252,15 @@ bool skill_readdb(ZString filename)
rv = false;
continue;
}
- if (/*i < SkillID() ||*/ i > SkillID::MAX_SKILL_DB)
+ if (/*i < SkillID() ||*/ i >= SkillID::MAX_SKILL_DB)
{
rv = false;
continue;
}
- if (castcancel == "yes")
+ if (castcancel == "yes"_s)
skdb.castcancel = true;
- else if (castcancel == "no")
+ else if (castcancel == "no"_s)
skdb.castcancel = false;
else
{
@@ -1261,17 +1268,17 @@ bool skill_readdb(ZString filename)
continue;
}
- if (flags == "passive")
+ if (flags == "passive"_s)
{
skill_pool_register(i);
skdb.poolflags = SkillFlags::POOL_FLAG;
}
- else if (flags == "active")
+ else if (flags == "active"_s)
{
skill_pool_register(i);
skdb.poolflags = SkillFlags::POOL_FLAG | SkillFlags::POOL_ACTIVE;
}
- else if (flags == "no")
+ else if (flags == "no"_s)
skdb.poolflags = SkillFlags::ZERO;
else
{
@@ -1290,7 +1297,7 @@ bool skill_readdb(ZString filename)
skill_db[i] = skdb;
skill_lookup_by_id(i).desc = RString(tmp);
}
- PRINTF("read %s done\n", filename);
+ PRINTF("read %s done\n"_fmt, filename);
return rv;
}
@@ -1312,3 +1319,4 @@ skill_name_db& skill_lookup_by_name(XString name)
return ner;
return skill_names[num_names - 1];
}
+} // namespace tmwa
diff --git a/src/map/skill.hpp b/src/map/skill.hpp
index 1a615c1..ec353ce 100644
--- a/src/map/skill.hpp
+++ b/src/map/skill.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_SKILL_HPP
-#define TMWA_MAP_SKILL_HPP
+#pragma once
// skill.hpp - Old-style skills.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,17 +20,23 @@
// 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"
+#include "skill.t.hpp"
+#include "skill-pools.hpp"
-# include "../strings/fwd.hpp"
-# include "../strings/rstring.hpp"
-# include "../strings/astring.hpp"
+#include "../strings/fwd.hpp"
+#include "../strings/rstring.hpp"
+#include "../strings/literal.hpp"
-# include "map.hpp"
+#include "../generic/fwd.hpp"
+#include "../generic/array.hpp"
+#include "map.hpp"
+
+
+namespace tmwa
+{
constexpr int MAX_SKILL_PRODUCE_DB = 150;
constexpr int MAX_SKILL_ARROW_DB = 150;
constexpr int MAX_SKILL_ABRA_DB = 350;
@@ -61,11 +66,11 @@ earray<skill_db_, SkillID, SkillID::MAX_SKILL_DB> skill_db;
struct skill_name_db
{
SkillID id; // skill id
- RString name; // search strings
+ LString name; // search strings
RString desc; // description that shows up for searches
// this makes const char(&)[] not decay into const char * in {}
- skill_name_db(SkillID i, RString n, RString d)
+ skill_name_db(SkillID i, LString n, LString d)
: id(i), name(n), desc(d)
{}
};
@@ -76,9 +81,6 @@ extern struct skill_name_db skill_names[];
skill_name_db& skill_lookup_by_id(SkillID id);
skill_name_db& skill_lookup_by_name(XString name);
-struct block_list;
-struct map_session_data;
-
bool skill_readdb(ZString filename);
// スキルデータベースへのアクセサ
@@ -110,7 +112,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);
@@ -164,4 +166,4 @@ int skill_power_bl(dumb_ptr<block_list> bl, SkillID skill);
// [Fate] Remember that a certain skill ID belongs to a pool skill
void skill_pool_register(SkillID id);
-#endif // TMWA_MAP_SKILL_HPP
+} // namespace tmwa
diff --git a/src/map/skill.t.hpp b/src/map/skill.t.hpp
index 4e30cba..d0e3926 100644
--- a/src/map/skill.t.hpp
+++ b/src/map/skill.t.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_SKILL_T_HPP
-#define TMWA_MAP_SKILL_T_HPP
+#pragma once
// skill.t.hpp - Old-style skills.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,12 +20,15 @@
// 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 <cstdint>
-# include "../generic/enum.hpp"
+#include "../generic/enum.hpp"
+
+namespace tmwa
+{
// TODO remove most of these as their corresponding SkillIDs get deleted.
enum class StatusChange : uint16_t
{
@@ -131,5 +133,4 @@ enum class SkillFlags : uint16_t
ENUM_BITWISE_OPERATORS(SkillFlags)
}
using e::SkillFlags;
-
-#endif // TMWA_MAP_SKILL_T_HPP
+} // namespace tmwa
diff --git a/src/map/storage.cpp b/src/map/storage.cpp
index 89357b9..a6e6a0d 100644
--- a/src/map/storage.cpp
+++ b/src/map/storage.cpp
@@ -1,14 +1,32 @@
#include "storage.hpp"
-// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
-// For more information, see COPYING in the main folder
-
-#include <cstdlib>
-#include <cstring>
+// storage.cpp - Storage handling.
+//
+// Copyright © ????-2004 Athena Dev Teams
+// Copyright © 2004-2011 The Mana World Development Team
+// Copyright © 2011-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 "../compat/nullpo.hpp"
#include "../generic/db.hpp"
+#include "../mmo/ids.hpp"
+#include "../mmo/mmo.hpp"
+
#include "chrif.hpp"
#include "clif.hpp"
#include "intif.hpp"
@@ -18,18 +36,21 @@
#include "../poison.hpp"
+
+namespace tmwa
+{
static
-Map<int, struct storage> storage_db;
+Map<AccountId, Storage> storage_db;
void do_final_storage(void)
{
storage_db.clear();
}
-struct storage *account2storage(int account_id)
+Storage *account2storage(AccountId account_id)
{
- struct storage *stor = storage_db.search(account_id);
- if (stor == NULL)
+ Storage *stor = storage_db.search(account_id);
+ if (stor == nullptr)
{
stor = storage_db.init(account_id);
stor->account_id = account_id;
@@ -38,13 +59,13 @@ struct storage *account2storage(int account_id)
}
// Just to ask storage, without creation
-struct storage *account2storage2(int account_id)
+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);
}
@@ -55,13 +76,13 @@ void storage_delete(int account_id)
*/
int storage_storageopen(dumb_ptr<map_session_data> sd)
{
- nullpo_ret(sd);
+ nullpo_retz(sd);
if (sd->state.storage_open)
return 1; //Already open?
- struct storage *stor = storage_db.search(sd->status_key.account_id);
- if (stor == NULL)
+ Storage *stor = storage_db.search(sd->status_key.account_id);
+ if (stor == nullptr)
{ //Request storage.
intif_request_storage(sd->status_key.account_id);
return 1;
@@ -83,20 +104,19 @@ int storage_storageopen(dumb_ptr<map_session_data> sd)
*------------------------------------------
*/
static
-int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor,
- struct item *item_data, int amount)
+int storage_additem(dumb_ptr<map_session_data> sd, Storage *stor,
+ Item *item_data, int amount)
{
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);
if (!itemdb_isequip2(data))
{ //Stackable
- for (i = 0; i < MAX_STORAGE; i++)
+ for (SOff0 i : SOff0::iter())
{
if (compare_item(&stor->storage_[i], item_data))
{
@@ -110,9 +130,12 @@ int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor,
}
}
//Add item
- for (i = 0; i < MAX_STORAGE && stor->storage_[i].nameid; i++);
-
- if (i >= MAX_STORAGE)
+ SOff0 i = *std::find_if(SOff0::iter().begin(), SOff0::iter().end(),
+ [&stor](SOff0 i_)
+ {
+ return !stor->storage_[i_].nameid;
+ });
+ if (!i.ok())
return 1;
stor->storage_[i] = *item_data;
@@ -129,17 +152,17 @@ int storage_additem(dumb_ptr<map_session_data> sd, struct storage *stor,
*------------------------------------------
*/
static
-int storage_delitem(dumb_ptr<map_session_data> sd, struct storage *stor,
- int n, int amount)
+int storage_delitem(dumb_ptr<map_session_data> sd, Storage *stor,
+ SOff0 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;
if (stor->storage_[n].amount == 0)
{
- stor->storage_[n] = item{};
+ stor->storage_[n] = Item{};
stor->storage_amount--;
clif_updatestorageamount(sd, stor);
}
@@ -153,21 +176,21 @@ int storage_delitem(dumb_ptr<map_session_data> sd, struct storage *stor,
* Add an item to the storage from the inventory.
*------------------------------------------
*/
-int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount)
+int storage_storageadd(dumb_ptr<map_session_data> sd, IOff0 index, int amount)
{
- struct storage *stor;
+ Storage *stor;
- nullpo_ret(sd);
+ nullpo_retz(sd);
stor = account2storage2(sd->status_key.account_id);
- nullpo_ret(stor);
+ nullpo_retz(stor);
if ((stor->storage_amount > MAX_STORAGE) || !stor->storage_status)
return 0; // storage full / storage closed
- if (index < 0 || index >= MAX_INVENTORY)
+ if (!index.ok())
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)
@@ -188,19 +211,19 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, int index, int amount)
* Retrieve an item from the storage.
*------------------------------------------
*/
-int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount)
+int storage_storageget(dumb_ptr<map_session_data> sd, SOff0 index, int amount)
{
- struct storage *stor;
+ Storage *stor;
PickupFail flag;
- nullpo_ret(sd);
+ nullpo_retz(sd);
stor = account2storage2(sd->status_key.account_id);
- nullpo_ret(stor);
+ nullpo_retz(stor);
- if (index < 0 || index >= MAX_STORAGE)
+ if (!index.ok())
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)
@@ -209,7 +232,7 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount)
if ((flag = pc_additem(sd, &stor->storage_[index], amount)) == PickupFail::OKAY)
storage_delitem(sd, stor, index, amount);
else
- clif_additem(sd, 0, 0, flag);
+ clif_additem(sd, IOff0::from(0), 0, flag);
// log_fromstorage(sd, index, 0);
return 1;
}
@@ -220,11 +243,11 @@ int storage_storageget(dumb_ptr<map_session_data> sd, int index, int amount)
*/
int storage_storageclose(dumb_ptr<map_session_data> sd)
{
- struct storage *stor;
+ Storage *stor;
- nullpo_ret(sd);
+ nullpo_retz(sd);
stor = account2storage2(sd->status_key.account_id);
- nullpo_ret(stor);
+ nullpo_retz(stor);
clif_storageclose(sd);
if (stor->storage_status)
@@ -252,9 +275,9 @@ int storage_storageclose(dumb_ptr<map_session_data> sd)
*/
int storage_storage_quit(dumb_ptr<map_session_data> sd)
{
- struct storage *stor;
+ Storage *stor;
- nullpo_ret(sd);
+ nullpo_retz(sd);
stor = account2storage2(sd->status_key.account_id);
if (stor)
@@ -267,9 +290,9 @@ 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;
+ Storage *stor;
stor = account2storage2(account_id);
if (!stor)
@@ -295,9 +318,9 @@ 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);
+ Storage *stor = account2storage2(account_id);
if (stor)
{
@@ -311,3 +334,4 @@ int storage_storage_saved(int account_id)
}
return 0;
}
+} // namespace tmwa
diff --git a/src/map/storage.hpp b/src/map/storage.hpp
index 702c908..f3875c8 100644
--- a/src/map/storage.hpp
+++ b/src/map/storage.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_STORAGE_HPP
-#define TMWA_MAP_STORAGE_HPP
+#pragma once
// storage.hpp - Storage handling.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,19 +20,25 @@
// 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"
+#include "../generic/fwd.hpp"
+#include "../mmo/fwd.hpp"
+
+#include "clif.t.hpp"
+
+
+namespace tmwa
+{
int storage_storageopen(dumb_ptr<map_session_data> sd);
-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_storageadd(dumb_ptr<map_session_data> sd, IOff0 index, int amount);
+int storage_storageget(dumb_ptr<map_session_data> sd, SOff0 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);
+Storage *account2storage(AccountId account_id);
+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);
-
-#endif // TMWA_MAP_STORAGE_HPP
+int storage_storage_save(AccountId account_id, int final);
+int storage_storage_saved(AccountId account_id);
+} // namespace tmwa
diff --git a/src/map/tmw.cpp b/src/map/tmw.cpp
index 46128d1..60b5027 100644
--- a/src/map/tmw.cpp
+++ b/src/map/tmw.cpp
@@ -19,17 +19,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 <cctype>
-#include <cstring>
-
#include "../compat/nullpo.hpp"
#include "../strings/astring.hpp"
#include "../strings/zstring.hpp"
#include "../strings/xstring.hpp"
+#include "../strings/literal.hpp"
#include "../io/cxxstdio.hpp"
+#include "../mmo/human_time_diff.hpp"
+#include "../mmo/utils.hpp"
+
#include "atcommand.hpp"
#include "battle.hpp"
#include "chrif.hpp"
@@ -40,6 +41,9 @@
#include "../poison.hpp"
+
+namespace tmwa
+{
static
void tmw_AutoBan(dumb_ptr<map_session_data> sd, ZString reason, int length);
static
@@ -91,7 +95,7 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message)
{
sd->chat_lines_in = sd->chat_total_repeats = 0;
- tmw_AutoBan(sd, "chat", battle_config.chat_spam_ban);
+ tmw_AutoBan(sd, "chat"_s, battle_config.chat_spam_ban);
return 1;
}
@@ -100,8 +104,8 @@ int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message)
(sd->chat_lines_in >= battle_config.chat_spam_warn
|| sd->chat_total_repeats >= battle_config.chat_spam_warn))
{
- clif_displaymessage(sd->sess, "WARNING: You are about to be automatically banned for spam!");
- clif_displaymessage(sd->sess, "WARNING: Please slow down, do not repeat, and do not SHOUT!");
+ clif_displaymessage(sd->sess, "WARNING: You are about to be automatically banned for spam!"_s);
+ clif_displaymessage(sd->sess, "WARNING: Please slow down, do not repeat, and do not SHOUT!"_s);
}
return 0;
@@ -114,23 +118,23 @@ void tmw_AutoBan(dumb_ptr<map_session_data> sd, ZString reason, int length)
sd->auto_ban_info.in_progress = 1;
- AString hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam",
+ AString hack_msg = STRPRINTF("[GM] %s has been autobanned for %s spam"_fmt,
sd->status_key.name,
reason);
tmw_GmHackMsg(hack_msg);
- AString fake_command = STRPRINTF("@autoban %s %dh (%s spam)",
+ AString fake_command = STRPRINTF("@autoban %s %dh (%s spam)"_fmt,
sd->status_key.name, length, reason);
log_atcommand(sd, fake_command);
- AString anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam.",
+ AString anotherbuf = STRPRINTF("You have been banned for %s spamming. Please do not spam."_fmt,
reason);
clif_displaymessage(sd->sess, anotherbuf);
/* 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 +163,7 @@ 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);
}
+} // namespace tmwa
diff --git a/src/map/tmw.hpp b/src/map/tmw.hpp
index 670599e..ffd6f7f 100644
--- a/src/map/tmw.hpp
+++ b/src/map/tmw.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_TMW_HPP
-#define TMWA_MAP_TMW_HPP
+#pragma once
// tmw.hpp - Some random functions added by TMW.
//
// Copyright © 2004-2011 The Mana World Development Team
@@ -20,15 +19,15 @@
// 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 "../strings/fwd.hpp"
-# include "../mmo/dumb_ptr.hpp"
+#include "../generic/fwd.hpp"
-# include "map.hpp"
+namespace tmwa
+{
int tmw_CheckChatSpam(dumb_ptr<map_session_data> sd, XString message);
void tmw_GmHackMsg(ZString line);
-
-#endif // TMWA_MAP_TMW_HPP
+} // namespace tmwa
diff --git a/src/map/trade.cpp b/src/map/trade.cpp
index c877d00..c52377d 100644
--- a/src/map/trade.cpp
+++ b/src/map/trade.cpp
@@ -34,21 +34,24 @@
#include "../poison.hpp"
+
+namespace tmwa
+{
/*==========================================
* 取引要請を相手に送る
*------------------------------------------
*/
-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;
nullpo_retv(sd);
- if ((target_sd = map_id2sd(target_id)) != NULL)
+ if ((target_sd = map_id2sd(target_id)) != nullptr)
{
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 +63,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 +100,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))) != nullptr)
{
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]
@@ -123,7 +126,7 @@ 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_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount)
{
dumb_ptr<map_session_data> target_sd;
struct item_data *id;
@@ -131,30 +134,29 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
int trade_weight = 0;
int free_ = 0;
int c;
- int i;
nullpo_retv(sd);
- if (((target_sd = map_id2sd(sd->trade_partner)) != NULL)
+ if (((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr)
&& (sd->deal_locked < 1))
{
- if (index < 2 || index >= MAX_INVENTORY + 2)
+ if (!index.ok())
{
- if (index == 0 && amount > 0 && amount <= sd->status.zeny)
+ if (index.index == 0 && amount > 0 && amount <= sd->status.zeny)
{
sd->deal_zeny = amount;
- clif_tradeadditem(sd, target_sd, 0, amount);
+ clif_tradeadditem(sd, target_sd, index, amount);
}
}
// note: amount is overridden below!
- else if (amount <= sd->status.inventory[index - 2].amount
+ else if (amount <= sd->status.inventory[index.unshift()].amount
&& amount > 0)
{
// determine free slots of receiver
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
- if (target_sd->status.inventory[i].nameid == 0
- && target_sd->inventory_data[i] == NULL)
+ if (!target_sd->status.inventory[i].nameid
+ && target_sd->inventory_data[i] == nullptr)
free_++;
}
for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
@@ -163,14 +165,14 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
{
// calculate trade weight
trade_weight +=
- sd->inventory_data[index - 2]->weight * amount;
+ sd->inventory_data[index.unshift()]->weight * amount;
// determine if item is a stackable already in receivers inventory, and up free count
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (target_sd->status.inventory[i].nameid ==
- sd->status.inventory[index - 2].nameid
- && target_sd->inventory_data[i] != NULL)
+ sd->status.inventory[index.unshift()].nameid
+ && target_sd->inventory_data[i] != nullptr)
{
id = target_sd->inventory_data[i];
if (id->type != ItemType::WEAPON
@@ -205,7 +207,7 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
return;
}
}
- pc_unequipinvyitem(sd, index - 2, CalcStatus::NOW);
+ pc_unequipinvyitem(sd, index.unshift(), CalcStatus::NOW);
sd->deal_item_index[trade_i] = index;
sd->deal_item_amount[trade_i] += amount;
clif_tradeitemok(sd, index, amount, 0); //success to add item
@@ -217,16 +219,16 @@ void trade_tradeadditem(dumb_ptr<map_session_data> sd, int index, int amount)
{
// calculate weight for stored deal
trade_weight +=
- sd->inventory_data[sd->deal_item_index[trade_i] -
- 2]->weight *
+ sd->inventory_data[sd->deal_item_index[trade_i].unshift()
+ ]->weight *
sd->deal_item_amount[trade_i];
// count free stackables in stored deal
- for (i = 0; i < MAX_INVENTORY; i++)
+ for (IOff0 i : IOff0::iter())
{
if (target_sd->status.inventory[i].nameid ==
sd->status.
- inventory[sd->deal_item_index[trade_i] - 2].nameid
- && target_sd->inventory_data[i] != NULL)
+ inventory[sd->deal_item_index[trade_i].unshift()].nameid
+ && target_sd->inventory_data[i] != nullptr)
{
id = target_sd->inventory_data[i];
if (id->type != ItemType::WEAPON
@@ -260,11 +262,11 @@ void trade_tradeok(dumb_ptr<map_session_data> sd)
for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
{
- int index = sd->deal_item_index[trade_i];
- if (index < 2 || index >= MAX_INVENTORY + 2)
+ IOff2 index = sd->deal_item_index[trade_i];
+ if (!index.ok())
continue;
if (sd->deal_item_amount[trade_i] >
- sd->status.inventory[index - 2].amount
+ sd->status.inventory[index.unshift()].amount
|| sd->deal_item_amount[trade_i] < 0)
{
trade_tradecancel(sd);
@@ -273,10 +275,10 @@ 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))) != nullptr)
{
sd->deal_locked = 1;
- clif_tradeitemok(sd, 0, 0, 0);
+ clif_tradeitemok(sd, IOff2::from(0), 0, 0);
clif_tradedeal_lock(sd, 0);
clif_tradedeal_lock(target_sd, 1);
}
@@ -293,26 +295,28 @@ 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))) != nullptr)
{
for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
{ //give items back (only virtual)
if (sd->deal_item_amount[trade_i] != 0)
{
+ assert (sd->deal_item_index[trade_i].ok());
clif_additem(sd,
- sd->deal_item_index[trade_i] - 2,
+ sd->deal_item_index[trade_i].unshift(),
sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- sd->deal_item_index[trade_i] = 0;
+ sd->deal_item_index[trade_i] = IOff2::from(0);
sd->deal_item_amount[trade_i] = 0;
}
if (target_sd->deal_item_amount[trade_i] != 0)
{
+ assert (target_sd->deal_item_index[trade_i].ok());
clif_additem(target_sd,
- target_sd->deal_item_index[trade_i] - 2,
+ target_sd->deal_item_index[trade_i].unshift(),
target_sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- target_sd->deal_item_index[trade_i] = 0;
+ target_sd->deal_item_index[trade_i] = IOff2::from(0);
target_sd->deal_item_amount[trade_i] = 0;
}
}
@@ -327,9 +331,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,11 +350,11 @@ 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))) != nullptr)
{
- MAP_LOG_PC(sd, " TRADECOMMIT WITH %d GIVE %d GET %d",
- target_sd->status_key.char_id, sd->deal_zeny,
- target_sd->deal_zeny);
+ MAP_LOG_PC(sd, " TRADECOMMIT WITH %d GIVE %d GET %d"_fmt,
+ target_sd->status_key.char_id, sd->deal_zeny,
+ target_sd->deal_zeny);
if ((sd->deal_locked >= 1) && (target_sd->deal_locked >= 1))
{ // both have pressed 'ok'
if (sd->deal_locked < 2)
@@ -363,23 +367,24 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
{
sd->deal_zeny = 0;
trade_tradecancel(sd);
- MAP_LOG_PC(sd, " TRADECANCEL");
+ MAP_LOG_PC(sd, " TRADECANCEL"_fmt);
return;
}
if (target_sd->deal_zeny > target_sd->status.zeny)
{
target_sd->deal_zeny = 0;
trade_tradecancel(sd);
- MAP_LOG_PC(sd, " TRADECANCEL");
+ 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)
{
- int n = sd->deal_item_index[trade_i] - 2;
+ assert (sd->deal_item_index[trade_i].ok());
+ IOff0 n = sd->deal_item_index[trade_i].unshift();
PickupFail flag = pc_additem(target_sd,
&sd->status.inventory[n],
sd->deal_item_amount[trade_i]);
@@ -390,12 +395,13 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
clif_additem(sd, n,
sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- sd->deal_item_index[trade_i] = 0;
+ sd->deal_item_index[trade_i] = IOff2::from(0);
sd->deal_item_amount[trade_i] = 0;
}
if (target_sd->deal_item_amount[trade_i] != 0)
{
- int n = target_sd->deal_item_index[trade_i] - 2;
+ assert (target_sd->deal_item_index[trade_i].ok());
+ IOff0 n = target_sd->deal_item_index[trade_i].unshift();
PickupFail flag = pc_additem(sd,
&target_sd->status.inventory[n],
target_sd->deal_item_amount[trade_i]);
@@ -405,10 +411,9 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
1);
else
clif_additem(target_sd, n,
-
target_sd->deal_item_amount[trade_i],
PickupFail::OKAY);
- target_sd->deal_item_index[trade_i] = 0;
+ target_sd->deal_item_index[trade_i] = IOff2::from(0);
target_sd->deal_item_amount[trade_i] = 0;
}
}
@@ -434,7 +439,7 @@ void trade_tradecommit(dumb_ptr<map_session_data> sd)
target_sd->deal_locked = 0;
clif_tradecompleted(sd, 0);
clif_tradecompleted(target_sd, 0);
- MAP_LOG_PC(sd, " TRADEOK");
+ MAP_LOG_PC(sd, " TRADEOK"_fmt);
}
}
}
@@ -449,14 +454,15 @@ 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))) != nullptr)
{
if (sd->deal_zeny > sd->status.zeny)
{
if (sd->deal_locked < 1)
- trade_tradeadditem(sd, 0, sd->status.zeny); // Fix money ammount
+ trade_tradeadditem(sd, IOff2::from(0), sd->status.zeny); // Fix money ammount
else
trade_tradecancel(sd); // Or cancel the trade if we can't fix it
}
}
}
+} // namespace tmwa
diff --git a/src/map/trade.hpp b/src/map/trade.hpp
index dc81c54..91ed954 100644
--- a/src/map/trade.hpp
+++ b/src/map/trade.hpp
@@ -1,5 +1,4 @@
-#ifndef TMWA_MAP_TRADE_HPP
-#define TMWA_MAP_TRADE_HPP
+#pragma once
// trade.hpp - Inter-player item and money transactions.
//
// Copyright © ????-2004 Athena Dev Teams
@@ -21,16 +20,20 @@
// 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"
+#include "../generic/fwd.hpp"
-void trade_traderequest(dumb_ptr<map_session_data> sd, int target_id);
+#include "clif.t.hpp"
+
+
+namespace tmwa
+{
+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_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount);
void trade_tradeok(dumb_ptr<map_session_data> sd);
void trade_tradecancel(dumb_ptr<map_session_data> sd);
void trade_tradecommit(dumb_ptr<map_session_data> sd);
void trade_verifyzeny(dumb_ptr<map_session_data> sd);
-
-#endif // TMWA_MAP_TRADE_HPP
+} // namespace tmwa